我对信号处理相当陌生,所以请多多包涵。我正在尝试实现一个带通滤波器以应用于从 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
我的问题是,我可以简单地将用于记录的浮点值数组传递给上面的带通滤波器吗?我已经尝试过了,但我不确定它是否有效,因为它似乎只是减少了数组中每个值的值。通过录音后我应该看到什么
但是,我看到一些资源说我首先需要使用 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 函数返回什么然后传递给过滤器?
提前致谢。