asoundrc mini-howto

author: joy ping
date: 01-04-2002

how it works

asoundrc is typically installed in the home-directory ($HOME/.asoundrc) and is called from /usr/share/alsa/alsa.conf. its also posible to install a systemwide configuration file as /etc/asound.conf. if an alsa-aplication starts both configuration files were read. both files are not installed by alsa automatically you have to do it manually!

why asoundrc? what is it good for?

till now nor .asoundrc neither alsa.conf is needed for alsa to properly work. all aplications should work without it. its only give some extra functionality to make routings, samplerate-conversions etc at a low-lewel-stage.

sections

the asoundrc consists of 3 main parts:

PCM section
MIDI section
CTL section

The PCM section is resposible for your PCM-device(s). PCM means PulseCodeModulationin, in short its the device which handles digital input and transform it (mainly in analog form) to the outside world. Or in reverse it takes a (mostly analog) signal (from your line-in) and transfrom it to a digital signal readable by your application. When you start your favorite player, e.g. alsaplayer, the signal goes trough a PCM-device. A more complete description of PCM is available from the ALSA-API-documentation:

links http://www.alsa-project.org/alsa-lib/pcm_plugins.html

MIDI is only a transport-layer for communication of different devices, originally developt for communication of different instruments. Its a bit like a networklayer, but more simple. You need a device, as an instrument, to use it. If your soundcard has a MIDI-device you can use the ALSA-Sequencer device, which have to be compiled in, and if you have a hardware-synthesizer on your soundcard, like the mpu401 you can use this as an instrument, but as the most soundcards have a poor MIDI-Section, its better to use a software-device like timidity, or external instruments. a complete definition of the current MIDI-Standart is available from:

links MIDI

The CTL-Section is something as a main node for the other devices of one soundcard.


in detail

a typical asoundrc starts with a 'PCM hw type'. this gives an alsa-aplication the posibility to start a special PCM-device on your soundcard (plugin, or slave) by a given name. without this you have to access your soundcard-pcm(s) by 'hw:0,0' or 'default'. example:

ecasound -i test.wav -o alsa,hw:0,0

or with aplay

aplay -D hw:0,0 test.wav

the numbers after hw: stands for 0 = your first soundcard, second 0 = subdevice. to acces the first subdevice on your second soundcard you have to type in hw:1,0. with the keyword 'default' you acces your default subdevice on your default soundcard which is mostly 0,0. now with the 'PCM hw type' you are able to define aliases for your pcm-devices. the syntax for this definition is:

pcm.NAME { 
type hw # Kernel PCM
card INT/STR # Card name or number
[device] INT # Device number (default 0)
[subdevice] INT # Subdevice number, -1 first available (default -1)
mmap_emulation BOOL # enable mmap emulation for ro/wo devices
} 

for example, to give your pcm on your first soundcard an alias:

pcm.ens1371 {

type hw
card 0
device 0
}

now you can acces this pcm-device by the alias 'ens1371'.

aplay -D ens1371 test.wav
some apllications as alsaplayer or also jack requires the CTL-definition, which have to have the same name as the required PCM-device. it looks like as follows:

ctl.ens1371 {

type hw
card 0
}

this definitions are needed to apply any further plugins or slaves in asoundrc.

now define a slave for this plugin. a very simple slave could be defined as follows:

pcm_slave.sltest {

pcm ens1371
}

this defines a slave without any parameters. its not more as another alias for your sounddevice. the bit complicate thing to understand is, that parameters for 'pcm types' must be defined in the slave-definition-block. lets setup a rate-converter, which shows this behaviour.

pcm_slave.sl2 {

pcm ens1371
rate 44100
}

pcm.rate_convert {

type rate
slave sl2
}

now you can call this newly created (virtual)-device by:

aplay -D rate_convert test.wav

which automatically converts your samples to 44.1 kHz samplerate while playing. its not very usefull cause the most players and alsa converts samples to the right samplerate, which your soundcard is capable of, but you can use it for a conversion to a lower static samplerate for example.

a more complex tool for conversion is the pcm type plug. the syntax is:

type plug # Format adjusted PCM
slave STR # Slave name (see pcm_slave)
# or
slave { # Slave definition
pcm STR # Slave PCM name
# or
pcm { } # Slave PCM definition
[format STR] # Slave format (default nearest) or "unchanged"
[channels INT] # Slave channels (default nearest) or "unchanged"
[rate INT] # Slave rate (default nearest) or "unchanged"
}
route_policy STR # route policy for automatic ttable generation
# STR can be 'default', 'average', 'copy', 'duplicate'
# average: result is average of input channels
# copy: only first channels are copied to destination
# duplicate: duplicate first set of channels
# default: copy policy, except for mono capture - sum
ttable { # Transfer table (bidimensional compound of
# cchannels * schannels numbers)
CCHANNEL {
SCHANNEL REAL # route value (0.0 ... 1.0)
}
}

we can use it as follows:

pcm_slave.sl3 {

pcm ens1371
format S16_LE
channels 1
rate 16000
}

pcm.complex_convert {

type plug
slave sl3
}

by calling it with:

aplay -vD complex_convert test.wav

you will convert the sample during playing to the sample format: S16_LE, one channel and a sample-rate of 16 kHz. as you called aplay with the verbose option -v you see the options you have set.

routing

adding the definition: 'route_policy average' to the above plug definition, routes the average of your channels to your given one.

you could define also a more complex routing behaviour with the 'plug'-plugin.

pcm.plug_convert2 {

type plug
slave.pcm m
ttable.0.0 0.8
ttable.1.1 0.1
}

here we added some so called routing tables to our plug. the first digit after table means the source channel, which must be an INT the second digit is the destination-channel, the last digit which is a float number describes the volume for the destination-channel, the range is 0.0-1.0
in short it could be written as: ttable.SOURCE_CHANNEL.DESTINATION_CHANNEL VOLUME

ttable.0.0 means routes channel 0 from source to channel 0 destination. 0.8 is the volume-value.

ttable.1.1 routes second channel (1) from source to second channel (1) at destination with a volume of 0.1.

with:

ttable.0.0 0.8
ttable.1.0 0.2

we route the first and second channel of the source to the first channel of destination.

this examples handles only two channel in and out as it is the case with most stereo-wav-files, its not very usefull in 'everydays life', but if you have some multi-channel-files found on dvd-tracks f.e. you can use such a configuration for routing it to a 2-channel-out, or routing only some special channels.

need to be added: dynamic routing, multi, shared and mix

the alsa-soundserver and the shared-memory-device

the 'new' alsa-lib-0.9 comes with a simple kind of soundserver, which allows you to play sound-streams over a network or socket. its NOT possible to send multiple streams to this server (or i didn't figured out how it works), but for sharing one pcm-device with multiple-streams i recommend to use jack, anyway.

how to set up the soundserver:

at first the server and controldevice have to be defined as for example:

ctl.shm_test {

type shm
server server_test
ctl ens1371 #this must be a real pcm device
}

server.server_test {

host localhost
socket '/tmp/alsa.sock'
}

instead of a socket you can also define a port which the server should listen to. as for example:

port 9999

at least the shared memory device has to be defined:

pcm.shm_test {

type shm
server server_test
pcm ens1371
}

pcm must be a real-device where the server is running!

then you have to start aserver with the defined server name:

aserver server_test
after this you can play (or record?) from/to the server as for example:

aplay -D shm_test test.wav
aserver is by default build and installed with the current alsa-lib.