This is a recurrent complaint in any open space: “There is too much noise!” (the other one is that the climate is too cold/too hot). There are some usual culprits, but it is nice to have data to back your complaints up.
I will here show you how to generate a real-time noise level graph in 15 minutes without any material beside our laptop or desktop, not even a microphone is needed. This is a dirty hack, but it works™ and can be put in place very quickly with just a few command lines. The steps, which will be mostly cut&paste are:
- install a noise recorder tool
- set up nginx to serve the data recorded
- use a nice javascript library to display the data properly
I used soundmeter, a python tool. So first, install it:
# make sure we can install python packages apt-get install virtualenv # install required dependencies for building soundmeter apt-get install python-dev portaudio19-dev python-dev alsa-utils # install other useful tools for later display apt-get install nginx expect-dev # set up a directory for the tool mkdir $HOME/soundmeter # create virtualenv virtualenv $HOME/soundmeter # activate it source $HOME/soundmeter/bin/activate # install soundmeter pip install soundmeter
Et voilà, your recorder is setup.
But do you not need a microphone? Well, either you have a laptop with a build in microphone, either you can just plug an headphone, which is basically a microphone used the other way (produce instead of record sound).
To get data, a one-liner is enough:
soundmeter --segment 2 --log /dev/stdout 2>/dev/null | unbuffer -p perl -p -e 's/\s*(\d+)\s+(.{19})(.*)/"$2,". 20*log($1)/e' > meter.csv
The explanation is as follow:
- soundmeter: run soundmeter forever (–seconds to limit the duration)
--
segment 2: output data every 2 seconds (default 0.5 seconds, but is very spiky)--
log /dev/stdout: default data on stdout is not useful for graphing, we need to log to a file. Use /dev/stdout as file to actually log to stdout- 2>/dev/null: do not pollute output
- |: the output is not in a great format, it needs to be reformatted
- unbuffer -p: by default data is buffered, which is annoying for real-time view. This does what the name suggests
- perl -p -e: yummy, a perl regexp!
- s///e: this will be a substitution, where the replacement part is a perl expression
- \s*(\d+)\s+(.{19})(.*): record value and timestamp stripped of the milliseconds
- “$2,”: display first the timestamp with a comma for csv format
- 20*log($1): the values from soundmeter are in rms, transform them in dB via the formula 20 * log (rms)
- > meter.csv: save data in a file
In short, we do the following transformation on the fly and write it to a csv file:
2015-09-22 13:36:13,082 12 => 21.5836249,2015-09-22 13:36:13
You now have a nice csv file. How to display it? Via a nice html page with the help of a javascript library, dygraphs,of course.
Set up nginx by adding in /etc/sites-enabled/noise the following content (replace YOUR_HOME by your actual home directory, of course):
server { listen 80; root YOUR_HOME/soundmeter; }
and restart nginx:
service nginx restart
Then setup you page in $HOME/soundmeter/noise.html:
<html> <head> <script src="//cdnjs.cloudflare.com/ajax/libs/dygraph/1.1.1/dygraph-combined.js"></script> <style> #graphdiv2 { position: absolute; left: 50px; right: 10px; top: 50px; bottom: 10px; } </style> </head> <body> <div id="graphdiv2"></div> <script type="text/javascript"> g2 = new Dygraph( document.getElementById("graphdiv2"), "http://localhost/meter.csv", // path to CSV file { delimiter: ",", labels: ["Date", "Noise level"], title: ["Noise (in dB)"], showRoller: true, } ); </script> </body> </html>
You can of course replace localhost by your IP to publish this page to your colleagues.
Now just go to http://localhost/noise.html: