Perl: Back-Ticks and Sound-Controlled Lights

Now that’s a heading! What’s this? Oh, I just went through some of the contents on my external hard drive and came across this interesting little Perl script, which I made a couple of years ago as a part of my sound-controlled lights project. Wanna see it?

As I implicitly declared in my Short Success Stories #2, I once had a Raspberry Pi wired up for switching my Christmas decoration lights remotely. The RasPi had a webserver running with some simple PHP for putting the lights on and off with HTML buttons (more specifically GET-parameters, but I’ll just cover the whole setup in another post someday). So I thought I’d put my mediaserver-laptop control the lights, responding to loud noises in my apartment! It was great fun: putting the lights on with a clap of my hands… though the barky dog occasionally ruined the awesomeness… but still!

And the script?


use Term::ReadKey;
system(“wget -o /dev/null -O /dev/null > /dev/null”);
my $state = 0;

my $amp = 0;
while(!defined( $key = ReadKey(-1) )){
system(“arecord -d 1 foo.wav > /dev/null”);

my $str = `/usr/bin/sox -t .wav foo.wav -n stat 2>&1 | grep “Maximum amplitude”`;
$amp = 0;

($amp) = $str =~ /0.(.*)$/;

if($amp > 283000){
if($state == 0){
system(“wget -o /dev/null -O /dev/null > /dev/null &”);
$state = 1;
print “on\n”;

system(“wget -o /dev/null -O /dev/null > /dev/null &”);
$state = 0;
print “off\n”;


I’m not really much of a Perl coder, but I got this working, so howdy, dear Perl regexers out there!

The wget-command puts the lights on and off by making HTTP requests to the RasPi in my local network with the GET-parameters “state=on” or “state=off”. And the back-ticks? I initially passed the string containing the maximum amplitude into the regex through a file. Then I realized I can get the output of system calls right into a string variable simply by wrapping the commands inside back-ticks without using the system()-function at all! Way to go, and life’s a learning!

Anyway, it sure took a lot of tweaking and testing to determine JUST the right amplitude value for toggling the lights, as the microphone was pretty sensitive to changes in the ambience.

But eventually, the main loop does the following:

1. Records a one-second sound sample into the file foo.wav using arecord

2. Uses sox to get metadata of the sample, and grep to extract the “Maximum Amplitude” -line.

3. Extracts the decimal part of the amplitude value and stores it to $amp

4. Checks the value of $amp, and toggles the lights if it’s big enough.

And there you have it!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: