我正在使用Novocaine框架來執行音調檢測。一切正常 - 只有使用圖形FFT表示,纔會出現一些問題。IOS和FFT(vDSP_fft_zrip):頻率低於appr。 100赫茲被切斷 - 爲什麼?
當我使用音頻文件輸入時,FFT工作正常 - 低於100赫茲的頻率顯示完美。
取而代之,當我使用麥克風作爲輸入時,100 Hz以下的頻率根本沒有顯示 - 我找不出原因!請參閱以下屏幕截圖:
正確顯示較高頻率(例如1000 Hz)!
這裏的FFT程序的源代碼:
- (NSMutableArray*)performFFT: (float*) data withFrames: (int) numSamples {
// 1. init
float bufferSize = numSamples;
uint32_t maxFrames = numSamples;
displayData = (float*)malloc(maxFrames*sizeof(float));
bzero(displayData, maxFrames*sizeof(float));
int log2n = log2f(maxFrames);
int n = 1 << log2n;
assert(n == maxFrames);
float nOver2 = maxFrames/2;
A.realp = (float*)malloc(nOver2 * sizeof(float));
A.imagp = (float*)malloc(nOver2 * sizeof(float));
fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);
// 2. calcuate
bufferSize = numSamples;
float ln = log2f(numSamples);
vDSP_ctoz((COMPLEX*)data, 2, &A, 1, numSamples/2);
//fft
vDSP_fft_zrip(fftSetup, &A, 1, ln, FFT_FORWARD);
// Absolute square (equivalent to mag^2)
vDSP_zvmags(&A, 1, A.realp, 1, numSamples/2);
// make imaginary part to zero in order to filter them out in the following loop
bzero(A.imagp, (numSamples/2) * sizeof(float));
//convert complex split to real
vDSP_ztoc(&A, 1, (COMPLEX*)displayData, 2, numSamples/2);
// Normalize
float scale = 1.f/displayData[0];
vDSP_vsmul(displayData, 1, &scale, displayData, 1, numSamples);
//scale fft
Float32 mFFTNormFactor = 1.0/(2*numSamples);
vDSP_vsmul(A.realp, 1, &mFFTNormFactor, A.realp, 1, numSamples/2);
vDSP_vsmul(A.imagp, 1, &mFFTNormFactor, A.imagp, 1, numSamples/2);
...
}
爲進一步圖形化的問題,我用displayData。由於我對較低頻率感興趣(有一個獨立的基音檢測算法,可以很好地工作),我將採樣率降低到了11.025(而不是44100)。
在奴佛卡因,我提出以下電話:
1)輸入
[audioManager setInputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels) {
// frequency analysis
vDSP_rmsqv(data, 1, &magnitude, numFrames*numChannels);
self->ringBuffer->AddNewInterleavedFloatData(data, numFrames, numChannels);
...
}
2)輸出:
[audioManager setOutputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels)
{
self->ringBuffer->FetchInterleavedData(data, numFrames, numChannels);
....
[fft performFFT:data withFrames:numFrames];
...
}
有人有想法嗎?
謝謝marko! 我試過了,但沒有任何效果。 我不認爲這是問題的根源 - 我不能告訴你爲什麼: 我用一種自相關來執行音高檢測。音高檢測非常適用於從20 Hz到1000 Hz的所有頻率,因此200 Hz以下的頻率不會被切斷 - 我使用相同的硬件和相同的Novocaine架構。相反,當我切換到FFT時,200 Hz以下的所有頻率都被切斷。對我來說,這似乎很奇怪...... –
看到我對FFT精度低頻效果窗口的建議。你的窗戶大小是多少? 您可能還想將一個方形窗口以外的東西應用於FFT。 – marko
Hi Marko,老實說,我不知道與FFT結合的「開窗」。我知道採樣率,但不知道窗口大小。我怎樣才能實現這樣的窗口? –