What: Measuring loudness with a simple USB microphone on a raspberry pi
Why: Create devices which are activated by a certain noise level
How: Use python and some python libraries to analyse the sound stream
Requirements
The following hardware was used for this setup:
- Raspberry pi 3B
- Mini USB microphone
The following os was used on the raspberry pi:
- Raspbian Stretch with desktop, version October 2018
The following python version was used (preinstalled with the corresponding raspbian):
- Python 2.7 (PyAudio was not working for me with Python3 easily)
Setup
Besides plugging the USB microphone in the corresponding USB port (such a surprise), the following things needs to be done.
Install PortAudio
Install the dependencies:
sudo apt-get install libasound-dev |
Download the corresponding version (at the time of writing this is 190600_20161030) and uncompress it:
wget http://www.portaudio.com/archives/pa_stable_v190600_20161030.tgz tar -xvf pa_stable_v190600_20161030.tgz |
Build PortAudio from source:
cd portaudio ./configure && make sudo make install sudo ldconfig |
Install NumPy, PyAudio and SoundAnalyse
pip install numpy pip install PyAudio pip install SoundAnalyse |
Code
Below is the code I used for measuring. There are some caveats with measuring the loudness:
- There are by default some warnings when opening the stream
- When reading the bytes from the stream, there may be an overflow exception which will kill the script. This can be avoided by the parameter exception_on_overflow = False
- The parameters for pyaud.open may be different depending on the used microphone. The parameters can be determined by iterating over the devices and use: pyaud.get_device_info_by_index(i)
1 2 3 4 5 6 7 8 9 10 11 12 13 | import analyse import numpy import pyaudio pyaud = pyaudio.PyAudio() stream = pyaud.open(format = pyaudio.paInt16,channels = 1,rate=44100,input_device_index=2,input=True) while True: raws=stream.read(1024, exception_on_overflow = False) samples= numpy.fromstring(raws, dtype=numpy.int16) loudness = analyse.loudness(samples) if loudness > -15: print "Really loud" |