使用 DCT 为麦克风输入创建实时“电平”动画

问题描述 投票:0回答:2

对于上下文:我正在尝试创建一个简单的“电平监视器”动画,用于从麦克风传输音频数据。我在 iOS 设备上运行此代码,并严重依赖 Accelerate 框架进行数据处理。

到目前为止,我所拥有的很多内容都深受 Apple 示例项目的影响:https://developer.apple.com/documentation/accelerate/visualizing_sound_as_an_audio_spectrogram

以下是我当前正在采取的步骤:

  1. 开始使用 AVFoundation 从麦克风接收 (Int16) 样本。
  2. 存储样本直到至少有 1024 个样本,然后将前 1024 个样本发送到我的处理算法。
  3. 将样本转换为非规格化 Float(单精度浮点)。
  4. 出于性能原因,对样本应用汉宁窗以防止混叠,因为样本数量相当低。
  5. 运行时域样本到频域样本的正向 DCT-II 变换。
  6. 所有样品的绝对值。
  7. “分箱”样本以匹配我必须设置动画的条数...对于每个 1024/n 个样本,找到每个范围内的最大值。
  8. 通过将每个箱除以全局范围内遇到的最高幅度样本,将每个箱归一化到 0...1 范围内。

老实说,在第5步之后,我对频域值的情况没有直观的了解。我知道较高的值意味着单个值表示的频率在时域数据中更普遍...但我不知道 12 vs 6492 的值意味着什么。

无论如何,最终结果是最低的 bin (0...255) 的幂基本上只是整体幅度,而较高的 3 个 bin 永远不会超过 0.001。我觉得我走在正确的轨道上,但我对 DCT 输出意味着什么的无知使我无法弄清楚这里出了什么问题。我也可以使用 FFT,如果这会产生更好的结果,但我知道 FFT 和 DCT 会产生类似的结果,并且 Apple 建议使用 DCT 来提高性能。

ios audio fft audio-processing dct
2个回答
0
投票

DFT/DCT 的输入是线性的。因此,当输入是幅度时(这是标准音频文件或麦克风输入的情况),输出也是如此。

看来这将用于可视化。在这种情况下,我建议将幅度转换为分贝。它将使值的范围更加紧凑,这在有限的屏幕空间上显示时是理想的,而且也很传统。 对于

20*log10(amp/ref)
的振幅,如果您随后要对其进行归一化,则 ref 可能只是 1.0 (8)。请注意,分贝域中的归一化将是加法偏移,而不是除法。

DCT 的频率 bin 为

k/(2N) * fs
,其中 k 是 bin,N 是变换长度,fs 是采样率。


0
投票

因此,与 Juha P 关于 DCT 堆栈交换的对话让我意识到我一直严重误解了 DCT 的结果。一旦我使用了扫频音,很明显我的数据很好,但范围太疯狂了 - 不适合我的预期用途。

我发现 iPhone 麦克风默认录制频率为 48kHz,因此我的奈奎斯特频率为 24kHz。鉴于人类语音通常在 100-300Hz 范围内,问题是所有可用数据都位于 1024 个结果值的底部几个容器中。

我将“分组”步骤 (#7) 更改为仅查看 bin 1-41(共 1024 个),每个“输出”值使用 10 个 bin。我立即就可以看到我想要的效果,条形图会响应我声音的音高变化。

非常感谢 Juha P 和 Jon Nordby 帮助我解决这个问题!

© www.soinside.com 2019 - 2024. All rights reserved.