# vim:noet:ts=8:sw=2
# Updated 060704 notes {at} notes.for.sabi.co.UK
#
# Syntax (somewhat) described in these links:
# http://ALSA-project.org/alsa-doc/alsa-lib/conf.html
# http://ALSA-project.org/alsa-doc/alsa-lib/confarg.html
# http://ALSA-project.org/alsa-doc/alsa-lib/conffunc.html
# http://ALSA-project.org/alsa-doc/alsa-lib/confhooks.html
# In this file I use a style similar to the one I use for CSS style sheets.
# It may also help to read:
# http://WWW.sabi.co.UK/Notes/linuxSoundALSA.html
# Also check carefully the contents of '/usr/share/alsa/alsa.conf',
# especially for the one liners defining standard device names
# and attributess, or the output of 'arecord -L' or 'aplay -L'.
# The device names "default", "dsp0", "mixer0" have special meanings.
# Standard channel number assignments:
# 0 front left 1 front right,
# 2 rear left 3 rear right
# 4 center 5 lfe/subwoofer
# 6 side left 7 side right
########################################################################
# Read very carefully the ALSA PCM plugin page at:
# http://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html
# For the 'asym', 'dsnoop', 'dmix' plugins also read:
# http://ALSA.OpenSrc.org/index.php?page=asym
# http://ALSA.OpenSrc.org/index.php?page=dsnoop
# http://ALSA.OpenSrc.org/index.php?page=DmixPlugin
pcm.c20
{
@args [ CARD ]
@args.CARD { type string; default "0"; }
type hw;
card $CARD;
}
pcm.c40 = pcm.surround40;
pcm.c51 = pcm.surround51;
pcm.dsp
{
@args [ SNOOP MIX ]
@args.SNOOP { type string; }
@args.MIX { type string; }
type asym;
capture.pcm $SNOOP;
playback.pcm $MIX;
}
pcm.rec
{
@args [ KEY SLAVE ]
@args.KEY { type integer; }
@args.SLAVE { type string; }
type dsnoop;
ipc_key $KEY;
slave.pcm $SLAVE;
}
pcm.iec
{
@args [ SLAVE ]
@args.SLAVE { type string; }
type iec958;
slave.pcm $SLAVE;
}
# For Tribes 2, which has the channels reversed.
# http://home.Erin.UToronto.CA/~jbonham/tribes2-alsa.html
pcm.swap
{
@args [ SLAVE ]
@args.SLAVE { type string; }
type route;
slave.pcm $SLAVE;
ttable.0.1 1;
ttable.1.0 1;
}
# Buffering (period time defaults to 125000 usecs).
# Size of period, expressed either in usec or byte units:
# period_time USECS
# period_size BYTES
# Size of buffers, expressed either in period, usec, or byte units:
# periods PERIODS
# buffer_time USECS
# buffer_size BYTES
# The ALSA docs have examples with 'period_time' set to 0, when
# 'period_size' and 'buffer_size' are used instead, but this can
# cause trouble in later releases of ALSA.
# For OSS compatibility, 'period_size' and 'buffer_size' should
# be powers of 2. Also, many cards cannot accept a 'period_size'
# much greater than 4096, so 4096 is mostly safe. Some like the
# nForce 8x0 compatibles require a smaller one still.
# On my VIA 8233A, any value for 'period_time' greater than
# 85333 usecs (precisely!) causes hiccups in sound output.
# Why? At 48kHz, 85333 usec are just over 4096 bytes/channel.
pcm_slave.dmix_slave
{
@args [ CHAN PCM RATE PSIZE BSIZE PTIME BTIME ]
@args.CHAN { type integer; }
@args.PCM { type string; }
@args.RATE { type integer; default 48000; }
@args.PSIZE { type integer; default 4096; }
@args.BSIZE { type integer; default 40960; }
@args.PTIME { type integer; default 84000; }
@args.BTIME { type integer; default 840000; }
pcm $PCM;
rate $RATE;
period_time $PTIME;
buffer_time $BTIME;
period_size $PSIZE;
buffer_size $BSIZE;
channels $CHAN;
}
# 2/4/6 CHANNEL SW SHARING
# ########################
pcm.dmix-20
{
@args [ KEY PCM RATE PSIZE BSIZE PTIME BTIME ]
@args.KEY { type integer; }
@args.PCM { type string; }
@args.RATE { type integer; default 48000; }
@args.PSIZE { type integer; default 4096; }
@args.BSIZE { type integer; default 40960; }
@args.PTIME { type integer; default 84000; }
@args.BTIME { type integer; default 840000; }
type dmix;
ipc_key $KEY;
slave { @func concat
strings [ "dmix_slave:2," $PCM "," $RATE ","
$PSIZE "," $BSIZE "," $PTIME "," $BTIME ] };
bindings.0 0;
bindings.1 1;
}
pcm.dmix-40
{
@args [ KEY PCM RATE PSIZE BSIZE PTIME BTIME ]
@args.KEY { type integer; }
@args.PCM { type string; }
@args.RATE { type integer; default 48000; }
@args.PSIZE { type integer; default 4096; }
@args.BSIZE { type integer; default 40960; }
@args.PTIME { type integer; default 84000; }
@args.BTIME { type integer; default 840000; }
type dmix;
ipc_key $KEY;
slave { @func concat
strings [ "dmix_slave:4," $PCM "," $RATE ","
$PSIZE "," $BSIZE "," $PTIME "," $BTIME ] };
bindings.0 0;
bindings.1 1;
bindings.2 2;
bindings.3 3;
}
pcm.dmix-51
{
@args [ KEY PCM RATE PSIZE BSIZE PTIME BTIME ]
@args.KEY { type integer; }
@args.PCM { type string; }
@args.RATE { type integer; default 48000; }
@args.PSIZE { type integer; default 4096; }
@args.BSIZE { type integer; default 40960; }
@args.PTIME { type integer; default 84000; }
@args.BTIME { type integer; default 840000; }
type dmix;
ipc_key $KEY;
slave { @func concat
strings [ "dmix_slave:6," $PCM "," $RATE ","
$PSIZE "," $BSIZE "," $PTIME "," $BTIME ] };
bindings.0 0;
bindings.1 1;
bindings.2 2;
bindings.3 3;
bindings.4 4;
bindings.5 5;
}
# 4/6 CHANNEL AS STEREO
# #####################
# Distribute 2 channel stereo to 4 or 5.1 surround channels
# 'surround40' and 'surround51' should be predefined.
# http://ALSA.OpenSrc.org/index.php?page=FAQ028
# http://ALSA.OpenSrc.org/index.php?page=SurroundSound
# 'table.X.Y Z' means add channel 'X' multiplied by 'Z' to 'Y'.
# Does not support sharing, stack 'dmix' for that.
# Note that all (some?) USB sound device config do not define the
# 'surroundXY' style name, so substitute the equivalent 'hw' name.
pcm.stereo-40
{
@args [ PCM ]
@args.PCM { type string; }
type route;
slave.pcm $PCM;
slave.channels 4;
ttable.0.0 1.0;
ttable.0.2 0.6;
ttable.1.1 1.0;
ttable.1.3 0.6;
}
pcm.stereo-51
{
@args [ PCM ]
@args.PCM { type string; }
type route;
slave.pcm $PCM;
slave.channels 6;
ttable.0.0 1.0;
ttable.0.2 0.6;
ttable.0.4 0.3;
ttable.0.5 0.3;
ttable.1.1 1.0;
ttable.1.3 0.6;
ttable.1.4 0.3;
ttable.1.5 0.3;
}
# 4 CHANNEL AS 2 STEREO
# #####################
# Using one four channel card as two stereo cards.
# http://ALSA.OpenSrc.org/index.php?page=.asoundrc
# Note that all (some?) USB sound device config do not define the
# 'surroundXY' style name, so substitute the equivalent 'hw' name.
pcm.card-f
{
@args [ PCM ]
@args.PCM { type string; }
type route;
slave.pcm $PCM;
slave.channels 2;
ttable.0.0 1.0;
ttable.1.1 1.0;
}
# Note that all (some?) USB sound device config do not define the
# 'surroundXY' style name, so substitute the equivalent 'hw' name.
pcm.card-r
{
@args [ PCM ]
@args.PCM { type string; }
type route;
slave.pcm $PCM;
slave.channels 4;
ttable.0.2 1.0;
ttable.1.3 1.0;
}
pcm.card-s
{
@args [ PCM ]
@args.PCM { type string; }
type route;
slave.pcm $PCM;
slave.channels 8;
ttable.0.6 1.0;
ttable.1.7 1.0;
}
########################################################################
# The top level shared pseudo device, with both PCM and CTL interfaces
# The ALSA default is "default", but many programs like XMMS and 'aoss'
# assume "dsp0" as default name for PCM and "mixer0" for CTL.
# Amazingly, XMMS has problems if one defines 'pcm.dsp0' to be
# 'plug' for 'pcm.asym0' and not directly as 'asym'.
ctl.!default = ctl.dsp0;
pcm.!default = pcm.dsp0;
########################################################################
# The two detailed card configurations are for generic 2 to 5.1 channel
# chipsets. It is assumed that both cards need software sharing, and can
# only natively handle 48000Hz.
# These assumptions are fairly typical of recent (2004) low end and
# on-motherboard cards and chipsets, and their configs are not really
# specific to either models.
########################################################################
# CARD 0 DEVICES
# ##############
ctl.card0 { type hw; card 0; }
pcm.card0 { type hw; card 0; }
ctl.mixer0 = ctl.card0;
ctl.dsp0 = ctl.card0;
pcm.dsp0 { type copy; slave.pcm "dsp:dsnoop0,dmix0"; }
pcm.dsnoop0 { type copy; slave.pcm "rec:23760,card0"; }
ctl.dmix0 = ctl.card0;
pcm.dmix0 { type copy; slave.pcm "dmix-20:13760,card0,48000"; }
ctl.dmix0-rev = ctl.card0;
pcm.dmix0-rev { type copy; slave.pcm "swap:dmix0"; }
ctl.stereo0-40 = ctl.card0;
pcm.stereo0-40 { type copy; slave.pcm "stereo-40:surround40:0"; }
ctl.stereo0-51 = ctl.card0;
pcm.stereo0-51 { type copy; slave.pcm "stereo-51:surround51:0"; }
ctl.digi0 = ctl.card0;
pcm.digi0 { type copy; slave.pcm "iec:hw:0,2"; }
ctl.card0-f = ctl.card0;
pcm.card0-f { type copy; slave.pcm "card-f:dsp0"; }
ctl.card0-r = ctl.card0;
pcm.card0-r { type copy; slave.pcm "card-r:surround40:0"; }
ctl.card0-s = ctl.card0;
pcm.card0-s { type copy; slave.pcm "card-s:surround71:0"; }
########################################################################
# CARD 1 DEVICES
# ##############
# For my #1 card, a CMI8738, the 'hw:1,1' device is either the
# rear channels or a multi channel device depending on a mixer
# control setting.
ctl.card1 { type hw; card 1; }
pcm.card1 { type hw; card 1; }
ctl.mixer1 = ctl.card1;
ctl.dsp1 = ctl.card1;
pcm.dsp1 { type copy; slave.pcm "dsp:dsnoop1,dmix1"; }
pcm.dsnoop1 { type copy; slave.pcm "rec:29370,card1"; }
ctl.dmix1 = ctl.card1;
pcm.dmix1 { type copy; slave.pcm "dmix-20:19370,card1,44100"; }
ctl.dmix1-rev = ctl.card1;
pcm.dmix1-rev { type copy; slave.pcm "swap:dmix1"; }
ctl.stereo1-40 = ctl.card1;
pcm.stereo1-40 { type copy; slave.pcm "stereo-40:surround40:1"; }
ctl.stereo1-51 = ctl.card1;
pcm.stereo1-51 { type copy; slave.pcm "stereo-51:surround51:1"; }
ctl.digi1 = ctl.card1;
pcm.digi1 { type copy; slave.pcm "iec:hw:1,2"; }
ctl.card1-f = ctl.card1;
pcm.card1-f { type copy; slave.pcm "card-f:dsp1"; }
ctl.card1-r = ctl.card1;
pcm.card1-r { type copy; slave.pcm "card-r:surround40:1"; }
ctl.card1-s = ctl.card1;
pcm.card1-s { type copy; slave.pcm "card-s:surround71:1"; }
########################################################################
# SW VOLUME CONTROL
# #################
#pcm.name { type softvol;
# slave STR;
# control {
# name STR;
# [card INT;]
# [iface STR;]
# [index INT;]
# [device INT;]
# [subdevice INT;]
# [count INT;]
# }
# }
########################################################################
# FILE OUTPUT
# ###########
pcm.file
{
@args [ PCM FILE ]
@args.PCM { type string; }
@args.FILE { type string; default "/tmp/alsa.raw"; }
type file;
file $FILE;
#[format "raw";]
#[perm 0600;]
slave.pcm $PCM;
}
ctl.file0 = ctl.card0;
pcm.file0 { type copy; slave.pcm "file:dsp0,/tmp/alsa0.raw"; }
ctl.file1 = ctl.card1;
pcm.file1 { type copy; slave.pcm "file:dsp1,/tmp/alsa1.raw"; }
########################################################################;
# 2 CARDS AS 1
# ############
# Using multiple cards to simulate a single card is usually a bad idea
# because they have different latencies and multichannel sound can come
# out with quite a bit of skew. Some people however have a legitimate
# need for this.
# Using two cards as one four channel card.
# http://ALSA.OpenSrc.org/index.php?page=TwoCardsAsOne
######################################
# 1st >= 2 channels, 2nd >= 2 channels
ctl.multi40-22 = ctl.card0;
pcm.multi-22
{
@args [ PCM1 PCM2 ]
@args.PCM1 { type string; }
@args.PCM2 { type string; }
type multi;
slaves.a.pcm $PCM1;
slaves.a.channels 2;
slaves.b.pcm $PCM2;
slaves.b.channels 2;
bindings.0.slave a;
bindings.0.channel 0;
bindings.1.slave a;
bindings.1.channel 1;
bindings.2.slave b;
bindings.2.channel 0;
bindings.3.slave b;
bindings.3.channel 1;
}
# Using two cards as one 5.1 channel card, the first has
# 2 channels and the second has 4 channels, and viceversa.
# http://ALSA.OpenSrc.org/index.php?page=TwoCardsAsOne
######################################
# 1st >= 2 channels, 2nd >= 4 channels
pcm.multi51-24
{
@args [ PCM1 PCM2 ]
@args.PCM1 { type string; }
@args.PCM2 { type string; }
type multi;
slaves.a.pcm $PCM1;
slaves.a.channels 2;
slaves.b.pcm $PCM2;
slaves.b.channels 4;
bindings.0.slave a;
bindings.0.channel 0;
bindings.1.slave a;
bindings.1.channel 1;
bindings.2.slave b;
bindings.2.channel 0;
bindings.3.slave b;
bindings.3.channel 1;
# Center, physically rear left, 2nd card
bindings.4.slave b;
bindings.4.channel 2;
# LFE/subwoofer, physically rear right, 2nd card
bindings.5.slave b;
bindings.5.channel 3;
}
######################################
# 1st >= 4 channels, 2nd >= 2 channels
pcm.multi51-42
{
@args [ PCM1 PCM2 ]
@args.PCM1 { type string; }
@args.PCM2 { type string; }
type multi;
# could be "dmix0"
slaves.a.pcm $PCM1;
slaves.a.channels 4;
# could be "dmix1"
slaves.b.pcm $PCM2;
slaves.b.channels 2;
bindings.0.slave a;
bindings.0.channel 0;
bindings.1.slave a;
bindings.1.channel 1;
bindings.2.slave a;
bindings.2.channel 2;
bindings.3.slave a;
bindings.3.channel 3;
# Center, physically front left, 2nd card
bindings.4.slave b;
bindings.4.channel 0;
# LFE/subwoofer, physically front right, 2nd card
bindings.5.slave b;
bindings.5.channel 1;
}