You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何验证Core Audio中音频幅值的正确性?附代码相关疑问

解答你的音频幅值验证与绘图问题

1. 为什么magnitudeAtBand数值极小?这正常吗?

这完全是正常的,核心原因有两点:

  • 首先,你录制的原始音频信号本身音量极低:从输出的data数组来看,数值都在±0.0001量级,说明当前环境安静或麦克风增益设置较低。而Float格式的PCM音频范围是**[-1.0, 1.0]**,1.0对应最大音量,弱输入信号自然会导致FFT后的幅值偏小。
  • 其次,TempiFFT返回的是线性幅值,这种刻度对弱信号的差异展示不直观。如果想更清晰地观察频段间的强弱对比,建议启用你注释掉的dB转换:
    let magnitudeDB = TempiFFT.toDB(fft.magnitudeAtBand(i))
    
    dB是对数刻度,会放大小信号的差异,结果通常为负数(因为小于1的数值取对数为负),但更符合人耳对声音的感知,也更适合绘图展示。

2. 如何绘制振幅图?

你可以绘制两种常见的振幅图,分别对应时域和频域:

时域波形图(原始音频振幅)

  • 数据来源:直接使用data数组的Float值,每个元素对应一个采样点的瞬时振幅。
  • 绘图逻辑:
    • X轴:可以是采样点序号,或转换为时间(采样点序号 ÷ 采样率,比如44100Hz下,2048个采样点对应约0.046秒)。
    • Y轴:振幅值,范围固定为[-1.0, 1.0]。
    • 实现方式:用SwiftUI的Path手动绘制折线,或者用第三方库如Charts的LineChartView,将data转为ChartDataEntry后传入即可。

频域振幅图(FFT频段幅值)

  • 数据来源:使用magnitudeArr(线性幅值)或magnitudeDBArr(dB幅值)。
  • 绘图逻辑:
    • X轴:每个频段对应的频率范围。你的代码分了20个频段,采样率44100Hz,奈奎斯特频率为22050Hz,因此每个频段宽度为22050 / 20 = 1102.5Hz,第i个频段的覆盖范围是i*1102.5Hz到(i+1)*1102.5Hz。
    • Y轴:线性幅值(0到当前最大幅值)或dB幅值(通常-60dB到0dB,0dB对应最大输入信号)。
    • 实现方式:用Charts的BarChartView(柱状图)或LineChartView(折线图),把每个频段的幅值和对应频率转为ChartDataEntry即可。

3. 为什么data中存在负数?

这是线性PCM音频的标准特性,完全正常:
Float格式的PCM数据用正负值表示声波的振动状态:正数对应空气被压缩的状态,负数对应空气被稀疏的状态,0代表静止。比如标准的正弦波音频信号,就是在[-1.0, 1.0]之间周期性正负波动的,所以你的data里出现负数是正确的信号表现。

额外验证建议

如果想确认数据是否准确,可以做个简单测试:

  1. 播放一个已知的测试信号(比如1kHz的正弦波,音量适中),同时用你的代码录制。
  2. 查看data数组,应该能看到明显的周期性正负波动,数值范围大概在±0.5左右(取决于音量)。
  3. 查看FFT结果,第一个频段(0-1102.5Hz)的幅值会明显高于其他频段,以此验证你的FFT逻辑是正确的。

内容的提问来源于stack exchange,提问作者John Doe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:25:04