Audacity 如何测量音频设备往返延迟以校准延迟补偿?
【免费下载链接】audacityAudio Editor项目地址: https://gitcode.com/GitHub_Trending/au/audacity
当项目播放与录音监控同时进行,输出端的音频会经过一条从输出设备回到输入设备的通路再次进入 Audacity。为了让监控录音与项目音频保持同步,Audacity 的延迟补偿机制会丢弃项目音频到达之前的所有输入音频,而这个"丢多久"的关键参数就是音频设备的往返延迟(round-trip latency)。PortAudio 会报告这些延迟值,但 Audacity 仓库的实测文档结论是:
PortAudio reports these latencies, but experiments showed that they weren't reliable.
因此仓库中记录了一套可控实验,能给出对往返延迟的准确估计,测得之后就可以手动校准延迟补偿设置("Audacity already has a latency-compensation setting for the user to adjust manually")。本文按 docs/portaudio-reported-playback-capture-latency.md 中的方法说明从测量到校准的完整路径。需要说明的是:该方法要求修改 Audacity 的音频 IO 回调加入测试逻辑,面向能读取并修改源码的开发者,不是用户界面里现成的按钮。
实验原理
文档对延迟补偿的定义是:假设有一根音频线把输出接回输入,按下播放后,项目音频最终会回到输入端被录下来;延迟补偿就是丢弃所有输入音频,直到项目音频到达为止。一旦知道了设备的往返延迟,最优地自动调整这个设置就是直接推论。所以整个实验的任务只有一个:精确测出所选输出设备到所选输入设备的往返延迟。
准备条件
- 用一根音频线把选定的输出设备连接到选定的输入设备。
- 一个能修改音频 IO 回调(在音频驱动线程上执行)的 Audacity 构建环境。
- 录音开始前,创建一个 wav 文件用于存放输入缓冲区的采样数据。
测量步骤
按文档描述,在音频 IO 回调中做以下事情:
- 用一秒静音、然后一个正弦波覆写输出缓冲区(overwrite the output buffer with one second of silence, then with a sine wave);
- 把输入缓冲区的采样写入 wav 文件;
- 录音停止时关闭 wav 文件。
之后在 Audacity 中打开这个 wav 文件,观察延迟——正弦波在录音中出现的位置,相对播放开始时刻,就是这条设备链路的往返延迟。
注意"请求缓冲区大小"的含义:文档脚注明确该值同时作用于输入和输出,即 250 表示输入 250 ms 加输出 250 ms,总共 500 ms。请求多大的缓冲区会影响实测结果,测量时应记录所用的请求值。
文档给出的测量结果示例
下表是文档中作者实测得到的数据(原文照录),用于说明 PortAudio 报告值与真实往返延迟之间的偏差可以大到数百毫秒:
| OS | Host | requested buffer size (ms) (*) | PA-reported output buffer size (ms) (**) | PA-reported input buffer size (ms) | Measured round-trip (ms) | error (reported - actual) (ms) |
|---|---|---|---|---|---|---|
| Win | WASAPI | 250 | 270 | 260 | 75 | 455 |
| Win | WASAPI | 100 | 120 | 110 | 75 | 155 |
| Win | WASAPI | 20 | 40 | 30 | 75 | -5 |
| Win | DirectSound | 250 | 250 | 62.5 | 420 | -107.5 |
| Win | DirectSound | 100 | 100 | 25 | 115 | 10 |
| Win | DirectSound | 20 | didn't work | didn't work | didn't work | didn't work |
| Win | ASIO | 500 | 50.5 | 47.9 | 100 | -1.6 |
| Win | ASIO | 100 | 50.5 | 47.9 | 100 | -1.6 |
| Win | ASIO | 20 | 26.5 | 24.7 | 54 | -2.8 |
(*) applies to both input and output, e.g. 250 means 250 for the input + 250 for the output, in total 500. (**) for one same requested size, may differ wildly depending on whether only playback is active or playback and recording. Here we write the values obtained when both are active.
这是文档示例结果,不是任何环境下必须复现的固定数值:WASAPI 下误差最大达到 455 ms,而 ASIO 下误差只有约 1.6 ms 到 2.8 ms,可见报告的延迟值在不同后端之间完全不可靠。你的环境需要用同一方法重新测量。表中 DirectSound 请求 20 ms 时四项均为 "didn't work",说明并非所有后端都支持小缓冲区请求。
用测量结果校准延迟补偿
测得往返延迟后,校准位置在 Audacity 偏好设置中。对应界面由 src/preferences/qml/Audacity/Preferences/internal/BufferAndLatencySection.qml 定义,"Buffer and latency" 面板包含三个相关控件:
- Buffer length(ms):缓冲区长度,增减控件;
- Latency compensation(ms):手动延迟补偿值,即本任务要写入测量结果的设置项;
- Automatic复选框:勾选后 Latency compensation 控件被禁用(QML 中为
enabled: !apiModel.automaticCompensationEnabled),手动值不再生效。
因此校准操作是:取消勾选 Automatic,在 Latency compensation 控件中填入刚才测得的往返延迟值。源码中该设置的默认值是 25 ms,见 au3/src/prefs/DevicePrefs.cpp 第 307 行:
AudioIOLatencyCompensation, 25验证方式以文档给出的观察方法为准:在 Audacity 中打开测量用 wav 文件,观察录音里正弦波相对播放起点的位置,即往返延迟。
限制与边界
- 文档的全部测量数据来自 Windows 平台的 WASAPI、DirectSound、ASIO 三种后端;文档没有给出 macOS 或 Linux 数据,也没有给出测量精度的保证条件。
- 测量依赖 IO 回调层面的输出覆写与输入落盘,测量时记录下来的项目内容会被替换为"一秒静音 + 正弦波",不要在生产录音流程中启用这段逻辑。
- PA-reported 值在仅播放与播放加录音同时激活两种状态下可能差异很大(脚注 **),对比时以"两种都激活"的取值为准,与文档记录口径一致。
文档没有进一步说明基于实测往返延迟的自动校准如何落地;它只是给出了"一旦知道了往返延迟,最优自动调整就是直接推论"这一前提。当前版本中,校准路径就是上面描述的手动设置。
【免费下载链接】audacityAudio Editor项目地址: https://gitcode.com/GitHub_Trending/au/audacity
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考