ここ数日、「母艦の音を PulseAudio で Raspberry Pi 1 Model B+ で再生する」というのをやっていたけど、ミュージックプレーヤーの2曲目がどうしても再生できないという問題を解決できず…。無線にしているのが悪いのかと思い有線にしてみたり、PulseAudio のモジュールを減らしてみたり追加したり。週末にようやくそれっぽい書き込みをいくつか見つけた。
うーん、なんか Raspberry Pi 1 Model B+ だと難しいような気がしてきた…。
「module-native-protocol-tcp 以外にオーディオを転送する方法はあるのか?」
PulseAudio の module-native-protocol-tcp が上手く動かないので他の方法をいくつか検討してみた。
parec
まずは parec と pacat の組み合わせ。
module-native-protocol-tcp を手動で行うイメージか。module-native-protocol-tcp の時のようにまったく応答しなくなることはないが、細かく途切れている感じ。parec のデバイスの指定は alsa_output.pci-0000_00_1b.0.analog-stereo.monitor のように指定することもできるが、デバイス番号でも指定ができる。デバイス名は pactl list short | grep monitor などで調べることができる。
$ parec -d 0 | ssh 192.168.1.100 pacat
次に parec と aplay の組み合わせ。先ほどに比べて音切れは無く、良い感じ。ただ、若干タイムラグがある。aplay の -f cd は -f S16_LE -c2 -r44100 の略式。
$ parec -d 0 | ssh 192.168.1.100 aplay -t raw -f cd - Playing raw data 'stdin' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
parec で母艦の音をキャプチャする場合、母艦のスピーカーでもそのまま音が再生されるので alsamixier などでスピーカーの音をオフにしておいた方が都合がいいことがあるかもしれない。

module-tunnel-sink
リモートのサウンドデバイスを母艦のデバイスとして扱える(?)。サーバを Raspberry Pi とした場合、母艦に bcm2835 ALSA Analog Stereo を接続できる。母艦に存在していることになっているので音量調整なんかもできる。

まず、サーバ(Raspberry Pi)側で module-native-protocol-tcp を有効にしておく。認証方法の説明についてはここでは省略する。
load-module module-native-protocol-tcp auth-anonymous=1
クライアント側で module-tunnel-sink をロードする。また、引数でサーバ側の sink を指定することもできる。
(IP アドレスでは指定できない…?)
$ pacmd load-module module-tunnel-sink server=alarmpi.local
上手く接続されればクライアント側の sink リストに表示される。
$ pacmd list-sinks
:
index: 1
name: <tunnel-sink.alarmpi.local>
driver: <module-tunnel.c>
flags: NETWORK HW_MUTE_CTRL HW_VOLUME_CTRL LATENCY
state: SUSPENDED
suspend cause: IDLE
priority: 0
volume: 0: 69% 1: 69%
balance 0.00
base volume: 100%
volume steps: 65537
muted: no
current latency: 0.00 ms
max request: 0 KiB
max rewind: 0 KiB
monitor source: 3
sample spec: s16le 2ch 44100Hz
channel map: front-left,front-right
Stereo
used by: 0
linked by: 0
fixed latency: 250.00 ms
module: 22
properties:
device.description = "bcm2835 ALSA Analog Stereo on USERNAME@alarmpi.local"
tunnel.remote.server = "alarmpi.local"
device.icon_name = "audio-card"
tunnel.remote_version = "30"
tunnel.remote.user = "USERNAME"
tunnel.remote.fqdn = "alarmpi.local"
tunnel.remote.description = "bcm2835 ALSA Analog Stereo"
mplayer ではデバイスを直接指定することができるので以下のようにして PulseAudio のデバイスを指定できる。
$ mplayer -ao pulse::tunnel-sink.alarmpi.local sound.wav
デバイスを選択出来ないアプリケーションの場合は PULSE_SINK 環境変数を使う。
$ PULSE_SINK=tunnel-sink.alarmpi.local speaker-test
母艦で PulseAudio を使っている音声を全て module-tunnel-sink に流すならデフォルトの sink を変えてしまえばよい。この時の sink は名前以外に index で指定ができる(つまり、set-default-sink 0 とすればデフォルトのデバイスに戻る)。list-sinks をインデックスの隣に * が表示されるのでどれが現在のデフォルトかすぐわかる。
$ pacmd set-default-sink tunnel-sink.alarmpi.local $ pacmd list-sinks $ pacmd set-default-sink 0
で、肝心の音はどうなのよ、と言うと pacat を使った時とあまり変わらず…。しかもボリューム調整とかしなきゃ音が割れるのでむしろ pacat よりも難しいかもしれない。
とりあえずオーディオ遊びはこの辺まで…。