How To Record What You Hear With Linux Alsa

On linux one does not require a 'play what you hear' driver to record what programs are playing. The Advanced Linux Sound Architecture system does this for you.

You must only ever record things for which you have copy-right permission. 

Do not use this technique to record from streaming services (like Spotify)

Do not use this technique to record sound from Flash videos (like those on youtube)

You have been warned!

Now, I do not use Pulse audio nor Jackd or any of those things. Why? Because Alsa does the job very well indeed and does not get in my way. IM(not so)MO everything beyond Alsa has been development for development's sake except for very speciallist applications. If the effort into all these other things had been put into good tooling for Alsa the Linux sound world would be a much better place.

The trick to getting the record to work is (on Fedora 15 at least) to use a file plugin. To do this, place a file plugin definition in your .asound.rc file in your home directory.

pcm.writeFile {
    type file
    slave {
        pcm builtin 
    }
    file "/home/ajt/Desktop/record.wav"
    format "wav"
}

Above is the one from my .asound.rc file. It is very simple, it acts just like the 'tee' command in the shell. It makes a forwards the digital sound stream to its slave and at the same time makes a recording of that sound in wav format. The file name is set using the 'file' attribute. It is essential to make a copy of this file directly after making a recording or the very next application which makes a sound will overwrite your recording! [ See 'Not Good Enough' below].

My .asound.rc file has a number of cards defined. I name them (rather than calling them card1 card0 etc). So 'pcm builtin' is the definition pcm.builtin which connects to the builtin sound card in my Samsung SF310 (very good sound by the way - sounds perfect even on Sony MDR-7506 monitors which hide nothing). 

pcm.roland {
    type hw
    channels 2
    card 1
    device 0
    subdevice 0
    format S24_3LE
}

pcm.builtin {
    type hw
    channels 2
    card 0
    device 0
    subdevice 0
}

pcm.hdmiCard {
    type hw
    channels 2
    card 0
    device 3
    subdevice 0
}

pcm.!default {
       type plug
       slave {
              #pcm builtin 
              pcm writeFile
              #pcm hdmiCard 
              #pcm roland 
              #format S24_3LE
       }
}

pcm.writeFile {
    type file
    slave {
        pcm builtin 
    }
    file "/home/ajt/Desktop/record.wav"
    format "wav"
}

NOT GOOD ENOUGH!

OK, that does kind'a work, but it is a pain to keep copying files. Also, some applications restart their connection to alsa between tracks and so it is near impossible to record more than one track this way without manually playing each one and then copying the file.

There is a better way. Linux supports named pipes on the file system:

mknod /home/ajt/Desktop/record1.wav p

The above run from the shell will make the target of the file alsa plugin become a special 'fifo' file. This has no storage its self, but allows us to connect other things to it. In this case, we can connect the command 'cat' to it with the following bash script:

#!/bin/bash

for (( i=1 ; i<1024 ; i++ ))
    do
    echo "Recording /home/ajt/Music/${1}_${i}.wav"             
    cat < ~/Desktop/record.wav > "/home/ajt/Music/${1}_${i}.wav"
done


Save the above script to record.sh

Now you can, from the shell, do something like...

record.sh last-nights-singing

... and a bunch of wav files will turn up in your Music directory.

Finally, I would suggest, if you are using the scripted method, to put the fifo somewhere else than on the desktop. I left it there in this example just to avoid confusion.