On modern WSL you no longer need this hack to play music with cmus, although sometimes cmus cannot resume after pausing and this hack would effectively fix that.
Version, Version and Version
This is the updated version, I use Windows 10 21H2 when writing the draft.
Windows: Version 22H2 (OS Build 25182.1000)
WSL: 2 (WSLg)
Distro: Devuan Testing
Windows PulseAudio: 1.1 (2011-10-25), installed via Chocolatey
Libpulse0: 15.0+dfsg1-4+b1
Cmus: 2.10.0-2
Windows Terminal: 1.14.2282.0
Intro
Today I wanted to enjoy my Memories Off OST collection on cmus on Debian on WSL 2 on Windows 10. As I did not upgrade to Windows 11 due to privacy and stability concerns, I could not use built-in GUI app feature for WSL.
I started the journey to fix broken audio output in WSL.
Get the Malody Working
Before I start, please be aware that each step is on Windows/WSL or you’ll get confused.
1. Download PulseAudio for Windows
On Windows:
The guide I followed used a third party built for X2Go (Remote Desktop client). I chose to use the good old Chocolatey anyway.
The package uses the preview binary provided by freedesktop.org.
Just run choco install pulseaudio -y in an elevated PowerShell window.
2. Configure PulseAudio for Windows
On Windows:
First we need to find the installation directory of PulseAudio for Windows.
$ Get-Command pulseaudio.exe
CommandType Name Version Source
----------- ---- ------- ------
Application pulseaudio.exe 1.0.0.0 C:\ProgramData\chocolatey\bin\pulseaudio.exe
Create a file called config.pa in the folder we got above. In this case, C: \ProgramData\chocolatey\bin.
Open the file and add following lines and save the file:
load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;172.16.0.0/12;172.30.0.0/16;172.32.0.0/16
load-module module-esound-protocol-tcp auth-ip-acl=127.0.0.1;172.16.0.0/12;172.30.0.0/16;172.32.0.0/16
load-module module-waveout sink_name=output source_name=input record=0
Explanation:
- We allow connections from
127.0.0.1(local IP address) and172.16.0.0/12(default IP range, i.e.172.16.0.0-172.31.255.255) for WSL2. - To stream the audio to external devices, change the first line to
load-module module-native-protocol-tcp auth-anonymous=1to allow anonymous connections. It’s better not to change it for better security. record=0disable the microphone. Change it torecord=1if you need that.
3. Run PulseAudio (Freely)
The guide I followed uses NSSM to install PulseAudio as a Windows service, but I did not like that.
Head to the installation folder and create a shortcut, copy it to a folder in $PATH and rename it to pa.
Under the “Shortcut” section of Properties:
- Target:
C:\ProgramData\chocolatey\bin\pulseaudio.exe -F C:\ProgramData\chocolatey\bin\config.pa --exit-idle-time=-1 - Start in:
C:\ProgramData\chocolatey\bin - Run:
Minimized - In the “Advanced” tab, enable the “Run as administrator” option.
Explanation:
-Ftells PulseAudio to run the specified script on program startup.--exit-idle-time=-1disables the option to terminate the daemon after a number of seconds of inactivity.
Now when we want to start PulseAudio server on Windows, just press Win + R, type pa, hit enter and go.
4. Configure PulseAudio in WSL
On WSL:
libpulse0 should be installed by default but just make sure by running sudo apt install libpulse0.
Edit shell config file using the favored editor. In this case, vim ~/.zshrc, paste the following to somewhere:
# Enable audio output (PulseAudio) on WSL 2
# Get the IP Address of the Windows 10 Host and use it in Environment.
# Internal WSL IP
export HOST_IP="$(ip route |awk '/^default/{print $3}')"
export PULSE_SERVER="tcp:$HOST_IP"
# Enable this only if I wanna use GUI
#export DISPLAY="$HOST_IP:0.0"
Note:
- Uncomment the last line to enable audio support for graphical applications.
- If you are on WSL 2.0.0 and above, and using
mirrorednetworking mode, changeexport PULSE_SERVER="tcp:$HOST_IP"toexport PULSE_SERVER="tcp:127.0.0.1".
Restart your default shell. In this case, exec zsh.
5. Configure Cmus in WSL
Edit ~/.config/cmus/rc(create it if it doesn’t exist) and add set output_plugin=pulse to get its sound output to work on Windows.
It can be done within cmus by running :set output_plugin=pulse and :save if you wish to do so.
Cmus may arise an error when starting:
cmus: Error: an error occured while initializing MPRIS: No medium found. MPRIS will be disabled.
This can be ignored by running :set mpris=false in cmus from this issue .
6. Enjoy
- On Windows:
Win + R->pa - On WSL:
cmus
Don’t forget to allow the PulseAudio server to bypass the firewall. It should only need local network access in most cases.
I don’t know why, but certain songs can cause cmus to jam, and WSL just halt with CPU burning and fun taking off.tmux kill-serverdid not solve the issue. I had to usewsl --shutdownin PowerShell to stop that.
I did not experience it for a long time so chances are WSL team fixed it already.
