使用 FFTW 计算音频数据的离散傅立叶变换

标签 c audio signal-processing fft fftw

我对信号处理还很陌生,所以请原谅我的吐槽。我已经下载并安装了适用于 Windows 的 FFTW。文档没问题,但我仍有疑问。

我的总体目标是从计算机上的声卡捕获以 44100 采样/秒采样的原始音频数据(此任务已使用库和我的代码实现),然后对该音频数据 block 执行 DFT。

我只对查找音频中的一系列频率分量感兴趣,我不会执行任何逆向 DFT。在这种情况下,是否需要真正到真正的转换,因此才有 fftw_plan_r2r_1d() 函数?

我要转换的数据 block 有 11025 个样本长。我的函数调用如下所示。这将产生 11025 个 bin 的频谱阵列。我如何知道结果中的最大频率分量?

我相信 bin 间距是 Fs/n,44100/11025,所以 4。这是否意味着我将在阵列中拥有从 0 Hz 一直到 44100Hz 的频谱,步长为 4,或更高奈奎斯特频率 22200 的一半?

这对我来说是个问题,因为我只想搜索从 60Hz 到 3000Hz 的频率。有什么方法可以限制变换范围吗?

我没有看到该函数的任何参数,或者可能还有其他方法?

非常感谢您对此提供的任何帮助。

p = fftw_plan_r2r_1d(11025, audioData, spectrum, FFTW_REDFT00, FFTW_ESTIMATE);

最佳答案

从上面回答您的一些个人问题:

  • 你需要一个实到复的转换,而不是实到实
  • 您将在感兴趣的频率下计算复数输出箱的幅度 (magnitude = sqrt(re*re + im*im))
  • 频率分辨率确实是Fs/N = 44100/11025 = 4 Hz,即每个输出bin的宽度是4 Hz
  • 对于实数到复数的转换,您将获得 N/2 + 1 个输出箱,为您提供从 0Fs/2
  • 的频率
  • 您只需忽略您不感兴趣的频率 - FFT 非常有效,因此您可以“浪费”不需要的输出箱(除非您只对相对较少的输出频率感兴趣)

补充说明:

  • 计划创建实际上并不执行 FFT - 通常您创建一次计划然后多次使用它(通过调用 fftw_execute)
  • 为了提高性能,您可能希望使用单精度调用(例如 fftwf_execute 而不是 fftw_execute,对于计划创建等也是如此)

StackOverflow 上一些有用的相关问题/答案:

您可能还想阅读更多类似的问题和答案 - 搜索 标签。

另请注意 dsp.stackexchange.com是有关 DSP 理论 而非实际特定编程问题的首选网站。

关于使用 FFTW 计算音频数据的离散傅立叶变换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39839391/

相关文章:

java - 录音机未处理的异常类型 IOException

objective-c - Swift:使用 strftime 和本地时间格式化 NSDate

c - 程序的执行顺序

c - 没有 pow() 或循环的递归二进制到十进制函数

audio - 在我的 Windows 应用商店 HTML5 应用中启用背景音频

android - 有没有办法改变来自Android的音频输出的左右声道的音量?

C 如何制作消息列表?

image - 转换为 8 位图像会导致黑色出现白点。为什么是这样?

c - 如何比较从数值食谱到 Matlab fft 的实傅里叶变换实现?

windows - 如何在 Windows 平台上实现吉他放大器或 FX 仿真?