Monday, June 23, 2014

Taming Pulseaudio

Taming PulseAudio

PulseAudio is a sound system for Linux.  It offers a few nice features, such as per-application volume control, hot-swapping input and output devices, and more cool stuff, all through an easy-to-use GUI.  Sounds great, but there's a catch: it's broken.  Actually, to be fair, PulseAudio isn't the only thing broken; all of Linux sound is broken.  From the pieces I've been able to glue together, here's enough of the story to understand what I'm talking about.

If you're just here for the guide, scroll down until the part after a large gap.  If you also want to know what the problems are, then you only have to skip until the end of the indented section.
Sound on Linux started with a system called OSS, or Open Sound System.  It was used not just by Linux but by BSD and I think even early versions Mac OS X.  OSS was very simplistic, to the point that only one application at a time could use sound, but it worked.  OSS's limitations could be bypassed by using a sound server.  ESD, Enlightened Sound Daemon, is one such sound server.  For a program to use ESD, the program had to be rewritten to use it.  Thus, you'd see programs coded to use both ESD and OSS as a fallback, as well as another sound server, aRts.  Three different sets of code each for different audio setups.  There had to be a better way.
The better way was ALSA.  It was conceived as a replacement for OSS, as OSS was stagnating in development or something like that.  It had everything from a brand new driver system to the ability to have multiple programs use sound at once without a sound server.  In theory, ALSA should have solved everyone's problems.  In practice, all this ended up doing is dividing the BSD and Linux communities, as ALSA was Linux-only while OSS was cross-platform.  Also, all it accomplished was adding yet another audio system for programmers to code for. 
Eventually, things progressed to the point that programs were dropping support for anything but ALSA.  The problem of Linux audio seemed to be solved, but there were two issues.  First, the BSD folks were getting upset because many of the newest and newest versions of programs weren't compatible with their system anymore.  Second, there were a few features some users wanted which ALSA couldn't provide, but a sound server could.  Third, programmers started to get really frustrated at how complicated ALSA is to code around. 
Enter PulseAudio.  PulseAudio is a sound server implemented on top of ALSA and OSS alike.  According to their wiki, it runs on Linux, Solaris, BSD, Mac OS X, and Windows 2000 and XP.  Basically, every relavent operating system can have it's sound work across all operating systems by using PulseAudio, solving the sound fragmentation issue between the open-source operating systems, and providing an allegedly-better coding experience compared to ALSA. 
What happened when ALSA replaced OSS is happening now with apps being programmed to support only PulseAudio and no longer directly use ALSA.  One such example is Skype for Linux.  Starting with version 4.3, PulseAudio is the only supported sound system.  As of writing this guide, that's the only example I can name, as currently most apps have support for both ALSA directly and PulseAudio.
In summary, PulseAudio is swinging on by to be the superhero and fix Linux's audio problems.  And yet, some programs don't want PulseAudio to save them.  One major example in my case is Wine.  Wine is a fake, fully-reprogrammed version of Windows made to be installed into Linux, BSD, or Mac OS X so that they can run Windows programs.  What this means in the realm of sound is that Wine has to write a program which translates the windows sound APIs used by windows programs into those used by the guest operating systems.  There's some holdup with getting a translation layer between PulseAudio and Windows Audio completed, meaning that Wine is one of the only major Linux programs not compatible with PulseAudio, yet fully compatible with ALSA.

The easiest way to solve PulseAudio's problems is to run PulseAudio and ALSA side-by-side.  Technically speaking, PulseAudio runs on top of ALSA and can't run without it, so they already do run side-by-side.  Practically speaking, they don't, because if PulseAudio is running, then no other program can use ALSA.  At least, that's how it works with the default configuration.  We'll be bypassing this with a custom configuration.

What's going wrong here is that PulseAudio, by default, does two very stupid things while attempting to be smart.  The first is grabbing complete, exclusive control of your sound card, done by attempting an automatic detection of all sound devices in your computer.  The proper fix is to modify PulseAudio's code to NEVER take exclusive control of auto-detected devices; instead we'll just edit settings to work around this problem.  The second stupid thing PulseAudio does is an attempt to work around this first problem.  PulseAudio includes an "ALSA compatibility layer", which from here on out will be referred to as a hijacker.  What this does is attempt to make any program which tries to use ALSA use PulseAudio instead through a translation layer.  Except this translation layer is just imperfect enough to cause migraines.  The proper fix is to fix the translation layer, but considering it hasn't been done yet, I doubt it'll ever be done; instead we'll be nuking the thing.  Speaking of which, let's get on to that guide.



This is a guide for allowing programs to play sound through ALSA and PulseAudio simultaneously.  Apps supporting PulseAudio will play sound through PulseAudio and apps not supporting PulseAudio will play through ALSA, bypassing any problems caused by certain programs such as Wine not supporting PulseAudio.  It was written for Lubuntu 14.04, but should translate well into any Ubuntu-derived or Debian-derived distribution of Linux, and shouldn't be too far off from what you're supposed to be doing in other distributions.

STEP 0: Install Pulseaudio.
A. Open a Terminal.
B. sudo apt-get install pulseaudio

STEP 1: Secure a program which can use both PulseAudio and ALSA by user choice.
One such example is the audio player Audacious.
A. Open a Terminal.
B. sudo apt-get install audacious

STEP 2: Configure your program to use ALSA and try to play a sound.
If you're using Audacious, the preferences menu makes this really easy.  Once set to ALSA, try to play a sound.  The program should throw up an error message.  If it somehow works, double check to see if it's configured for ALSA.  If it is, then PulseAudio's ALSA hijacker is active, a hijacker which needs to be crushed.

STEP 3: Disable PulseAudio's ALSA hijacker.
A. Open a terminal.
B. cd /usr/share/alsa/alsa.conf.d
C. sudo rm *pulse*
Now, reopen your test program and try again in ALSA mode.  Now it should be throwing up that error message.

STEP 4: Edit Pulseaudio's Configuration.
A. Check if ~/.config/pulse/default.pa exists.
If it does, open it with a text editor.
If it doesn't, open /etc/pulse/default.pa, and save it as ~/.config/pulse/default.pa.
B. Around line 44, you'll see something like this:
### Load audio drivers statically
### (it's probably better to not load these drivers manually, but instead
### use module-udev-detect -- see below -- for doing this automatically)
#load-module module-alsa-sink
#load-module module-alsa-source device=hw:1,0
#load-module module-oss device="/dev/dsp" sink_name=output source_name=input
#load-module module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
#load-module module-null-sink
That comment block is full of crap.  Uncomment the two lines related to ALSA by deleting the # at the front.  Also, remove the device=whatever parts of the lines you uncommented if they're present.
NOTE: If you're using a custom .asoundrc, this may or may not work as-is, but it should get you on the right track. If you're not or you have no idea what I mean by .asoundrc, ignore this; you're fine.
C. Save.

STEP 5: Restart Pulseaudio.
A. Open a terminal
B. pulseaudio -k

STEP 6: Try out your test program.
Your program sould be perfectly able to play sound when configured for both ALSA and PulseAudio.

Congratulations, you just made PulseAudio infinitely better!  The one downside is that ALSA-only programs can't use PulseAudio's cool features, but at least they'll be able to play sound, something they couldn't do before!

No comments:

Post a Comment

Copyright Notice:

All text (unless otherwise attributed) is copyright (C) 2011-2014 Joel "iLag" Hammond and licensed under the CC BY-SA 3.0 License.
Creative Commons License