私は信号処理にかなり慣れていないので、ご容赦ください。iPad から取得したオーディオ録音に適用するバンドパス フィルターを実装しようとしています。録音は、ExtFile 関数と AudioBufferList を使用して Float32 ポインターに変換されています。サンプリングレートは44100Hzです。録音の長さは約 9 秒 (約 396900 サンプル) で、2 ~ 6kHz のチャープと周囲のノイズが含まれています。どの時点でチャープが発生するかを見つけるために、2 ~ 6kHz の周波数範囲で録音をバンドパス フィルター処理する必要があります。バンドパス フィルターを作成するために、次のリソースを参照しました。
https://github.com/bartolsthoorn/NVDSP/blob/master/NVDSP.mm
https://github.com/bartolsthoorn/NVDSP/blob/master/Filters/NVBandpassFilter.m
私の質問は、録音用の float 値の配列を上記のバンドパス フィルターに単純に渡すことはできますか? これを試してみましたが、配列内のすべての値の値を単純に減らすように見えるため、機能しているかどうかはわかりません。レコーディングを通過した後、何が見られると期待すべきですか
ただし、最初に FFT を使用して値を時間領域から周波数領域に変換する必要があると言うリソースを見たことがあります。いくつかの vDSP 関数を使用してこれを行うために、次のコードを試しました。
- (Float32 *)calculateFFT
{
// Acquired from http://batmobile.blogs.ilrt.org/fourier-transforms-on-an-iphone/
int numSamples = _recordingLength; //~9 seconds * 44100Hz ~= 396900 samples
// Setup the length
vDSP_Length log2n = log2f(numSamples);
// Calculate the weights array. This is a one-off operation.
FFTSetup fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);
// For an FFT, numSamples must be a power of 2, i.e. is always even
int nOver2 = numSamples/2;
// Populate *window with the values for a hamming window function
float *window = (float *)malloc(sizeof(float) * numSamples);
vDSP_hamm_window(window, numSamples, 0);
// Window the samples
vDSP_vmul(_recordingSamples, 1, window, 1, _recordingSamples, 1, numSamples);
// Define complex buffer
COMPLEX_SPLIT A;
A.realp = (float *) malloc(nOver2*sizeof(float));
A.imagp = (float *) malloc(nOver2*sizeof(float));
// Pack samples:
// C(re) -> A[n], C(im) -> A[n+1]
vDSP_ctoz((COMPLEX*)_recordingSamples, 2, &A, 1, numSamples/2);
//Perform a forward FFT using fftSetup and A
//Results are returned in A
vDSP_fft_zrip(fftSetup, &A, 1, log2n, FFT_FORWARD);
//Convert COMPLEX_SPLIT A result to magnitudes
Float32 *amp = new Float32[numSamples];
amp[0] = A.realp[0]/(numSamples*2);
for(int i=1; i<numSamples; i++) {
amp[i]=A.realp[i]*A.realp[i]+A.imagp[i]*A.imagp[i];
//printf("%f ",amp[i]);
}
return amp;
}
しかし、この関数から何が返されているのかわかりません。録音をフィルターに渡す前に FFT を適用する必要がある場合、calculateFFT 関数から何を返してフィルターに渡す必要がありますか?
前もって感謝します。