Linux 音訊架構

最後更新: 2023-01-24 01:00:34 +0800 +0800
tags: Linux | Audio
原文以英文撰寫。您正在閱讀AI翻譯版本。

Linux 音訊是一套堆疊,而非一個可互換的 API。ALSA 提供核心音效裝置與使用者空間 函式庫。PulseAudio 或 PipeWire 可進一步讓應用程式共用這些裝置、轉換格式、混合 串流,以及套用桌面路由政策。依照訊號流向逐層測試,可讓疑難排解成為確定性的 程序。

ALSA:核心裝置與 libasound #

ALSA 核心驅動程式會註冊音效卡及其邏輯裝置。使用者空間可透過 /dev/snd 存取 音效卡、裝置與子裝置識別碼,而 /proc/asound 則提供診斷狀態。桌面音訊主要 涉及四種介面:

  • PCM 裝置傳送取樣後的播放或擷取訊框。
  • 控制裝置提供混音器開關、增益、時脈、插孔狀態及其他整張音效卡共用的控制項。
  • Raw MIDI 與 sequencer 裝置承載 MIDI 資料及排程。
  • 計時器裝置提供音訊與 MIDI 用戶端使用的計時功能。

一個 PCM 訊框包含某一時間點每個聲道的一個取樣。開始串流前,用戶端會協商存取 模式、取樣格式、聲道數、取樣率、週期大小與緩衝區大小。驅動程式與硬體透過環形 緩衝區傳送資料,用戶端則讀取或寫入訊框。若播放端在用戶端提供資料前就耗盡資料, 便會發生 underrun;若擷取資料覆寫尚未讀取的訊框,則會發生 overrun。ALSA 將兩者 都回報為 XRUN,常見錯誤為 -EPIPE,而 snd_pcm_recover() 可復原支援的情況。

libasound 提供 snd_pcm_* 與 snd_ctl_* API,以及設定與外掛層。裝置名稱具有 不同語意:

  • hw:0,0 直接定址硬體 PCM,只接受驅動程式支援的參數。另一個直接開啟裝置的 程序可能收到 EBUSY。
  • plughw:0,0 會在需要時插入 libasound 的格式、取樣率或聲道轉換。
  • default 依循 ALSA 設定,可能解析為軟體混音器、PulseAudio 外掛或 PipeWire 外掛,而非實體硬體。

因此,aplay -D hw:0,0 測試成功只能證明核心/ALSA 路徑正常,無法證明桌面 伺服器、其選定的路由或應用程式的伺服器用戶端設定正確。

在不變更設定的情況下檢查 ALSA:

sh
cat /proc/asound/cards
aplay -l
arecord -l
aplay -L
amixer -c 0

小寫 -l 列出硬體裝置;大寫 -L 列出包含外掛在內的已設定 PCM 名稱。 alsamixer 以互動方式呈現控制項。即使 PulseAudio 與 PipeWire 的軟體音量不為 零,靜音的硬體控制項仍可能使其沒有聲音。

PulseAudio 的伺服器模型 #

PulseAudio 執行一個擁有一或多個 ALSA 裝置的伺服器,並透過 libpulse 或相容性 外掛接受用戶端串流。其術語依照伺服器所見的方向定義:

  • sink 接收播放串流,通常寫入輸出裝置。
  • source 產生擷取串流,通常從輸入裝置讀取。
  • sink input 是應用程式的播放串流。
  • source output 是應用程式的錄音串流。
  • monitor source 擷取送往 sink 的音訊。

伺服器會協商用戶端格式、在取樣率不同時重新取樣串流、套用各串流音量、混合播放 內容,並將產生的串流寫入 ALSA。擷取則沿相反路徑進行。模組負責探索裝置,並提供 網路音訊、虛擬裝置、串流還原及政策整合等功能。

PulseAudio 的設計是以每位使用者為單位執行,因為路由、音量、藍牙授權與應用程式 串流都屬於登入工作階段。依發行版及 PulseAudio 版本而異,它會由使用者 systemd 服務/socket 或 libpulse 自動衍生機制啟動。全系統 daemon 是具有不同安全性及裝置 存取權衡的特殊設定,並非桌面環境的預設值。

使用下列命令檢查執行中的伺服器:

sh
pactl info
pactl list short cards
pactl list short sinks
pactl list short sources
pactl list short sink-inputs
pactl list short source-outputs

pacat 可透過 PulseAudio 協定播放或錄音;在提供舊稱的安裝環境中,pamon 是其 別名。pa-info 會收集更完整的報告,供 PulseAudio 錯誤調查使用。

探索、設定檔、連接埠與預設值 #

實體控制器首先會成為 ALSA 音效卡。PulseAudio 的裝置探索接著將它表示為具有 設定檔與連接埠的音效卡:

  • **設定檔(profile)**選擇整張音效卡的模式,例如立體聲輸出或雙工輸入/輸出。 硬體限制可能使設定檔互斥。
  • **連接埠(port)**表示設定檔內的路由,例如揚聲器、耳機或麥克風插孔。
  • sink 或 source 是所選設定檔建立的作用中串流端點。

若作用中設定檔停用擷取,或作用中連接埠指向已中斷的路由,只選對音效卡仍不足以 正常運作。使用 pactl list cards、pactl list sinks 及 pactl list sources 的詳細輸出檢查可用性、設定檔、連接埠、靜音、音量與取樣規格。

