c++ - 将 FFT 转换为频谱图

标签 c++ fft spectrogram intel-ipp

我有一个音频文件,我正在遍历该文件并在每个步骤中采集 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/

相关文章:

c++ - while() 不同的输出;相同的变量

c++ - RHEL6 上的自定义 GCC 4.8.2 使用 std::shared_ptr 给出构建错误

vb.net - MP3音频频谱图?

java - 通过FFT获取频率分量

python - 为什么来自 librosa 库的频谱图与实际音轨的持续时间不同?

python - 如何使用 Python 将 scipy.signal.spectrogram 反转为音频?

c++ - 哪个更快 : x<<1 or x<<10?

c++ - 为什么我可以在函数的返回语句后输入任意多的分号?

python - Accelerate 和 NumPy 为 FFT 产生不同的结果

c++ - 真正的 fft 错误 - ffmpeg