跳转到内容

JACK Audio Connection Kit

来自 Arch Linux 中文维基

来自 维基百科的 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 选项指定。

注意:根据硬件和系统配置的不同,过低的延迟可能导致音频中断(也称为 Xruns)。 建议先采用相对较高的 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 上游项目表示,大多数用户并不需要realtime kernel。[1]

启动音频图

不同 JACK 实现启动音频图的方式各不相同。

Jack

Jack1 只支持通过 jackd(1) 可执行文件,或通过支持库接口启动功能的图形前端启动。

Jack2

Jack2 支持通过 jackd(1) 可执行文件、jack_control 脚本(由 jack2-dbus包 提供)、jack@.service systemd用户服务(配置说明见 /etc/jack/example.conf),或支持库接口及 D-Bus 接口的图形前端启动。

警告:启动音频图时,只能选择 jackd(1) 或 jackdbus/jack_control 其中一种方式。混用两种方式可能导致非常混乱的结果!

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-example-tools包 中的 jack_load 使用内部客户端的说明。 (在 Talk:JACK Audio Connection Kit 中讨论)

与 JACK 及其音频图交互的应用程序

  • Cadence — 一组有助于音频制作的工具,可检查系统、管理 JACK、调用其他工具并调整系统设置。
https://kx.studio/Applications:Cadence || cadenceAUR
  • Carla — 功能完善的插件宿主,支持多种音频驱动和插件格式。
https://kx.studio/Applications:Carla || carla包
  • Jack Mixer — 适用于 JACK Audio Connection Kit 的多声道音频混音器。
https://github.com/jack-mixer/jack_mixer || jack_mixer包
  • Patchage — 基于 JACK 和 ALSA 的模块化音频及 MIDI 接线面板。
https://drobilla.net/software/patchage || patchageAUR
  • PatchMatrix — 采用矩阵形式呈现连接关系的 JACK 接线面板。
https://git.open-music-kontrollers.ch/~hp/patchmatrix || patchmatrix包
  • QjackCtl — 用于控制 JACK 音频服务器守护进程的简易 Qt 应用程序。
https://qjackctl.sourceforge.io/ || qjackctl包
  • RaySession — 具有接线面板并支持 NSM 的音频会话管理器。
https://raysession.tuxfamily.org/ || raysessionAUR
  • Studio-Controls — 提供 USB 设备和 PulseAudio 桥接功能的 JACK 音频配置工具。
https://github.com/ovenwerks/studio-controls/ || studio-controls-gitAUR

使用 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 控制器将显示在其中。

注意:jack2包 默认不包含针对仅支持旧式 ALSA MIDI 的应用程序的桥接功能。因此,在上游实现相应功能之前,需要安装 a2jmidid包。

要将 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 自动启动。

注意:在 QjackCtl 中连接 MIDI 键盘控制器时,请先选择 Expand All,然后将所需的 Output Ports(位于 Readable Clients 下)连接到 Input Ports(位于 Writable Clients 下)。也可以直接选择可写客户端作为目标,而不逐一选择端口,这样会连接其下方当前显示的所有输出端口。
  • 问: 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 模块,或重启计算机。

网络/远程音频

本文或本节内容已经过时。

原因: 本节未涵盖 jackAUR 与 jack2包 的 netJACK 实现之间的差异,也未介绍 zita-njbridge包 或 jacktrip包。 (在Talk:JACK Audio Connection Kit讨论)

可以配置 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:自动连接到可写客户端(启用)

参见