【问题标题】:Using PCM samples as input for DFT使用 PCM 样本作为 DFT 的输入
【发布时间】:2014-05-24 06:16:10
【问题描述】:

我正在编写一个应用程序来计算声音信号的 DFT(使用 FFT 算法)。 FFT 算法的输入是 PCM 样本 - 即,我有一个 16 位无符号整数的大列表。

我知道我需要使用窗口函数独立计算声音信号的几个片段的 DFT,并且我已经编写了将输入声音文件解码为原始 PCM 样本的工作代码。

我的问题是关于definition of the DFT given on Wikipedia

DFT 应该对输入 x(0), x(1), ..., x(N-1) 执行可逆的线性变换,其中每个 x(n) 是一个复数。但是,我不明白如何将解码后的样本整数转换为适合算法的复数。

我在网上看到过一些例子,每个样本被除以得到一个[0, 1)范围内的浮点值,然后虚部设置为0。

这是否需要缩小到 [0, 1)?并将每个样本表示为x + 0i,其中x 的样本值是否正确?

【问题讨论】:

  • yes 虚部 = 0 对于所有输入值,不需要缩放到 。请注意,有许多具有不同缩放因子的 DFT 实现,因此请检查输出信号的幅度或功率并根据您的需要重新缩放(以避免溢出......)我通常使用不会改变信号幅度的归一化 DFT
  • 也看这里:stackoverflow.com/a/21658139/2521214 在其中一个 cmets 中是我的 win32 声卡示波器/频谱分析仪和发生器的链接,因此您可以将结果与它进行比较...

标签: algorithm fft pcm


【解决方案1】:

是的,您可以通过将 0 的虚部添加到每个实数值来创建复数。试试看,它会起作用的。但是,您只是将要处理的数据量增加了一倍,并且创建了很多冗余。您可以注意到输出中的冗余:正频率和负频率的结果系数将相同,除了虚部的符号不同。因此,为了提高效率和减少冗余,通常使用不同的转换将N 实值转换为N/2 复值,因此您得到(大致)N/2 频率。我不会在这里详细介绍,但是可以在这里找到复杂 FFT 和实际输入转换的一个很好的实现:http://sourceforge.net/projects/kissfft/

关于您的最后一个问题:不。您不需要调整输入。 DFT 是一种线性变换,因此缩放的输入只会产生相同缩放的输出。

编辑:顺便说一句,您确定这是您想要的复杂 DFT 吗?对于真实数据,尤其是 PCM 数据,您应该考虑使用 Cosine Transform,它直接从真实输入数据映射到真实输出。

【讨论】:

  • 这是一个很好的答案。 :) 正是我不清楚的信息。我的目标是产生这样的东西:en.wikipedia.org/wiki/File:Spectrogram-19thC.png,从我读过的内容来看,应该使用短时傅里叶变换(这似乎只是在输入信号的几个小段上计算 DFT)。但是,由于 DCT-II“与偶数索引元素为零的偶数对称的 4N 个实际输入的 DFT 完全等效(总比例因子为 2)”,也许我可以使用它来代替 DFT ,并应用相同的窗口技术?
  • 我会使用普通的 DFT,从而产生复杂的频率分量。这些复系数的范数将是各个频率处的能量。对 DCT 结果的正确后处理和解释更为重要。看到该示例图像中的点状伪影了吗?可能是不正确的后处理的结果。你不会想要那个。但是,当然,如果您小心,DCT 的结果也可能非常好。为了获得完美的性能,您甚至可以在这里考虑 MDCT:en.wikipedia.org/wiki/MDCT
  • 太好了,感谢您的帮助!我会在网上做更多的阅读,并检查 KissFFT 的源代码。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多