【问题标题】:FFT - Applying window on PCM dataFFT - 在 PCM 数据上应用窗口
【发布时间】:2012-03-27 14:35:21
【问题描述】:

我目前正在尝试重现 FMOD 音频库的 getSpectrum 函数。此函数读取当前播放缓冲区的 PCM 数据,在此数据上应用一个窗口并应用 FFT 来获取频谱。

它返回一个浮点数数组,其中每个浮点数介于 0 到 1 dB (10.0f * ( float)log10(val) * 2.0f) 之间。

我不确定我应该做什么,所以我会解释一下:

首先,我在 4096 字节缓冲区中获取 PCM 数据,根据文档,PCM 数据由左右一对数据的样本组成。

就我而言,我正在使用上图中的 16 位样本。所以,如果我只想使用左声道,我将左 PCM 数据保存在一个短数组中:

short *data = malloc(4096);
FMOD_Sound_ReadData(sound, (void *)data, 4096, &read);  

因此,如果一个样本 = 4 个字节,我有 1024 个样本,即代表左通道的 1024 个短路和代表右通道的 1024 个短路。

为了执行 FFT,我需要一个浮点数组并在我的数据上应用一个窗口(汉宁):

float hanningWindow(short in, size_t i, size_t s)
{
    return in*0.5f*(1.0f-cos(2.0f*M_PI*(float)(i)/(float)(s-1.0f)));
}

in 是输入,i 是数组中的位置,s 是数组的大小 (1024)。

只获取左声道:

float *input = malloc(1024*sizeof(float));
for (i = 0; i < 1024; i++)
    input[i] = hanningWindow(data[i*2], i, 1024);

然后我通过 Kiss_fft 执行 FFT(从真实到复杂)。我得到一个大小为 1024/2+1 = 513 的kiss_fft_cpx *ouput(复数数组)。

我计算每个频率的幅度:

kiss_fft_cpx   c = output[i];
float          amp = sqrt(c.r*c.r + c.i*c.i);

以分贝计算:

amp = 10.0f * (float)log10(amp) * 2.0f;

amp 不在 0 和 1 之间。我不知道我必须在哪里规范化我的数据(在 PCM 数据上或最后)。我也不确定我在 PCM 数据上应用我的窗口的方式。

这是我从 0 到 20kHz 歌曲中得到的结果与 getSpectrum 函数的结果相比。 (对于矩形窗口

             My Result                         getSpectrum Result

我怎样才能达到同样的效果?

【问题讨论】:

  • 在速度笔记上,您应该真正存储 Hann 窗口系数,而不是每次都从 trig 计算它们。
  • 不需要取sqrt。注意:20*log10(sqrt(x)) == 10*log10(x)

标签: c signal-processing fft fmod kissfft


【解决方案1】:

您对 log (dB) 刻度有点困惑 - 您没有得到 0 - 1 dB 的范围,对于 16 位音频,您得到的范围通常为 96 dB,其中上端和下端有点任意的,例如0 到 -96 dB,或 96 dB 到 0 dB,或您喜欢的任何其他范围,具体取决于各种因素。您可能只需要通过适当的偏移量和因子来移动和缩放您的频谱图即可。

(注意:96dB的范围来自公式20 * log10(2^16),其中16为比特数。)

【讨论】:

  • 感谢您的回复,但奇怪的是,在应用 20 * log10(amp) 时,我得到的值最高为 120。这可能是因为我使用了 (float) 转换但不确定。
  • 真正重要的只是 范围 - dB 是相对于一些名义上的 0 dB 参考的比率 - 您只需要查看您获得的最小/最大值并相应地移动/缩放以在您的频谱图上获得合理的强度范围。
  • 上面的 Hann 窗口乘以 0.5 的平均值。带符号的 16 位数据的最大值也是 2^15-1,而不是 2^16。每次将这些比例减半后退 -6dB 将峰值 dB 设置为 84dB
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-30
  • 1970-01-01
  • 1970-01-01
  • 2015-11-08
  • 1970-01-01
相关资源
最近更新 更多