ALSA

Alsa is the Advanced Linux Sound System. It contains of two parts the kernel drivers and the user space library.

Important

ALSA standardizes the way sound hardware is accessed but it is not a sound server. Without a sound server as pulseaudio a program might prevent other programs to access the sound hardware.

There might be more than one device that gets handled by ALSA:

  1. the sound card where the loudspeakers are attached

  2. the graphic card having a HDMI output

  3. but also a DVB-T cards sound

  4. the microphone built into a web cam

Caution

ALSA might working well but the speakers are not plugged in there where the sound comes out or mute is active.

Setting up ALSA

  1. Prepare the kernel with the corresponding sound drivers. It might be considered to have them as modules and not built into the kernel. This allows to insert them by modprobe as well as passing options to the modules. Verify them by lsmod and remove them by rmmod

  2. Set the alsa useflag then every other packages get alsa support. Then install alsa-utils

  3. Make that the Alsa daemon starts at boot and start it. For OpenRC this is done with rc-update add alsasound boot and /etc/init.d/alsasound start

  4. When having just one sound card than it should work right away. When having more than one then sooner or later troubles arrive, due to their enumeration.

    Check with cat /proc/asound/cards, aplay -L, aplay --list-devices or alsamixer (F6) to see how many sound-cards are there. Check the settings of the sound cards, maybe something is muted pressing M in alsamixer will toggle the muting.

  5. Type ls -l /dev/dsp* to see how many dsps are there. Then type cat /dev/urandom > /dev/dsp<n>. If noise (abort with Ctrl + C) appears, then the hardware and its drivers work well. If no noise appears, a hardware problem might exist. On laptops some mute and volume buttons might be the trouble (The wost problems are always the ones that are no problems but features)!

    Note

    /dev/dsp is actually used just for older programs written for the ALSA predecessor OSS. If /dev/dsp does not exist it can be created via kernel configuration. Under ALSA enable OSS PCM (digital audio) API

  6. aplay /usr/share/sounds/alsa/* should sound when everything is ok and the setup is done. It lets you find your speakers! Or speaker-test -t wav -c 2 that does almost the same but must be turned off by Ctrl + C

  7. If the standard call to aplay does not work, test the sound of the cards and their devices with aplay -D plughw:<x>,<y> /usr/share/sounds/alsa/* where <x> is card and <y> device as aplay -l shows.

    Important

    There is also hw instead of plughw. hw gives more direct access to the sound hardware and is therefore picky when it comes to channel numbers and sample rate. plughw is a layer above that can handle those things.

    Important

    Card0 and Device0 must be the sound-card where your speakers (or microphone) are attached to work with the ALSA default settings.

    What happens if this is not the case:

    1. Wondering why the sound does not come out? The reason is that it goes into a TV card that obviously fails, since it has no loudspeaker.

    2. Having a jumper cable between TV card and sound card. Troubleshooting the sound cards mixer, but the problem is not there, the TV card has muted the sound. In such cases the jumper cable can be replaced by a headphone and a mp3 player, so the problem can be immediately located.

    3. aplay gets an error since it wants to play a sound on a sound device that can not play sounds

    If the order of cards and/or devices is wrong there are the ways to fix it:

    • Define the order how the sound drivers get loaded

    • Use a ~/.asoundrc or a system wide /etc/asound.conf file

No headphones

Build the driver as module and then pass options to it via /etc/modprobe.d/alsa.conf

options snd-hda-intel model=headset-mic

or

options snd-hda-intel enable_msi=1 single_cmd=1 model=laptop

Set sequence of ALSA cards and devices

Pass parameters to the sound drivers via /etc/modprobe.d/alsa.conf. For that you should know the device names. When having a kernel with the sound drivers not included type lsmod to see.

Important

If the kernel has the sound devices included, build a new kernel using modules for it.

options snd cards_limit=2
options snd-via82xx index=0
options saa7134-alsa index=1

Caution

The driver shown by lsmod is snd_via82xx but in the file snd-via82xx needs to be written.

The next complexity is when a sound driver as snd_hd_intel supports more than one device and their sequence is mixed up. This can be corrected inside /etc/moduprobe.d/alsa.conf as follows:

options snd-hda-intel index=1,0

Some other example showing a sound card and a video card

options snd-hda-intel index=0,1,2
options saa7134-alsa index=3

Reboot takes effect of the new sequence.

Important

Changing the sequences can just be done if the drivers are compiled as modules. It will not work when they are inside the kernel.

Or better use something as rmmod snd_hda_intel and modprobe snd_hda_intel index=1,0

ALSA config files

When ALSA gets used then the file /usr/share/alsa/alsa.conf gets called and this file calls if present a user file in ~/.asoundrc or the system wide file /etc/asound.conf.

Those files can do simple things as creating names for the cards (aliases) or exchanging the default card with:

pcm.!default {
  type plug
  slave {
    pcm "hw:<x>,<y>"
  }
}
ctl.!default {
  type hw
  card <x>
}

Or they can create virtual devices that do audio processing or more easier stuff as routing audio streams. See http://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html

Setting up ALSA for HDMI

The HDMI card is quite limited but it has a mute switch that is muted by default so check it using alsamixer.

aplay -l shows you the sound card assuming it is card1 device 3 as aplay --list-devices

**** List of PLAYBACK Hardware Devices ****

card 0: Generic [HD-Audio Generic], device 0: ALC887-VD Analog [ALC887-VD Analog]

Subdevices: 1/1

Subdevice #0: subdevice #0

card 0: Generic [HD-Audio Generic], device 1: ALC887-VD Digital [ALC887-VD Digital]

Subdevices: 1/1

Subdevice #0: subdevice #0

card 1: HDMI [HDA ATI HDMI], device 3: HDMI 0 [HDMI 0]

Subdevices: 1/1

Subdevice #0: subdevice #0 :

aplay -D plughw:1,3 /usr/share/sounds/alsa/* will play it

Since HDMI is not card0 and device 0, the ALSA default setting will not work. Just doing that would also be possible by changing the sequences of the devices but this section does it by adding HDMI as default for a user in ~/.asoundrc or system wide in /etc/asound.conf

pcm.!default {
  type plug
  slave {
    pcm "hw:1,3"
  }
}
ctl.!default {
  type hw
  card 1
  device 3
}

Test it with aplay /usr/share/sounds/alsa/*

Now the analog output might be mute. So what comes next is having both running simultaneously.

It is best to rename the above /etc/asound.conf to /etc/hdmi_asound.conf and work using link as ln -s /etc/hdmi_asound.conf /etc/asound.conf

Check what analog needs and create the file /etc/analog_asound.conf with:

pcm.!default {
  type plug
  slave {
    pcm "hw:0,0"
  }
}
ctl.!default {
  type hw
  card 0
}

then link it with ln -s /etc/analog_asound.conf /etc/asound.conf

Now the analog audio should be heard but the digital not.

Next merge both together to the file /etc/both_asound.conf and link it ln -s /etc/both_asound.conf /etc/asound.conf

# Connect HDMI and analog simultaneously to the output  

# exchange the default pcm
pcm.!default {
    type plug
    slave.pcm both
}

# Create a 4 channel pcm input device from the 2 cards
pcm.quad {
        type multi
        slaves {
                a {
                        pcm "hw:1,3" # HDMI
                        channels 2
                }
                b {
                        pcm "hw:0,0" # analog
                        channels 2
                }
        }
        bindings {
                0 {
                        slave a
                        channel 0
                }
                1 {
                        slave a
                        channel 1
                }
                2 {
                        slave b
                        channel 0
                }
                3 {
                        slave b
                        channel 1
                }
        }
}

# Feed 2 channel stereo to the 4 input channels
# ttable: 
# - first is input channel, 
# - second is output channel, 
# - third is volume
pcm.both {
  type route
  slave.pcm "quad"
  ttable.0.0 1
  ttable.1.1 1
  ttable.0.2 1
  ttable.1.3 1
}

ALSA Mixer

To check alsa open two console windows change them to su and do:

alsamixer -V all to have in the first window the sound card

alsamixer -c 3 all to in the second window the TV card

A brief description about the device and all controls can be seen.

The controls can be grouped in two:

  1. Playback: A sound source gets mixed to the output load speaker). A sound sources is the D/A converter others are analog signals coming directly from the CD player or TV card or the mixer.

  2. Capture: The analogue sound signal gets converted into a digital data stream by the A/D converter

F3, F4, F5 keys in alsamixer making the individual groups visible or hiding them. The H key opens a help window. M to mute and unmute the channels. The capture channels have a capture property, press space to enable capture. Capture and mute are quite similar:

  1. Capture is muting inputs

  2. Mute is muting outputs

The DSP is the digital signal processor that can manipulated the digital data streams (compress, encode, decode). Every sound control has mixer sound levels. Additional there are switches as mute, or diverse options (My VIA sound chips needs to put exchange front surround to off and VIA DXS sliders to maximum).

If you get really bad sound quality from the line out socket, but everything seems to work, check if it is also the case for the front audio socket. If the front audio quality is good and very loud, then probably there is a audio saturation problem inside the sound chips. So take the sound levels back to 50% and try to get a setting that satisfies all outputs.

To check if sound works in principle, turn all captures on and give maximum level, this produces a lot of noise and let you find out that something is going on. For the final settings mute all captures and put the not used input levels to zero.

Command line sound tools

The following command line tools come with ALSA:

  1. To record 5 seconds of arecord -d 5 sound.wav or arecord hw:1,0 -d 5 sound.wav to record from card 1 device 0 as returned by arecord -l

  2. To play it aplay sound.wav

  3. To see (or set) mixer options amixer -i

  4. To set mixer amixer set Master 90% unmute and amixer set PCM 85% unmute. Type amixer scontrols to get a list of all controls.

/etc/asound.state restores mixer settings.

To play mp3 from the command line madplay and

madplay -v /<path>/<song>.mp3

To store the mixer settings in /etc/asound.state type alsactl store and to restore type alsactl restore.

lame can be used to create mp3 files, it supports various input formats as: raw pcm, wav, ...:

lame<input>.wav <output>.mp3

lame -B 80 <infile>.mp3 <outfile>.mp3 re-samples the file to get a lower bit rate. This might be useful when an older or smaller device runs into performance problems when playing a high quality mp3

Capture audio

The first issue is selecting one of the many capture sources and audio card. alsamixer shows Mic, CD Line.

Capture Audio from microphone

Set the alsamixer to have captures active (red CAPTURE text), correct input selection and volumes high and not muted. arecord -l will show what hardware there is. Obvious a microphone is required, when extern then it needs to be plugged into the usually pink socket.

arecord -vv --device=plughw:0,0 --duration=5 --format=dat /dev/null will record from Card 0 Device 0 (as arecord -l showed) for 5sec microphone noise and destroys its recording immediately by writing it to /dev/null instead to a file (as mic.wav). The options -vvv or -vv will put some verbose text containing a VU meter (volume meter) producing some ### characters, clap in your hands and you should see an effect.

When it works, add a filename as mic.wav instead of /dev/null and when done aplay mic.wav will then play it back.

Capture audio via line input

What comes out of the speakers might not be recorded and what is recorded might not appear on the PC loudspeakers, just what alsamixer F4 Capture shows can be recorded and what F3 playback can be heard . A jumper cable can feed back e.g the black audio output to blue line input. The next thing is identify the capture source and the playback device and adjust the levels so the audio does not run in saturation.

Figure 12.1. Playback

Playback line recording


Important

To not create a feedback, mute the Line input in the playback settings.

arecord -f cd -d 10 sound.wav will record 10 seconds and aplay sound.wav plays it back

Capture audio via loopback driver

A solution without the jumper cable from a speaker output to the line input is making use of the generic ALSA loop back driver coming with the kernel. If compiled as module it can be loaded with modprobe snd-aloop to get a virtual soundcard. alsamixer F6 shows it usually as sound card 1. alsamixer can not do anything with it, since it has no controls. It also has no speakers attached, so it can not be listened to its outputs.

The applications creating the sound need to make use of the virtual sound card. This can be done by setting it temporarily as the users default sound card in ~/.asoundrc as (assuming the virtual sound card is card 1):

pcm.!default {
    type hw
    card 1
    device 0
}

Important

The virtual soundcard has no speakers attached so nothing comes out of the speakers. Assuming the virtual soundcard is hw1 arecord -D hw:1,1 -f cd | aplay -D hw:0 -f cd will pass its output back to the physical soundcard having the speakers attached. When now an application is started then sound appears from the speakers.Crtl + Z, ps and kill -9 <PID> should be executed to free the soundcards for the next steps.

To record the audio via loop back is a bit tricky since the recorded sound will go into a file and not to the speakers. If the recorded sound is played using aplay then it will end up at the virtual soundcard that has no speakers attached. The following procedure shows a user friendly procedure for ALSA loopback sound recording:

  • Instead of creating a ~./.asoundrc file create a ~/.asoundrc_loopback file and then create a symbolic link ln -s ~/.asoundrc_loopback ~/.asoundrc

  • modprobe snd-aloop

  • Start the application that produces the sound. Nothing can be heard since the application uses now the speaker less virtual sound card of the ALSA loopback device.

  • Delete the link rm ~/.asoundrc but keep the ~/.asoundrc_loopback file for later use. The still running sound producing application will keep using the virtual sound card.

  • Open a console and arecord -D hw:1,1 -f cd -d 20 sound.wav to capture 20s sound from the application using the virtual sound card. If an error pops up then adapting the audio type as -f FLOAT_LE -c2 -r 44100 might be necessarily.

  • After recording sound aplay sound.wav will play back the sound to the speaker using the physical sound card (since ~/-asoundrc has been deleted before)

For details google for ALSA generic loopback driver

Gui sound tools

audacity to let you record analog audio e.g. from a tape.

aumix is a mixer program.

In the mixer do the settings:

  1. Click on red radio buttons (LED) so it illuminates Capture and Line

  2. Put the sliders to max.

  3. All other inputs turn off so no noise comes in red radio button (LED) dark.

qastools comes with different gui tools as qasmixer that is as alsamixer, qashctl a more complex mixer and qasconfig a ALSA configuration browser.

There is alsamixergui that has not much functionality and does not look nice.

To have an standalone graphical mixer aumix.


Linurs startpage