// get the data
AudioUnitRender(...);
// convert int16 to float
Convert(...);
// divide the signal into even-odd configuration
vDSP_ctoz((COMPLEX*)outputBuffer, 2, &A, 1, nOver2);
// apply the fft
vDSP_fft_zrip(fftSetup, &A, stride, log2n, FFT_FORWARD);
// convert split real form to split vector
vDSP_ztoc(&A, 1, (COMPLEX *)outputBuffer, 2, nOver2);
接着,Demetri 根据以下方法确定“主导”频率:
float dominantFrequency = 0;
int bin = -1;
for (int i=0; i<n; i+=2) {
float curFreq = MagnitudeSquared(outputBuffer[i], outputBuffer[i+1]);
if (curFreq > dominantFrequency) {
dominantFrequency = curFreq;
bin = (i+1)/2;
}
}
memset(outputBuffer, 0, n*sizeof(SInt16));
// Update the UI with our newly acquired frequency value.
[THIS->listener frequencyChangedWithValue:bin*(THIS->sampleRate/bufferCapacity)];
首先,我认为需要应用低通滤波器...但我不是FFT专家,也不确定在哪里或如何对从vDSP函数返回的数据执行该操作。我也不确定如何提高低频代码的准确性。似乎有其他算法可以确定主导频率 - 但再次,希望在使用苹果加速框架返回的数据时给出正确的方向指引。
更新:
加速框架实际上有一些窗口函数。我设置了一个基本的窗口,如下所示:
windowSize = maxFrames;
transferBuffer = (float*)malloc(sizeof(float)*windowSize);
window = (float*)malloc(sizeof(float)*windowSize);
memset(window, 0, sizeof(float)*windowSize);
vDSP_hann_window(window, windowSize, vDSP_HANN_NORM);
我随后应用它,通过插入。
vDSP_vmul(outputBuffer, 1, window, 1, transferBuffer, 1, windowSize);
在vDSP_ctoz函数之前。然后我更改了其余的代码,使用“transferBuffer”而不是“outputBuffer”...但到目前为止,没有注意到最终音高猜测有任何显著变化。