Okay… if you have read my previous post on ALSA Configuration you will know that I am trying to solve my sound setup problem in linux. The basic problem can be summarized as:
- Use the sound cards at their native sample-rate to improve over their rather poor hardware re-samplers.
- Mix audio from multiple applications on the cards.
- Be able to easily designate audio cards on a per application basis at application launch time.
I had commented earlier that I decided against pulseaudio because of its lack of 32 bit signed integer audio support. I realized after some general use of my previous alsa configuration that even though some applications use 32 bit audio well, most other applications have problems. Typically mplayer and ut2004 (through aoss) couldn’t correctly figure out that the device was running at 32 bit precision and sent it 16 bit audio data. This caused both the applications to run audio at half the speed with the audio crackling all over. The fix was simple: change S32_LE in .asoundrc to S16_LE. However, that would be the end of any 32 bit audio on my system. I also realized that the only application which I used (heavily) with 32 bit audio was madplay (piped through aplay; madplay directly outputs to hardware alone). I grudgingly agreed to sacrifice that
.
Pulseaudio configuration is pretty straight forward. I configured the /etc/pulse/default.pa for the two cards in the following way. I happily noticed that pulseaudio used a good resampler by default (speex-float-3 which has similar CPU usage as alsa’s plugin speexrate).
/etc/pulse/default.pa
#!/usr/bin/pulseaudio -nF .nofail ### Load something into the sample cache #load-sample-lazy x11-bell /usr/share/sounds/gtk-events/activate.wav #load-sample-lazy pulse-hotplug /usr/share/sounds/startup3.wav #load-sample-lazy pulse-coldplug /usr/share/sounds/startup3.wav #load-sample-lazy pulse-access /usr/share/sounds/generic.wav .fail ### Load audio drivers statically load-module module-alsa-sink device=intelHDA sink_name=Spkr rate=192000 load-module module-alsa-sink device=iMic sink_name=HeadPh rate=48000 ### Load several protocols #load-module module-esound-protocol-unix load-module module-native-protocol-unix ### Automatically restore the volume of playback streams #load-module module-volume-restore ### Automatically restore the default sink/source when changed by the user during runtime #load-module module-default-device-restore ### Automatically move streams to the default sink if the sink they are ### connected to dies, similar for sources load-module module-rescue-streams ### Automatically suspend sinks/sources that become idle for too long load-module module-suspend-on-idle ### Make some devices default set-default-sink Spkr #set-default-source input
To make alsa applications work directly with pulseaudio we just need to set the default pcm and ctl to the pulse alsa plugin (configuration shown later). The pulse plugin creates a new audio device called pulseaudio and maps its audio I/O to the default pulse sink which can be changed at runtime. The pulseaudio device also has two mixer controls; a “Master” for playback and a “Capture” for recording.
The problem with the above is that pulseaudio starts looking for mixer controls “Master” for every configured sink hardware device (with a fallback to “PCM”). The default alsa configuration doesn’t provide a “Master” control for either the intelHDA card or the iMic card. The “PCM” on iMic controls the hardware mixer directly and that for intelHDA controls a software volume for alsa’s default dmix configuration. Thus, the pulseaudio fallback to “PCM” works correctly for iMic (changing the pulseaudio “Master” control changes the volume) but not for intelHDA (changing pulseaudio “Master” control has no change on volume, but changing “Front” directly on the hardware using alsamixer -c does work). To work around this I configured two virtual softvol (software volume) devices for my two cards naming the softvol control “Master”. The configuration is shown below.
.asoundrc
pcm.!default {
type pulse
}
ctl.!default {
type pulse
}
# Create softvol devices for intelHDA and iMic.
# For intelHDA, its "PCM" control controls its default (not used) softvol.
# For iMic, its "PCM" control controls its hardware directly.
pcm.intelHDA {
type softvol
slave.pcm "hw:0,0"
control.name "Master"
control.card 0
}
pcm.iMic {
type softvol
slave.pcm "hw:1,0"
control.name "Master"
control.card 1
}
# It seems we require these dummies as pulseaudio tries to look up mixer devices.
ctl.intelHDA {
type hw
card 0
}
ctl.iMic {
type hw
card 1
}
# For UT2004 (which uses dsp0 through aoss), always go directly to headphone hardware.
pcm.dsp0 {
type plug
slave.pcm "hw:1,0"
}
ctl.dsp0 {
type hw
card 1
}
Note that the pcm names used (intelHDA and iMic) are used in /etc/pulse/default.pa as sinks. More information on the softvol alsa plugin can be found here. There is some nice documentation about the various alsa plugins here. There some good documentation about alsa is also present here, here and here.
To change the current default pulseaudio sink I rewrote the audio.sh from the previous post to the following:
audio.sh
#!/bin/bash
pulse_set_default_sink () {
pacmd << EOF
set-default-sink $1
EOF
}
h=`cat $HOME/.dwm/status_audio`;
if [ "x$1" == "x" ]; then
if [ "x$h" == "x[ Spkr ] " ]; then
echo -n "[ HeadPh ] " > $HOME/.dwm/status_audio ;
pulse_set_default_sink HeadPh ;
else
echo -n "[ Spkr ] " > $HOME/.dwm/status_audio ;
pulse_set_default_sink Spkr ;
fi
elif [ $1 == "up" ]; then
amixer set Master 2%+ ;
elif [ $1 == "down" ]; then
amixer set Master 5%- ;
elif [ $1 == "toggle" ]; then
amixer set Master toggle ;
else
echo "$0: Unknown command $1";
fi
v=`amixer get Master | grep "Front Left:" | egrep -o "[0-9]+%"`
m=`amixer get Master | grep "Front Left:" | egrep -o "off"`
if [ "x$m" == "x" ]; then
echo -n "vol:$v "
else
echo -n "vol:(M) "
fi > $HOME/.dwm/status_volume
Note that now environment based device settings are gone as the current default pulseaudio sink automatically maps to the global alsa default pcm device. Once an application connects to pulseaudio, it retains its sink mapping even after the default sink is changed. (Update: It seems that module-volume-restore remembers the volume and sink of a client and restores both when it sees the client again. This behavior is definitely useful but we need to disable module-volume-restore if we want our current default sink logic to work). Pulseaudio also support hot swapping an application’s audio from one sink to another. I am still thinking of a way to toggle the sink device of the currently focussed application using dwm shortcuts… that would be some nifty configuration
.


