No More Silence!
No More Silence!... or Taking the ‘alas’ out of ALSA
A common discovery after installing a Linux distro or changing your computer’s audio hardware is to find that the “sound isn’t working properly” when you want to play something. This may mean you can get audio output, but it emerges via the a route that isn’t the one you wanted. For example, via HDMI or a headphone socket, but you wanted SPDIF. Or in some cases you can’t find any sign of audio emerging at all! This can also sometimes happen to the unwary simply as a result of installing new software or a distro ‘update’ of the packages installed.
The cause of such problems with modern distros tends to be that some of the installed software has decided on your behalf that “Nanny knows best” what you want. So it is waving a magic wand for you under the assumption you’ll be happy. Alas, I’ve found that some sound systems (you know who I mean, Pulse Audio!) can then ignore or interfere with attempts to correct its mistakes. So in my experience the best solution is to go direct – via ALSA. With that in mind, this page provides a guide to getting sound working and bypassing all the fancy added sound layers like Pulse!
Step one is to ensure you have the hardware you want to use connected and ready. For the sake of this walk-though I’ll assume you have an external asynchronous USB DAC. After all, they can provide superb results. So if your interest is – like mine – in optimum sound quality, the chances are you’ll be using one. But don’t worry, what follows should work for internal soundcards as well...
Step two is to open a terminal and type in the command aplay -l (that’s a lower-case ‘l’). This asks ALSA to list what sound playing cards and devices are connected to your computer. On the laptop I’m using for the sake of example it gives the following info
**** List of PLAYBACK Hardware Devices ****
card 0: Intel [HDA Intel], device 0: ALC888 Analog [ALC888 Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 1: ALC888 Digital [ALC888 Digital]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 3: HDMI 0 [HDMI 0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: Bridge [SPDIF Bridge], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
This shows two sound ‘cards’ connected. Card 0 is the internal sound hardware in the laptop. Card 1 is the external USB sound ‘card’. In this case a Halide Bridge. From this list I can see that the Halide Bridge that I want to have play the music is card 1, device 0, subdevice 0.
To tell my laptop this is where I want sound output to go I can now create a file with the name .asoundrc which I put in my home directory. This contains the lines
pcm.!default {
type plug
slave {
pcm "hw:1"
channels 2
format S24_3LE
}
}
When ALSA is called to handle any sound capture or playback it looks to see if it can find such a file. When it finds the .asoundrc file it scans the contents for instructions telling it what you want. (Note that in fact I’ve found that this particular .asoundrc file gets every USB DAC I’ve tried working OK.)
The pcm.!default line tells ALSA that what follows is a set of instructions that over-rule any previous default setup info it has been given regarding how to play LPCM soundfiles. This means it will then ignore any settings auto-installed by other software that may be preventing you from getting the results you want.
The pcm "hw:1" tells ALSA that sound output should be sent to the ‘card 1’ hardware – which in this example is the Halide Bridge USB. This becomes the default output. I could actually have been more specific and used "hw:1,0,0" rather than abbreviate to "hw:1" but ALSA will assume zeros for these if no device or subdevice values are given.
In many cases the above is only line you will need, and you just have to change the numbers after the hw: to match what card/device.subdevice you wish to have output the music. It’s quite likely you can omit the channels and format lines altogether.
However some hardware – without software help – can only accept a few audio data formats. The Halide Bridge hardware can only accept stereo, so I’ve included the channels 2 line to specify this. It also expects sample values to be given to it in the form of signed 24 bit values packed into 32 bit integers. i.e. the S24_3LE format. Hence the format line I included. More generally, internal soundcard hardware tends to accept formats like S16_LE. So if a format is needed you may find format S16_LE gets things working rather than S24_3LE.
The added details will at first seem mystical. But bear in mind that with many sound devices you may not need them. Fortunately ALSA provides ways to diagnose what may be needed or even bypass some possible complications. To explain, let’s assume I didn’t know about the extra lines and just put
pcm.!default {
type plug
slave {
pcm "hw:1"
}
}
In the .asoundrc file. All I’ve done in this case is tell ALSA which card to use. But I’ve given no info on what its hardware can understand. To test the behaviour I then use the aplay command again and see if it will successfully play an LPCM wave file OK. To do this you need to already have a suitable soundfile ready to play.
Tip:
To improve your chances of success when testing, use a stereo LPCM Wave file with a sample rate of 48000 samples/sec (the best option) or 44100 samples/sec (the Audio CD standard). Most computer hardware tends to be able to handle these rates, but may not be able to accept ultra-low sample rate files, or even mono! So don’t do initial tests with something like a mono file with a sample rate below 44100 samples/sec. For the same reasons, stick to files with LPCM 16-bit samples for tests.
|
If your test file is called ‘fred.wav’ try the command aplay fred.wav. If that produces music from the output you wish, bingo! Success! You can jump to Step three: choosing your playing software!
If not, then either you’ll get an error message from aplay, or sound will emerge from the ‘wrong’ output and you misread or misunderstood the info provided by aplay -l! If you got an error message it may have complained about the number of channels or the format. This will be your clue to what extra lines may need to be added to the .asoundrc file if any are needed. For the Halide Bridge (and all the other asynchronous USB DACs I’ve tried) this led me to the channels 2 and format S24_3LE lines which specify the required arrangements for sound to work correctly.
Swings and Roundabouts.
An alternative approach is to change the basic .asoundrc file to read
pcm.!default {
type plug
slave {
pcm "plughw:1"
}
}
Where, as before, remember that your sound card and device may be some other number than ‘1’.
Now we’re telling ALSA to send to the same soundcard as before, but by via a route called plughw: rather than hw:. This change tells ALSA it can send the sound data via any available ‘format conversions’ layer in software. So when you try to play something which the hardware of the card doesn’t understand ALSA will try to convert your supplied input into a format that the hardware can happily accept. ALSA will try to sort this out for you. So in many cases if you can’t find what settings will make the hw: route work, you can succeed by using plughw:.
Looks ideal. But there are two potential drawbacks to this approach. Firstly, if you are like me and don’t want the audio data sample values ‘mucked about’ on the way to the DAC then you may feel that using plughw: rather than hw: risks degrading the sound quality. However, if you find it works and you’re happy with the results, fair enough! On to Step three and using your music playing software...
The second possible snag is that some settings or choices may allow ALSA to run the data though added software layers which may not be set up as you want. For example, you may get silence because the data is being sent though a ‘volume control’ that is wound down or muted. To check for problems like this, use alsamixer as explained on this page and see if any relevant controls need to be un-muted or their gain/volume changed before you can hear output.
|
Fortunately the aplay command has an extra trick up its sleeve when you are doing tests. You can tell it where to send its output directly. So you can try various cards and devices to see if they will play, and check the numbers given by aplay -l. The above .asoundrc files specify the alsa ‘default’ output, but you can still use others if you wish. So for example,
aplay -Dhw:0,3,0 fred.wav
would play the file via the HDMI output of my laptop. And if the file’s sample rate or format needed conversion so that failed, then
aplay -Dplughw:0,3,0 fred.wav
would be likely to work. The -D tells ALSA that the aplay command wants to use card 0, device 3, regardless of the ALSA default specified in the .asoundrc file. When you don’t give a -D value, aplay sends output to the default output route. i.e. the output you’ve specified in your .asoundrc file.
The above all identifies cards, devices, etc, by the numbers assigned by ALSA to the hardware it found when the computer was booted up or extra hardware was connected. But there is an alternative approach which is sometimes useful. You can see this by using the aplay -L command and examining the info this lists. Note that this time the ‘L’ is upper-case. For my laptop this gives a much longer output list as it provides more information. So I’ll just quote the relevant parts below
hw:CARD=Bridge,DEV=0
SPDIF Bridge, USB Audio
Direct hardware device without any conversions
plughw:CARD=Bridge,DEV=0
SPDIF Bridge, USB Audio
Hardware device with all software conversions
Here the Halide Bridge is identifying itself with some strings, and telling us what they mean. So the string hw:CARD=Bridge,DEV=0 means the Halide Bridge direct hardware connection, no conversions. i.e. as things stand it means exactly the same as hw:1 or hw:1,0,0 which use numbers assigned by ALSA. This means I could have my .asoundrc file contain
pcm.!default {
type plug
slave {
pcm "hw:CARD=Bridge,DEV=0"
channels 2
format S24_3LE
}
}
and it will work just the same as if I’d used "hw:1".
The choice between using numbers or strings is a swings-and-roundabouts one. If I change the audio hardware the numbers assigned may alter. So I might then also need to alter any hw: specification to match the new numbers for a given bit of hardware. However if I only have one Halide Bridge connected, then the hw:CARD=Bridge,DEV=0 will find it even if the numbers have been altered. The snag with that being that in the (unlikely!) event of my having two Halide Bridges connected I’d need to use the numbers assigned by ALSA to indicate which of them I wanted! I doubt most people will encounter this, but it illustrates a point to bear in mind. In practice, using the string provided by the card can be convenient. But either way usually works - once you’ve found the relevant numbers or string.
Step three is to chose your preferred programs/applications for playing sound. The vital point here is to only use programs that provide the user with an option to play via ALSA. Programs that don’t give you this choice and blindly insist on playing out by other method like Pulse, etc, may simply not be able to deliver to the output you want. Although of course you may be lucky. But if you were, you probably wouldn’t be reading this!
Pulse Alert!
The best advice I can give about the Pulse audio system is stark.
Remove it from your machine!
My experience is that it persistently interferes with being able to get audio playing in a direct and controlled way. Sometimes the problem is obvious: No sound from the audio port or DAC you have chosen. Setting the alsa default may not work if Pulse is messing things up behind the scenes. The result may be silence, or baffling error messages from programs like Audacious. But even if you can hear sound from the output you prefer, Pulse may still be degrading the quality without telling you.
For example, when I installed Xubuntu 12.04 on one machine I could get the sound playing via my preferred external USB DAC. But everything reaching the DAC was being downsampled to 44.1k – even high quality 96k sample rate material. Removing Pulse audio instantly solved the problem. Having got rid of it, what went to the DAC matched each file I played. If you have an external DAC that shows the sample rate it is being fed you can check this. If not, take care!
So un-install Pulse audio if you want to control what is happening to your audio, and you care about sound quality! Audacious, etc, all work fine without it.
|
My personal recommendations/favourites for playing audio and AV files are Audacious, VLC, and Audacity. They all work fine when set to play out directly using ALSA. In some cases you can simply set them to play via the ALSA ‘default’ or ‘direct’. Alternately they may have an option menu showing a list of the ALSA ‘sinks’ or ‘outputs’. If aplay lets you play a file as you wish, each of these programs should be able to do the same. And although aplay itself can’t do format conversions, programs like Audacious, etc, will convert other file and stream formats into the LPCM that the hardware tells ALSA it expects. For serious audio quality this means formats like Flac will then play as easily as LPCM Wave. For lower-fi, it also lets you play mp3, etc, from sources like internet radio streams and podcasts. So the result should be that you can then play the files you want via the output you prefer!
2400 Words
3rd March 2013
Jim Lesurf