Saturday, July 27, 2013

Command-line Sound Recording

Chances are if you're running the common varieties of Linux or Windows or MacOS you've got a GUI tool already for recording from either your sound card or an internal/external microphone or whatever.  Turns out I don't since a while back I gave up on my former infatuation with Ubuntu and Xubuntu.  Switching to Crunchbang is a decision I would make again in a heartbeat, but it does mean that I'm back to the days of searching for tools and deciding between options rather than finding them all pre-installed.

This is, for what it's worth, a good thing in my mind.

So my situation is a little complex.  The summary is I wanted to record a phone call and turn it into a sound file that's in some way useful to me.  That is, some raw audio format or high quality MP3 or something.  Should be easy enough, right?  Time was I'd just use Google Voice to record my call, or Google Talk, but the former has become much more difficult to use in Canada these days and the latter no longer appears to support recording of outgoing calls.  I searched, trust me.  I suspect that's a workaround for problems they had with enabling recording and having someone try to dial in to conference bridges or use automated menu systems or such.  I don't miss the loss of that feature at all, by the way, except in this one scenario.

Okay, so I can't use Google Voice or Google Talk.  Next obvious option is hunt through the Google Play store and find something to record calls there, then make the call on my phone.  I won't link to the various apps I tried, I'm sure most of them are quite good and have probably earned their 4+ star ratings.  I tried six different ones before I gave up on that angle.  Not a single one successfully recorded any audio on my phone.  Well, two of them might have, but they only produced 3gpp files and I wasn't able to find anything that played back 3gpp files for me on my laptop.  Or if I did, those files were full of silence as well, it's kind of tough to tell.

So back to the desktop, then.  There are a lot of audio recorder programs in Linux.  The best of them, though, either seem to depend on Gnome or KDE and there is no way I wanted to drag in all of that onto my nice, relatively clean platform just to record a single phone call.  That's ridiculous.

Back to searching, then.

Now anyone who talks to me for any length of time about operating systems knows I absolutely hate two things about Linux.  All of them suck without qualification of any kind.  Printers.  Printing in Linux is a disaster and it shows little sign of improving over where it was in the late 1990s when I started in with Linux.  And sound.  When it works well, it's okay.  Often, though, it barely works or produces inconsistent results.  That infuriates me.  Almost enough to make me learn something about sound architectures in Linux and try to fix one of them enough to be usable.  The barrier, there, is the distributed nature of sound in Linux.  It's not like "sound" is even a thing.  There's kernel support for at least two architectures, and there's userspace tools that interact with some set of those architectures.

Of those tools, the one that I have the most distaste for -- though probably because it is the one I encounter the most, not because it's any worse than any other -- is Pulse.  Pulseaudio is gawdawful.  The only redeeming quality it has, if I can feel that it has any, is it is installed by default on my last three chosen distributions and oftentimes it successfully manages to produce sounds from my speakers.  Frequently it is even the sounds I want it to produce (though if I ever sort out the agony it is currently causing me when playing music from Chrome, I'll have another post about that little slice of hell...).

But today it actually turns out to be a good thing for me.  Some refinements on my search criteria turned up pacat.  I've never heard of this thing before, but within a minute of finding the manpage I was done, I had exactly what I needed.

Since I wanted to capture audio that was playing through my speakers, I was looking for monitor on an alsa output device (I knew ahead that I was using Alsa, if you don't know if you're using Alsa or OSS or something else, you'll need to google that too, I suppose), so I did this:

% pactl list | grep Monitor\ Source
Monitor Source: alsa_output.pci-0000_00_1b.0.analog-stereo.monitor

And searched for monitors.  In my case, there happened to be only one.  That helps.  So then I make my phone call and start up pacat with flac as the file format, because why not?  The call is short and I wanted good quality:

% pacat --verbose --device=alsa_output.pci-0000_00_1b.0.analog-stereo.monitor\
--record --file-format=flac phone.flac
Opening a recording stream with sample specification 's16le 2ch 44100Hz' and channel map 'front-left,front-right'.
Connection established.
Stream successfully created.
Buffer metrics: maxlength=4194304, fragsize=352800
Using sample spec 's16le 2ch 44100Hz', channel map 'front-left,front-right'.
Connected to device alsa_output.pci-0000_00_1b.0.analog-stereo.monitor (0, not suspended).
Got signal, exiting
%

And there you are.  phone.flac is a capture of what was playing on the speakers from the time I started until the time I ^C'd it.

Definitely want to remember this one.  By far the easiest way to record audio in Linux I've ever encountered.  So, y'know, score one for pulseaudio.

No comments: