我是音频信号处理的初学者 现在我尝试实现音高检测算法 我找到了一些倒谱的步骤
result1 = IFFT(log(abs(FFT(Audio Input))))
peak = max(result);
out_frequency = 1/peak; // last step
因此,我使用kissfft和portaudio作为FFT和IFFT的库,在C中实现这些算法 问题是在我得到IFFT结果并做最后一步提取频率后,结果不是我所期待的。 (注意。我通过在音符A(440Hz)中唱歌来测试
我不确定我是否错过了倒谱的最后一步,或者我做错了。
要测试的麦克风是我的笔记本电脑麦克风,我知道它是一台电容麦克风。 我应该将MIC更改为动态麦克风,还是可以使用普通的Labtop麦克风
听到我已经实施的代码
kiss_fft_cpx cin[FFT_SIZE];
kiss_fft_cpx cout[FFT_SIZE];
kiss_fft_cpx fftBins[FFT_SIZE];
for ( i = 0; i <FFT_SIZE; i++){
cin[i].r = zero;
cin[i].i = zero;
cout[i].r = zero;
cout[i].i = zero;
fftBins[i].r = zero;
fftBins[i].i = zero;
}
for(j=0;j < FFT_SIZE;j++){
cin[j].r = *in++ ;
}
kiss_fftr_cfg fftConfiguration = kiss_fftr_alloc( FFT_SIZE, 0, NULL, NULL );
kiss_fftr_cfg ifftConfiguration = kiss_fftr_alloc( FFT_SIZE, 1, NULL, NULL );
// FFT...
kiss_fftr( fftConfiguration, (kiss_fft_scalar*)cin, fftBins );
for(i = 0; i<FFT_SIZE;i++){
fftBins[i].i = log(fabs(fftBins[i].r));
fftBins[i].r = zero;
}
// iFFT...
kiss_fftri( ifftConfiguration, fftBins, (kiss_fft_scalar*)cout );
double maxi = 0;
double maxr = 0;
for(i = 0; i<FFT_SIZE;i++){
if(maxi<cout[j].i){
maxi = cout[j].i;
}
if(maxr<cout[j].r){
maxr = cout[j].r;
}
}
printf("%f\t%f\n",maxi,maxr);
double result;
result = 1./maxr;
printf("result = %f\n",result);
free(fftConfiguration);
free(ifftConfiguration);
方面
答案 0 :(得分:1)
您正在创建一个复杂的数组(kiss_fft_cpx),然后将其用作实数组(kiss_fft_scalar)。你需要使用kiss_fft_scalar将你的麦克风样本发送给kiss_fftr。
真实fft返回N / 2 + 1个复杂点。
计算幅度时,不要忽略虚部。您可以使用sqrt(re ^ 2 + im ^ 2)或跳过sqrt而不影响倒谱的峰值。
需要根据fft大小和采样频率调整感兴趣的频率。