microsoft/WSL

PulseAudio doesn't work.

KoolenDasheppi opened this issue ยท 73 comments

I am trying to use minimodem on the bash shell, and it gives me an error:

E: Cannot create PulseAudio stream: Connection refused.

I am not sure how to fix it... Help please?

This looks related to #237 in the sense that we are not exposing hardware / drivers through WSL. For this, your best bet is to submit a feature request over on our User Voice Page to help us prioritize future releases.

It is possible to run PulseAudio over TCP, and there is a native Windows port of the PulseAudio server. However, it seems to want to use a SOCK_DGRAM, which doesn't seem to be supported yet.

Specifically, the failure is as follows:

socketpair(PF_LOCAL, SOCK_DGRAM, 0, 0x21daae0) = -1 ESOCKTNOSUPPORT (Socket type not supported)
write(2, "AO: [pulse] Init failed: Connect"..., 44AO: [pulse] Init failed: Connection refused) = 44

On real-Ubuntu, the equivalent socketpair() call succeeds.

My understanding is that Pulse uses local sockets for some sort of internal communication. I think, though I'm not sure, that it starts a helper process to handle communication with the remote server, and it handles communication with that process using this socket pair.

fpqc commented

@aseering So I commented on the other thread with some info, and I also found some other stuff: By default, Pulse loads a module called module-native-protocol-unix, and another module called module-native-protocol-tcp can also be enabled. I wonder if you can start pulse with a config that does not enable module-native-protocol-unix at all, then disable all of the non-native modules that listen over datagram-mode unix sockets. It looks like this might be possible, and if it is, Pulse won't try opening that unix socket and should startup fine, I think. As I mentioned in the other thread though, I won't be able to test it this weekend bc hardware problems, but maybe this could help.

Here is a list of the modules that have both TCP and unix variants: https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Modules/#index22h3

Maybe if you turn off all of the unix modules and replace them with TCP variants, you can start the pulse server.

Aren't those modules loaded by the server? The server in this model runs under Windows. This strace is from the client.

fpqc commented

@aseering Nope, it runs those as well as the sink modules on the linux side. That's why I mentioned "trunking" from one to the other. Basically, there are two modes, a "bridging mode" that basically pipes all of the channels in multiplex to the remote server (Windows), to allow mixing of channels, etc on the remote machine, and a "flattened" version where the mixing and filtering and stuff are done on the "linux side" and then the output of the mix is piped to the Windows "client".

However, both modes of operation do have to use some kind of socket or port. For example, OSS sound (for which pulse has a sink) uses unix ports, so Pulse's OSS sink module will trick all OSS applications into piping their output to a unix socket opened by Pulse. Similarly, you can have a pulse module for Alsa, etc. In addition to those sink modules, pulse has a "pulse sink" for pulse-aware programs. This "pulse sink" module is "pulse-native-protocol-*".

Remember, pulse needs a some kind of socket that the linux programs have to talk to on the linux side. Then Pulse can either bundle them up and pipe a multiplexed stream to another Pulse server for processing or process them and then pipe a single processed stream to the other pulse server.

