JACK Audio Connection Kit
来自 维基百科的 JACK Audio Connection Kit 条目:
- JACK Audio Connection Kit(简称 JACK,是一个递归缩写)是一种专业音频服务器守护进程,可在实现其 API 的应用程序之间为音频和 MIDI 数据提供实时、低延迟的连接。
安装
JACK API 有三种不同的实现:jackAUR、jack2包 和 pipewire-jack包。概览请参阅 #JACK 实现的比较。
安装上述软件包之一。若需支持 32 位应用程序,还应从 multilib 仓库中分别安装 lib32-jack2包 或 lib32-pipewire-jack包。
要使用 JACK 官方示例客户端和工具,请安装 jack-example-tools包。
要为 jack2包 提供另一种 ALSA MIDI 支持方式,请安装 a2jmidid包。
要让 jack2包 支持 D-Bus,请安装 jack2-dbus包。
配置
根据使用场景和硬件情况,系统可能需要进一步配置,才能使 JACK 实现获得额外资源或正常运行。
延迟
运行中的 JACK 实例的延迟(即处理一个音频数据块所需的时间)由 frames per period(每周期帧数)与 sample rate(采样率)的比值决定。
以 jackd(1) § ALSA_BACKEND_OPTIONS 为例,这两个参数分别由 -p 和 -r 选项指定。
frames per period 值(例如 1024)进行测试,再尽可能逐步降低。实时调度与额外资源
所有 JACK 实现都可以使用更高的实时调度优先级,使其比其他应用程序更频繁地获得 CPU 执行时间(例如参见 jackd(1) § OPTIONS 中的 -P)。
realtime-privileges包 软件包提供 realtime 系统用户组。通过 sysctl 配置片段,该组可使用更高的 rtprio 优先级和无限制的 memlock,也允许修改系统的 /dev/cpu_dma_latency 文件;应用程序可借此阻止 CPU 进入较深的 C 状态。
安装 realtime-privileges包,并将用户加入 realtime 组,以便使用高于默认值的实时调度优先级。
实时内核与高级调整
当需要极低延迟时,可以使用realtime kernel(例如 linux-rt包 或 linux-rt-lts包)。有关更多信息及其他高级调整,请参阅 专业音频。
启动音频图
不同 JACK 实现启动音频图的方式各不相同。
Jack
Jack1 只支持通过 jackd(1) 可执行文件,或通过支持库接口启动功能的图形前端启动。
Jack2
Jack2 支持通过 jackd(1) 可执行文件、jack_control 脚本(由 jack2-dbus包 提供)、jack@.service systemd用户服务(配置说明见 /etc/jack/example.conf),或支持库接口及 D-Bus 接口的图形前端启动。
Pipewire-jack
PipeWire 的 JACK 实现不提供 jackd(1) 可执行文件,也不集成 D-Bus。音频图由 pipewire.service systemd用户服务启动。
JACK 实现的比较
下表列出了当前的 JACK API 实现及其功能差异。
| 名称 | 维护状态 | 语言 | SMP 支持 | jackd 可执行文件 | D-Bus 集成 | Systemd 集成 | FireWire 支持 | ALSA MIDI 支持 | 多声卡支持 | 网络支持 |
|---|---|---|---|---|---|---|---|---|---|---|
| jackAUR | 停止维护 | C | 否 | 是 | 否 | 否 | ALSA/libffado包 | 内置 | jack-example-tools包 | netJACK1/ jacktrip包/ zita-njbridge包 |
| jack2包 | 活跃 | C/C++ | 是 | 是 | 是 | 是 | ALSA/libffado包 | 内置/ a2jmidid包 [2] | 内置/jack-example-tools包 | netJACK2/ jacktrip包/ zita-njbridge包 |
| pipewire-jack包 | 活跃 | C/C++ | 是 | 否 | 否 | 是 | ALSA | 内置 | 内置 | jacktrip包/ zita-njbridge包 |
JACK 控制图形界面的比较
下表列出了用于控制 JACK 的图形界面,以及它们的功能和对不同 JACK 实现的支持情况。
| 名称 | 启动/停止 jack1 | 启动/停止 jack2 | 启动/停止 pipewire-jack | 接线面板 | 保存音频图连接 | 支持 new-session-manager包 |
|---|---|---|---|---|---|---|
| cadenceAUR | 否 | 是 | 否 | 是(Catia) | 否(不支持通过 Claudia 使用 LADISH) | 否 |
| carla包 | 否 | 否 | 否 | 是 | 是 | 是 |
| patchageAUR | 否 | 否 | 否 | 是 | 否 | 否 |
| patchmatrix包 | 否 | 否 | 否 | 是 | 否 | 否 |
| qjackctl包 | 是 | 是 | 否 | 是 | 是 | 否 |
| raysessionAUR | 否 | 否 | 否 | 是 | 是 | 是 |
| studio-controls-gitAUR | 是 | 是 | 否 | 否 | 否 | 否 |
提示与技巧
与 JACK 及其音频图交互的应用程序
- Cadence — 一组有助于音频制作的工具,可检查系统、管理 JACK、调用其他工具并调整系统设置。
- Carla — 功能完善的插件宿主,支持多种音频驱动和插件格式。
- Jack Mixer — 适用于 JACK Audio Connection Kit 的多声道音频混音器。
- Patchage — 基于 JACK 和 ALSA 的模块化音频及 MIDI 接线面板。
- PatchMatrix — 采用矩阵形式呈现连接关系的 JACK 接线面板。
- QjackCtl — 用于控制 JACK 音频服务器守护进程的简易 Qt 应用程序。
- RaySession — 具有接线面板并支持 NSM 的音频会话管理器。
- Studio-Controls — 提供 USB 设备和 PulseAudio 桥接功能的 JACK 音频配置工具。
使用 MIDI 设备
JACK 能很好地处理一张声卡,同时可以处理任意数量的 MIDI 设备(例如通过 USB 连接的设备)。 如果启动 JACK 后希望使用 MIDI 键盘、合成器或其他纯 MIDI 设备,就必须先让 JACK 使用合适的声卡(即实际能够输入或输出 PCM 音频的声卡)。 完成上述步骤后即可连接 MIDI 设备。例如在 QjackCtl(qjackctl包)中单击连接按钮,便可根据使用的驱动,在 JACK-MIDI 或 ALSA-MIDI 下找到设备。
对于 JACK-MIDI,可以在 QjackCtl 的 Setup > Settings 中将 MIDI Driver 设置为 seq 或 raw,使 MIDI 设备出现在 MIDI 选项卡中。还可以在 Setup > Display > Enable client/port aliases 中启用客户端/端口别名,再启用 Enable client/port aliases editing (rename),将通用名称(如 "midi_capture_1")改成更易识别的名称。
对于 ALSA-MIDI,应在 QjackCtl 的 Setup > Misc 中启用 Enable ALSA Sequencer support。这会在 QjackCtl 的 Connect 窗口中添加 ALSA 选项卡,MIDI 控制器将显示在其中。
要将 ALSA-MIDI 桥接至 JACK-MIDI,可以使用 a2jmidid(a2jmidid包)。以下命令会将所有可用的 ALSA MIDI 端口导出为 JACK MIDI 端口:
$ a2j_control --ehw && a2j_control --start
这些端口将在 QjackCtl 的 MIDI 选项卡中显示为名为 "a2j" 的客户端。
可以在 QjackCtl 的 Setup > Options > Execute script after Startup 中添加 /usr/bin/a2j_control --ehw && /usr/bin/a2j_control --start,使 a2jmidid 自动启动。
- 问: JACK-MIDI 和 ALSA-MIDI 有什么区别?
- 答: 前者具有更好的时序精度,能够让 MIDI 事件与音频采样精确对齐。它扩展了后者,甚至可能取代后者,但目前两者仍然共存。
要安装某些 M-Audio MIDI 键盘,需要固件包 midisport-firmwareAUR,同时还必须提供 snd_usb_audio 内核模块。
有关特定 USB MIDI 设备的更多信息,请参阅 USBMidiDevices 条目。
基于 Shell 的配置示例
JACK2 可以直接通过 jackd 可执行文件启动,也可以通过基于 D-Bus 的 jack_control 程序控制。使用 jack_control 可以方便地通过 Shell 脚本启动和配置 JACK2。注意,使用 jack_control 需要安装 jack2-dbus包;使用 a2j_control 命令还需要安装 a2jmidid包(更多信息请参阅 #使用 MIDI 设备)。
创建一个在登录 X 时执行的 Shell 脚本:
start_jack.sh
#!/bin/sh jack_control start jack_control ds alsa jack_control dps device hw:HD2 jack_control dps rate 48000 jack_control dps nperiods 2 jack_control dps period 64 sleep 10 a2j_control --ehw a2j_control --start sleep 10 qjackctl &
以上脚本会启动可供其他程序使用的 JACK 实例。下面逐行解释。在寻找适合自己的最佳配置时,可以使用未通过 D-Bus 启动的 JACK2 版本,并借助 QjackCtl 图形界面反复尝试。
Shell 配置示例详解
$ jack_control start
如果 JACK 尚未启动,则将其启动。
$ jack_control ds alsa
将 JACK 配置为使用 ALSA 驱动。
$ jack_control dps device hw:HD2
让 JACK 使用名为 HD2 的 ALSA 兼容声卡。可以使用 cat /proc/asound/cards 查看声卡名称。大多数 ALSA 教程和默认配置使用声卡编号,但连接外部 MIDI 设备时编号可能让人困惑,因此使用名称更方便。
$ jack_control dps rate 48000
将 JACK 的采样率设置为 48000 Hz。此设置恰好很适合这张声卡。有些声卡仅支持 44100 Hz,很多则支持更高采样率。采样率越高,延迟越低,但对声卡、CPU 和软件支持的要求也越高。
$ jack_control dps nperiods 2
将 JACK 设置为每缓冲区 2 个周期。对于主板集成声卡、PCI、PCI-X 等设备,2 通常比较合适;对于 USB 设备,则可以使用 3。
$ jack_control dps period 64
将 JACK 设置为每周期 64 帧。帧数越少,延迟越低;此示例中的设置产生 2.67 ms 的延迟,既足够低,又不会给相应硬件带来太大压力。如果使用 USB 音频设备,可以尝试 32 帧。对于实时合成和音频效果处理,低于 3~4 ms 的延迟通常已经足够;原文认为约 5 ms 是人类能察觉的最小延迟。QjackCtl 可帮助查看运行情况:在没有客户端连接的空载状态下,CPU 使用率最好不超过 3%~5%。如果无法在避免 Xruns(表示系统处理能力跟不上需求的红色数字)的同时达到这一目标,则需要改善硬件条件。
$ sleep 10
等待上述操作完成并稳定下来。
$ a2j_control --ehw && a2j_control --start
启动 ALSA 到 JACK 的 MIDI 桥接。适合让只支持通过 ALSA 接收 MIDI 输入、不支持 JACK 的应用程序参与混音。
$ sleep 10
等待上述操作完成并稳定下来。
$ qjackctl &
启动 QjackCtl。图形界面配置可使它常驻系统托盘。它能够顺利识别由 D-Bus 启动的 JACK 会话,并管理接线面板,即这些应用程序与随后手动启动的其他 JACK 应用程序之间的连接。接线面板通过图形界面手动配置,但其中预先设置的连接会在相应应用程序启动时由 QjackCtl 自动建立。
基于图形界面的配置示例
此示例侧重于通过图形界面配置和管理 JACK。
- 安装 jack2包 和 jack2-dbus包。
- 安装 qjackctl包,并将其配置为随图形窗口/桌面系统启动。
- 确保在 QjackCtl 中设置以下选项:
- 使用 D-Bus 接口;
- 开机启动;
- 将配置保存至默认位置;
- 在应用程序启动时启动 JACK 音频服务器;
- 启用系统托盘图标;
- 启动时最小化至系统托盘。
- 重启计算机。
- 登录后,系统托盘中会出现 QjackCtl。左键单击其图标。
- 在 QjackCtl 图形界面中调整设置以降低延迟。帧大小、帧缓冲区和比特率都会影响延迟。原文指出,更大的帧大小、更小的帧缓冲区和更高的比特率有助于降低延迟,但都会增加声卡和 CPU 的负担。直接监听乐器或麦克风时,延迟最好在约 5 ms,因为更高的延迟开始变得可察觉。
另一种基于图形界面的配置方法
如果只是偶尔使用 JACK 执行高负载任务,可以在使用 JACK 时通过 QjackCtl 暂停正在运行的 PulseAudio 会话。对于初始配置,在 Settings > Advanced 子菜单中将 Server prefix 选项修改为:
pasuspender -- jackd
关闭 QjackCtl 后,PulseAudio 会话应能正常恢复。此技巧来自这篇帖子。
与 ALSA 协同运行
要使 ALSA 程序能在 JACK 运行期间播放音频,需要安装 alsa-plugins包 中的 ALSA JACK 插件。
若使用简单的双声道配置,还需要编辑(或创建)系统级配置文件 /etc/asound.conf,添加以下内容以启用插件:
# 将 ALSA API 转换至 JACK API
# 使用方法
# % aplay foo.wav
# 将其设为默认设备
pcm.!default {
type plug
slave.pcm "jack"
hint.description "Jack Audio"
}
如果输入/输出声道数不同,或者最前面的两个声道不是需要输出音频的目标声道,就不能使用 /etc/alsa/conf.d/50-jack.conf 中预定义的 JACK PCM 源,而应使用类似以下的配置:
pcm.!jack {
type jack
# 如果 "mpv --ao:alsa ..." 报错:
# [ao/alsa] Unable to set buffer time near: Invalid argument
# 取消下一行注释,以允许周期大小不与 JACK 对齐:
#align_psize = 0
playback_ports {
0 system:playback_2
1 system:playback_3
}
}
pcm.!default {
type plug
slave.pcm "jack"
hint.description "Jack Audio"
}
无需重启计算机。只需编辑 ALSA 配置文件并启动 JACK,即可使用。
请记得以普通用户身份启动。如果用户 X 运行 jackd -d alsa,则用户 Y 将无法使用该实例。
另一种更可靠但也更复杂的方法,是加载 snd-aloop 内核模块,配置并使用 ALSA 回环设备,具体说明参见这篇文章。如这里所述,这种 snd-aloop 方法也能将 Wine 的 ALSA 输出桥接到 JACK。
GStreamer
GStreamer 需要 gst-plugins-good包 软件包才能使用 JACK。该软件包包含 jackaudiosink 插件,可提供 JACK 音频播放支持。
更多信息(已过时):https://jackaudio.org/faq/gstreamer_via_jack.html
PulseAudio
如果必须保留 PulseAudio(例如 gnome-settings-daemon包 等其他软件包依赖它),则可能需要阻止它随 X 自动启动,以免抢占 JACK 使用的音频设备。
编辑 /etc/pulse/client.conf,取消 "autospawn" 一行的注释并将其设置为 "no":
;autospawn = yes autospawn = no
如果希望两者同时工作,请参阅:PulseAudio/Examples#PulseAudio through JACK。
已知 Cadence 和其他 JACK 图形界面应用程序会向 ~/.pulse/daemon.conf 写入配置。这些值会覆盖系统级默认值,可能造成意外行为(例如平坦音量)。如何更新这些配置,请参阅 PulseAudio#Configuration。
FireWire
为防止 ALSA 干扰 FireWire 设备,需要将所有与 FireWire 相关的内核模块列入黑名单。这也会阻止 PulseAudio 使用 IEEE 1394。创建以下文件:
/etc/modprobe.d/alsa-no-jack.conf
blacklist snd-fireworks blacklist snd-bebob blacklist snd-oxfw blacklist snd-dice blacklist snd-firewire-digi00x blacklist snd-firewire-tascam blacklist snd-firewire-lib blacklist snd-firewire-transceiver blacklist snd-fireface blacklist snd-firewire-motu
此模块列表在编写时是 ALSA Firewire Improve Repository 中提供的最新版本。
现在可以卸载已加载的 FireWire 模块,或重启计算机。
网络/远程音频
可以配置 JACK,让它通过网络向一台“主机”发送音频数据,再由主机将音频输出至实体设备。这可用于混合多台“从机”的音频,而不需要额外线缆或硬件混音器,并尽可能延长音频信号保持数字形式的传输路径(因为带数字输入的硬件混音器非常少见)。
配置非常简单,但网络必须支持组播流量(即在可管理网络交换机上启用 IGMP Snooping),并且所有计算机都必须运行相同主版本的 JACK(JACK1 或 JACK2),因为这两个版本的网络协议互不兼容。对于 JACK2,需要加载 netmanager 模块:
master$ jack_load netmanager -i -c
-i -c 选项指示 netmanager 将所有传入连接自动映射到默认音频设备。不使用这些选项时,每次建立传入连接都必须手动映射。可以改用 -i -h 查看所有可用选项,但请注意,选项说明会打印到 jackd 服务器输出中,jack_load 命令本身不会显示任何内容。
在客户端,需要以网络模式启动 JACK:
slave$ jackd -d net
两台计算机将建立连接,主机上会显示新的音频源:
master$ jack_lsp system:playback_1 system:playback_2 remotehost:from_slave_1 remotehost:from_slave_2
如果如上所示向 jack_load 传递 -c 选项,远程系统现在就可以播放音频。
故障排除
启动时提示“Cannot lock down memory area (Cannot allocate memory)”
请参阅 实时进程管理#配置PAM,并确认用户属于 realtime 用户组。
jack2 和 qjackctl 错误
单击 QjackCtl 的启动按钮时,仍然出现“Cannot allocate memory”和/或“Cannot connect to server socket err = No such file or directory”错误吗?
请删除 ~/.jackdrc、~/.config/jack/conf.xml 和 ~/.config/rncbc.org/QjackCtl.conf,终止 jackdbus 进程,然后重新开始配置。
(感谢 nedko)
还可以尝试执行:
$ fuser /dev/snd/*
然后根据得到的 PID 检查相应进程:
$ ps ax | grep [PID here]
这样有望找到发生冲突的程序。
日志中出现“ALSA: cannot set channel count to 1 for capture”错误
将 ALSA 输入和输出声道数从 1 改为 2。
音频出现噼啪声或爆音
CPU 或声卡的性能可能不足以承受当前的 JACK 设置。可以逐步降低比特率、减小帧大小,并增加每缓冲区的周期数,直到爆音消失。也可以尝试将采样率改为 44100 Hz 或设备原生支持的采样率,使 JACK 无需重采样便可向系统输出音频。在 jack2包 中使用 jack_control 可通过以下命令设置:
jack_control dps rate 44100
没有声音
如果所有功能看起来都正常——JACK 的界面能够显示音频活动,PulseAudio 等其他程序也能输出声音——请检查声卡支持的最大采样位深度。如果声卡只支持 16 位采样,那么在告诉 JACK 不要使用更高位深度之前,可能完全听不到声音:
jack_control dps shorts true
如果安装了 jack-example-tools包,可运行 jack_simple_client 向 JACK 输出端发送测试音。
特定应用程序的问题
VLC:启动 JACK 后没有声音
启动 VLC 并修改以下菜单选项:
- 工具 > 首选项
- 显示设置:全部
- 音频 > 输出模块 > 音频输出模块:JACK 音频输出
- 音频 > 输出模块 > JACK:自动连接到可写客户端(启用)