WSL2+Ubuntu 20.04環境から音声を出力する
Windows 10のWSL2(Windows Subsystem for Linux)のUbuntu 20.04から、音を出せるように設定してみました。
先日のGUIアプリ実行と同様に、Windows側にソフトを入れて接続受け入れ設定をして、Ubuntu側にはWindows宛てに音を出力するように設定します。
これを行うと、Ubuntu側にインストールしたChromeなどから音を出力できるようになります。
WindowsのInsider Preview参加者の方へ(追記)
Windows 10のInsider Preview(ビルド21362以降)やWindows 11のInsider Previewをお使いの方は、「WSLg (Windows Subsystem for Linux GUI)」のプレビュー版を利用してGUIアプリを実行すれば、そのまま音声も出力されます。
Windows 10 Insider Previewの方向けのインストール方法は別記事にまとめていますので、こちらをご覧ください。
また、Windows 11 Insider Previewでのインストール方法はこちらをご覧ください。
2021/06/14時点の通常リリース版である「21H1」でWSLgは利用できませんので、本記事(次項以降)の通りにセットアップを進めてください。
Windows側の準備
この記事では、既にWindows 10にWSL2をインストール済み、という所から説明します。WSL2のインストールは、こちらの記事をご覧ください。
PulseAudio on Windowsをダウンロード・解凍
Windows用のPulseAudioをダウンロードします。
こちらのサイトから「zipfile containing preview binaries」のリンクをクリックすると、バージョン1.1がダウンロードできます。かなり古いバージョンですが、Windows用バイナリとしてはこれが最新のようです。
ダウンロードしたZIPファイルを任意の場所に解凍します。今回は、C:\ProgramFilesX86\PulseAudio-1.1
に解凍しました。
PulseAudioの設定
解凍したフォルダを開いていくと、default.pa
という設定ファイルがあります(今回の例では C:\ProgramFilesX86\PulseAudio-1.1\etc\pulse\default.pa
です)。これを参考サイト[2]に従って編集していきます。ただし、auth-ip-aclの部分は参考サイト[1]を元に変えています。
default.paをテキストエディタで開いて、下記の通り変更します。
43行目のload-module module-waveout sink_name=output source_name=input
をload-module module-waveout sink_name=output source_name=input record=0
に変更します。Windows 10のApril 2018 Update以降、録音デバイスへのアクセスに制限がかかっているらしく、それを回避するために追加しています。単に音を聞くだけなら大丈夫ですが、録音したい場合は何か代替案を見つける必要があります。
61行目の#load-module module-native-protocol-tcp
をload-module module-native-protocol-tcp auth-ip-acl=127.0.01;10.0.0.0/8;172.16.0.0/12;192.168.0.0/16
に変更します。行頭の#はコメント行を示すものですので、これを消して設定を有効にします。書き足している部分は、Windows側から見て、どのIPアドレスからの接続を許可するか指定しています。WSL2は仮想イーサネットでWindows側とつながっていますので、Windowsから見たWSL2のネットワークを指定します。WSL2のIPアドレスは、再起動ごとに変わる可能性がありますので、決め打ちではなく範囲指定しています。
default.paの編集が終わったら、保存して閉じます。
続いて、daemon.confを編集します。これも同じフォルダにあります(今回の例では C:\ProgramFilesX86\PulseAudio-1.1\etc\pulse\daemon.conf
です)。
39行目の; exit-idle-time = 20
をexit-idle-time = -1
に変更します。通常、PulseAudioは、20秒間 非接続状態が続くと自動的に終了するそうです。それを無効にするため、この変更を行います。
daemon.confの編集が終わったら、保存して閉じます。
PulseAudioを起動する
設定が終わったら、PulseAudioを起動します。コマンドプロンプト等でC:\ProgramFilesX86\PulseAudio-1.1\etc\pulse
に行って、pulseaudio.exeを実行します。なぜか、一発目は即終了してしまったので、もう一度実行しています。いろいろ警告やエラーが出るものの、起動しっぱなしになればOKです。
PS C:\> cd C:\ProgramFilesX86\PulseAudio-1.1\bin
PS C:\ProgramFilesX86\PulseAudio-1.1\bin> .\pulseaudio.exe
W: [(null)] pulsecore/core-util.c: Secure directory creation not supported on Win32.
PS C:\ProgramFilesX86\PulseAudio-1.1\bin> .\pulseaudio.exe
W: [(null)] pulsecore/core-util.c: Secure directory creation not supported on Win32.
W: [(null)] pulsecore/core-util.c: Secure directory creation not supported on Win32.
W: [(null)] pulsecore/core-util.c: Secure directory creation not supported on Win32.
W: [(null)] pulsecore/core.c: failed to allocate shared memory pool. Falling back to a normal memory pool.
W: [(null)] pulsecore/core-util.c: Secure directory creation not supported on Win32.
W: [(null)] pulsecore/core-util.c: Secure directory creation not supported on Win32.
W: [(null)] pulsecore/core-util.c: Secure directory creation not supported on Win32.
E: [(null)] daemon/main.c: Failed to load directory.
初回起動時、Windowsのファイアウォールから、外部からのアクセスを許可するか問われます。WSL2のネットワークはパブリックネットワーク扱いなので、「パブリックネットワーク」にチェックを入れてアクセスを許可します。
pulseaudio.exeを終了する場合は、Ctrl+Cを押します。
pulseaudio.exeのスタートアップ設定
WSL2から音を出したい場合は、常にpulseaudio.exeを実行しておく必要があります。
私は、Windows起動時にpulseaudio.exeがスタートアップするように、次のスクリプトをスタートアップフォルダに保存しました。ちなみに、スタートアップフォルダは、Win+Rからshell:startup
で開けます。このスクリプトは、コマンドプロンプトの画面を表示せずに、裏でpulseaudio.exeを起動してくれます。(このスクリプトは、こちらのサイトを参考にさせていただきました)
pulseaudio.exeのファイルパスは、ご自身の環境に合わせて変更してください。
Set objWShell=CreateObject("Wscript.Shell")
Set objFSO=CreateObject("Scripting.FileSystemObject")
set ObjNetwork=CreateObject("WScript.Network")
pidFilePath=objWShell.ExpandEnvironmentStrings("%USERPROFILE%\.pulse\" & ObjNetwork.ComputerName & "-runtime\pid")
If objFSO.FileExists(pidFilePath) then
objFSO.DeleteFile(pidFilePath)
End If
objWShell.run "cmd /c ""C:\ProgramFilesX86\PulseAudio-1.1\bin\pulseaudio.exe""", vbHide
Ubuntu側の設定
続いて、WSL2のUbuntu 20.04側でも、音が出せるように準備していきます。
まず、pulseaudioをインストールします。
$ sudo apt install -y pulseaudio
続いて、オーディオの出力先を設定するため、環境変数PULSE_SERVER
を設定します。環境変数は、PULSE_SERVER=tcp:192.168.240.1
のように、「tcp」とWSL2から見たWindowsのIPアドレスを指定します。これを.profile
に書き込むため、次のコマンドを実行します。ただし、Windows側のIPアドレスは変更される場合がありますので、IPアドレスの部分は動的に指定します。
$ echo 'export PULSE_SERVER=tcp:$(grep nameserver /etc/resolv.conf | awk '\''{print $2}'\'')' >> ~/.profile
.profile
を再読み込みするため、source ~/.profile
を実行したら準備完了です。
試しに、wavファイルを再生してみて、Windows側から音が流れてきたら完了です。
$ paplay /mnt/c/path/to/test.wav
トラブルシューティング
Ubuntu側でpaplayが動かない
paplayがうまく動かない場合、次のようなエラーが表示されます。
$ paplay /mnt/c/path/to/test.wav
Connection failure: Connection refused
Ubuntu側からサウンドを出力する時に、Windows側のPulseAudioへの接続に失敗しています。
これらの原因が考えられますので、一つ一つ確認してみてください。
- Ubuntu側の環境変数
PULSE_SERVER
が間違っている:echo $PULSE_SERVER
で、Ubuntuから見たWindowsのIPアドレスが指定されているか確認してみてください。 - Windows側でpulseaudio.exeが起動していない:
タスクマネージャーの[詳細]タブでpulseaudio.exeが動いているか確認してください。 - Windows側のファイアウォールで接続をはじいている:
パブリックネットワークからpulseaudio.exeへのアクセスが認められているか確認してください。設定は、
スタート → 設定 → 更新とセキュリティ → Windowsセキュリティ → Windowsセキュリティを開く → ファイアウォールとネットワーク保護 → ファイアウォールによるアプリケーションの許可 から行えます。
「設定の変更」ボタンを押してpulseaudio.exeのパブリックのチェックを入れて、OKを押せば設定完了です。
Windows側でpulseaudio.exeが「Daemon already running」と言って起動しない
PulseAudioは、実行中であることを示すために一時ファイルを作成するようです。この一時ファイルは、Ctrl+CでPulseAudioを停止すれば削除されますが、コマンドプロンプトのウィンドウの×を押した場合は削除されずに残ってしまい、次回以降、次のようなエラーを出して起動しなくなります。
PS C:\ProgramFilesX86\PulseAudio-1.1\bin> .\pulseaudio.exe
W: [(null)] pulsecore/core-util.c: Secure directory creation not supported on Win32.
W: [(null)] pulsecore/core-util.c: Secure directory creation not supported on Win32.
W: [(null)] pulsecore/core-util.c: Secure directory creation not supported on Win32.
E: [(null)] pulsecore/pid.c: Daemon already running.
E: [(null)] daemon/main.c: pa_pid_file_create() failed.
この場合は、ユーザーフォルダにある一時ファイルを削除してあげればOKです。
うちの環境の場合、C:\Users\ユーザー名\.pulse\コンピューター名-runtime
にpid
というファイルが残っていました。これを削除すれば、pulseaudio.exeが起動するようになります。
参考サイト
参考サイト[1]
参考サイト[2]
記事の変更履歴
default.paの記述変更(2020/8/14)
default.paの61行目の設定について、当初「Ubuntu側でip aコマンドでIPアドレスを見て、そのネットワーク範囲をipcalcコマンドで調べて記載する」としていました。
記事執筆時は192.168.240.0/20の範囲で大丈夫だったのですが、パソコンを再起動したら172.24.192.0/20に変わっていました。範囲指定すれば良いと思っていましたが、それでは不十分のようなので、ローカルIPをすべて指定するように変更しました。
pulseaudio.exeの自動起動VBSを変更(2020/8/14)
pulseaudio.exeを自動起動するVBSファイルを書き換えました。当初はpulseaudio.exeを起動するだけだったのですが、既存のpidファイルが存在する場合、削除してから起動するようにしました。多重起動してしまう恐れがありますが、実害はなさそうです。
export文を.profileに移動(2020/8/28)
コマンドプロンプトやショートカットからwsl.exe -d "Ubuntu-20.04" <Ubuntu上のコマンド>
を実行して直接Ubuntu上のコマンドを実行した場合、.bashrc
は読み込まれません。なので、.bashrc
にexport文を書いて、この方法で起動しても音が出ません。
ということで、このような起動方法でもexport文が実行されるよう、export文を.profile
に移動しました。(GUIアプリを動かす記事と同様の変更です)
Insider Preview(ビルド21362以降)の方向けの案内を追記しました(2021/6/14)
Windows 10 Insider Preview(ビルド21362以降)ではWSLgのプレビュー版が利用できるようになりました。これに関する案内を追記しました。
Windows 11 Insider Previewの方向け案内を追記しました(2021/7/10)
Windows 11 Insider PreviewでのWSLgインストール方法の紹介記事も執筆しましたので、その案内を追記しました。
ディスカッション
コメント一覧
Surface Pro X Windows 11(21H2)のVLCで音出せました。ありがとうございます。
ピンバック & トラックバック一覧
[…] (1)Linux側 https://astherier.com/blog/2020/08/wsl2-ubuntu-sound-setting/ ①pulseaudioの再インストール $ sudo apt remove –purge pulseaudio $ sudo apt install […]