PulseAudio 將預設裝置稱為 fallback,因為已儲存的個別串流政策可以覆寫它。新出現 的串流會前往 fallback sink 或 source,而 module-stream-restore 可將已知應用程式 串流送回先前使用的裝置。以下列命令設定 fallback:

sh
pactl set-default-sink SINK_NAME
pactl set-default-source SOURCE_NAME

現有串流可能需要明確移動或重新開啟。桌面控制面板或 pavucontrol 會更新相同的 伺服器端概念,而且通常更方便移動即時串流。

延遲、重新取樣與混音 #

完整路徑中的延遲會逐層累積:

  1. 應用程式將訊框排入佇列。
  2. 伺服器緩衝區與排程量程會暫存混音工作。
  3. 重新取樣器或聲道混音器可能轉換串流。
  4. ALSA 週期與硬體緩衝區會保存額外訊框。
  5. 轉換器、藍牙編解碼器或網路傳輸會增加裝置特有的延遲。

較小的週期與緩衝區可降低延遲,但需要應用程式與排程器更頻繁地喚醒。錯過期限會 造成 XRUN 或伺服器音訊中斷。較大的緩衝區能提高對排程抖動的容忍度,但會增加 互動延遲。回報延遲時應一併提供取樣率,因為 N 個訊框的緩衝區會產生 N / sample_rate 秒的延遲。

混音需要共通的格式與取樣率。因此,當串流的取樣率與圖形或硬體取樣率不同時, PulseAudio 或 PipeWire 會進行重新取樣。ALSA 的 plug 外掛也能重新取樣,所以 不明確的裝置路徑可能在多個層級執行轉換。進行量測時,應辨識用戶端、伺服器與 ALSA 端點協商出的格式,而不是假設檔案取樣率未經變更就抵達 DAC。

直接存取 ALSA 可避開桌面伺服器的混音階段,但可能會獨占裝置並妨礙其他應用程式。 低延遲取決於正確的排程、週期選擇與硬體行為,而不是只避開某個具名元件。

PipeWire 邊界 #

PipeWire 可取代 PulseAudio 的桌面伺服器角色,但不會取代 ALSA。PipeWire 伺服器 使用 libasound 將 ALSA 裝置呈現為圖形節點;應用程式提供節點與連接埠,連結則 在節點之間傳送媒體。WirePlumber 通常提供工作階段政策:它監控由 udev 支援的 ALSA 裝置、選擇設定檔與路由、選擇預設值,以及建立連結。

相容性服務會保留既有 API:

  • pipewire-pulse 實作 PulseAudio 協定,因此 libpulse、pactl 與 PulseAudio 應用程式可操作 PipeWire 管理的物件。
  • ALSA 與 JACK 相容性外掛可將用戶端重新導向 PipeWire。
  • 原生 PipeWire 用戶端直接使用 PipeWire 協定。

因此,pactl info 成功不代表 /usr/bin/pulseaudio daemon 正在執行。請檢查回報 的伺服器名稱與作用中的使用者單元:

sh
systemctl --user status pipewire.service wireplumber.service pipewire-pulse.service
systemctl --user status pulseaudio.service pulseaudio.socket
wpctl status

每個工作階段 socket 應只由一個 PulseAudio 協定伺服器擁有。在 PipeWire 系統上, wpctl status、wpctl inspect ID、pw-dump 與 pw-top 顯示原生圖形及排程狀態; pactl 則顯示相容性檢視。

依訊號流向排解問題 #

從最低層的失敗邊界開始,避免同時變更多個層級:

  1. 核心探索: 在 /proc/asound/cards、aplay -l 與 arecord -l 中確認 音效卡。檢查開機核心訊息中與韌體、探測、USB 或 HDMI 有關的錯誤。
  2. ALSA 控制項: 使用 amixer 或 alsamixer 檢查靜音、增益與路由控制項。 只有在停止擁有該 PCM 的伺服器後,才測試已知的 PCM;否則 EBUSY 是預期結果, 而非診斷依據。
  3. 伺服器狀態: 判斷由 PulseAudio 或 pipewire-pulse 服務此工作階段。 檢查使用者單元日誌,並確認伺服器能看見 ALSA 音效卡。
  4. 設定檔與路由: 驗證作用中設定檔會建立所需的 sink 或 source,且其選定的 連接埠可用。
  5. 串流路由: 確認即時 sink input 或 source output 存在、未靜音,且指向 預期裝置。已儲存的個別應用程式路由可能覆寫 fallback。
  6. 格式與時序: 比較協商的取樣率、聲道、緩衝區大小及 XRUN 計數器。若音訊 中斷與排程負載相關,請在 PipeWire 上使用 pw-top,或查看詳細 PulseAudio 日誌。
  7. 實體路徑: 在確認軟體已將訊框送至端點後,測試纜線、接收器、編解碼器、 麥克風偏壓與硬體音量。

編輯設定前先擷取命令輸出及日誌。裝置名稱與 ID 可能在重新開機後改變,因此持久 規則應比對穩定屬性,而非暫時性的音效卡數字索引。

上游參考資料 #

評論

在 GitHub 上閱讀或評論(發表評論需要登入)