Posted at

Docker for mac のコンテナ内の処理で出た音をmacで聞く

音関連の実験・開発・機械学習なんかをしたい時、音関連のモジュールは依存関係のインストールをするのがややこしく、Dockerを使うと「Linux」という統一的な環境下で自由にセットアップできるのでやりやすい事が多々あります。

ただ、「処理に関して」はそうなんですが、実際に生成された音を聞きたい時、Dockerで作られた仮想環境にはもちろんスピーカーが存在しませんので音は鳴りません。

wav等のファイル化をすればホストPCで簡単に聞くことはできますが、場合によっては多少面倒なのと、システムが直接音を生成しながら実行させたい場合、聞きながら実行することができません。

ではどうしたら良いかと言うと、pulseaudioというものを使います。


pulseaudioとは

本来は「サウンドサーバー」と呼ばれるもので、音に関するデータを受け取ったり配信したりと、音をコントロールしてくれるもののようです。(正直詳しい事は結構複雑なのでまだわからない…)

丸投げ) https://ja.wikipedia.org/wiki/PulseAudio


Dockerとmacを繋ぐには

結果的に音が出るまでの流れ

① ホストのMacにpulseaudioをインストール

$ brew install pulseaudio

② ホスト側でpulseaudioのデーモンを起動する

$ pulseaudio --load=module-native-protocol-tcp --exit-idle-time=-1 --daemon

確認

$ pulseaudio --check -v

W: [] caps.c: Normally all extra capabilities would be dropped now, but that's impossible because PulseAudio was built without capabilities support.
I: [] main.c: Daemon running as PID 1747

③ Dockerfileに以下を記載する

apt-get install -y pulseaudio

④ 環境変数PULSE_SERVERdocker.for.mac.localhostを設定し、

ホストMacの~/.config/pulseをDocker内のユーザーディレクトリ/root/.config/pulse(rootユーザーの場合)にバインドする

docker-compose.ymlの場合

version: "3.3"

services:
service_name:
build: .
environment:
- PULSE_SERVER=docker.for.mac.localhost
volumes:
- type: bind
source: ~/.config/pulse
target: /root/.config/pulse

dockerコマンドで立ち上げる場合

$ docker run -it -e PULSE_SERVER=docker.for.mac.localhost -v ~/.config/pulse:/root/.config/pulse [imagename] [cmd]

⑤ 後はお好きにプログラムから音を出してみよう

この手順で一応デフォルトの出力デバイスがMac側のスピーカーへとつながっている状態になり音が出るはずです。

ただし、どうしてもこういうハードウェアに直に絡んでくる系は、OS・ライブラリ・モジュールのバージョンが少し変わることで動作が変わることもあるので本当は音声データの流れを正しく理解した上で使いたいのが本音。。


留意点

上記の手順でMacの本体スピーカーと「有線」イヤホンであれば音が聞こえましたが、BluetoothイヤホンをMacに繋いだ状態だと音が出ませんでした。

おそらくMacが音を出力する先が、本体スピーカーはもちろんデフォルトのオーディオデバイスだと思うのですが有線のイヤホンの場合はネイティブに切り替えてくれるのだと思います。

Bluetoothの場合はそれが仕組み上違うのかな、、と想像していますが、厳密な所はもう少し詳しく理解する必要がありそうです。