【发布时间】:2010-06-01 12:59:25
【问题描述】:
我正在查看 iPhone SDK 的 aurioTouch sample application。当您选择“FFT”选项时,它有一个基本的spectrum analyzer 实现。该应用缺少的一件事是 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();
}
}
据我了解,这部分代码用于决定在 UI 中为每个频率绘制哪个幅度。我的问题是如何确定每次迭代(或y 值)在for 循环内代表的频率。
例如,如果我想知道 6kHz 的幅度是多少,我正在考虑添加类似于以下内容的行:
if (yValueRepresentskHz(y, 6))
NSLog(@"The magnitude for 6kHz is %f", (interpVal * 120));
请注意,虽然他们选择使用变量名y,但据我了解,它实际上代表频谱分析仪可视图表中的x轴,以及drawBuffers[0][y]的值表示y轴。
【问题讨论】: