Delta 1010 synchronization under Linux

Linux can handle multiple sound cards, but unless the two have their clocks synchronized, it's possible that tracks recorded or played back on ports across the breakout boxes can drift apart.

Adding the second card was easy enough, but when I started Linux, while I saw both cards, I no longer saw the MIDI control surface that was plugged into a USB port. The following lines appeared in my /var/log/messages file:

Feb 27 21:54:35 xtc kernel: ALSA sound/core/init.c:137: cannot find the slot for index 1 (range 0-7), error: -16 Feb 27 21:54:35 xtc kernel: ALSA sound/usb/usbaudio.c:3402: cannot create card instance 0 Feb 27 21:54:35 xtc kernel: snd-usb-audio: probe of 1-2.3:1.1 failed with error -5 Feb 27 21:55:00 xtc gconfd (jh-3127): starting (version 2.18.0.1), pid 3127 user 'jh'

The problem here is that my /etc/modprobe.conf file assigned an index value to each of the cards as well as the USB device. Here's the old file:

alias eth0 skge
alias scsi_hostadapter ata_piix
alias scsi_hostadapter1 usb-storage
options snd cards_limit=8
alias snd-card-0 snd-ice1712
options snd-ice1712 index=0
alias snd-card-1 snd-usb-audio
options snd-usb-audio index=1

Adding an extra pair of lines to define the second 1010 was required:

alias eth0 skge
alias scsi_hostadapter ata_piix
alias scsi_hostadapter1 usb-storage
options snd cards_limit=8
alias snd-card-0 snd-ice1712
options snd-ice1712 index=0
alias snd-card-1 snd-ice1712
options snd-ice1712 index=1
alias snd-card-2 snd-usb-audio
options snd-usb-audio index=2

Once modprobe.conf was modified, I had to do a "rmmod snd-usb-audio" followed by a "modprobe snd-usb-audio" and then the control surface showed up in QJackCtl.

Next step was to modify my ~/.asoundrc file to combine the cards into a single device.

# .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.

########### Old .asoundrc config
#pcm.ice1712 {
# type hw
# card 0
#}
#
#ctl.ice1712 {
# type hw
# card 0
#}
############

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
}

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
}

ctl.multi_playback {
type hw
card 0
}

Because the ice1712 chip has 12 capture channels but only 10 playback channels, they have to be defined separately in .asoundrc. That means we have to select the input and output devices separately in QJackCtl.

qjackctl setup

Next is to make one card time master, and slave the other to it via S/PDIF

The Basics (from the M-Audio website):

When linking Delta cards, one card sends the master clock signal. The rest of the cards that are synced must receive signal from the card sending the signal. The S/PDIF connections on the sound cards are color coded for in and out. On the Delta series sound cards, the out is white and the in is red. SPDIF cables can be obtained from any Music Industry store or Home Stereo store.

Note that the S/PDIF connections on the Delta Audiophile 192 are both orange, but are labeled accordingly (I=in, O=out).

Note about SPDIF cables, these cables are not the same type of cabling used for analog audio, the internal resistance of the cable is different than for analog audio. Although analog RCA may appear to work, it is not reliable. Examples of SPDIF cables can be found at www.hosatech.com

1. Connect the 75-Ohm cable from the out S/PDIF connection of the card sending master clock to the in connection of the receiving card. Each additional card must be hooked in a daisy chain type of configuration.

If a Delta Audiophile 192 card is part of your setup, make sure to use this card as the last device in the synchronization chain.

2. Open the M Audio Delta Control Panel. (In Linux, this is the envy24control program). The installed sound cards will appear down the right hand side of the panel. Select the card sending master clock.

Note: On some systems, you may not see more than one card. In this case you'll have to start envy24control from a terminal and give it the arguments "-c 1" to bring up a control panel for the second card.

3. On the Hardware settings tab of the master card select "Internal Xtal" for the "Master Clock setting". In the "MultiTrack Driver Devices", please select "Single and In-Sync".

4. On the Hardware settings tab of all other synced cards, select "S/PDIF in" for the "Master Clock setting". In the "MultiTrack Driver Devices", please select "Single and In-Sync".

At this point, when I start jack, it now spits out a lot of xruns. Or does it?? This page http://www.jrigg.co.uk/linuxaudio/ice1712multi.html indicates that there really aren't a lot of xruns and that it's the QJackCtl client misreporting. If I start jackd with the same command line that's saved by QJackCtl in .jackdrc, I don't see a single xrun.

I tested the setup by recording an electronic metronome. I plugged it into my mixer and put the left channel out to the first card and the right into the second. I recorded for an hour. There was no drift at the end of the tracks. I then played back for over a half hour. There was no drift between the channels. Jack never reported an xrun. I'm very happy with this setup. Now if I only had enough preamps for all the input channels!