UPDATE 2016-03-15
请看这个项目:https://github.com/ooper-shlab/aurioTouch2.0-Swift.它已经移植到Swift,并包含你要找的所有答案,如果你在这里凸轮.
我做了大量的研究,并学到了很多关于FFT和加速框架.但经过几天的实验,我感到很沮丧.
我想在图中播放时显示音频文件的频谱.对于每个时间间隔,应在X轴上通过FFT计算的每个频率(在我的情况下为512个值)中显示Y轴上的数值(以红色条显示).
输出应如下所示:
我填写一个1024个样本的缓冲区,仅提取左侧通道开始.然后我做所有这些FFT的东西.
这是我的代码到目前为止
设置一些变量
- (void)setupVars { maxSamples = 1024; log2n = log2f(maxSamples); n = 1 << log2n; stride = 1; nOver2 = maxSamples/2; A.realp = (float *) malloc(nOver2 * sizeof(float)); A.imagp = (float *) malloc(nOver2 * sizeof(float)); memset(A.imagp,nOver2 * sizeof(float)); obtainedReal = (float *) malloc(n * sizeof(float)); originalReal = (float *) malloc(n * sizeof(float)); setupReal = vDSP_create_fftsetup(log2n,FFT_RADIX2); }
进行FFT. FrequencyArray只是一个包含512个浮点值的数据结构.
- (FrequencyArry)performFastFourierTransformForSampleData:(SInt16*)sampleData andSampleRate:(UInt16)sampleRate { NSLog(@"log2n %i n %i,nOver2 %i",log2n,n,nOver2); // n = 1024 // log2n 10 // nOver2 = 512 for (int i = 0; i < n; i++) { originalReal[i] = (float) sampleData[i]; } vDSP_ctoz((COMPLEX *) originalReal,2,&A,1,nOver2); vDSP_fft_zrip(setupReal,stride,FFT_FORWARD); float scale = (float) 1.0 / (2 * n); vDSP_vsmul(A.realp,&scale,A.realp,nOver2); vDSP_vsmul(A.imagp,A.imagp,nOver2); vDSP_ztoc(&A,(COMPLEX *) obtainedReal,nOver2); FrequencyArry frequencyArray; for (int i = 0; i < nOver2; i++) { frequencyArray.frequency[i] = log10f(obtainedReal[i]); // Magnitude in db??? } return frequencyArray; }
输出看起来总是有点奇怪,虽然它有些似乎根据音乐移动.
我很高兴我来到这么远,感谢一些非常好的帖子,像这样:
Using the apple FFT and accelerate Framework
但现在我不知道该怎么办我失踪了什么
解决方法
首先,在FFT之前您不应用
window function,这将导致
spectral leakage发生频谱的拖延.
其次,您正在使用FFT输出槽的实际分量来计算dB幅度 – 您需要使用复数幅度:
magnitude_dB = 10 * log10(re * re + im * im);