Hello! I’d like to leave my congratulations for this objective and useful post. There’s times that I’m looking for something like that about pulseaudio with Alsa. I’m using an Intel_hda sound card on my PC, and I’m still trying to configure the sample rate to 96/24 through pulseaudio, no success yet =/. Can you tell me how to get this config?
sorry my poor english, I’m brazilian.
good job!
This very usable.
My system is an upgrade, some element is gaining control and pulse is unable to find the hardware devices. Do you have any way to identify which module driver has the device? Or what configuration caused that to take place?
Thanks – Dan
Hi there, do you know of anything like this for Windows (Vista 64), in particular the ability to designate the default audio device on a per application basis. Ideally it would be integrated in to the audio mixer. I’ve tried looking around the web but the closest I could find was your web site for this Linux tweak.
I am aware that Vista has a per application audio mixing capability. However, I have not used Vista much esp. not with audio so I am unable to tell you exactly how to do that.
Pulseaudio is available for windows, but I don’t know if you can route windows audio to pulseaudio similar to the alsa routing in linux.
Pulse Audio is, unfortunately, a LEMON.
I am in the fortunate position of owning a sound card which can do hardware mixing (it’s a cheap-o SBLive). For the last month or two, since the last upgrade to Ubuntu 8.10, I’ve been thinking that there was a problem with one of my cables connecting my soundcard to my headphones and Creative 4.1 speaker set — often in a game, the sound just deadens quite a bit (as if a cable is half-unplugged), and there is crackling whenever there is a sound with reasonable bass (eg explosions in Quake4, life-leach in Sacred under WINE, etc). I uninstall Pulse Audio so that ALSA is being used directly, and the problem immediately goes away.
I certainly see the need for something like Pulse Audio — but it seems to be just as broken as ESD and ARTS, failing when the system is under load. Since I don’t need network transparency, sound card unification or a software mixer (nor do I care for per-application sound settings), I’m reverting back to the good old basic ALSA. At least I can play a game without feeling like I’m playing a scratchy old record.
Hi Dave, Its unfortunate that you had a bad experience with Pulseaudio. Your problem might be due to the fact that WINE doesn’t have a driver for pulseaudio. It uses alsa and the redirection from alsa to pulseaudio (and back to alsa) doesn’t work well if the application doesn’t use alsa well. I know there was some talk about the WINE guys writing a really good alsa based sound driver… but I don’t know how far that went. I personally think that its high time the non-pro audio apps on linux move to a standard sound API. Pulseaudio is a good choice because its designed and implemented well, has support from RedHat and comes with a lot of desktop goodies (network transparency is only part of the goodies).
Personally, I used pasuspender to launch applications I didn’t want to go through pulseaudio. You may have to configure wine to not go through the “default” alsa devices. Just use specific hardware or virtual device names in the wine audio configuration. My two articles on linux audio setup should be sufficient for you to configure and operate such devices. I wish pasuspender could avoid the cumbersome alsa configuration and direct audio directly to alsa.
This is complete madness with this pulseaudio! I am unable to grasp all this stuff! Post is very informative. Ritesh, it’s a pitty I couldn’t find any contacts of you in this blog.
You know who’s bloody awesome? You are! Here I am, thinking, ‘oh yeah, I might try out Pulseaudio for Slackware 13.37′ (hopefully Google finds that and points other people in my situation your way). Hmm… But how do I go about configuring it…? Google google google… Ubuntu stuff, some other stuff, aha! I was a bit wary of the age of this post (nearly five years!), but read through it.
Tried some stuff out here, works perfectly! Not even a reboot required! A++++ Would buy from this seller again.
PS: for the Slackware 13.37 + KDE folks, go into the System Settings>Multimedia>Phonon and move Esound (ESD) up to the top for every category. Install Pulseaudio from SlackBuilds.org After that, do everything down to (and including) the .asoundrc step here.