22、音频延时测量工具:dumpsys media.audio_flinger、AudioFlinger的latency命令、第三方工具(AudioLatency/Dr.Latency)

做音频低延时优化,最怕什么?

怕你改了半天代码,不知道延时到底降了多少。

我见过不少开发者,上来就调 buffer size、改 HAL 参数,结果一测延时反而变大了。嗯,这就是典型的「盲人摸象」。所以今天这章,咱们专门聊聊怎么测量音频延时。工具就三样:系统自带的 dumpsys media.audio_flinger、AudioFlinger 的 latency 命令,还有两个第三方 App——AudioLatency 和 Dr.Latency。

22.1 dumpsys media.audio_flinger:系统级的「体检报告」

先说最基础的。你在 adb shell 里敲一行命令:

adb shell dumpsys media.audio_flinger

输出会很长,但咱们只关心几个关键字段。我个人习惯先看 Output thread 那一块。

举个例子,输出里会有类似这样的内容:

Output thread 0x7b4a0000, name: AudioOut_D, tid: 1234
  - FrameCount: 960
  - SampleRate: 48000
  - Latency: 20 msec
  - Underrun count: 0

这里 Latency: 20 msec 就是系统估算的音频输出延时。注意,它只是一个理论值,不是实测值。怎么算的?说白了就是 FrameCount / SampleRate * 1000。960 / 48000 * 1000 = 20 ms。

我的经验:这个值只能作为参考。我在项目中遇到过,系统报告 20ms,但实际用耳朵听延迟感明显更大。所以别完全信它,但可以用它来快速判断你的 buffer 配置有没有生效。

另外,Underrun count 也很重要。如果这个数字一直在涨,说明你的 buffer 太小了,音频数据来不及喂给硬件。这时候延时虽然低了,但会出现爆音、卡顿。嗯,这就是典型的「捡了芝麻丢了西瓜」。

22.2 AudioFlinger 的 latency 命令:更细粒度的调试

除了 dumpsys,AudioFlinger 还提供了一个更直接的命令:

adb shell service call audio 3

这个命令会调用 AudioFlinger 的 getLatency() 方法,返回当前输出流的延时。输出格式是 Parcel,需要解析一下。不过 Android 8.0 之后,你也可以用:

adb shell dumpsys media.audio_flinger --latency

这个命令会直接打印出每个音频输出流的延时值,比解析 Parcel 方便多了。

我建议你在调试时,先跑一次这个命令,记下基线值。然后改完代码,再跑一次。对比一下,延时有没有降下来。如果降了,但 underrun 也上来了,那就得权衡一下了。

注意:这个命令返回的延时是「理论最小值」。实际延时还会受到 mixer 线程调度、HAL 驱动、硬件 FIFO 等因素影响。我曾经在一个项目上,理论延时 10ms,实测 25ms。所以,理论值只能帮你定位方向,不能替代实测。

22.3 第三方工具:AudioLatency 和 Dr.Latency

理论值看完了,咱们得用耳朵和仪器来验证。这里推荐两个 App。

22.3.1 AudioLatency

这个工具的原理很简单:它通过扬声器发出一个声音,同时用麦克风录制。然后计算发出和录制之间的时间差。说白了就是「自说自话,然后算延迟」。

使用步骤:

  1. 安装 AudioLatency App
  2. 戴上耳机(避免扬声器声音被麦克风直接录到,造成误差)
  3. 点击 Start 按钮
  4. 等待几秒钟,App 会显示一个延时值

这个值包含了从 App 写入数据到扬声器发出声音,再到麦克风录制回来的完整链路延时。我一般用它来做「端到端」验证。

避坑指南:我曾经用 AudioLatency 测延时,发现结果忽高忽低。后来发现是耳机没戴紧,漏音了。所以测试时一定要确保耳机密封性好,最好在安静环境下测。

22.3.2 Dr.Latency

Dr.Latency 和 AudioLatency 类似,但它多了一个「手动校准」功能。你可以用一根音频线把手机的耳机口和麦克风口连起来,这样信号是直接电信号传输,不受环境噪音影响。

我个人更推荐 Dr.Latency,因为它可以测出更精确的「纯系统延时」,排除了空气传播的误差。不过需要一根 3.5mm 音频线,现在很多手机没有耳机孔了,得用转接线。

使用步骤:

  1. 用音频线连接手机的耳机口和麦克风口
  2. 打开 Dr.Latency
  3. 点击 Measure
  4. App 会发出一个脉冲信号,通过音频线直接回到麦克风
  5. 结果会显示在屏幕上

这个值通常比 AudioLatency 测出来的小一些,因为它排除了空气传播的延时。我一般用 Dr.Latency 做「系统级」验证,用 AudioLatency 做「用户感知级」验证。

22.4 知识体系:延时测量工具全景图

下面这张图帮你理清这三个工具的关系和适用场景:

音频延时测量工具全景图 dumpsys media.audio_flinger AudioFlinger latency 命令 第三方工具 理论延时值 Underrun 统计 getLatency() 调用 理论最小值 端到端实测 纯系统延时 使用建议: 1. 先用 dumpsys 看理论值,确认 buffer 配置是否正确 2. 再用 latency 命令验证理论最小值是否合理 3. 最后用第三方工具做端到端实测,验证用户感知 4. 三者结合,才能全面评估延时优化效果

22.5 实战:如何用这三个工具定位延时问题

假设你接到一个任务:把某款手机的音频延时从 40ms 降到 20ms 以下。你会怎么做?

我的做法是这样的:

  1. 先跑 dumpsys,看看理论延时是多少。如果理论值已经 30ms 了,那说明 buffer 配置就有问题。先调 buffer size。
  2. 调完 buffer 再跑 latency 命令,确认理论最小值降到了 15ms 左右。
  3. 最后用 Dr.Latency 实测,如果实测值在 20ms 以内,说明优化有效。如果实测值还是 30ms,那问题可能出在 HAL 层或者硬件上。

我曾经在一个项目上,理论延时已经降到 10ms 了,但实测始终在 25ms 左右。后来发现是 HAL 层里有个固定的 15ms 缓存,怎么调都没用。最后只能找芯片厂商改驱动。

所以你看,这三个工具就像三把尺子,一把量理论,一把量系统,一把量用户感知。缺了哪一把,你都可能被「假象」迷惑。

总结一下:
  • dumpsys media.audio_flinger:看理论延时和 underrun,适合快速验证配置
  • latency 命令:看系统报告的最小延时,适合对比优化效果
  • AudioLatency / Dr.Latency:做端到端实测,验证用户真实体验

嗯,工具就这些。但记住,工具只是辅助,真正重要的是你理解延时从哪里来、到哪里去。下一章咱们会深入 HAL 层,看看驱动里那些「看不见的延时」到底藏在哪里。


公众号:蓝海资料掘金营,微信deep3321