I believe (and I can't check bc my pc broke) that if you disable linux-side pulse from using any modules that use unix sockets, it should launch fine. Basically, this hypothesized fix should work similar to how the dbus fix works, I think.

That all sounds very complicated... I just have every Pulse application individually opening a TCP socket to the Windows daemon.

fpqc commented

@aseering Oh, seems like that should work. You are saying that you aren't running pulse on the Linux side, but you also told me that it crashes, which seems like you are running it.

Or are you saying you used a workaround to get it to work?

(Also, fwiw, the benefit of running Pulse as a remote server and connecting it to another instance of pulse on your local machine is that not every Linux application with sound will output audio to pulse over tcp, mostly older programs or games. That's why pulse in Linux has all of those sink modules).

@fpqc -- oh, sorry, terminology confusion. Let me define some more-specific terms:

  • libpulse -- the client library that pulse-based applications link
  • Linux pulseaudio -- the daemon that run on Linux
  • pulseaudio.exe -- the daemon that runs on Windows

By editing /etc/pulse/client.conf in WSL, I have configured Linux binary applications that link libpulse (tested with both paplay and mplayer) to connect over TCP to localhost.

I have also configured pulseaudio.exe to listen on TCP localhost.

I have not configured Linux pulseaudio, nor attempted to start it.

I am observing a failure (not a crash, simply an error as well as no audio) coming from libpulse inside WSL, when I run applications that link libpulse. If I modify the IP addresses used in this setup and use libpulse on a real Linux system (but still pulseaudio.exe on Windows), I do not see this failure, and I do hear audio, so the Windows side of the setup seems to be working properly.

When I strace the application that's calling into the relevant libpulse code, I observe that the first syscall that obviously differs between the working Linux execution and the failing WSL execution is socketpair(). socketpair() generates a pair of sockets that's typically used to communicate between a parent and a child process, or two threads within the same process; it has no on-disk nor TCP representation so AFAIK it can't be easily used to emulate any of these protocols.

I was looking around on the Internet and I thought I read somewhere (unfortunately I don't remember the source; it was unofficial) that libpulse actually tries to internally start is own mini Linux pulseaudio subsystem, to handle communication with the actual target pulseaudio. My suspicion, though I didn't read enough code to prove it, was that this socket was for communicating between the client application and that application's own custom pulseaudio instance.

fpqc commented

I wonder, if you do run the pulse daemon in unix socket mode, do the applications still start a mini pulse instance and create its socketpair in order to connect to the daemon. How about if you run the pulse daemon in tcp mode? (on a single linux system, no remote machine).

@fpqc -- good point re: disabling automatic spawning. Unfortunately, I tried it and it doesn't seem to help...

I tried running a local pulse daemon (which started after I disabled a bunch of plugins for things like bluetooth and hardware autodiscovery); that actually failed differently. In libpulse, as run from paplay:

getsockopt(7, SOL_SOCKET, SO_ERROR, 0x7fffd7c21f08, 0x7fffd7c21f0c) = -1 EINVAL (Invalid argument)
write(2, "getsockopt(): Invalid argument\n", 31getsockopt(): Invalid argument
) = 31

mplayer segfaults in this configuration. I haven't dug into the root cause, but prior to segfaulting, one of its pids tries a getsockopt(SO_ERROR) and fails in the same ways as above.

I got paplay working with pulseaudio 9.0 on WSL and the win32 server here. Build instructions are here.

Interestingly, I didn't need to patch the source, just judiciously disable some stuff with configure. The SO_ERROR problem that @aseering found, which is in pulsecore/socket-client.c, doesn't appear to be in the control flow for paplay, for whatever reason.

On the WSL (ie, client) side, all you need is:

export PULSE_SERVER=tcp:localhost
/usr/local/bin/paplay -p <somefile>

You can also edit /etc/pulse/client.conf and set default-server = tcp:localhost. The server is never launched on WSL, so you can ignore default.pa. [Heads up that paplay doesn't support .mp3 files. You can get the list of supported formats with paplay --list-file-formats.]

That's the good news. The bad news is that mplayer and minimodem don't work because:

futex(0xb325c4, FUTEX_CMP_REQUEUE_PI_PRIVATE, 1, 2147483647, 0xbbe770, 2) =
-1 ENOSYS (Function not implemented)

Firefox and VLC also don't make noise yet, but I haven't tracked why. They do open the socket to the win32 server before choking, though.

@therealkenc -- ooh, that's really interesting. Good to know.

What ABI-compatibility guarantees does pulseaudio provide? Ubuntu 14.04's packages are all built against pulseaudio 4.0.

fpqc commented

@aseering Hahahahahaha, Compatibility guarantees with pulse.

I'm an Arch user from time to time, pulse just breaks for no reason and the only answer is to reinstall the system or track down some strange config file you need to destroy. Any time you do an Arch update, it's a potential adventure!

@aseering - the Pulse client API is stable to a first order, FWIW. That is, the same Firefox binary will make the same sounds on Trusty, Wily, Xenial, and Yakkety. It looks like Pulse keeps bumping major numbers because the server plugin API is relatively unstable.

I got back to the futex problem. Amusingly, the patch is utterly trivial. Just add #undef HAVE_PTHREAD_PRIO_INHERIT at the top of pulsecore/mutex-posix.c at around line 23 like this:

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#undef HAVE_PTHREAD_PRIO_INHERIT

#include <pthread.h>

VLC works out of the box with the replacement shared library installed. I confess I don't know how to get minimodem to make screeching noises but it probably works too. Youtube videos on Firefox stream with audio completely in sync.

wsl-vlc-cap

fpqc commented

@therealkenc Wow, that's fantastic! How is performance? Also, some insight on how you tracked that down if you don't mind!?

Performance (if that is the word) is great. The amount of cpu horsepower and memory bandwidth required to push a couple of audio channels over localhost is dwarfed by what it takes to decode an H.264 video stream coming down from GoogleCorp. That is, the difference between having audio and not audio isn't measurable. I pessimistically just assumed there was going to be sync problems (which is an A/V problem on a good day), because "buffering", but apparently not.

Tracking this one down was pretty straightforward because the failing syscall is futexey, and there's only one place the in PA library that calls those. Widely ported OSS packages always have build configuration knobs to tweak because the FreeBSD, Android, IoT and OS X guys don't necessarily have all the esoteric Linux syscalls or crazy /proc and /sys stuff either. When in doubt, you just turn the feature off.

@therealkenc -- I played around some more with your instructions. From your list of packages, it sounds like you're using an upgraded xenial system? I got your instructions to work on trusty by playing around with the set of installed build-deps and the set of enabled/disabled flags for pulseaudio's ./configure script.

So far, works great for me! I haven't exercised it very much, though.

If anyone wants to try this without rebuilding pulseaudio: I've taken yakkety's pulseaudio package (which is based on v9) and backported it to trusty, using a modification of @therealkenc 's build instructions plus some playing around to get the packaging right (since a bunch of different modules are being built / not being built).

I posted that package to a PPA:

https://launchpad.net/~aseering/+archive/ubuntu/wsl-pulseaudio

If you:

  • Add that PPA
  • Run sudo apt-get update ; sudo apt-get install libpulse0
  • Add default-server = 127.0.0.1 to /etc/pulse/client.conf
  • Download and configure Pulseaudio on the Windows side as discussed above (I'll put together a more-complete unified set of instructions sometime)

then pulseaudio-based applications should play sound for you.

I did this on Trusty FWIW, but I put the dependency list together after the fact so if something was missing that isn't too surprising.

๐Ÿ‘ on the PPA. People who are used to adding export DISPLAY=:0 to their .bashrc for X might find it easier to use export PULSE_SERVER=tcp:localhost and pretend the config files don't exist.

For people setting up the Win32 side, the tl;dr is you need the following in your etc/pulse/default.pa:

load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/24 auth-anonymous=1

Interesting; it was partly the packages that were listed as well as packages that were omitted. For example, trusty's official repo doesn't have a package for gcc 6. There were a couple others as well; I forget the list, you can check out the Build-Deps in the PPA if you're curious.

For default.pa on the Windows side, I think it would be correct and safer to omit ;192.168.0.0/24? Otherwise, yeah, that's the main thing.

I also found that the Windows server was automatically exiting after some period of time (order of a minute?) of being idle, but only after I stopped playing music (not before I started). I think there's a setting for that too? But I forget which setting offhand.

The gcc-6 thing was an omission on my part; apologies for that. I updated the instructions yesterday, probably just after you read them. PA seems to prefer a C11 compiler (Xenial doesn't have gcc-6 either).

sudo add-apt-repository ppa:ubuntu-toolchain-r/test

Yes omitting 192.168.0.0/24 would be safer. As for the timeout yeah that is annoying too. For those playing along you just need the following in daemon.conf:

exit-idle-time = -1

I don't have a microphone so I also needed the following in default.pa:

load-module module-waveout record=0 sink_name=output
load-module module-null-sink sink_name=input

That's probably enough in a nutshell for your HOWTO.

Also heads up that I get a 404 on Trusty when trying to apt-get update your PPA:

W: Failed to fetch https://launchpad.net/~aseering/+archive/ubuntu/wsl-pulseaudio/dists/trusty/main/binary-amd64/Packages  HttpError404

E: Some index files failed to download. They have been ignored, or old ones used instead.

There is probably also a way to make your PPA Unubtu release agnostic for the Xenial people, like ubuntu-toolchain-r/test, but I wouldn't know how to do that.

"C11 compiler" -- thanks for the update! PPA packages are built in Launchpad's build environment, which AFAIK can only install official Ubuntu packages, so I had to play around a little more to get things working.

Also, thanks for the additional config directives; they'll be useful to have.

For the PPA, sorry for the confusion -- the URL above is for the pretty webpage, not the apt repo. For the actual repo, sudo add-apt-repository ppa:aseering/wsl-pulseaudio adds the following to sources.list; feel free to tweak it to taste:

deb http://ppa.launchpad.net/aseering/wsl-pulseaudio/ubuntu trusty main
deb-src http://ppa.launchpad.net/aseering/wsl-pulseaudio/ubuntu trusty main

Edit your msg above to add say **ppa:**aseering/wsl-pulseaudio for those pasting (I knew what you meant). Also maybe tweak your instructions a few messages back to say **tcp:**127.0.0.1 for client.conf. For my part, the build instructions should now actually work.

ppa: -- thanks; good catch.

tcp: -- nope, actually that one is correct as-is.

I finally got around to pulling all of these instructions into one place. Rather than try to explain the details of each step in English, I just wrote a script:

https://github.com/aseering/wsl_gui_autoinstall

I'd appreciate any feedback on the script. I've tried it on my own computer, but my own computer is far from a clean Windows install at this point :-)

In particular, if anyone knows how to extract a .zip file using native Windows commands, I'd appreciate that addition. Right now I'm using the "unzip" Linux command. But that command doesn't ship with WSL's stock Ubuntu image, and I'd like this installer to have as few dependencies as possible, just on principle.

I've found a few approaches online, but they all either didn't work for my use case or had Windows-side dependencies.

fpqc commented

I have a suggestion: For GTK apps to run with font hinting and antialiasing enabled, (and without running the very very heavy gnome-settings-daemon or unity-settings-daemon), you could ship with xsettingsd and a sane default config (I think the config is called .xsettingsrc).

xsettingsd must be run with a display chosen (DISPLAY=:0 xsettingsd), and therefore must run after vcXsrv. This will allow proper running of things like gnome-terminal with reasonable fonts and maybe even adding solarized and other color schemes to the defaults.

The easiest way to generate a good sane xsettingsrc file is to use xsettingsd in dump mode with unity-settings-daemon running, then paring it down. I can make one and post it somewhere, if you want!

@fpqc -- if you could post one, that would be great! If you could submit a PR to my script, that would be even better :-)

fpqc commented

@aseering already posted the file (unedited) as an issue on your github. You are going to have to decide which settings you want, since some depend on specific unity and ubuntu packages (ubuntu mono font, ubuntu gtk theme, etc)

Just FYI that most or all of the AF_LOCAL\PF_UNIX fixes should be available starting build 14915. We would appreciate if you can try out the scenarios again without the dbus workaround and close out the issues. The only changes required to start the dbus daemon is in /etc/init.d/dbus, changing
from:
DAEMON=/usr/bin/dbus-daemon UUIDGEN=/usr/bin/dbus-uuidgen
to:
DAEMON=/bin/dbus-daemon UUIDGEN=/bin/dbus-uuidgen
then:
sudo /etc/init.d/dbus start should work.

As mentioned on July 25 the problem with PA isn't AF_LOCAL, it is:

futex(0xb325c4, FUTEX_CMP_REQUEUE_PI_PRIVATE, 1, 2147483647, 0xbbe770, 2) =
-1 ENOSYS (Function not implemented)

Issue #1006. The PA client library talks to the Windows PA server over AF_INET.

Hi,
I installed pulseaudio on windows and jack. Pulseaudio now is configured to start with native-protocol-TCP enabled. Now, How can i configure pulseaudio on Linux to connect? Why7 not use jack instead of pulseaudio?

Unfortunately it looks that 16.04 is shipped with pulseaudio 8.

ATM I'm following https://gist.github.com/therealkenc/5dae7eefbacb0083e485348bd25ee33c made by @therealkenc (:+1:) but it takes ages to pull all dependencies and compile.

--
@aseering Will you be so kind and add also a version for Xenial? Your PPA worked like a charm with Trusty.

For what it is worth, #1006 got flipped from feature to bug last week. Cross your fingers and maybe Pulse will run out of the box soon enough.

@asria - I put up a new PulseAudio 8 PPA for 16.04 here:

sudo add-apt-repository ppa:therealkenc/wsl-pulseaudio
sudo apt-get update && sudo apt-get upgrade

YRMV

Thank you so much! @therealkenc

TULOA commented

therealkenc I had to install this using your link as the other PPA wouldnt install due to it missing the release version for AMD it looks like. However doing an aplay -L doesnt show it in the list. Is it not suppose to?

And is it possible to restart this without a system reboot?

The previous PPA was generated for Ubuntu Trusty (which was current at the time). WSL now defaults to Xenial.

aplay -l won't list any sound cards because there aren't any (a stands for) ALSA kernel drivers in WSL. This is PulseAudio, a which is made up of a user mode library and a server/service component. Typically the server runs on Linux (and talks to Linux kernel sound drivers). Here the server runs on Windows (and talks, ultimately, to NT sound drivers).

There is no reboot necessary. It is just a user mode library (libpulse.so.0).

A good launch point for PulseAudio is here. The page is geared to Arch Linux but the principles apply equally to Ubuntu. Bonne chance.

TULOA commented

Ok so how is this suppose to work with the bash. I am getting errors for example with speaker-test about not being able to find card '0'

Also on that page pacmd does not function. It states:
No PulseAudio daemon running, or not running as session daemon.

Short story

export PULSE_SERVER=tcp:localhost
/usr/local/bin/paplay -p <somefile>

YRMV (I have not run audio on WSL myself in ages, though nothing has changed that would break anything since then.)

PA runs on WSL the same as on any Real Linux box which has no sound card. You can find the PulseAudio community here. The Windows (sic) Pulse Audio server, linked previously, can be found here. The port has gone a little stale, but still works. [I am sure the PA community would appreciate someone bringing the Windows port up to a newer version.] There is also an autoinstaller for WSL here, although I have never run it personally. But be aware there have been no updates to the github repo since August, so you would need to adapt it to the new PPA.

TULOA commented

Ok so ill have to wait to find another solution for firefox and things then.

Verld commented

I have a similar problem. No sound in Ubuntu XServer. I am using Ubuntu 16.0.4 w/ Unity on VCXSrv with WSL. I am using Windows 10 Home on a Dell Inspiron 1545. Sound works fine in Windows. No audio in Windows X Server.

Verld commented

What pulse servers are there for Windows? Apparently Xming and VCXSrv don't support audio. Will need a separate program for audio.

fpqc commented

@Verld If I remember correctly, @aseering had found one that worked alright.

@Verld - It isn't an Xming or VcXsrv thing. The server url was linked literally three posts above yours.

You can find PulseAudio 6 for Windows here https://github.com/kitor/wsl

Motivated by #2658 I put up (another) new PulseAudio 8 PPA, this time 1:8.0-0ubuntu3.4ppa1 for Ubuntu Xenial 16.04.3 here:

sudo add-apt-repository ppa:therealkenc/wsl-pulseaudio
sudo apt-get update && sudo apt-get upgrade

It looks like an even newer one (1:10.0-1ubuntu2) ships with Zesty 17.04, but I am not going to chase every release Canonical decides to push. Fingers crossed that #1006 (message) will get squashed in the new year.

I am not going to chase every release Canonical decides to push

Well that was a wishful thought, anyway. I've bumped the PPA again, this time to 1:8.0-ubuntu3.7ppa1, which is where Ubuntu 16.04.3 is at as of this writing. Motivated by #2293.

3.8 has been published if you plan on bumping again.

I have same problem with running pulseaudio, I described it on reddit:
https://www.reddit.com/r/bashonubuntuonwindows/comments/7zgt4i/sound_doesnt_work_via_pulseaudio_tried_to_tinker/
Any ideas how to fix?

Use ppa linked above but it may not work since there is now a new update. Hence the FYI to @therealkenc

the latest update doesn't work with the PPA, however someone in that reddit thread has said that one of the devs is working to implement whatever missing function. so hopefully that means there won't be a need of waiting for patches.

someone in that reddit thread has said that one of the devs is working to implement whatever missing function

It's currently on the backlog per this cited above.

Build 17627
Add support for the futex pi-aware operations.

And Pulseaudio now works beautifully on build 17627. ๐ŸŽ‰

This one is slightly awkward. "Audio" categorically does not work in WSL, because there are no OSS/ALSA/FFADO drivers in WSL. But there are no remaining blockers on the PulseAudio client (libpulse0) or even the native PulseAudio server (in the sense you can install a sink driver). This is analgous to there being no blockers on libX11, despite the fact WSL can't display a damn thing. The native PulseAudio server cannot make noise; but that is because #237, like Russ said way up top; not because of Pulse. Calling this fixinsiderbuilds being there are no PulseAudio actionables left. User Voice for audio drivers is here. Bonne chance.

Did the fix seen in the 17627 insider build get pushed out in the big April W10/WSL public update?

@cuprousoxide - In general, the fixes in 17627 will not make it to April W10.

Hi @tara-raj, is there any other reference ticket/issue where we can see progress of this issue?
Best regards,
P

Hi,

I got this to work with great thanks to everyone in this thread.

I am now able to use paplay while being ssh-d into a remote machine (CentOS 7) and hear sounds on my local machine (Windows 7). However, I wanted to use padsp and that does not seem to work. I am running my application like so while being ssh-d to my remote machine:

/usr/bin/padsp-32 application_name

And I don't hear any sounds on my local machine. Could this be because the pulseaudio for Windows does not have padsp? I know that padsp forwards sound to the PulseServer which I know to be working fine because of paplay. But, does it attempt to use something like a "padsp.exe" on the local machine and doesn't find it? Or do I need to do something else? Like load a particular module into my pulse audio on the Windows side?

@therealkenc, do you have any ideas?

(CentOS 7)

/usr/bin/padsp-32 isn't an application in my supported Ubuntu distro from the store, so I could not run it and take a quick look-see. I have a guess (name screams 32 bit application) but rather not speculate on this one. Best place to ask would be in the discussion forum for wherever it is you got CentOS 7.

Could you take a look with padsp? I just want to get an idea on what I can do.. Getting paplay to work itself was quite the task, really need this one though.

Could you take a look with padsp?

Makes noise here.

$ padsp cp /dev/random /dev/dsp

So the pulse audio server on my windows stops after a few seconds of inactivity, this is even though I am running it with the --daemonize flag. Any ideas? @therealkenc

@therealkenc I am getting the following error while attempting to start pulseaudio.exe on my Windows:

Daemon already running
pa_pid_file_create() failed

And I get a failed to kill daemon, no such file or directory if I try pulseaudio.exe --kill

Do you have any idea how to go about fixing this?

Not really. Suggestion would be to not run pulseaudio.exe --daemonize in the first place, and let it run in the foreground. Longer answer on how to go about fixing it: Fork the source, compile it, set a breakpoint at the fail, type on keyboard, compile again, and (optionally) upstream the patch.

I fixed it by simply restarting my machine. What's the best way to keep pulseaudio running? It keeps stopping for me. @therealkenc

For anyone interested, the above Ubuntu xenial repo is working with WSL Debian testing as well.
I had to import the key for Launchpad PPA manually though with apt-key add using this file https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x715bfae95321fdc8ef2146fda5a09224e1919fad