Я смотрю пример приложения aurioTouch для iPhone SDK. Он имеет базовый анализатор спектра , реализованный при выборе опции «БПФ». Одной из вещей, которой не хватает в приложении, являются метки оси X (то есть метки частоты).
В файле aurioTouchAppDelegate.mm , в функции - (void)drawOscilloscope
в строке 652 он имеет следующий код:
if (displayMode == aurioTouchDisplayModeOscilloscopeFFT)
{
if (fftBufferManager->HasNewAudioData())
{
if (fftBufferManager->ComputeFFT(l_fftData))
[self setFFTData:l_fftData length:fftBufferManager->GetNumberFrames() / 2];
else
hasNewFFTData = NO;
}
if (hasNewFFTData)
{
int y, maxY;
maxY = drawBufferLen;
for (y=0; y<maxY; y++)
{
CGFloat yFract = (CGFloat)y / (CGFloat)(maxY - 1);
CGFloat fftIdx = yFract * ((CGFloat)fftLength);
double fftIdx_i, fftIdx_f;
fftIdx_f = modf(fftIdx, &fftIdx_i);
SInt8 fft_l, fft_r;
CGFloat fft_l_fl, fft_r_fl;
CGFloat interpVal;
fft_l = (fftData[(int)fftIdx_i] & 0xFF000000) >> 24;
fft_r = (fftData[(int)fftIdx_i + 1] & 0xFF000000) >> 24;
fft_l_fl = (CGFloat)(fft_l + 80) / 64.;
fft_r_fl = (CGFloat)(fft_r + 80) / 64.;
interpVal = fft_l_fl * (1. - fftIdx_f) + fft_r_fl * fftIdx_f;
interpVal = CLAMP(0., interpVal, 1.);
drawBuffers[0][y] = (interpVal * 120);
}
cycleOscilloscopeLines();
}
}
Насколько я понимаю, эта часть кода используется для определения того, какую величину рисовать для каждой частоты в пользовательском интерфейсе. Мой вопрос заключается в том, как определить частоту каждой итерации (или значение y
) внутри цикла for
.
Например, если я хочу узнать, какова величина для 6 кГц, я подумываю добавить строку, подобную следующей:
if (yValueRepresentskHz(y, 6))
NSLog(@"The magnitude for 6kHz is %f", (interpVal * 120));
Обратите внимание, что хотя они решили использовать имя переменной y
, насколько я понимаю, она фактически представляет ось x на визуальном графике анализатора спектра и значение drawBuffers[0][y]
представляет ось Y.