Forwarding ESD-played sounds to a remote machine
So I’ve been using PulseAudio for a while on my desktop and I’m absolutely loving it. Now, at some point in the past I was able to automatically have sounds on XDMCP sessions (using Xephyr in this case) forwarded back to me (from esd) so that I would get remote sounds played on my desktop. That stopped working at some point so I decided to look into fixing it. Turns out that there’s a couple of different pieces to this. First, if you want esound to forward sounds to a remote machine you need to set the ESPEAKER environment variable. I didn’t find any documentation for this in the esd man page, but googling pointed me in the right direction.
But then there’s the problem that doing an export ESPEAKER=mymachinename might work fine if I’m going to be using esdplay in that terminal window, but I want GNOME to automatically know to do this. Now, I’m not sure about this, but I think that support for ~/.gnomerc was removed in some previous version of GNOME, but thankfully 2.18 and later in Debian have an Xsession script that will automatically load .gnomerc if it exists. (Look for /etc/X11/Xsession.d/55gnome-session_gnomerc)
So I could just put export ESPEAKER=mymachinename in my .gnomerc, but what if I connect from a different machine? So I hacked together a quick test that tries to determine if you’re a remote user by looking at your $DISPLAY, and then tries to get your IPv6 or IPv4 address from it.
if [ `echo $DISPLAY | cut -f 1 -d :`x != 'x' ]; then
REMOTEMACHINE6=`echo $DISPLAY | cut -d : -f -8`
REMOTEMACHINE4=`echo $DISPLAY | cut -d : -f 1`
if ping6 -q -c 1 $REMOTEMACHINE6; then
export ESPEAKER=$REMOTEMACHINE6
elif ping -q -c 1 $REMOTEMACHINE4; then
export ESPEAKER=$REMOTEMACHINE4
fi
fi
This has ended up working beautifully. Whenever I connect to that machine, regardless of the machine I’m connecting from or if it’s IPv4 or IPv6, I get sounds sent back to me. Obviously, this doesn’t work so well if you aren’t listening for sounds from a remote esound server, but the default PulseAudio configuration (at least in Debian) has this enabled already.
Now all I have to do is see if I can use this with a combination of PulseAudio for Windows and Xming so that if I connect to my Linux box from Windows I’ll still get sounds forwarded.
Update: I have successfully gotten Xming and PA to work together in Windows. It’s not pretty, but it works. After installing Xming and making sure that it works fine on its own, it’s time to set up pulseaudio on Windows. Cendio has contributed pre-built Windows binaries that you can use to simplify the setup. For some reason they don’t include a default.pa in the archive, so I grabbed the win32 default from the PulseAudio source tarball. To save you the effort, here is the config that I’m using:
# Load audio drivers statically load-module module-waveout sink_name=output source_name=input # Load several protocols load-module module-esound-protocol-tcp auth-anonymous=1 load-module module-native-protocol-tcp auth-anonymous=1 # Make some devices default set-default-sink output set-default-source input
Note the auth-anonymous=1 bit in the esound and native protocols. This is not secure, but it’s easy. I’m using this on a completely private network so I’m not concerned about it, but YMMV.
Now, in my case, I don’t want pulse always to be running while I’m in Windows since all I’m going to use it for is my Xming sessions. So I created a small batch file to start up pulse, start my xming session, and then shut down pulse once it’s complete.
@echo off set PULSEDIR=%USERPROFILE%\Desktop\pulseaudio-0.9.6 set XLAUNCHDIR=%PULSEDIR% set XLAUNCHFILE=Roosevelt.xlaunch start /D"%PULSEDIR%" pulseaudio -D start /WAIT /D"%XLAUNCHDIR%" %XLAUNCHFILE% start /D"%PULSEDIR%" /B pactl exit
Just edit PULSEDIR, XLAUNCHDIR, and XLAUNCHFILE to point to the appropriate directories. For all of you *nix folks out there who are looking at XLAUNCHDIR and XLAUNCHFILE and wondering why they’re separate variables, it’s because the Windows command interpreter is stupid. You can’t just do a start <full path to file>, you have to pass it as a separate argument. Go figure.
Update: Thanks to Lennart Poettering for pointing out that pactl is a cleaner solution than taskkill as I had been doing before.
So, with all of that out of the way, and assuming you followed the top part of this to get ESD working properly on the server, you now should have sounds in your Windows-based Xsession connected to a remote server.







