对于上下文:我正在尝试创建一个简单的“电平监视器”动画,用于从麦克风传输音频数据。我在 iOS 设备上运行此代码,并严重依赖 Accelerate 框架进行数据处理。
到目前为止,我所拥有的很多内容都深受 Apple 示例项目的影响:https://developer.apple.com/documentation/accelerate/visualizing_sound_as_an_audio_spectrogram
以下是我当前正在采取的步骤:
老实说,在第5步之后,我对频域值的情况没有直观的了解。我知道较高的值意味着单个值表示的频率在时域数据中更普遍...但我不知道 12 vs 6492 的值意味着什么。
无论如何,最终结果是最低的 bin (0...255) 的幂基本上只是整体幅度,而较高的 3 个 bin 永远不会超过 0.001。我觉得我走在正确的轨道上,但我对 DCT 输出意味着什么的无知使我无法弄清楚这里出了什么问题。我也可以使用 FFT,如果这会产生更好的结果,但我知道 FFT 和 DCT 会产生类似的结果,并且 Apple 建议使用 DCT 来提高性能。
DFT/DCT 的输入是线性的。因此,当输入是幅度时(这是标准音频文件或麦克风输入的情况),输出也是如此。
看来这将用于可视化。在这种情况下,我建议将幅度转换为分贝。它将使值的范围更加紧凑,这在有限的屏幕空间上显示时是理想的,而且也很传统。 对于
20*log10(amp/ref)
的振幅,如果您随后要对其进行归一化,则 ref 可能只是 1.0 (8)。请注意,分贝域中的归一化将是加法偏移,而不是除法。
DCT 的频率 bin 为
k/(2N) * fs
,其中 k 是 bin,N 是变换长度,fs 是采样率。
因此,与 Juha P 关于 DCT 堆栈交换的对话让我意识到我一直严重误解了 DCT 的结果。一旦我使用了扫频音,很明显我的数据很好,但范围太疯狂了 - 不适合我的预期用途。
我发现 iPhone 麦克风默认录制频率为 48kHz,因此我的奈奎斯特频率为 24kHz。鉴于人类语音通常在 100-300Hz 范围内,问题是所有可用数据都位于 1024 个结果值的底部几个容器中。
我将“分组”步骤 (#7) 更改为仅查看 bin 1-41(共 1024 个),每个“输出”值使用 10 个 bin。我立即就可以看到我想要的效果,条形图会响应我声音的音高变化。
非常感谢 Juha P 和 Jon Nordby 帮助我解决这个问题!