Mixing System Audio Into The Microphone Output With ALSA So It Can Be Easily Recorded

In this video I am showing how to set up ALSA, so that you can mix the system sounds into the microphone output, which then allows you to then record all of the sounds that are being produced on a GNU/Linux based computer. I am not running this on a specific distribution, so it should work for anyone who is running ALSA directly to the kernel, rather than via pulseaudio. The best thing about this setup is how lightweight it is, which helps to keep the latency low and it does not need you to run a sound server, which helps to keep the dependancies low. Obviously this sort of thing can be done in Pulseaudio, but it obviously contains a lot of unnecessary code that does not help it's performance, so it is not the lightest solution ot this problem. There is also the Jack Audio Connection Kit that can be used to do something like this, but even though it is a lightweight solution, it does suffer from being complicated to setup, because you have to use the command line or a gui application to configure it.
I have to admit that ALSA is also not that easy to configure, but the thing that I like about it is that you can put everything into one configuration file, which makes it easy to see what is going one, even though it can sometimes look like a mess.

pcm.card0 {
  type hw
  card 0
# mmap_emulation true
}

pcm.card2 {
  type hw
  card 2
# mmap_emulation true
}

#pcm.dmix0 {
#  type dmix
#  ipc_key 34521
#  slave {
#    pcm "card0"
#  }
#}

pcm.dmix0 {
        type dmix
        ipc_key 1024 ## needs to be a power of 2
ipc_perm 0666
        slave {
                pcm "hw:0"
# pcm "multi"
                period_time 0
                period_size 1024
                buffer_size 8192
        channels 2 # must match bindings
              # format S16_LE
              # rate 44100 ## not necessary
        }
    bindings {
        0 0
        1 1
    }
#slowptr true
}

pcm.dmixerloop {
    type dmix
    ipc_key 2048
    ipc_perm 0666 # allow other users
    slave.pcm "hw:Loopback,0,0"
    slave {
        period_time 0
        period_size 1024
        buffer_size 4096
        channels 2 # must match bindings
    }
    bindings {
        0 0
        1 1
    }
}

pcm.dsnoop0 {
  type dsnoop
  ipc_key 2048
  ipc_perm 0666 # allow other users
  slave {
    pcm "card0"
  #  rate 48000
    period_time 0
    period_size 1024
    buffer_size 4096
    channels 2
  }
    bindings {
        0 0
        1 1
    }
}

pcm.dsnooperloop {
  type dsnoop
  ipc_key 4096
  ipc_perm 0666 # allow other users
  slave {
    pcm "hw:Loopback,1,0"
  #  rate 48000
    period_time 0
    period_size 1024
    buffer_size 4096
    channels 2
  }
    bindings {
        0 0
        1 1
    }
}

pcm.dsnoop2 {
  type dsnoop
  ipc_key 4096
  slave {
    pcm "card2"
  #  rate 48000
    period_time 0
    period_size 1024
    buffer_size 4096
    channels 2
  }
    bindings {
        0 0
        1 0
    }
}

pcm.asym0 {
  type asym
  playback.pcm "multi"
  capture.pcm "multi_snoop"
}

pcm.pasym0 {
  type plug
  slave.pcm "asym0"
}

pcm.usbaudio {
  type plug
  slave.pcm "multi_snoop2"
}

# 'dsp0' is expected by OSS emulation etc.
pcm.dsp0 {
  type                  plug
  slave.pcm            "asym0"
}

ctl.dsp0 {
    type                hw
    card                0
}

#pcm.!default {
#    type asym
#    playback.pcm "multi"
#    capture.pcm "dsnoop0"
#}

pcm.!default {
       type plug
       slave.pcm "asym0"
}
#pcm.!default {
#  type                  plug
#  slave.pcm            "asym0"
#}

ctl.!default {
    type                hw
    card                0
}

pcm.multi {
    type route;
    slave.pcm {
        type multi;
        slaves.a.pcm "dmix0";
        slaves.b.pcm "dmixerloop";
        slaves.a.channels 2;
        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;
    }

    ttable.0.0 1;
    ttable.1.1 1;
    ttable.0.2 1;
    ttable.1.3 1;
}

pcm.multi_snoop {
    type route;
    slave.pcm {
        type multi;
        slaves.a.pcm "dsnoop0";
        slaves.b.pcm "dsnooperloop";
        slaves.a.channels 2;
        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;
    }

    slave.channels 4    # the slave has 4 channels
    ttable.0.0 0.5      # master ch 0 - slave ch 0
    ttable.1.1 0.5      # master ch 1 - slave ch 1
    ttable.0.2 0.5      # master ch 0 - slave ch 2
    ttable.1.3 0.5      # master ch 1 - slave ch 3
}

pcm.multi_snoop2 {
    type route;
    slave.pcm {
        type multi;
        slaves.a.pcm "dsnoop2";
        slaves.b.pcm "dsnooperloop";
        slaves.a.channels 2;
        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;
    }

    slave.channels 4    # the slave has 4 channels
    ttable.0.0 0.5      # master ch 0 - slave ch 0
    ttable.1.1 0.5      # master ch 1 - slave ch 1
    ttable.0.2 0.5      # master ch 0 - slave ch 2
    ttable.1.3 0.5      # master ch 1 - slave ch 3
}

#pcm.!default {
# type plug
# slave.pcm "multi"
#}

pcm.loopin {
type plug
slave.pcm "hw:Loopback,0,0"
}

pcm.loopout {
type plug
slave.pcm "hw:Loopback,1,0"
}

pcm.snoopin {
type plug
slave.pcm "hw:Loopback,0,1"
}

pcm.snoopout {
type plug
slave.pcm "hw:Loopback,1,1"
}

 

Download: 
asound.conf.gz — Downloaded 255 times