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 には診断用の状態が公開されます。デスクトップオーディオでは、次の 4 種類のインターフェースが重要です。

  • PCM デバイスは、サンプリングされた再生フレームまたは録音フレームを転送します。
  • コントロールデバイスは、ミキサースイッチ、ゲイン、クロック、ジャックの状態、およびカード全体に関わるその他のコントロールを公開します。
  • Raw MIDI デバイスとシーケンサーデバイスは、MIDI データとスケジューリングを扱います。
  • タイマーデバイスは、オーディオクライアントと MIDI クライアントが使用するタイミング機能を提供します。

PCM フレームには、ある時点における各チャンネルのサンプルが 1 つずつ含まれます。ストリーミングを開始する前に、クライアントはアクセスモード、サンプル形式、チャンネル数、サンプルレート、ピリオドサイズ、バッファーサイズをネゴシエーションします。ドライバーとハードウェアがリングバッファー内を進む一方、クライアントはフレームを読み書きします。再生時にクライアントからデータが供給される前に消費されるとアンダーランが発生し、録音時に未読フレームが上書きされるとオーバーランが発生します。ALSA は両方を XRUN(一般には -EPIPE)として報告し、対応可能な場合は snd_pcm_recover() で復旧できます。

libasound は snd_pcm_* API と 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 は、1 つ以上の ALSA デバイスを所有し、libpulse または互換プラグインを介してクライアントストリームを受け付けるサーバーを実行します。用語はサーバーから見た方向に基づきます。

  • sink は再生ストリームを受け取り、通常は出力デバイスへ書き込みます。
  • source は録音ストリームを生成し、通常は入力デバイスから読み取ります。
  • sink input はアプリケーションの再生ストリームです。
  • source output はアプリケーションの録音ストリームです。
  • monitor source は sink に送られている音声を録音します。

サーバーはクライアント形式をネゴシエーションし、レートが異なるストリームをリサンプリングし、ストリーム単位の音量を適用し、再生音をミキシングして、生成したストリームを ALSA に書き込みます。録音では逆の経路をたどります。モジュールはデバイスを検出し、ネットワークオーディオ、仮想デバイス、ストリームの復元、ポリシー統合などの機能を提供します。

ルーティング、音量、Bluetooth の認可、アプリケーションストリームはログインセッションに属するため、PulseAudio はユーザーごとに実行するよう設計されています。ディストリビューションと PulseAudio のバージョンに応じて、ユーザー systemd サービス/ソケットまたは libpulse の自動起動機能が起動します。システム全体で動作するデーモンは、セキュリティとデバイスアクセスのトレードオフが異なる特殊な構成であり、デスクトップの既定構成ではありません。

稼働中のサーバーを調べるには、次を実行します。

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 のデバイス検出機能が、プロファイルとポートを持つカードとして表現します。

  • プロファイルは、ステレオ出力や入出力デュプレックスなど、カード全体のモードを選択します。ハードウェア上の制約により、プロファイルが相互排他的になることがあります。
  • ポートは、スピーカー、ヘッドフォン、マイク端子など、プロファイル内の経路を表します。
  • sink または source は、選択されたプロファイルによって作成される、アクティブなストリーミングエンドポイントです。

適切なカードを選択しただけでは不十分です。アクティブなプロファイルで録音が無効になっていたり、アクティブなポートが未接続の経路を指していたりする可能性があるためです。pactl list cards、pactl list sinks、pactl list sources の詳細出力を使用して、可用性、プロファイル、ポート、ミュート、音量、サンプル仕様を確認します。

保存済みのストリーム単位のポリシーが既定デバイスを上書きできるため、PulseAudio では既定デバイスをフォールバックと呼びます。新しく検出されたストリームはフォールバックの sink または source に送られますが、module-stream-restore は既知のアプリケーションストリームを以前のデバイスに戻すことができます。フォールバックは次のコマンドで設定します。

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

既存のストリームは、明示的に移動するか開き直す必要があります。デスクトップのコントロールパネルや pavucontrol も同じサーバー側の概念を更新し、稼働中のストリームを移動する場合にはより便利です。

レイテンシー、リサンプリング、ミキシング #

