3、音频延迟基础:延迟的定义与分类、延迟对用户体验的影响、延迟测量指标

3.1 延迟到底是个什么东西?

音频延迟,说白了就是声音从发出到被听到之间的时间差。

我举个例子你就明白了。你对着麦克风说话,声音先变成电信号,经过处理,再通过耳机放出来。这个过程需要时间。哪怕只有几十毫秒,人耳也能察觉到。

我个人习惯把延迟分成三类:

  • 输入延迟:从声源到设备的时间。比如麦克风采集声音,AD转换需要时间。
  • 处理延迟:设备内部处理数据的时间。比如降噪、混响、编码解码。
  • 输出延迟:从设备到耳朵的时间。比如DA转换、耳机驱动响应。

你想想看,这三类加起来,就是总延迟。我在项目中遇到过最头疼的情况是,明明每个环节都优化了,但总延迟还是超标。后来发现是缓冲区设置的问题。

3.2 延迟的分类:别被术语搞晕了

其实延迟的分类方式有很多种。我按实际工作中最常用的分法来讲。

3.2.1 按产生环节分

分类 典型场景 典型值
采集延迟 麦克风拾音、AD转换 1-5ms
传输延迟 蓝牙、WiFi、USB传输 5-50ms
处理延迟 算法处理、DSP运算 2-20ms
渲染延迟 DA转换、耳机驱动 1-10ms

嗯,这里要注意,蓝牙传输延迟是最容易出问题的。我曾经调试一个蓝牙耳机项目,传输延迟占了总延迟的60%以上。

3.2.2 按感知特性分

  • 绝对延迟:从源头到终点的总时间。比如直播时观众听到的声音比现场晚多少。
  • 相对延迟:两个声音之间的时间差。比如左右声道不同步。
  • 抖动延迟:延迟值不稳定,忽大忽小。这个最烦人。

我建议你重点关注抖动延迟。为什么?因为绝对延迟可以通过预测补偿,但抖动延迟会让用户感觉声音「一卡一卡的」。

3.3 延迟对用户体验的影响:别小看那几十毫秒

很多人觉得延迟几毫秒无所谓。但实际体验下来,差别巨大。

关键数据:

  • 10ms以下:几乎无感知,专业录音棚标准
  • 10-20ms:大部分人可以接受,但敏感用户能察觉
  • 20-50ms:明显感觉延迟,影响演唱、演奏
  • 50ms以上:无法忍受,对话都会觉得别扭

我做过一个在线K歌项目。用户唱歌时听到自己声音延迟了30ms,结果就是唱不准调。你想想看,你唱歌时听到自己的声音比实际晚,你会不自觉地拖拍子。

还有游戏场景。FPS游戏里,枪声延迟超过50ms,玩家就会觉得「我开枪了怎么没声音?」。这种体验直接劝退用户。

我的经验: 做音频产品时,先把延迟目标定在20ms以内。如果做不到,至少保证抖动小于5ms。稳定的延迟比低延迟更重要。

3.4 延迟测量指标:怎么量化延迟?

测量延迟,说白了就是测时间差。但具体怎么测,有讲究。

3.4.1 常用指标

指标 含义 测量方法
RTT 往返时间 发一个信号,等它回来
单向延迟 单程时间 需要同步时钟
抖动 延迟的方差 多次测量取标准差

我个人习惯用RTT来估算单向延迟。因为单向延迟需要两端时钟同步,这个在工程上很难做到。

3.4.2 实测方法

我常用的方法有两种:

  1. 脉冲响应法:发一个短脉冲信号,记录接收时间。简单粗暴。
  2. 互相关法:发一段已知信号,用互相关算法找峰值。精度更高。

给你看个简单的代码示例:

// 伪代码:测量音频延迟
send_signal(click_sound);
start_time = get_current_time();
receive_signal(recorded_audio);
end_time = get_current_time();
delay = end_time - start_time;
printf("延迟: %d ms", delay);

注意: 测量延迟时,要排除系统调度的影响。我建议多测几次取中位数,不要取平均值。因为偶尔的异常值会拉高平均值。

3.5 避坑指南:我踩过的那些坑

我曾经调试一个USB音频设备,测出来的延迟总是比理论值大。折腾了两天,最后发现是USB的传输模式没选对。用同步传输模式,延迟能降低一半。

还有一次,蓝牙耳机的延迟在实验室测出来是30ms,但用户反馈说感觉有100ms。后来发现是手机端的A2DP协议栈有额外的缓冲。嗯,这里要注意,测量环境要和实际使用环境一致。

我建议你准备一个延迟测试工具箱:

  • 一个能发脉冲信号的音频源
  • 一个高精度的录音设备
  • 一个示波器(看波形对齐)
  • 一个延迟测试软件(比如Oscilloscope)

说白了,延迟测量就是个精细活。别嫌麻烦,多测几次,取稳定值。

总结一下:

  • 延迟分输入、处理、输出三类
  • 20ms以内是目标,抖动要小于5ms
  • 测量用RTT或互相关法
  • 多测几次取中位数

下一章我会讲怎么优化延迟。到时候给你看几个实战案例,保证有用。