Showing posts with label alsa. Show all posts
Showing posts with label alsa. Show all posts

Sunday, February 12, 2012

Alsa: multiple output, multiple sound cards, multiple users

I had some difficulties setting up alsa as I wanted, because I encountered some troubles:
  • when more than one application was playing sound, the first one played nicely but the others wasn't playing at all, complaining about a "busy resource"
  • solved this one, I had to setup the whole thing to work with two sound cards at the same time
  • eventually, I wanted to enable concurrent sound for multiple users
Alsa Wiki's guides were useful only for a few things, but none of them gave me the whole solution. So after a deep digging, I ended up with this config:
pcm.USBmic {
    type hw
    card CNF8215
}

ctl.USBmic {
    type hw
    card CNF8215
}

pcm.internal {
    type hw
    card SB
}

ctl.internal {
    type hw
    card SB
}

pcm.wireless {
    type hw
    card Transceiver
}

ctl.wireless {
    type hw
    card Transceiver
}

pcm.internalDmixed {
   type dmix
   ipc_key 1024
   ipc_key_add_uid false
   ipc_perm 0666
   slave {
       pcm "internal"
       period_time 0
       period_size 2048
       channels 4
    }
    bindings {
       0 0
       1 1
       2 2
       3 3
    }
}

pcm.wirelessDmixed {
   type dmix
   ipc_key 2048
   ipc_key_add_uid false
   ipc_perm 0666
   slave {
       pcm "wireless"
       period_time 0
       period_size 2048
       channels 2
    }
    bindings {
       0 0
       1 1
    }
}

pcm.both {
    type route;
    slave.pcm {
        type multi;
        slaves.a.pcm "wirelessDmixed";
        slaves.b.pcm "internalDmixed";
        slaves.a.channels 2;
        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;
        bindings.4.slave b;
        bindings.4.channel 2;
        bindings.5.slave b;
        bindings.5.channel 3;
    }
  
    ttable.0.0 1;
    ttable.1.1 1;
  
    ttable.0.2 1;
    ttable.1.3 1;
    ttable.2.4 1;
    ttable.3.5 1;
}

pcm.!default {
        type plug
        slave {
                pcm both
        }
}

ctl.!default {
        type hw
        card SB
}

How does this strange thing work? Let's look at it step by step: