Multiple Sound Cards (ICE1712/Delta 1010)
ICE1712 based sound cards like the M-Audio Delta 1010 are a popular choice for
Linux sound recording. However, setting up several of them so that ALSA and
jackd will play nicely is a little tricky.
This tutorial assumes a certain level of familiarity
with Linux audio configuration. As I said, using multiple sound cards with
Linux and ALSA is tricky, so much so that it is officially `not recommended'
by the JACK and Ardour developers. Please read the whole page before
you try any of it. It's amazing how many people contact me or the Linux audio
mailing lists with a problem caused by not reading an important part of this
page.
ALSA .asoundrc
The ALSA pcm_multi plugin is used to merge several cards into one large virtual
card. This allows programs like jackd, which can only handle one card at a
time, to deal with them. This isn't completely straightforward with the ICE1712
chip, as it has 12 inputs and 10 outputs (regardless of how many hardware
inputs/outputs your card has). This means that separate devices need to be
defined in the
.asoundrc file for capture and playback. Here's an example
.asoundrc for two Delta 1010s used for 16 channels of input and output:
# .asoundrc for two Delta 1010s
#
# Create virtual devices out of multiple soundcards.
# JACK will need MMAP_COMPLEX support to use this.
# ICE1712 chip has 12 capture channels and 10 playback channels.
# No. of channels in slaves must equal 12 for capture and 10 for playback
# otherwise "invalid argument" errors result.
pcm.multi_capture {
type multi
slaves.a.pcm hw:0
slaves.a.channels 12
slaves.b.pcm hw:1
slaves.b.channels 12
# First 8 channels of first soundcard (capture)
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
bindings.4.slave a
bindings.4.channel 4
bindings.5.slave a
bindings.5.channel 5
bindings.6.slave a
bindings.6.channel 6
bindings.7.slave a
bindings.7.channel 7
# First 8 channels of second soundcard (capture)
bindings.8.slave b
bindings.8.channel 0
bindings.9.slave b
bindings.9.channel 1
bindings.10.slave b
bindings.10.channel 2
bindings.11.slave b
bindings.11.channel 3
bindings.12.slave b
bindings.12.channel 4
bindings.13.slave b
bindings.13.channel 5
bindings.14.slave b
bindings.14.channel 6
bindings.15.slave b
bindings.15.channel 7
# S/PDIF section. Uncomment bindings if required.
# S/PDIF first soundcard (capture)
#bindings.16.slave a
#bindings.16.channel 8
#bindings.17.slave a
#bindings.17.channel 9
# S/PDIF second soundcard (capture)
#bindings.18.slave b
#bindings.18.channel 8
#bindings.19.slave b
#bindings.19.channel 9
}
ctl.multi_capture {
type hw
card 0
}
pcm.multi_playback {
type multi
slaves.a.pcm hw:0
slaves.a.channels 10
slaves.b.pcm hw:1
slaves.b.channels 10
# First 8 channels of first soundcard (playback)
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
bindings.4.slave a
bindings.4.channel 4
bindings.5.slave a
bindings.5.channel 5
bindings.6.slave a
bindings.6.channel 6
bindings.7.slave a
bindings.7.channel 7
# First 8 channels of second soundcard (playback)
bindings.8.slave b
bindings.8.channel 0
bindings.9.slave b
bindings.9.channel 1
bindings.10.slave b
bindings.10.channel 2
bindings.11.slave b
bindings.11.channel 3
bindings.12.slave b
bindings.12.channel 4
bindings.13.slave b
bindings.13.channel 5
bindings.14.slave b
bindings.14.channel 6
bindings.15.slave b
bindings.15.channel 7
# S/PDIF section. Uncomment bindings if required.
# S/PDIF first soundcard (playback)
#bindings.16.slave a
#bindings.16.channel 8
#bindings.17.slave a
#bindings.17.channel 9
# S/PDIF second soundcard (playback)
#bindings.18.slave b
#bindings.18.channel 8
#bindings.19.slave b
#bindings.19.channel 9
}
ctl.multi_playback {
type hw
card 0
}
Here's another example .asoundrc for three Delta
1010's. It allows either the first two cards or all three to be run
depending on the device names used when starting JACK.
The above .asoundrc's require MMAP_COMPLEX support in JACK (any version later
than 0.102.20 has this). It is possible
to use the ALSA route plugin to interleave the blocks of channels so
MMAP_COMPLEX isn't needed, but the extra overhead of the route plugin will
increase latency (in fact it completely screws up low latency operation).
If this doesn't bother you, there's an example .asoundrc
here.
JACK
This tutorial assumes the use of JACK 1, version 0.116.1 or later. JACK 0.109.x
is not recommended due to a bug that disconnects client programs at
random. If you're compiling JACK from source, do yourself a favour and
configure it with --prefix=/usr. The default value is
--prefix=/usr/local, which
may result in client programs like Ardour being unable to find libjack, so only
use that if you know what you're doing.
jackd can be started using the following command-line syntax:
$ jackd -d alsa -C multi_capture -P multi_playback
or with realtime privileges:
$ jackd -R -d alsa -C multi_capture -P multi_playback
Obviously you'd add extra options as necessary. If you prefer to use qjackctl to
start jackd, you will still have to configure it to give the correct
command line.
You'll notice that I haven't mentioned JACK 2. This is because I haven't had
time to try it recently. Some earlier versions I tried worked, but if anyone
has used the current version successfully with pcm_multi I'd be interested to
hear about it so I can update this page.
Problems with pcm_multi
Users may have problems using the -rt kernel with pcm_multi. The versions of -rt
that I've tried in the past gave lots of xruns when using
pcm_multi (that's on AMD64 SMP - on UP it locked up completely). It works fine
with a single sound card. Recent linux kernels do work well with
preemption enabled (CONFIG_PREEMPT=y) and no -rt patch however.
Update - There have been reports that -rt kernels work with jackd and
pcm_multi on AMD64x2 dual core systems, but so far I have been unable to
confirm this on my own hardware.
Word Clock Sync
To run multiple cards the word clocks need to be synchronized. With two
Delta 1010 cards this can be done by connecting the word clock output on the
first breakout box to the word clock input on the second box.
Alternatively, they can be linked via S/PDIF (connect the S/PDIF output on the
first card to the S/PDIF input on the second card).
Then use envy24control
from the alsa-tools package to set up the first card to use its internal clock
and the other card(s) to use the word clock input or S/PDIF. Cards without word
clock in/out can be synchronized via the SPDIF in/out.
If you have more than two
cards you can either daisy chain them by linking the third card to the second
etc., or make a multi-way splitter cable for the first card's S/PDIF output.
I've successfully used a three way S/PDIF splitter to link three cards to the
first one (more than that might not work due to the extra load attenuating
the signal too far).
Problems with Delta 1010 Word Clock Sync
The English edition of the Delta 1010 manual gives the maximum word clock input
frequency as 50kHz. This looks like it could be a typo but unfortunately it
isn't. The phase locked loop (PLL) that is used to lock onto the word clock
input signal can't go to a high enough frequency to lock to 96kHz.
You might be lucky and find that your particular cards work beyond
specification, but it isn't something you should rely on.
The S/PDIF receiver on the other hand uses its own internal PLL which works
with 96kHz sample rate.
Something else to be aware of when syncing cards is that the word clock input
uses a 74HC4046 PLL chip, which is quite an efficient jitter generator. In
other words, you could use the best external word clock available and still get
jittery clocking. The S/PDIF input isn't perfect either, but it's better. The
unit that is using its internal clock will sound better than the slave
units, so use those channels for the most critical sounds.
If you really want to minimise jitter, it's worth replacing
the 3m long host cables with shorter ones to reduce the distance between
the clocks on the PCI cards and the converters in the rack box. It's possible
to use 1m IEEE 1284 25-pin male-male printer cables with a gender changer
at the rack box end. Don't confuse these with 25 pin RS232 cables which will
not work.
The improvement in sound is subtle but quite noticeable (if you don't
have low resolution speakers and/or low resolution ears!).
Here's a more extreme solution to clocking
problems.
Problems with envy24control
If something in envy24control doesn't work, make sure the version of alsa
in your kernel matches your version of alsa-tools/envy24control. If they do
match and the problem still occurs, it's a bug and should be reported on the
alsa-devel mailing list.
Some users get confused about
envy24control's behaviour when jackd is running. In the version of
envy24control (0.6.0) in alsa-tools-1.0.12
to 1.0.16, the sample rate buttons in the `Master Clock' section do not
necessarily indicate the correct sample rate when jackd is running,
but the `Actual Rate' window is correct. The sample rate buttons are disabled
when jackd is running, but `S/PDIF in' and `Word Clock' buttons work.
If you select one of the latter two while jackd is running,
you will not be able to go back to internal clock without stopping jackd.
The obvious solution is not to mess with clock sources or sample rates while
jackd is running.
Alternative to envy24control
All of the parameters set by envy24control can be set on the command line
using alsactl. This command uses a configuration file
(/etc/asound.state by default) to load the parameters. There's an example
asound.state file here for two Delta
1010s running at 44.1kHz default frequency and using S/PDIF to sync the clocks,
first card master, second card slave.
To use it run this command:
alsactl -f asound.state.delta1010x2 restore
This will load the parameters from the file. To change anything edit the file
and rerun the command. If you set up your cards with envy24control initially,
the settings can be stored:
alsactl -f asound.state.delta1010x2 store
This overwrites the file if it already exists, so make a copy first if you
want to save the original.
JACK reports xruns
JACK clients like Jamin are likely to indicate xruns when using pcm_multi. At
first I was concerned about this, but it doesn't appear to cause any audible
effects. I've never noticed any clicks, and haven't been able to
find any discontinuities when inspecting sample values in recorded files.
Note that this does not apply to xruns reported by the ALSA driver, which are
real and will be audible. I run Ardour with xrun markers disabled in the
`Misc Options' menu when using pcm_multi to avoid the annoyance of seeing
hundreds of xrun markers when nothing is wrong with the sound. If this causes
you serious concern, the only way to avoid it is to use a single interface card.