我有一个音频文件,我正在迭代该文件,并在每一步中获取512个样本,然后通过FFT传递它们。
我将数据输出为块514浮点长度(使用IPP的ippsFFTFwd_RToCCS_32f_I),其中实部和虚部交错。
我的问题是,一旦我得到了这些复数,我该如何处理它们?目前,我正在为每个值执行
const float realValue = buffer[(y * 2) + 0];
const float imagValue = buffer[(y * 2) + 1];
const float value = sqrt( (realValue * realValue) + (imagValue * imagValue) );
这给出了一些稍微有用的东西,但我更希望得到0到1范围内的值。上面的问题是,峰值最终返回到9或更多。这意味着事情变得非常饱和,然后频谱图的其他部分几乎没有显示出来,尽管当我通过试听的频谱图运行音频时,它们看起来相当强。我完全承认我不能100%确定FFT返回的数据是什么(除了它代表我传入的512个样本长块的频率值)。特别是我对compex数字到底代表什么缺乏理解。
任何建议和帮助都将不胜感激!
编辑:只是为了澄清一下。我最大的问题是,如果不知道规模是多少,返回的FFT值是没有意义的。有没有人能告诉我怎么算出那个标尺?
Edit2:通过执行以下操作,我获得了非常漂亮的结果:
size_t count2 = 0;
size_t max2 = kFFTSize + 2;
while( count2 < max2 )
{
const float realValue = buffer[(count2) + 0];
const float imagValue = buffer[(count2) + 1];
const float value = (log10f( sqrtf( (realValue * realValue) + (imagValue * imagValue) ) * rcpVerticalZoom ) + 1.0f) * 0.5f;
buffer[count2 >> 1] = value;
count2 += 2;
}
在我看来,这甚至比我看过的大多数其他频谱图实现都要好。
我的所作所为有什么重大错误吗?
发布于 2009-11-05 22:28:09
为了让所有的FFT都可见,通常的做法是取数值的对数。
因此,输出缓冲区的位置告诉您检测到的频率。复数的幅值(L2范数)告诉您检测到的频率有多强,相位(L2)提供的信息在图像空间比音频空间重要得多。由于FFT是离散的,因此频率范围从0到奈奎斯特频率。在图像中,第一项(DC)通常是最大的,因此如果您的目标是归一化,则是一个很好的候选者。我不知道这是否也适用于音频(我很怀疑)
发布于 2009-11-05 23:09:22
对于每个包含512个样本的窗口,您可以像以前一样计算FFT的大小。每个值表示信号中存在的相应频率的大小。
mag
/\
|
| ! !
| ! ! !
+--!---!----!----!---!--> freq
0 Fs/2 Fs
现在我们需要计算出频率。
由于输入信号是实数值,因此FFT是围绕中间(奈奎斯特分量)对称的,第一项是直流分量。已知信号采样频率Fs
,奈奎斯特频率为Fs/2。因此,对于指数k
,对应的频率为k*Fs/512
因此,对于长度为512的每个窗口,我们得到指定频率下的幅度。这些在连续窗口上的组形成了谱图。
发布于 2011-12-17 08:30:57
只是为了让人们知道我在整个问题上做了很多工作。我发现的最主要的事情是,FFT需要在完成之后进行规范化。
为此,您可以将窗口向量的所有值平均在一起,以获得一个略小于1的值(如果使用的是矩形窗口,则为1)。然后,将该数字除以经过FFT变换后的频率位数。
最后,将FFT返回的实际数字除以归一化数字。现在,振幅值应在-Inf到1的范围内。日志,等等,随你喜欢。您仍将使用已知的范围。
https://stackoverflow.com/questions/1679974
复制相似问题