我有一个音频文件,我正在遍历该文件并在每个步骤中采集 512 个样本,然后将它们传递给 FFT。
我将数据作为 block 514 float 很长(使用 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 个样本长 block 的频率值)。特别是我对复杂数字的确切含义缺乏了解。
任何建议和帮助将不胜感激!
编辑:只是为了澄清。我的大问题是如果不知道比例是多少,返回的 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;
}
在我看来,这甚至比我看过的大多数其他频谱图实现都要好。
我正在做的事情有什么严重错误吗?
最佳答案
使所有 FFT 可见的通常做法是取幅值的对数。
因此,输出缓冲区的位置告诉您检测到的频率。复数的幅度(L2 范数)告诉您检测到的频率有多强,而相位(反正切)为您提供在图像空间中比音频空间更重要的信息。因为 FFT 是离散的,所以频率从 0 到奈奎斯特频率。在图像中,第一项 (DC) 通常是最大的,因此如果您的目标是标准化,那么它是一个很好的候选者。我不知道音频是否也是如此(我对此表示怀疑)
关于c++ - 将 FFT 转换为频谱图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1679974/