專業音頻
該文章描述了如何將你的系統針對多軌錄音,混音,回放或是合成音頻應用進行配置。 這類活動通常使用術語「專業音頻」進行描述,並相對需要較低的延遲。
相對於視頻剪輯或遊戲,該類應用通常不需要高端硬體。更多信息請參考 The Right Computer System for Digital Audio 一文。
高級 Linux 聲音體系(ALSA)是 Linux 內核的一部分,並在 Arch Linux 的驅動及接口中是默認的音頻系統。ALSA 在完成默認的 Arch Linux 安裝流程後應當可以開箱即用。如果出現異常,你需要在進行下一步前先排清問題。
我已正確配置好聲音系統了嗎?
$ speaker-test
- 進一步排障可參考 ALSA 。
在多數情況下,默認的 Arch Linux 內核已能滿足低延遲應用。進一步的系統配置只需在你遇到了音頻丟失,或是你確實需要/想要極低延遲的情況下進行。
為了完成優化工作,你可能需要配置一個實時內核。
儘管有些專業音頻軟體可以直接使用 ALSA,但該文章提到的大多數軟體都屬於 JACK Audio Connection Kit(又稱 JACK)客戶端。因此,你需要根據下方描述安裝並配置一個可用的音頻伺服器。
音頻硬體無法同時播放來自多個應用的聲音。雖然理論上 ALSA 可以被配置為混合來自多個應用的聲音,但這方面的工作通常會交由音頻伺服器來處理。
單獨使用 ALSA 時難以實現低延遲,無法協調多個音頻應用的實時播放、同時播放以及維持同一速率等,並且無法簡單通過連接客戶端的方式在多個應用間傳輸音頻流,因此在這一場景下,你需要一個專業音頻級的音頻伺服器:
- PipeWire 在音頻方面同時取代了 JACK 和 PulseAudio。除本文涉及內容外,它同時可以處理視頻路由。
- 注意:目前尚不明確 PipeWire 是否僅適用於日常使用,而不建議在專業場景中使用。
- JACK Audio Connection Kit(JACK)專門針對專業音頻的需要進行開發,並已在全球範圍內獲得長期應用,因此其非常成熟和穩定。大部分專業音頻應用都針對 JACK API 進行開發。
音頻伺服器的配置很大程度上由使用場景、工作流及應用交互限制所決定。JACK 設計為在不同應用間傳輸音頻,並在維持低延遲下通過客戶端的同步執行來同時訪問同一音頻硬體。它對應的 PipeWire 替代品提供了適用於大多數情況的伺服器。
以下為將要介紹的音頻伺服器配置的模型:
#仅使用 PipeWire #PipeWire 作为 JACK 的客户端 #仅使用 JACK ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Applications │ │ Applications │ │ Applications │ ├──────────────┤ ├──────────────┤ ├──────────────┤ │ PipeWire │ │ PipeWire+JACK│ │ JACK │ ├──────────────┤ ├──────────────┤ ├──────────────┤ │ ALSA │ │ ALSA │ │ ALSA │ └──────────────┘ └──────────────┘ └──────────────┘
新的 PipeWire 框架通過更優秀的簡潔性取代了 JACK 及其它音頻伺服器。因此,建議先嘗試在默認 Arch Linux 內核下使用僅 PipeWire 配置,並通過安裝 pipewire-jack包 為 JACK 客戶端提供支持。
對於專業音頻應用,你同時需要使用 Pro Audio profile 及 PulseAudio 的混音器 pavucontrol包。請點擊連結並閱讀 PipeWire 維基頁。
通過安裝 pipewire-jack-client包,PipeWire 也可以被用作 JACK 的客戶端。詳細內容請參考 PipeWire 維基頁。
在通用性的原則下,你可以將 JACK 與實時內核搭配進一步的系統配置以達到進階應用所需的低延遲。使用 JACK 作為唯一的音頻伺服器時,需要所有音頻交互應用都作為 JACK 客戶端運行。
不幸的是,一些流行的桌面應用(例如火狐)以及大多數遊戲都取消了或是根本不支持 JACK。因此,該配置僅適合作為專業音頻系統的獨立設備,此時不支持 JACK 的軟體影響可以忽略不計。如果你仍需使用到不支持 JACK 的軟體,可以在完成下列設置後參考專業音頻/示例#高級音頻伺服器配置。在安裝和運行 JACK 前,請確保它可以訪問到你的音頻設備。
PulseAudio 或者其它軟體在占用我的設備嗎?
$ lsof +c 0 /dev/snd/pcm* /dev/dsp*
或者
$ fuser -fv /dev/snd/pcm* /dev/dsp*}}
如果你的音頻設備沒有顯示出來,它可能是在被 PulseAudio 占用(可能是由其它軟體作為需求包安裝)。如果你不打算使用專業音頻/示例#PulseAudio+JACK,可以將 PulseAudio 連帶其它軟體一起移除,以使其釋放音頻設備。
JACK 版本 1 已處於 「逐漸淘汰」[1] 階段中,其不支持對稱多處理(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.
此處的目標為根據你當前使用的硬體,找到緩衝區大小和處理周期數的最佳搭配,可以先從 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 [2].
- 更多信息可參考 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 設置中將其禁用)
- Be creative, try different settings.
- Measurement is the only source of trust—always measure before and after.
你可以參考下列常見的系統優化方式:
- 將 CPU 調頻調速器設至 performance
-
配置 pam_limits(例如安裝 realtime-privileges包 並將用戶添加至
realtime組) - 使用
threadirqs內核參數(參考 [3])- 實時內核已默認啟用該參數 - 使用實時內核
- 添加
noatime至 fstab(參考性能優化#掛載選項) - 通過在啟動階段執行下列命令來提高最大 RTC 中斷請求頻率(默認為 64 Hz):
# echo 2048 > /sys/class/rtc/rtc0/max_user_freq # echo 2048 > /proc/sys/dev/hpet/max-user-freq
- 降低系統的 swappiness 值(即交換頻率,默認為
60),例如:將該值設為10可讓系統在試圖交換到硬碟前等待更長時間。More precisely, it makes the kernel to prefer keeping all applications in RAM instead of swapping background applications out. 該值可通過執行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)
- 在錄製時禁用 Wi-Fi,並關閉如瀏覽器等不需要的應用。很多人報告稱禁用 Wi-Fi 可提高 JACK 的性能穩定性。
- 有些 USB 音頻硬體在 USB 3 接口下工作會出現問題,在該情況下請嘗試 USB 2/1 接口。
- IRQ 有可能會導致問題出現。舉個例子,如果顯示硬體占用了總線,就會導致系統 I/O 路徑被不必要地中斷。具體內容請參考 FFADO IRQ Priorities How-To。如果你在使用實時或較新的內核,那可以使用 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])解決。
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 專業音頻相關的郵件列表,有更高的活躍度及大規模的用戶和開發者群體關注。
- #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 補丁維基