该文章描述了如何将你的系统针对录音,混音,回放或是合成音频应用进行配置。 这类活动通常使用术语 “专业音频” 进行描述,并相对需要较低的延迟。
相对于视频剪辑或游戏,该类应用通常不需要高端硬件。生产于2012 年后的大多数硬件都可以针对专业音频工作进行优化。更多信息请参考 Ardour 用户手册 The Right Computer System for Digital Audio 一节。
开始
在阅读完音频系统一文后,你可能已大致了解到 ALSA 属于 Linux 内核的一部分,并在 Arch Linux 的驱动及接口中作为默认声音系统。ALSA 在完成默认的 Arch 安装流程后应当可以开箱即用。如果出现意外,你需要在进行下一步前先排清问题。
然而,如果出现 “没有声音” 的情况,则很可能是需要在 ALSA 混音器配置中解除声道的静音。如果你在使用多个音频设备(例如 USB 音频接口及内置声卡),你可能需要设置默认声卡.
我已正确配置好声音系统了吗?
$ speaker-test
- 进一步排障可参考 ALSA 。
在多数情况下,默认的 Arch Linux 内核已能满足低延迟应用。进一步的系统配置只需在你遇到了音频丢失,或是你确实需要/想要极低延迟的情况下进行。
为了完成优化工作,你可能需要配置一个实时内核。
尽管有些专业音频软件可以直接使用 ALSA,但该文章提到的大多数软件都属于 JACK Audio Connection Kit(又称 JACK)客户端。因此,你需要根据下方描述安装并配置一个可用的音频服务器。
系统配置
你可以参考下列常见的系统优化方式:
- 配置 CPU 调频调速器至 performance。
-
配置 pam_limits(例如安装 realtime-privileges包 并将用户添加至
realtime
组)。 - 使用
threadirqs
内核参数(参考 [1])- 实时内核补丁集已默认启用该参数。 - 使用实时内核补丁集。
- 添加
noatime
至 fstab(参考性能优化#挂载选项)。 - 通过在启动阶段执行下列命令来提高最大 requested RTC interrupt frequency(默认为 64 Hz):
# echo 2048 > /sys/class/rtc/rtc0/max_user_freq # echo 2048 > /proc/sys/dev/hpet/max-user-freq
- 降低系统的 swappiness 值(即交换频率,默认为
60
),例如:将该值设为10
可让系统在试图交换到硬盘前等待更长时间(可参考 wikipedia:Paging#Swappiness)。该值可通过执行sysctl vm.swappiness=10
实时更改(详情请参考 sysctl(8)),或是通过修改配置文件永久修改(参考 sysctl.d(5)),具体如下:
/etc/sysctl.d/90-swappiness.conf
vm.swappiness = 10
- 将 inotify 跟踪用户的最大文件数量(默认为
524288
)提升到如600000
有助于同时需要处理大量文件的程序(例如 DAW)。该值可通过执行sysctl fs.inotify.max_user_watches=600000
实时更改,或是通过单独的配置文件永久修改:
/etc/sysctl.d/90-max_user_watches.conf
fs.inotify.max_user_watches = 600000
你可能也会想最大化 PCI 声卡的 PCI 延迟计时器,并为所有 PCI 外设提高延迟计时器(默认为 64).
$ setpci -v -d *:* latency_timer=b0 # setpci -v -s $SOUND_CARD_PCI_ID latency_timer=ff
假设 SOUND_CARD_PCI_ID=03:00.0
。
可通过以下方式获取 SOUND_CARD_PCI_ID:
$ lspci | grep -i audio
03:00.0 Multimedia audio controller: Creative Labs SB Audigy (rev 03) 03:01.0 Multimedia audio controller: VIA Technologies Inc. VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller (rev 01)
选择音频服务器
音频硬件无法同时播放来自多个应用的声音。虽然理论上 ALSA 可以被配置为混合来自多个应用的声音,但这方面的工作通常会交由音频服务器来处理。单独使用 ALSA 时难以实现低延迟,无法协调多个音频应用的实时播放、同时播放以及维持同一速率等,并且无法简单通过连接客户端的方式在多个应用间传输音频流,因此在这一场景下,你需要一个专业音频级的音频服务器。
有三个音频服务器可以选择,其中两个专为专业音频应用而设计:
- PulseAudio 是用于回放和如视频、浏览器、音乐及游戏等多媒体内容的标准服务器之一。它并没有针对专业音频进行构思,并缺乏低延迟及应用间同步的能力。
- JACK 专门针对专业音频的需要进行开发,并已在全球范围内获得长期应用,因此其非常成熟和稳定。多数专业音频应用针对 JACK API 进行开发。
- PipeWire 是在音频方面同时替代 JACK 和 PulseAudio 的选项。它适用于日常使用,不适于非常“专业”的场景。除本文涉及内容外,它同时可以处理视频路由。
音频服务器的配置很大程度上由使用场景、工作流及应用交互限制所决定。JACK Audio Connection Kit 设计为在不同应用间传输音频,并在维持低延迟下通过客户端的同步执行来同时访问同一音频硬件。它对应的 PipeWire 替代品提供了适用于大多数情况的服务器。
以下为将要介绍的音频服务器配置的模型:
#仅使用 PipeWire #PipeWire 作为 JACK 的客户端 #仅使用 JACK ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Applications │ │ Applications │ │ Applications │ ├──────────────┤ ├──────────────┤ ├──────────────┤ │ PipeWire │ │ PipeWire+JACK │ │ JACK │ ├──────────────┤ ├──────────────┤ ├──────────────┤ │ ALSA │ │ ALSA │ │ ALSA │ └──────────────┘ └──────────────┘ └──────────────┘
仅使用 PipeWire
新的 PipeWire 框架通过更优秀的简洁性取代了 JACK 及其它音频服务器。因此,建议先尝试在默认 Arch Linux 内核下使用仅 PipeWire 配置,并通过安装 pipewire-jack包 为 JACK 客户端提供支持。
对于专业音频应用,你同时需要使用 Pro Audio profile 及 PulseAudio 的混音器 pavucontrol包。请点击链接并阅读 PipeWire 维基页。
PipeWire 作为 JACK 的客户端
通过安装 pipewire-jack-client包,PipeWire 也可以被用作 JACK 的客户端。详细内容请参考 PipeWire 维基页。
仅使用 JACK
在通用性的原则下,你可以将 JACK 与实时内核搭配进一步的系统配置以达到进阶应用所需的低延迟。使用 JACK 作为唯一的音频服务器时,需要所有音频交互应用都作为 JACK 客户端运行。
不幸的是,一些流行的桌面应用(例如火狐)以及大多数游戏都取消了或是根本不支持 JACK。因此,该配置仅适合作为专业音频系统的独立设备,此时不支持 JACK 的软件影响可以忽略不计。如果你仍需使用到不支持 JACK 的软件,可以在完成下列设置后参考专业音频/示例#Advanced sound server setups。在安装和运行 JACK 前,请确保它可以访问到你的音频设备。
PulseAudio 或者其它软件在占用我的设备吗?
$ lsof +c 0 /dev/snd/pcm* /dev/dsp*
或者
$ fuser -fv /dev/snd/pcm* /dev/dsp*}}
如果你的音频设备没有显示出来,它可能是在被 PulseAudio 占用(可能是由其它软件作为需求包安装)。如果你不打算使用专业音频/示例#PulseAudio+JACK,可以将 PulseAudio 连带其它软件一起移除,以使其释放音频设备。
JACK 版本 1 已处于 “逐渐淘汰”[2] 阶段中,其不支持对称多处理(SMP),缺乏 D-Bus 及 Systemd 整合,因此建议使用官方软件源中的版本 2 jack2包。If you're going to use a JACK control GUI or a Systemd user service for Starting the audio graph, also install jack2-dbus包.
- More details in JACK Audio Connection Kit#Comparison of JACK implementations
The article on JACK describes a GUI-based and a shell-based example setup as a point of reference for your own scenario. Parameter values of JACK are discussed in detail in the #JACK parameters section and may depend on other system factors covered by the #System configuration section above.
JACK 参数
此处的目标为根据你当前使用的硬件,找到缓冲区大小和处理周期数的最佳搭配,可以先从 Frames/Period = 256 开始。对于板载和 USB 设备,在降低这两者前先试试 Periods/Buffer = 3。常用的值有:256/3, 256/2, 128/3, 128/2。
另外,采样率也需要与硬件设备匹配,你可以通过以下命令查看设备支持的采样率选项:
$ cat /proc/asound/card0/codec#0
将 card0 和 codec#0 替换为你的设备对应的值;在输出结果中,在 Extended ID 中找到 rates 和 VRA 的值。目前常见的采样率值为 48000 Hz,另外比较常见的值有 44100 Hz,96000 Hz 和 192000 Hz。
在重点关注录制或与外部设备进行调度的情况下,基本上必须使用 realtime 参数。另外,你可能会有需要设置最大优先级(至少比 /etc/security/limits.d/99-realtime-privileges.conf
中设定的系统限制低 10;最大值是预留给设备自己的)。
使用你找到的参数启动 jack,如下所示:
$ /usr/bin/jackd -R -P89 -dalsa -dhw:0 -r48000 -p128 -n2
可以使用 qjackctl包,cadenceAUR,patchageAUR 和 studio-controls-gitAUR 通过图形界面来监控 JACK 的状态和修改配置。
- 建议阅读 Linux Magazine article (2006) 来理解 JACK 参数调优
验证延迟
JACK 参数在很大程度上影响着往返延迟(RTD)。在本文中,这表示音频信号从录制,处理到回放这一过程的总耗时。下一部分将介绍影响 RTD 的各个来源相关背景,如果你已了解这一概念,可直接跳到 #测量延迟一节,或是完全跳过该部分。
延迟来源
假设有一标准的歌手录音场景。歌手的声音以声速通过空气传播到麦克风并被捕获。接下来,通过模数转换使得捕获的电信号可以被计算机进行数字信号处理。最后,通过数模转换将信号传到歌手的耳机进行回放监听,与舞台监听系统的使用场景类似。
在这一场景中,有五个对 RTD 影响最大的延迟源,并按如下顺序出现:
- 声音从歌手的嘴通过空气进行传播
- 模数转换
- 数字信号处理
- 数模转换
- 声音通过空气传播到歌手的耳朵
由于在技术上,必须在录音及回放过程中保持特定距离才能获得理想的声音,因此很难对第一个及最后一个延迟源进行改善。另外,在近距离进行录制并使用耳机进行回放时,由声音传播造成的延迟通常在个位数毫秒范围内,对人类而言难以察觉。所以,需要通过优化其它延迟源来降低 RTD。
转换延迟
理论上,JACK 通过在采样过程中使用固定值(包括帧,周期及采样率)并对模数转换过程中的音频数据进行缓存来保持低延迟,反之亦然。采样过程中的延迟可以用以下公式描述:
- Lc = n / f
Lc:毫秒(ms)为单位的采样延迟,n:帧或缓冲大小(从 16 开始的 2 的倍数),f:赫兹(Hz)为单位的采样率。
回放延迟同时用到了周期值:
- Lp = n * p / f
Lp:毫秒(ms)为单位的回放延迟,n:帧或缓冲大小(从 16 开始的 2 的倍数),p: 周期值,f:赫兹(Hz)为单位的采样率。
如之前所说,音频接口的性能决定了可用的参数搭配,具体的配置需要你进行试错。虽然需要在防止 xrun 及低延迟间进行取舍,但现在的音频接口基本都可以通过高采样率(通常到 192 KHz)来满足该需求。The audio flux of JACK clients in the digital domain is about zero and thus, negligible for latency measurements [3].
- 更多信息可参考 ALSA 维基的FramesPeriods 一节。
测量延迟
在完成#JACK 参数配置后,你可能会想验证下当前 RTD。例如,在帧或缓存大小 n = 128,周期值 p = 2,采样率 f = 48000 时,采样延迟大约为 Lc = 2,666... ms,回放延迟大约为 Lp = 5,333... ms,加起来总往返延迟 RTD = 8 ms。
由 Fons Adriaensen 编写的 jack_delay包 工具可以在单个回放通道播放一个测试音,并在单个录制通道上进行捕获来,通过测量信号的相位差来估计整个链的往返延迟。建议使用合适的线缆将音频接口的输入和输出通道连一起,或是参照 JACK 延迟测试将音响和麦克风靠近放一起。
例如,在一台仅配置 JACK 的设备上,将 playback_1 和 capture_1 (名称根据设备不同可能会改变)用线缆连接起来运行 jack_delay
,并根据上文描述的参数得到以下输出:
$ jack_delay -O system:playback_1 -I system:capture_1
capture latency = 128 playback_latency = 256 Signal below threshold... Signal below threshold... Signal below threshold... 422.507 frames 8.802 ms total roundtrip latency extra loopback latency: 38 frames use 19 for the backend arguments -I and -O 422.507 frames 8.802 ms total roundtrip latency extra loopback latency: 38 frames use 19 for the backend arguments -I and -O 422.506 frames 8.802 ms total roundtrip latency extra loopback latency: 38 frames use 19 for the backend arguments -I and -O 422.507 frames 8.802 ms total roundtrip latency extra loopback latency: 38 frames use 19 for the backend arguments -I and -O <output omitted>
根据输出的提示,可以使用 -I 19
和 -O 19
参数对 JACK 进行进一步优化,以补偿链中额外的回环延迟:
$ /usr/bin/jackd -R -P89 -dalsa -dhw:0 -r48000 -p128 -n2 -I19 -O19
- 更多信息可参考 Ardour 文档中的 延迟与延迟补偿一节。
实时内核
"实时" 这一概念在操作系统中的定义为:操作的结果可以在固定时间内得出,只有在更广的意义上才是“与现实时间同步”,例如:用户在输入后可以立即产生相应的声音。这个案例称为“低延迟”,而达成它的操作这篇文章的主要目标之一。
从一段时间前开始,默认的 Linux 内核(Arch Linux 的初始内核默认带 CONFIG_PREEMPT=y
选项)已被证明适用于低延迟操作。操作系统中对延迟的定义为:从硬件中断的开始,到对应的中断线程开始运行的时间。不幸的是,某些硬件的驱动会导致更高的延迟。因此,根据你的硬件、驱动和需求,你可能需要一个满足实时计算标准的内核。
优势与劣势
Ingo Molnar 和 Thomas Gleixner 创造的 RT_PREEMPT 补丁集是对于软/硬实时应用而言非常有意思的选项,涵盖了从专业音频到工业控制等范围。大多数专注于音频的 Linux 发行版都启用了该补丁集。一个可实时抢占的内核也将使调整 IRQ 处理线程的优先级成为可能,并有助于确保几乎不受负载影响的流畅音频。
安装
安装 linux-rt包 或是 linux-rt-lts包 包。
编译
如果你要使用实时内核补丁集来编译你自己的内核,请记住,移除模块或选项并不等同于精简内核。虽然内核映像的体积会减小,但现代的计算机系统以不再像 1995 年那时对大小敏感了。
- 更多信息可参考如何正确配置带 PREEMPT_RT 的 Linux 。
不论如何,你必须要确保:
-
Timer Frequency 设为 1000Hz(
CONFIG_HZ_1000=y
;不使用 MIDI 可以无视该项) -
禁用 APM(
CONFIG_APM=n
;在某些硬件上会产生问题 - 在 x86_64 中为默认配置)
If you truly want a slim system, we suggest you go your own way and deploy one with static /devs. You should, however, set your CPU architecture. Selecting "Core 2 Duo" for appropriate hardware will allow for a good deal of optimisation, but not so much as you go down the scale.
(实时)内核的常见问题:
- 超线程(如果怀疑是它导致的问题,可以在 UEFI 设置中将其禁用)
小技巧
- 在录制时禁用 WiFi,并关闭如浏览器等不需要的应用。很多人报告称禁用 WiFi 可提高 JACK 的性能稳定性。
- 有些 USB 音频硬件在 USB 3 接口下工作会出现问题,在该情况下请尝试 USB 2/1 接口。
- IRQ 有可能会导致问题出现。举个例子,如果显示硬件占用了总线,就会导致系统 I/O 路径被不必要地中断。具体内容请参考 FFADO IRQ Priorities How-To[失效链接 2024-07-30 ⓘ]。如果你在使用实时或较新的内核,那可以使用 rtirq包 来调整 IRQ 处理线程的优先级。
- 不要或谨慎使用 irqbalance 守护进程 [4]。
- 如果你要在 JACK 2 上使用多个音频设备,alsa_in 和 alsa_out 可将额外设备涵盖在一起,并在 JACK 接线面板上作为多个输出显示。
- 有些(守护)进程会导致 xruns 出现。如果你不需要该进程,直接杀掉就行,无需多问。
$ ls /var/run/daemons $ top # or htop, ps aux, whatever you are comfortable with $ killall -9 $processname # systemctl stop $daemonname
- 如果你碰到了大量 xruns 问题,尤其是使用了 nvidia包 的情况下,请禁用 GPU 节流。这一步可通过显卡控制面板或英伟达的“prefer maximum performance”选项(感谢 Frank Kober 在 LAU 发布的文章 [5])解决。
- 你可能会想进一步了解 ALSA:https://www.volkerschatz.com/noise/alsa.html
软件
Arch Linux 提供了 pro-audio包组 软件包组,其中包含了所有(准)专业音频相关应用。pro-audio 包组中的软件都属于 JACK 客户端,另外 lv2-plugins包组,ladspa-plugins包组,dssi-plugins包组,vst-plugins包组 和 clap-plugins包组 也是 pro-audio 的子包组。
部分软件包的信息及简介可于应用程序列表/多媒体#音频获取。特别是数字音频工作站、声音特效、音乐 Tracker、音频合成环境和音频生成器几类,它们提供了用于录制、混音、母带及音频设计的一系列工具示例。其它类别包括作谱工具、音频编辑器、音频转换器及 DJ 软件。
(尚)未包含在官方仓库的软件可通过 proaudio 获取。浏览软件包列表来查找你需要的应用,或是通过 GitHub 提出你的软件需求。
硬件
多数声卡和音频硬件都不需要安装特殊软件包或进行额外设置,只需将 JACK 配置到目标硬件即可。
并不是所有硬件都这样,针对特殊硬件请查阅分类:声音,/硬件以及 Envy24control#Supported cards 来获取更多信息。
获取帮助
邮件列表
- Arch Linux Pro-audio 关于实时多媒体相关的讨论,其中包括(准)专业音频及视频。
- Linux Audio User 与 Linux 专业音频相关的邮件列表,有更高的活跃度及大规模的用户和开发者群体关注。
IRC
- #archlinux-proaudio - Arch Linux 专业音频频道
- #lau - Linux 音频相关用户频道
- #jack - JACK 音频系统相关的开发及支持
- #lv2 - LV2 插件格式相关的开发及支持
- #ardour - Ardour DAW 相关的讨论及支持
- #opensourcemusicians - 开源软件音乐家的大型讨论频道
参考
- 专业音频 - 配置基于 Arch Linux 的专业音频环境指南
- AUR 元包:proaudio-metaAUR,soundfonts-aur-metaAUR,lv2-plugins-aur-metaAUR
- awesome-linuxaudio - 适用于 Linux 平台的专业音/视频及现场制作环境的软件和资源清单
- 多媒体及游戏 / Arch Linux 论坛
- 实时 - Linux 基金会的 PREEMPT_RT 补丁维基