Ubuntu-22.04 on RPi4でオーディオシステムについてのメモ
以前に色々調べたけども、実際に動かしながらもう少し整理
なお、ゴールはPipewireを使うこと。
マイクとスピーカーは以下。
バッファロー BUFFALO PC用スピーカー USB電源コンパクトサイズ ホワイト BSSP105UWH
DUNGZDUZ USB Microphone for Laptop and Desktopノートパソコン・デスクトップ用USBマイク
スピーカーはオーディオジャック、マイクはUSBで接続している。
オーディオデバイスの確認
sudo apt update
sudo apt install -y alsa-utils
出力デバイスの確認
aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: b1 [bcm2835 HDMI 1], device 0: bcm2835 HDMI 1 [bcm2835 HDMI 1]
Subdevices: 4/4
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
card 1: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
Subdevices: 4/4
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
入力デバイスの確認
arecord -l
**** List of CAPTURE Hardware Devices ****
card 2: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
再生の確認
aplay /usr/share/sounds/alsa/Front_Center.wav
何も聞こえない。出力デバイスのデフォルトがどうやらHDMIの方になっているようなので、デバイスを明示的に指定する。
aplay -D plughw:1,0 /usr/share/sounds/alsa/Front_Center.wav
こちらは問題なく聞こえた。
録音の確認。5秒間録音する。入力デバイスもデフォルトが存在していないため、こちらも明示的にデバイスを指定する。
arecord -D plughw:2,0 -d 5 test.wav
aplay -D plughw:1,0 test.wav
録音した内容が聞こえればOK。
再生・録音デバイスのデフォルト設定を行う。~/.asoundrc
もしくは /etc/asound.conf
に設定する。今回は ~/.asoundrc
に。
# 再生用デバイスの定義
pcm.playback {
type plug
slave.pcm "hw:1,0"
}
# 録音用デバイスの定義
pcm.capture {
type plug
slave.pcm "hw:2,0"
}
# default を asym (playback + capture) にマップ
pcm.!default {
type asym
playback.pcm "playback"
capture.pcm "capture"
}
これでデバイス指定不要で使える。
arecord -d 5 test.wav
aplay test.wav
ステレオのテスト
speaker-test -c2 -twav
以下のように左右のスピーカーからそれぞれ聞こえてくればOK。
speaker-test 1.2.6
Playback device is default
Stream parameters are 48000Hz, S16_LE, 2 channels
WAV file(s)
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 480 to 32768
Period size range from 480 to 32768
Using max buffer size 32768
Periods = 4
was set period_size = 8192
was set buffer_size = 32768
0 - Front Left
1 - Front Right
Time per period = 2.403406
0 - Front Left
1 - Front Right
Time per period = 3.069295
0 - Front Left
1 - Front Right
Time per period = 2.900497
0 - Front Left
1 - Front Right
Time per period = 3.069938
0 - Front Left
ミキサーでボリュームなどの設定
amixer
HDMIが選択されている。
Simple mixer control 'HDMI',0
Capabilities: pvolume pvolume-joined pswitch pswitch-joined
Playback channels: Mono
Limits: Playback -10239 - 400
Mono: Playback 0 [96%] [0.00dB] [on]
~/.asoundrc
で設定したのは音声データの入出力(pcm
)のデフォルトであって、音量はミュートなどミキサーの設定はctl
で指定する必要がある。
とりあえず個別に指定する場合は-c カード番号
で指定すれば良い。
スピーカー側
amixer -c 1
Simple mixer control 'Headphone',0
Capabilities: pvolume pvolume-joined pswitch pswitch-joined
Playback channels: Mono
Limits: Playback -10239 - 400
Mono: Playback 31 [97%] [0.31dB] [on]
ボリュームの変更は以下のような感じで行える。
# ボリュームを50%に設定
amixer -c 1 set Headphone 50%
Simple mixer control 'Headphone',0
Capabilities: pvolume pvolume-joined pswitch pswitch-joined
Playback channels: Mono
Limits: Playback -10239 - 400
Mono: Playback -4919 [50%] [-49.19dB] [on]
ミュート
amixer -c 1 set Headphone mute
offになっている
Simple mixer control 'Headphone',0
Capabilities: pvolume pvolume-joined pswitch pswitch-joined
Playback channels: Mono
Limits: Playback -10239 - 400
Mono: Playback -4919 [50%] [-49.19dB] [off]
ミュート解除しつつ音声を最大に。
amixer -c 1 set Headphone 100% unmute
Simple mixer control 'Headphone',0
Capabilities: pvolume pvolume-joined pswitch pswitch-joined
Playback channels: Mono
Limits: Playback -10239 - 400
Mono: Playback 400 [100%] [4.00dB] [on]
次にマイク側
amixer -c 2
マイクは2つある。
Simple mixer control 'Mic',0
Capabilities: cvolume cvolume-joined cswitch cswitch-joined
Capture channels: Mono
Limits: Capture 0 - 16
Mono: Capture 0 [0%] [0.00dB] [on]
Simple mixer control 'Auto Gain Control',0
Capabilities: pswitch pswitch-joined
Playback channels: Mono
Mono: Playback [on]
マイク入力のゲインやミュートについてはスピーカーとやり方は同じ。で、マイク側には自動ゲイン調整もあって、入力レベルに応じて自動でゲインを調整してくれるらしい。あと、自動ゲイン調整はON/OFFもできるみたい。
ミキサーにはalsamixerもある。こちらはTUIで確認・設定ができる。
alsamixer
F6でデバイスを切り替えて、カーソルの上下で音量を変更できる。
サウンドサーバ。ALSAとサウンドサーバの関係性は以下がわかりやすい。
ということで、o4-miniによると、Linuxの主なサウンドサーバには以下のようなものがある。
- PulseAudio
- 主な用途: 一般的なデスクトップ再生・録音
- レイテンシ: 中程度(約10~30ms)
- 互換性: ALSA クライアント多数、PulseAPI 依存アプリ広く対応
- ルーティング: シンプルなシンク/ソース切替、仮想デバイス作成可
- ネットワーク機能: RTP ストリーミング、module-raop(AirPlay)対応
- Bluetooth: A2DP/LE、HSP/HFP(module-bluetooth)
- 設定: GUI(pavucontrol)やシンプル設定ファイル
- 備考: Ubuntu 22.04 標準、PipeWire へ移行中
- PipeWire
- 主な用途: オーディオ&ビデオの統合管理、低レイテンシ/高機能
- レイテンシ: 低(設定次第で5ms以下も可能)
- 互換性: PulseAudio と JACK クライアント両方をネイティブサポート
- ルーティング: ノード&ポートを自由にグラフ状に接続(qpwgraph/helvum)
- ネットワーク機能: RTP、RAOP、Bluetooth LE など内蔵
- Bluetooth: libspa-bluetooth 経由で A2DP/LE、HFP/HSP
- ビデオ対応: 映像ストリームも扱える
- 設定: 設定ファイル多め、WirePlumber でポリシー管理
- 備考: 将来性高、Linux のメディア統合プラットフォーム
- JACK Audio Connection Kit
- 主な用途: プロ音響・音楽制作、リアルタイムルーティング
- レイテンシ: 極低(1ms台を狙える)
- 互換性: ALSA バックエンド経由で多くのアプリ対応
- ルーティング: ケーブル接続感覚でアプリ間を細かくルーティング
- ネットワーク機能: ネイティブなし(外部プラグインで対応可)
- Bluetooth: なし(外部ブリッジで実装可能)
- 設定: 設定ファイル少なめ、qjackctl で GUI 操作可能
- 備考: DAW/ソフトシンセ用に成熟、低レイテンシ重視環境に最適
で、自分の今回の目的はPipeWireを試すことなのだけれども、どのサウンドサーバを選ぶべきか?どういうステップで学ぶべきか?をo4-miniに聞いたところ、以下のような感じだった。
サウンドサーバー層(PulseAudio/PipeWire/JACK)に絞った選択ガイドと学習ステップです。
1. どれを選ぶべきか?(用途別ガイド)
- 一般的なデスクトップ用途
- → PulseAudio
- デスクトップアプリの音量管理や Bluetooth が手軽
- GUI ツール(pavucontrol)が豊富で学習コストが低い
- Audio+Video を統合して低レイテンシ運用したい
- → PipeWire
- PulseAudio/JACK クライアントをそのまま動かせる
- 低レイテンシかつ映像も含むメディア処理が可能
- プロ向け・音楽制作向けのミキシング/ルーティング
- → JACK
- 1ms 台の極低遅延
- ケーブル接続感覚でアプリ同士を細かくパッチベイ接続
2. 学習ステップ
- PulseAudio 入門
- インストール&起動
sudo apt install pulseaudio pavucontrol systemctl --user enable --now pulseaudio
- GUI で体験:
pavucontrol
を使い、アプリごとのシンク/ソース切替を試す- CLI 操作:
pactl list-sinks
/pactl set-default-sink
などで出力先変更を練習- PipeWire(on Pulse) への移行
- ブリッジ導入
sudo apt install pipewire pipewire-pulse wireplumber systemctl --user disable pulseaudio systemctl --user enable --now pipewire pipewire-pulse wireplumber
- 確認:
pactl info
で “Server Name: PulseAudio (on PipeWire…)” を見る- GUI 操作:引き続き
pavucontrol
で動作を確かめる- PipeWire ネイティブ操作
- ネイティブツール体験:
pw-cli list-objects
/pw-top
でノード確認qpwgraph
orhelvum
でグラフ上にノード&ポートを繋いでみる- JACK クライアントも動かす:
libspa-0.2-jack
を入れて、jack_simple_client
等で接続テスト- JACK 入門
- 環境構築
sudo apt install jackd2 qjackctl jack_control start
- GUI でパッチベイ操作:
qjackctl
でクライアント間ルーティングを体験- DAW 連携:Ardour などを繋いで、複数トラックのルーティングを練習
- 応用:マルチサーバ運用と自動化
- PulseAudio と JACK(あるいは PipeWire 上の JACK)を併用する方法を学ぶ
- WirePlumber のポリシー設定で、自動接続ルールを定義してみる
ポイント
- まずは GUI で感覚を掴む → 次に CLI/ネイティブツールへ
- 段階的に切り替え → PulseAudio → PipeWire(on Pulse) → PipeWire ネイティブ → JACK
- 目的に合わせた最適解を選択 → デスクトップなら PulseAudio、制作なら JACK、統合なら PipeWire
以上の流れで進めれば、各サウンドサーバの特徴と操作感をしっかり学べます。
PulseAudioは以前少し触れているけども、改めておさらいしつつ、PipeWireを試そうと思う。JACKはちょっと今回はパスで。
PulseAudio
インストール
sudo apt install -y pulseaudio pulseaudio-utils pavucontrol
ユーザサービスとして起動する。enable --now
とかあるの初めて知った。
systemctl --user enable --now pulseaudio
Created symlink /home/kun432/.config/systemd/user/default.target.wants/pulseaudio.service → /usr/lib/systemd/user/pulseaudio.service.
Created symlink /home/kun432/.config/systemd/user/sockets.target.wants/pulseaudio.socket → /usr/lib/systemd/user/pulseaudio.socket.
出力先(sink)の確認
pactl list short sinks
0 alsa_output.platform-bcm2835_audio.stereo-fallback module-alsa-card.c s16le 2ch 44100HzSUSPENDED
1 alsa_output.platform-bcm2835_audio.stereo-fallback.2 module-alsa-card.c s16le 2ch 44100HzSUSPENDED
0がHDMIで、1がヘッドフォン。
入力元(source)の確認
pactl list short sources
0 alsa_input.usb-C-Media_Electronics_Inc._USB_PnP_Sound_Device-00.analog-mono module-alsa-card.cs16le 1ch 44100Hz SUSPENDED
1 alsa_output.platform-bcm2835_audio.stereo-fallback.monitor module-alsa-card.c s16le 2ch 44100Hz SUSPENDED
2 alsa_output.platform-bcm2835_audio.stereo-fallback.2.monitor module-alsa-card.c s16le 2ch 44100Hz SUSPENDED
0 が USB マイクで、1、2はsinkのそれぞれのモニターになっている。
こういう感じか。
現在の設定を確認
pactl info
erver String: /run/user/1000/pulse/native
Library Protocol Version: 35
Server Protocol Version: 35
Is Local: yes
Client Index: 5
Tile Size: 65496
User Name: kun432
Host Name: rpi2
Server Name: pulseaudio
Server Version: 15.99.1
Default Sample Specification: s16le 2ch 44100Hz
Default Channel Map: front-left,front-right
Default Sink: alsa_output.platform-bcm2835_audio.stereo-fallback.2
Default Source: alsa_input.usb-C-Media_Electronics_Inc._USB_PnP_Sound_Device-00.analog-mono
Cookie: 7eda:bc6c
ALSAのデフォルトと同じく、PulseAudioでも、ヘッドフォン・USBマイクがそれぞれデフォルトになっている。PulseAudio側でデフォルトを変えたい場合は以下のようにすれば良い。
pactl set-default-sink alsa_output.platform-bcm2835_audio.stereo-fallback
pactl set-default-source alsa_input.usb-C-Media_Electronics_Inc._USB_PnP_Sound_Device-00.analog-mono
ではテスト。
PulseAudio経由で再生させるにはpaplay
を使う。
paplay /usr/share/sounds/alsa/Front_Center.wav
録音はparec
。parec
は生のPCMデータ(ヘッダなどがないrawデータ)を出力するので、WAV等にするには変換が必要になる。ここではsoxを使ってWAVファイルに変換するが、ffmpegでもよい。
sudo apt install -y sox
parec --format=s16le --rate=44100 --channels=1 | sox -t raw -r 44100 -e signed-integer -b 16 -c 1 - test.wav
paplay test.wav
あとparecord
を使うと、WAVでそのまま出力できる。こっちが楽だな。
parecord --file-format=wav test.wav
paplay test.wav
上記はデフォルトのsink/sourceが使用されていたが、デバイスを指定する場合は-d/--device
でsink/source名を指定すればいいみたい。以下のような感じ。
# paplay
paplay
--device=alsa_output.platform-bcm2835_audio.stereo-fallback.2 \
/usr/share/sounds/alsa/Front_Center.wav
# parec
parec \
--device=alsa_input.usb-C-Media_Electronics_Inc._USB_PnP_Sound_Device-00.analog-mono \
--format=s16le --rate=44100 --channels=1 \
| sox -t raw -r 44100 -e signed-integer -b 16 -c 1 - test.wav
# parecord
parecord \
--device=alsa_input.usb-C-Media_Electronics_Inc._USB_PnP_Sound_Device-00.analog-mono \
--file-format=wav test.wav
上でも少し触れたが、デフォルトのsink/sourceの切り替えやボリューム調整などはpactl
で行える。例えば出力ボリュームの確認・変更。
まずボリュームの確認。デフォルトsink/sourceの場合は@DEFAULT_SINK@
/ @DEFAULT_SOURCE@
みたい。sink/sounceのそれぞれの名前を指定、または一覧時のインデックスで指定することもできるみたい。
pactl get-sink-volume @DEFAULT_SINK@
Volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
balance 0.00
50%に変更
pactl set-sink-volume @DEFAULT_SINK@ 50%
pactl get-sink-volume @DEFAULT_SINK@
Volume: front-left: 32768 / 50% / -18.06 dB, front-right: 32768 / 50% / -18.06 dB
balance 0.00
ミュートの確認
pactl get-sink-mute @DEFAULT_SINK@
Mute: no
ミュート
pactl set-sink-mute @DEFAULT_SINK@ 1
pactl get-sink-mute @DEFAULT_SINK@
Mute: yes
ミュート解除
pactl set-sink-mute @DEFAULT_SINK@ 0
pactl get-sink-mute @DEFAULT_SINK@
Mute: no
同じことを対話っぽくできるpacmd
というのもあるがパス。
GUIの場合は、pavucontrol
を使えば良いみたいなのだが・・・
pavucontrol
(pavucontrol:5606): Gtk-WARNING **: 06:41:48.851: cannot open display:
これはデスクトップ環境もしくはX11フォワーディングが必要にある・・・
TUIでできるものに ncpamixer
というのがあるみたい。ただこれはパッケージがないので、ビルドする必要がありそう。
なお、上でいろいろPulseAudioの設定を変更しているが、これらはランタイムのみ有効で再起動するとリセットされるみたい。設定の永続化は、ユーザサービスの場合は ~/.config/pulse/default.pa
を使うのが良さそう。/etc/pulse/default.pa
はシステム全体となる。
ncpamixer試してみた
git clone https://github.com/fulhax/ncpamixer && cd ncpamixer
sudo apt install -y build-essential cmake libncurses-dev libpulse-dev pandoc
make USE_WIDE=True
./build/ncpamixer
自分の環境はキーボードショートカットがあまり動かないのだが、マウスクリックは動く様子。
PulseAudioの少し凝った使い方
エコーキャンセラーをかます
マイクの低遅延モニタリング(ハウリングするのでヘッドフォン推奨)
pactl load-module module-loopback \
source=alsa_input.usb-C-Media_Electronics_Inc._USB_PnP_Sound_Device-00.analog-mono \
sink=alsa_output.platform-bcm2835_audio.stereo-fallback.2 \
latency_msec=1
# モニタリングを止める場合
pactl list short modules | grep loopback
# ex: 以下のように出力される
# 23 module-loopback source=alsa_input.usb-C-Media_Electronics_Inc._USB_PnP_Sound_Device-00.analog-mono sink=alsa_output.platform-bcm2835_audio.stereo-fallback.2 latency_msec=1
# 該当のモジュ―ルのインデックス番号でアンロード
pactl unload-module 23
再起動してたら色々変わった。
aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
pactl list short sinks
0 alsa_output.platform-bcm2835_audio.stereo-fallback module-alsa-card.c s16le 2ch 48000Hz SUSPENDED
pactl list short sources
0 alsa_input.usb-C-Media_Electronics_Inc._USB_PnP_Sound_Device-00.analog-mono module-alsa-card.c s16le 1ch 44100Hz SUSPENDED
1 alsa_output.platform-bcm2835_audio.stereo-fallback.monitor module-alsa-card.c s16le 2ch 48000Hz SUSPENDED
うーん、デバイスが1つづつしかないので、デフォルトもそれっぽく動いてるけど、.asoundrc
の書き方は果たしてどうすべきかぁ・・・
とりあえずこれで。
pcm.playback {
type plug
slave.pcm {
type hw
card "Headphones"
device 0
}
}
pcm.capture {
type plug
slave.pcm {
type hw
card "Device"
device 0
}
}
pcm.!default {
type asym
playback.pcm "playback"
capture.pcm "capture"
}
PipeWire
PipeWireをインストール。
- pipewire: Core デーモン
- pipewire-pulse: PulseAudio クライアントの互換レイヤー
- wireplumber: セッションマネージャ。PipeWire のポリシー を管理する。
sudo apt install -y pipewire pipewire-pulse wireplumber
PulseAudioを停止して無効化
systemctl --user disable --now pulseaudio.service pulseaudio.socket
systemctl --user mask --now pulseaudio.socket
PipeWireを起動して有効化、PulseAudio APIへのブリッジも。
systemctl --user enable --now pipewire pipewire-pulse wireplumber
確認
pactl info
"Server Name"にPipeWireと表示されていればOK
Server String: /run/user/1000/pulse/native
Library Protocol Version: 35
Server Protocol Version: 35
Is Local: yes
Client Index: 75
Tile Size: 65496
User Name: kun432
Host Name: rpi2
Server Name: PulseAudio (on PipeWire 0.3.48)
Server Version: 15.0.0
Default Sample Specification: float32le 2ch 48000Hz
Default Channel Map: front-left,front-right
Default Sink: alsa_output.platform-bcm2835_audio.stereo-fallback
Default Source: alsa_input.usb-C-Media_Electronics_Inc._USB_PnP_Sound_Device-00.mono-fallback
Cookie: b1fc:16a8
PipeWireのネイティブなCLIで確認
pw-cli ls Node
PipeWireでは、PipeWireが管理するあらゆる要素を「ノード」と呼ぶらしい。例えば、ハードウェアデバイス、PulseAudioブリッジ、アプリケーション、WirePlumber・media-sessionなどが作成するポリシー管理ノード、などが「ノード」にあたる。
id 28, type PipeWire:Interface:Node/3
object.serial = "28"
factory.id = "10"
priority.driver = "20000"
node.name = "Dummy-Driver"
id 29, type PipeWire:Interface:Node/3
object.serial = "29"
factory.id = "10"
priority.driver = "19000"
node.name = "Freewheel-Driver"
id 36, type PipeWire:Interface:Node/3
object.serial = "37"
factory.id = "10"
client.id = "34"
node.name = "Midi-Bridge"
media.class = "Midi/Bridge"
id 55, type PipeWire:Interface:Node/3
object.serial = "56"
object.path = "v4l2:/dev/video14"
factory.id = "10"
client.id = "34"
device.id = "46"
node.description = "bcm2835-isp"
node.name = "v4l2_input.platform-bcm2835-isp.2"
media.class = "Video/Source"
media.role = "Camera"
id 57, type PipeWire:Interface:Node/3
object.serial = "58"
object.path = "v4l2:/dev/video15"
factory.id = "10"
client.id = "34"
device.id = "47"
node.description = "bcm2835-isp"
node.name = "v4l2_input.platform-bcm2835-isp.3"
media.class = "Video/Source"
media.role = "Camera"
id 59, type PipeWire:Interface:Node/3
object.serial = "60"
object.path = "v4l2:/dev/video21"
factory.id = "10"
client.id = "34"
device.id = "50"
node.description = "bcm2835-isp"
node.name = "v4l2_input.platform-bcm2835-isp.6"
media.class = "Video/Source"
media.role = "Camera"
id 61, type PipeWire:Interface:Node/3
object.serial = "62"
object.path = "v4l2:/dev/video22"
factory.id = "10"
client.id = "34"
device.id = "51"
node.description = "bcm2835-isp"
node.name = "v4l2_input.platform-bcm2835-isp.7"
media.class = "Video/Source"
media.role = "Camera"
id 67, type PipeWire:Interface:Node/3
object.serial = "68"
object.path = "alsa:pcm:1:hw:1:capture"
factory.id = "18"
client.id = "34"
device.id = "53"
priority.session = "2000"
priority.driver = "2000"
node.description = "PCM2902 Audio Codec Mono"
node.name = "alsa_input.usb-C-Media_Electronics_Inc._USB_PnP_Sound_Device-00.mono-fallback"
node.nick = "USB PnP Sound Device"
media.class = "Audio/Source"
id 68, type PipeWire:Interface:Node/3
object.serial = "69"
object.path = "alsa:pcm:0:hw:0:playback"
factory.id = "18"
client.id = "34"
device.id = "54"
priority.session = "1000"
priority.driver = "1000"
node.description = "Built-in Audio Stereo"
node.name = "alsa_output.platform-bcm2835_audio.stereo-fallback"
node.nick = "bcm2835 Headphones"
media.class = "Audio/Sink"
上記のうち、以下がマイクとヘッドフォンのノード。
id 67, type PipeWire:Interface:Node/3
(snip)
node.description = "PCM2902 Audio Codec Mono"
node.name = "alsa_input.usb-C-Media_Electronics_Inc._USB_PnP_Sound_Device-00.mono-fallback"
node.nick = "USB PnP Sound Device"
media.class = "Audio/Source"
id 68, type PipeWire:Interface:Node/3
(snip)
node.description = "Built-in Audio Stereo"
node.name = "alsa_output.platform-bcm2835_audio.stereo-fallback"
node.nick = "bcm2835 Headphones"
media.class = "Audio/Sink"
次に「ポート」。「ポート」は各ノードの入出力ポートを示す。つまりノード間のつながりやルーティングを確認できる。
pw-cli ls Port
id 31, type PipeWire:Interface:Port/3
object.serial = "70"
object.path = "alsa:pcm:1:hw:1:capture:capture_0"
format.dsp = "32 bit float mono audio"
node.id = "67"
audio.channel = "MONO"
port.id = "0"
port.name = "capture_MONO"
port.direction = "out"
port.physical = "true"
port.terminal = "true"
port.alias = "USB PnP Sound Device:capture_MONO"
id 37, type PipeWire:Interface:Port/3
object.serial = "38"
object.path = "alsa:seq:default:client_14:playback_0"
format.dsp = "8 bit raw midi"
node.id = "36"
port.id = "0"
port.name = "Midi Through:(playback_0) Midi Through Port-0"
port.direction = "in"
port.physical = "true"
port.terminal = "true"
port.alias = "Midi Through:Midi Through Port-0"
id 38, type PipeWire:Interface:Port/3
object.serial = "39"
object.path = "alsa:seq:default:client_14:capture_0"
format.dsp = "8 bit raw midi"
node.id = "36"
port.id = "0"
port.name = "Midi Through:(capture_0) Midi Through Port-0"
port.direction = "out"
port.physical = "true"
port.terminal = "true"
port.alias = "Midi Through:Midi Through Port-0"
id 56, type PipeWire:Interface:Port/3
object.serial = "57"
node.id = "55"
port.id = "0"
port.name = "out_0"
port.direction = "out"
port.physical = "true"
port.terminal = "true"
id 58, type PipeWire:Interface:Port/3
object.serial = "59"
node.id = "57"
port.id = "0"
port.name = "out_0"
port.direction = "out"
port.physical = "true"
port.terminal = "true"
id 60, type PipeWire:Interface:Port/3
object.serial = "61"
node.id = "59"
port.id = "0"
port.name = "out_0"
port.direction = "out"
port.physical = "true"
port.terminal = "true"
id 62, type PipeWire:Interface:Port/3
object.serial = "63"
node.id = "61"
port.id = "0"
port.name = "out_0"
port.direction = "out"
port.physical = "true"
port.terminal = "true"
id 63, type PipeWire:Interface:Port/3
object.serial = "74"
object.path = "alsa:pcm:0:hw:0:playback:monitor_1"
format.dsp = "32 bit float mono audio"
node.id = "68"
audio.channel = "FR"
port.id = "1"
port.name = "monitor_FR"
port.direction = "out"
port.monitor = "true"
port.alias = "bcm2835 Headphones:monitor_FR"
id 64, type PipeWire:Interface:Port/3
object.serial = "72"
object.path = "alsa:pcm:0:hw:0:playback:monitor_0"
format.dsp = "32 bit float mono audio"
node.id = "68"
audio.channel = "FL"
port.id = "0"
port.name = "monitor_FL"
port.direction = "out"
port.monitor = "true"
port.alias = "bcm2835 Headphones:monitor_FL"
id 65, type PipeWire:Interface:Port/3
object.serial = "73"
object.path = "alsa:pcm:0:hw:0:playback:playback_1"
format.dsp = "32 bit float mono audio"
node.id = "68"
audio.channel = "FR"
port.id = "1"
port.name = "playback_FR"
port.direction = "in"
port.physical = "true"
port.terminal = "true"
port.alias = "bcm2835 Headphones:playback_FR"
id 66, type PipeWire:Interface:Port/3
object.serial = "71"
object.path = "alsa:pcm:0:hw:0:playback:playback_0"
format.dsp = "32 bit float mono audio"
node.id = "68"
audio.channel = "FL"
port.id = "0"
port.name = "playback_FL"
port.direction = "in"
port.physical = "true"
port.terminal = "true"
port.alias = "bcm2835 Headphones:playback_FL"
上記のうち、以下が、
- マイク音声を他のノードに出力するポート
- ヘッドフォン向けの左右2チャンネルの入力ポート
になる
id 31, type PipeWire:Interface:Port/3
(snip)
node.id = "67"
(snip)
port.name = "capture_MONO"
port.direction = "out"
(snip)
id 65, type PipeWire:Interface:Port/3
(snip)
node.id = "68"
(snip)
port.name = "playback_FR"
port.direction = "in"
(snip)
id 66, type PipeWire:Interface:Port/3
(snip)
node.id = "68"
(snip)
port.name = "playback_FL"
port.direction = "in"
(snip)
再生・録音の確認。
再生はpw-play
を使う。
pw-play /usr/share/sounds/alsa/Front_Center.wav
録音はpw-record
を使う。
pw-record --format s16 \
--channels 1 \
--rate 44100 \
test.wav
pw-play test.wav
PipeWireを入れたときに、pipewire-pulseもインストールしてあった。
このフレームワークは、マルチメディアルーティングとパイプライン処理を行う事ができ、Pulse AudioとJack Audio Connection KitとGStreamerの代替サーバを含んでいます。つまり、PipeWireを導入する事でPulse AudioとJackとGStreamerが持つ機能をひとまとめにして管理し易くなります。
これで、PipeWireでPulseAudioの互換インタフェースが提供されることになる。これを確認する。
まずターミナルを立ち上げてpw-top
を起動する。pw-top
は現在動いているデバイスやノードの状態をリアルタイムに確認することができるツール。
pw-top
別ターミナルを開いてpaplay
でWAVファイルを再生してみる。わかりやすいようにちょっと長めの音声ファイルを用意した。
paplay sample_5min.wav
どうやらPipeWire経由で再生が動いている様子。
この時、pw-cli ls Node
を見てみると以下のようにアプリケーションがノードとして表示される。
id 69, type PipeWire:Interface:Node/3
object.serial = "99"
factory.id = "6"
client.id = "74"
application.name = "paplay"
node.name = "paplay"
media.class = "Stream/Output/Audio"
また、pw-cli ls Port
にも同様に以下のポートが表示されている。
id 71, type PipeWire:Interface:Port/3
object.serial = "101"
object.path = "paplay:output_1"
format.dsp = "32 bit float mono audio"
node.id = "69"
audio.channel = "FR"
port.id = "1"
port.name = "output_FR"
port.direction = "out"
port.alias = "paplay:output_FR"
id 73, type PipeWire:Interface:Port/3
object.serial = "100"
object.path = "paplay:output_0"
format.dsp = "32 bit float mono audio"
node.id = "69"
audio.channel = "FL"
port.id = "0"
port.name = "output_FL"
port.direction = "out"
port.alias = "paplay:output_FL"
なお、aplay
でも同様。
pw-cli ls Node
id 69, type PipeWire:Interface:Node/3
object.serial = "111"
factory.id = "6"
client.id = "74"
application.name = "ALSA plug-in [aplay]"
node.name = "ALSA plug-in [aplay]"
media.class = "Stream/Output/Audio"
pw-cli ls Port
id 71, type PipeWire:Interface:Port/3
object.serial = "112"
object.path = "ALSA plug-in [aplay]:output_0"
format.dsp = "32 bit float mono audio"
node.id = "69"
audio.channel = "FL"
port.id = "0"
port.name = "output_FL"
port.direction = "out"
port.alias = "ALSA plug-in [aplay]:output_FL"
id 72, type PipeWire:Interface:Port/3
object.serial = "113"
object.path = "ALSA plug-in [aplay]:output_1"
format.dsp = "32 bit float mono audio"
node.id = "69"
audio.channel = "FR"
port.id = "1"
port.name = "output_FR"
port.direction = "out"
port.alias = "ALSA plug-in [aplay]:output_FR"
色々見てると、ALSAに直接アクセスする場合の処理をPipeWireに横取りさせるには pipewire-audio-client-libraries
パッケージが必要みたいなのだけど、上の結果だけ見てると動いてるように見えるんだけどな。自分の理解が違うんだろうか?
オーディオのルーティングは、
- CLI
- WirePlumber
- GUI
- qpwgraph
- Helvum
あたりを使うみたい。で、GUIの場合はデスクトップが必要になるのだけど、X11フォワーディングでMac側でGUIを表示してみようと思う。
Mac側でXQuartzをインストール
brew install xquartz
XQuartzを起動して、設定で以下を設定。
XQuartzの「アプリケーション」→「ターミナル」でxhosts +localhost
XQuartzのターミナルからSSHでRPiにログイン。X転送を許可しておく。
ssh -Y kun432@rpi
RPiにログインしたらDISPLAY変数を確認
echo $DISPLAY
こんな感じで表示されればOKみたい。
localhost:10.0
qpwgraphやHelbumはFlatpakを使うのが一般的みたいなのだが、Flatpakをインストールしてパッケージを追加しようとすると以下となる
error: Nothing matches org.pipewire.Helvum in remote flathub
んー、アーキテクチャが対応していないとかなのだろうか?
ちょっとデスクトップ環境でやり直そうかな。