Writing

Feed Software, technology, sysadmin war stories, and more.

Wednesday, October 5, 2011

Audio card, GNU Radio, and evil hacks for BayMACS coverage

Let's talk evil hacks to get audio happening in a pinch.

Today, there's a nutcase running around Cupertino and Sunnyvale with an assault rifle. He shot some people, carjacked another, and now a joint strike force is going door-to-door looking for this guy.

I heard it by way of the Santa Clara PD system, since they were called for mutual aid. A K-9 unit was sent in, and then they sent the "bear cat". This is some kind of armored vehicle used for this kind of event. This means it's a big deal.

Pro-2006 on 482.3375 MHz

Then, around 9 this morning, they switched to "BayMACS" -- a mutual aid channel. All of the interesting traffic about them sweeping through houses looking for the bad guy vanished as they moved off the city's trunked system.

Now, I have a scanner here, so I can just turn on that frequency. However, that does nothing for people listening online. It also makes things really annoying for me, since I have to listen to both things at the same time and try to not miss anything. Also, there's no way to replay what comes in on the scanner, since it's live and it's a one-shot deal.

Here's where the evil hack comes in. I routed my scanner's audio into an audio jack on my Linux box and fired up GNU Radio. I made a really simple flow graph to handle this: an audio source at 48 kHz feeds a power squelch running with a -40 dB threshold. That then feeds a WAV file sink. That sink is pointed at a FIFO I created somewhere on my filesystem.

That sounds like overkill, but I really did not want to write my own power squelch on short notice here! So now the problem is one of chopping up this call data into smaller pieces. This is where the magic of select() comes in. I wrote something quick and dirty which opens that same FIFO for reading and feeds it to select().

select will sit there until there's some activity. Any time that happens, it just dumps that straight into a temp file. When select times out (currently at 2 seconds of inactivity), it returns 0. I catch that and stop the current call, rename it to a permanent file name, then open a new temp file and start over.

That gives me a bunch of nice split WAV files with my recordings, but now I need to get them coaxed into MP3 format and added to my calls database. Yet another evil hack comes into play: a shell script loops and looks for new WAVs. Upon spotting one, it encodes it and emits an appropriate INSERT directive for the database. That goes in with "mysql -e" since it's a dumb shell script and has no real API-ish way to do that.

The rest happens automatically by way of the existing software.

Now, the catch: since this is happening with a horrible analog audio connection instead of my usual magic hardware goodness, the audio quality is far from ideal. The way I see it, it's better than nothing.

This is just part of my Super Trunking Scanner.