Duplicating audio with ALSA

On Linux the most used sound system is the Advanced Linux Sound Architecture, ALSA for short. It’s a very configurable system, but it’s not easy to dig down far enough to get to its power.

What I wanted to do was to get the same music in the living room and the computer room. The rooms are right next to each other, and my desktop is sitting with its back towards the living room. My desktop has two audio cards, one built-in VIA-82xx and my trusty SB Audigy. All I had to do hardware-wise was to connect the VIA-82xx to the amplifier in the living room and the Audigy to the amplifier in the computer room.

But then came the tricky part - to have one application send its sound to both cards simultaneously. You can configure this on a per-user basis in ~/.asoundrc or globally for the entire system in /etc/asound.conf. It takes two steps:

  1. Create a virtual “sound card” that has four channels. Channels 0 and 1 will be sent to one sound card, and channels 2 and 3 will be sent to the other.
  2. Create a routing “sound card” that mixes its stereo input to the quad-channel virtual sound card.

Place this into ~/.asoundrc or /etc/asound.conf:

# This is the four-channel card that sends its first two channels
# to one real card, and the other two channels to the other card.
pcm.tworooms {
    type multi;
    slaves {
        a {
           # The first real card, change to "channel:CARD=CardName"
           # for your system.
            pcm "front:CARD=Audigy";
            channels 2;
        }
        b {
           # The second real card, change to "channel:CARD=CardName"
           # for your system.
            pcm "iec958:CARD=VT82xx";
            channels 2;
        }
    }

    # This configures how the four channels of this virtual
    # card are distributed amongst the real cards.
    bindings {
        0 { slave a; channel 0; }
        1 { slave a; channel 1; }
        2 { slave b; channel 0; }
        3 { slave b; channel 1; }
    }
}

# This virtual "sound card" mixes two channels up to four.
pcm.both {
    type route

    # Its four-channel output is sent to the "tworooms" device.
    slave {
        pcm "tworooms"
    }

    # This defines how the channels are mixed. Input channel 0 is
    # sent for 100% to channels 0 and 2 of device "tworooms",
    # and its channel 1 is sent for 100% to channels 1 and 3.
    ttable {
        0 { 0 1.0; 2 1.0 }
        1 { 1 1.0; 3 1.0 }
    }
}

So far so good. Now I want surround sound. Unfortunately, when I change slave “A” to surround51:CARD=Audigy and increase its channels to 6 (updating the bindings accordingly) it refuses to work. MPlayer tells me The number of output channels must be between 1 and 6. Current value is 8.

If you know how to solve this, please let me know. ALSA should support more than 6 channels, as demonstrated in the ALSA wiki.

dr. Sybren A. Stüvel
dr. Sybren A. Stüvel
Open Source software developer, photographer, drummer

Related