The Big Picture
Using a cheap microphone and an Arduino that I had lying around, I realized I should be able to detect loud noises and send the mute key to my computer automatically via Arduino's keyboard emulation capabilities.
Signal Processing FTW
In my past life, I was a Control Systems Engineer, where I learned signal processing techniques before Data Science was cool. Most microphones send an analog signal which must be sampled at a given rate and then processed to extract the features necessary to make control decisions. Luckily for us, we simply want to extract the peak-to-peak amplitude over a given time period, which represents the intensity of the audio signal.
const int sampleWindow = 50; // Sample window width in mS (50 mS = 20Hz)
unsigned long startMillis= millis(); // Start of sample window
unsigned int peakToPeak = 0; // peak-to-peak level
unsigned int signalMax = 0;
unsigned int signalMin = 1024;
// collect data for 50 mS
while (millis() - startMillis < sampleWindow)
sample = analogRead(0);
if (sample < 1024) // toss out spurious readings
if (sample > signalMax)
signalMax = sample; // save just the max levels
else if (sample < signalMin)
signalMin = sample; // save just the min levels
peakToPeak = signalMax - signalMin; // max - min = peak-peak amplitude
The code sample above shows how simple it is to calculate the peak-to-peak amplitude from an analog signal. Of course, when sampling, we always have to be aware of missing peaks due to aliasing — but in practice, with these audio signals, it doesn't seem to be an issue.
For the current implementation of AutoShusher, I simply send the mute key every time the peak-to-peak amplitude exceeds a hard-coded threshold. It seems to work fairly well in practice, but I’m definitely interested in improving it over time.
Wrapping Things Up
The projects that live outside my server closet require a high "wife acceptance factor." I've learned (the hard way) that this means two things: it has to work well, and it can't look like an elementary school arts and crafts project. So I took the time to design a decent-looking case in Fusion360 and print it on my 3D printer.
Getting Your Hands on One
Head on over to the github repo for more detailed instructions, including the CAD files. This was designed in order to be flexible and easy for new makers to build, so I left it as a basic Arduino script. If you want to learn more about how I might build this as a production-ready product, check out our Guide to IoT Development Frameworks & Best Practices.
If you use it and think it sucks, that's okay — feel free to submit a PR. I spent longer writing this post than I did making the AutoShusher ¯_(ツ)_/¯, and it won't be long until I've saved more time holding down my mute button than I've spent working on the project. (That’s some pretty sweet ROI.)