Building a Raspberry Pi-powered Barkometer, Part 3

Capturing sound from a microphone on a Raspberry Pi isn't simple and which microphone you use will have a huge impact on the quality

oscilli ac hum on sound leak

In the last two parts of the Barkometer, which is an IoT project to prove that my dog is not a barkoholic, I discussed the hardware and my problems with getting a clean recording. It turns out, much to my irritation, that the Sabrent USB 2.0 External 2.1 Surround Sound Adapter was the problem all along. But before I discuss the hardware problems, let me explain how to record sound on a Raspberry Pi …

The subsystem of Raspbian that deals with sound is called the Advanced Linux Sound Architecture (ALSA). ALSA is a huge, complex project with support for an incredible number of sound cards and is basically death by features. It handles everything from single channel recording (what I’m trying to do) to generating tones, white noise, and all sorts of test signals, to playback of multi-channel audio. Truly a massive engineering feat.

So, here’s my command line to record sound:

arecord -D plughw:1,0 \
        -f dat \
        -c 1 \
        -t wav \ 
        --max-file-time 60 \
        --use-strftime $HOME/bark/%Y-%m-%d-%H-%M-%S.wav

Let’s break this down:

  • arecord … this is “a command-line soundfile recorder for the ALSA soundcard driver. It supports several file formats and multiple soundcards with multiple devices.” 
  • -D plughw:1,0 … this is where it gets complicated. -D is the switch to select which pulse code modulation (PCM, a method used to digitally represent sampled analog signals) plugin to use and pluginhw is the interface that allows you to ignore the sound hardware (it automatically performs sample rate conversion). The arguments 1,0 specify that the sound source we want is  sound card 1 and the number of the device on that card. How can you determine these values? This is a complicated issue but if you plug a USB audio input device into a vanilla Raspbian setup it will be identified as 1,0 … we’ll slice and dice this in a future article.
  • -f dat … the -f switch specifies the format for recording and dat sets that format to 16 bit, little endian, 48,000 samples per second, in stereo.
  • -c 1 … sets recording to be single channel and overrides the stereo channel setting specified by the -f switch.
  • -t wav … specifies that the output is to be in WAV format
  • --max-file-time 60 … specifies that the when the output file has captured sound for 60 seconds, it should be closed and a new output file opened. Keeping this to a low value has two benefits; first, it’s easier to handle 28MB files (which is what 60 seconds of 48,000 samples per second audio generates) than some multiple of that and second, longer recording times seem to cause buffer overruns (the condition where there’s more incoming data than can be stuffed into the output buffer which causes samples to be lost).
  • --use-strftime $HOME/bark/%Y-%m-%d-%H-%M-%S.wavWhen recording, interpret %-codes in the file name parameter using the strftime facility whenever the output file is opened. In this case, the output file will be saved in the subdirectory $HOME/Bark and named something like 2016-09-07-04-42-27.wav.

With this command, a new sound file in WAV format will be recorded in the subdirectory $HOME/bark every 60 seconds. This command is launched at startup (I’ll explain how to set this up in a subsequent post) and unless interrupted, it'll run forever saving files in that subdirectory.

So, back to the audio: Having accumulated a number of test files using the above command, I tried to reduce the 60-cycle hum by post processing with Audacity, a “free, open source, cross-platform audio software for multi-track recording and editing,” but in the process of removing the hum, the overall volume and clarity suffered making the recording quality less than desirable. Eve so, if you haven’t checked out Audacity and you’re doing anything with audio you really need to take a look. Audacity is a real gem and delivers a huge range of the sophisticated features you might want for cleaning up, adding effects, and mixing audio but sadly, Audacity couldn’t turn my audio sow’s ear into a digital silk purse.

Back to the hardware: Following the publishing of Part 2, reader Michael commented:

I was having the same problem with 60/50 Hz mains hum when using a USB microphone on the Raspberry Pi. I'm posting here because I must have spent a good 10 hours tracking down the problem, so maybe this is useful to someone else.

My RPI is positioned close to a power supply for a different device, and with the mic gain set to max, arecord showed a volume level of about 40% just for the humming noise. Running the Pi on batteries didn't fix the problem, but unplugging the other power supply did, so the Pi power supply wasn't the problem. Makes sense too, because a switch-mode power supply puts out noise in the 10s or 100s of kHz, but not 60 Hz mains hum. 

The problem is actually that the mic and the wiring between the mic and the USB sound card are picking up 60 Hz hum from nearby devices and mains wiring. The pre-amp inside the sound card then amplifies that hum. Shortening the mic cable to the sound card only had a small effect, but shielding it  and the mic eliminated the hum completely.

I'm also using an unshielded USB extension, but that shouldn't be a problem because the A/D conversion happens inside the sound card. It's only what happens between the mic capsule and the sound card that's relevant. In my case I wrapped the sound card and the mic in aluminum foil (a single layer is enough), and left a hole so the mic could still pick up sound. Here's the important part: The aluminum foil needs to be connected electrically to the outside of the USB connector. In your case the female connector overmolded, so it's a bit tricky, but if you have an extension with an exposed female connector, you can simply use a small magnet or some electrical tape to press the foil against the outside of the metal connector. 

In my case the noise floor went from 40% of 60 Hz hum to 3% of static. Huge difference. The mic is now clean enough that I can record myself whispering from 8 ft away.


Genius Webcam

Interesting. Never one to stick with subpar solutions, I dug out an old Genius Webcam, plugged it in and voila! Clean audio. Either my Sorbent adapter is faulty or it’s got serious problems. Anyway, I tried both the Webcam and a Logitech USB Desktop Microphone. The sound from the Logitech mic was perhaps the best but it was also very directional with a steep fall-off either side of the mic. The Genius Webcam wasn’t so directional so that’s what I’ve stuck with.

So, I now have sound samples in files in WAV format on a Raspberry Pi in the subdirectory $HOME/bark. I need to get these files over to my Network Attached Storage for processing and that’s what we’ll discuss in the next installment.

Comments? Thoughts? Drop me a line or comment below then follow me on Twitter and Facebook.

Join the Network World communities on Facebook and LinkedIn to comment on topics that are top of mind.
Must read: 10 new UI features coming to Windows 10