レイテンシーは経路全体で累積します。

  1. アプリケーションがフレームをキューに入れます。
  2. サーバーバッファーとスケジューリング量子が、ミキシング対象の処理を保持します。
  3. リサンプラーまたはチャンネルミキサーがストリームを変換することがあります。
  4. ALSA のピリオドとハードウェアバッファーが追加のフレームを保持します。
  5. コンバーター、Bluetooth コーデック、またはネットワーク転送によってデバイス固有の遅延が加わります。

ピリオドとバッファーを小さくするとレイテンシーは短くなりますが、アプリケーションとスケジューラーはより頻繁にウェイクアップする必要があります。期限に間に合わないと、XRUN またはサーバーのドロップアウトが発生します。バッファーを大きくすると、対話的な遅延と引き換えにスケジューリングジッターへの耐性が高まります。N フレームのバッファーによる遅延は N / sample_rate 秒なので、レイテンシーはサンプルレートと併せて報告してください。

ミキシングには共通の形式とレートが必要です。そのため、ストリームのレートがグラフまたはハードウェアのレートと一致しない場合、PulseAudio または PipeWire がリサンプリングします。ALSA の plug プラグインもリサンプリングできるため、デバイス経路が不明確だと複数の層で変換される可能性があります。測定時には、ファイルのサンプルレートが変更されず DAC に到達したと仮定せず、クライアント、サーバー、ALSA エンドポイントでネゴシエーションされた形式を特定してください。

ALSA に直接アクセスするとデスクトップサーバーのミキシング段階を回避できますが、デバイスを排他的に占有して他のアプリケーションを動作不能にすることがあります。低レイテンシーは、特定のコンポーネントを 1 つ迂回するだけでなく、適切なスケジューリング、ピリオド選択、ハードウェア動作に依存します。

PipeWire との境界 #

PipeWire は ALSA を置き換えることなく、PulseAudio が担うデスクトップサーバーの役割を置き換えられます。PipeWire サーバーは libasound を使用して ALSA デバイスをグラフノードとして公開します。アプリケーションもノードとポートを提供し、リンクがそれらの間でメディアを運びます。通常は WirePlumber がセッションポリシーを提供します。udev を基盤とする ALSA デバイスを監視し、プロファイルとルートを選択し、既定値を決定して、リンクを作成します。

互換サービスにより、既存の API が維持されます。

  • pipewire-pulse は PulseAudio プロトコルを実装するため、libpulse、pactl、PulseAudio アプリケーションは PipeWire が管理するオブジェクトを操作できます。
  • ALSA と JACK の互換プラグインは、クライアントを PipeWire にリダイレクトできます。
  • ネイティブ PipeWire クライアントは PipeWire プロトコルを直接使用します。

したがって、pactl info が成功しても、/usr/bin/pulseaudio デーモンが実行中であるとは限りません。報告されるサーバー名とアクティブなユーザーユニットを確認します。

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

セッションソケットを所有する PulseAudio プロトコルサーバーは 1 つだけにします。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 をテストする前に、そのデバイスを所有するサーバーを停止してください。停止しなければ EBUSY が返るのは想定される動作であり、診断結果にはなりません。
  3. サーバーの状態: PulseAudio と pipewire-pulse のどちらがセッションを提供しているか確認します。ユーザーユニットのログを調べ、サーバーが ALSA カードを認識していることを確認します。
  4. プロファイルとルート: アクティブなプロファイルが必要な sink または source を作成し、選択されたポートが利用可能であることを確認します。
  5. ストリームのルーティング: 稼働中の sink input または source output が存在し、ミュートされておらず、意図したデバイスを対象としていることを確認します。保存済みのアプリケーション単位のルートはフォールバックを上書きできます。
  6. 形式とタイミング: ネゴシエーションされたレート、チャンネル、バッファーサイズ、XRUN カウンターを比較します。ドロップアウトとスケジューリング負荷に相関がある場合は、PipeWire では pw-top、PulseAudio では詳細ログを使用します。
  7. 物理経路: ソフトウェアからエンドポイントまでフレームが送られていることを確認した後、ケーブル、レシーバー、コーデック、マイクのバイアス、ハードウェア音量をテストします。

設定を編集する前に、コマンドとログを記録してください。デバイス名と ID は起動ごとに変わる可能性があるため、永続的なルールでは一時的な数値のカードインデックスではなく、安定したプロパティを照合します。

アップストリームの参考資料 #

コメント

GitHub で閲覧・コメントする(投稿にはログインが必要です)