ALSA recording of device output

Sat Jan 02 2016 23:54:31 GMT-0800 (Pacific Standard Time)

tags: linux audio sound alsa looprec

On more than a few occasions, I've wanted to be able to software-record the sound coming out of my computer speakers.  Many users faced with similar problems resort to using pulseaudio as their sound system, which is reasonble, because it provides a very extensible/pluggable framework for sound.  Unfortunately, my experience with pulseaudio in the past has been "meh", probably due in large part to my heavy use of Pd.  So I've stuck with ALSA through the years when doing simple stuff, resorting to jack when doing more complicated routing between applications.  Simply recording what's playing seems simple enough...right?  Not so much...

I guess some (nicer?) sound cards provide a built-in hardware recording channel that can mix back in the currently playing audio.  Most built-in ones, like the one in my aging T410, do not.  After some sleuthing, I discovered that ALSA's plugin system does, in fact, provide a way to do this.  I'll describe the process here, but it's basically ripped from this thread where kokoko3k serves up the right approach:  https://bbs.archlinux.org/viewtopic.php?id=147852

There's an ALSA kernel module called snd_aloop that "provides a pair of cross-connected devices, forming a full-duplex loopback soundcard".  With just a little fiddling, you can create a "looprec" device that has loops back the audio output into a new recordable ALSA device.  The steps, just like in the above-mentioned post, are:

  1. $ sudo modprobe snd_aloop
    (this inserts the relevant kernel module into the kernel)

  2. create/edit ~/.asoundrc and paste in the following (a bit of alsa black magic):

    pcm.!default {
      type asym
      playback.pcm "LoopAndReal"
      #capture.pcm "looprec"
      capture.pcm "hw:0,0"
    }
    
    pcm.looprec {
        type hw
        card "Loopback"
        device 1
        subdevice 0
    }
    
    pcm.LoopAndReal {
      type plug
      slave.pcm mdev
      route_policy "duplicate"
    }
    
    pcm.mdev {
      type multi
      slaves.a.pcm pcm.MixReale
      slaves.a.channels 2
      slaves.b.pcm pcm.MixLoopback
      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
    }
    
    pcm.MixReale {
      type dmix
      ipc_key 1024
      slave {
        pcm "hw:0,0"
        rate 48000
        #rate 44100
        periods 128
        period_time 0
        period_size 1024 # must be power of 2
        buffer_size 8192
      }
    }
    
    pcm.MixLoopback {
      type dmix
      ipc_key 1025
      slave {
        pcm "hw:Loopback,0,0"
        rate 48000
        #rate 44100
        periods 128
        period_time 0
        period_size 1024 # must be power of 2
        buffer_size 8192
      }
    }
    

That's it!  Your recording software should now have a device available called "looprec", and if you record from it you'll get whatever is playing on your speakers.  You can make this permanent by adding the snd_aloop module to /etc/modprobe.d/sound.conf.

Since you've made it this far, I'll share what I was trying to record:  http://websdr.ewi.utwente.nl:8901 -- which is pretty much the raddest thing ever.