我想把FFT应用到真正的音频设备上,并计算出它的峰值。
这是我的密码。
N=8192
kiss_fft_cpx out[N/2 +1];
int len = fft->N / 2 + 1;
kiss_fft_scalar* samples = &samples2[0]; //inputs from the mic
kiss_fftr(fft->config, samples, out);
for (int i = 0; i < len; i++) {
float re = scale(out[i].r) * N;
float im = scale(out[i].i) * N;
if (i > 0)
spectrum[i] = sqrtf(re * re + im * im) / (N / 2);
else
spectrum[i] = sqrtf(re * re + im * im) / N;
}现在,我使用代码计算挑选。但是每次它返回0
float peak = 0;
float maxEnergy = 0;
for (int i = 0; i < BUFFER_SIZE / 2 + 1; i++) {
float binEnergy = spectrum.at(i);
if (binEnergy > maxEnergy) {
maxEnergy = binEnergy;
peak = i;
}
}在这里,我总是得到peak=0。请帮帮忙
以下是我对前25个FFT样本的频谱输出:
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[0]: 0.036530
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[1]: 0.011568
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[2]: 0.012086
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[3]: 0.011568
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[4]: 0.040397
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[5]: 0.011568
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[6]: 0.012086
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[7]: 0.011568
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[8]: 0.044121
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[9]: 0.011568
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[10]: 0.012086
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[11]: 0.011568
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[12]: 0.040396
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[13]: 0.011568
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[14]: 0.012086
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[15]: 0.011568
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[16]: 0.116464
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[17]: 0.011568
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[18]: 0.012086
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[19]: 0.011568
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[20]: 0.040397
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[21]: 0.011568
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[22]: 0.012086
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[23]: 0.011568
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(257) > specturm[24]: 0.044121
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(267) > peak 2223.000000
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(270) > FREQUENCY 4342.773438
06-05 17:28:34.512 : INFO / HelloWorld ( 3351 : 3351 ) : void GuitarTunerMainForm::calculateFrequency(Tizen::Base::ByteBuffer *)(281) > octave 8发布于 2013-06-05 07:39:01
我怀疑你(a)没有在快速傅立叶变换之前应用合适的窗口函数和/或(b)你有一个大的直流分量。这将导致一个很大,可能是涂抹(由于光谱泄漏)峰值在0赫兹。您可以通过打印/绘制光谱阵列来验证这一点。
为补救这一问题:
const int PEAK_MIN = BUFFER_SIZE / 1024;
for (int i = PEAK_MIN; i < BUFFER_SIZE / 2 + 1; i++) { ...发布于 2013-06-06 10:12:36
有一个相当简单,但计算密集的方法来做基音检测使用自相关方法。我不明白为什么它也不适用于吉他!然而,当有一个以上的基本频率时,这将是一场斗争。不过,我不知道有一种算法能处理这个问题。
你需要采取足够的样本,以涵盖至少3个音高周期。然后,将信号进行自相关(自相关可以有效地实现用FFT执行)。
如果你有你的自相关信号,你会在滞后0时找到最大的峰值。第二高峰应该是你的投球。
在自相关之前,使用类似hamming窗口的方法对输入信号进行加窗,可以得到更好的结果。
更有甚者,普拉特名声的保罗·波尔斯玛( Paul )提出了一个“远更精确的基音检测方法”( far 更精确的基音检测方法)。
基本上是用他的计划。您可以使用窗口函数的自相关,然后存储以供以后使用。接下来,你要打开输入信号。自动关联那个信号。现在除以窗口函数的自相关。最后,选择最高的峰值和偏移从滞后0是样本的数目,以您的基音检测。
值得注意的是,您确实需要插值自相关峰值才能得到最佳结果。就我个人而言,我使用了抛物线插值,我获得的精度提高是巨大的。抛物线插值非常容易:
void ParabolicInterpolation( const float kA, const float kB, const float kC, float& p, float& m )
{
p = 0.5f * ((kA - kC) / (kA - (2.0f * kB) + kC));
m = (0.25f * (kA - kC) * p);
}其中,kB是您识别的自相关峰值,kA是它之前的自相关样本,kC是之后的样本。
编辑:,如果不需要这种精度,上面的方法提供了另一种非常简单的计算基频的方法,叫做谐波乘积谱(检查此演示文稿的开头。)。基本上你从FFT开始。你把它转换成星等光谱。最后,将其降为2x、3x和4x。然后你把样本相乘。最大的峰值将由你的基本频率。然而,这是严重限制您的FFT分辨率。
希望这能帮上忙!
https://stackoverflow.com/questions/16934097
复制相似问题