The code used in this post no longer works. For an up-to-date example, please see demo_alsa.py.
Aubio is an audio analysis library which contains implementations of some useful algorithms, including pitch detection. It can be used with Python (through SWIG), but the documentation is very light and there doesn’t appear to be any Python-specific instructions.
Below is a small program that listens to the default audio input using alsaaudio, finds the pitch and energy of the signal using aubio, and prints the results to stdout. For the program to work, you will need the aubio and alsaaudio Python libraries installed, which can be done in Ubuntu/Debian with the following command:
sudo apt-get install python python-alsaaudio python-aubio
The smpl_t
data type referred to in the code can be replaced by Python’s float type, but the fvec_t
type must be populated one-by-one using the fvec_write_sample
function.
import alsaaudio, struct from aubio.task import * # constants CHANNELS = 1 INFORMAT = alsaaudio.PCM_FORMAT_FLOAT_LE RATE = 44100 FRAMESIZE = 1024 PITCHALG = aubio_pitch_yin PITCHOUT = aubio_pitchm_freq # set up audio input recorder=alsaaudio.PCM(type=alsaaudio.PCM_CAPTURE) recorder.setchannels(CHANNELS) recorder.setrate(RATE) recorder.setformat(INFORMAT) recorder.setperiodsize(FRAMESIZE) # set up pitch detect detect = new_aubio_pitchdetection(FRAMESIZE,FRAMESIZE/2,CHANNELS, RATE,PITCHALG,PITCHOUT) buf = new_fvec(FRAMESIZE,CHANNELS) # main loop runflag = 1 while runflag: # read data from audio input [length, data]=recorder.read() # convert to an array of floats floats = struct.unpack('f'*FRAMESIZE,data) # copy floats into structure for i in range(len(floats)): fvec_write_sample(buf, floats[i], 0, i) # find pitch of audio frame freq = aubio_pitchdetection(detect,buf) # find energy of audio frame energy = vec_local_energy(buf) print "{:10.4f} {:10.4f}".format(freq,energy)
Thank you so much for posting this. This is the only example on Aubio in Python I found…
Anyway I am still having problems running it. I get an error at the unpack command saying: “error: unpack requires a string argument of length 4096”. I changed from PCM_NONBLOCK to PCM_NORMAL to make sure no empty chunks are read.
Any idea?
Xwö, I too was having this same issue. I solved it by adjusting the struct.unpack command to this…
floats = struct.unpack(‘f’*length,data)
Hope this helps.
Thank You! I needed an example just like this.
Since the Raspberry Pi does not have an input device standard, I had to add the card=’…’ parameter to this line (I have a USB microphone connected):
recorder=alsaaudio.PCM(type=alsaaudio.PCM_CAPTURE, card=’Microphone’)
Thank you DJ for the struct.unpack correction. I needed that as well.
This was very helpful. I am just starting out programming on the Raspberry Pi after 20 years of not coding. This saved me no end of time in getting something working quickly. Thanks!
How could I modify the code to play an audio file and do the same analysis? If I could do that, I think I could get the rest of my project working. Any help would be GREATLY appreciated! Thanks in advance.
Probably useful to mention that you can find your audio card names using: cat /proc/asound/cards
I am having a problem with the line: “PITCHALG = aubio_pitch_yin”
it says that “aubio_pitch_yin is not defined.”
Any ideas?
Thanks for the example. Unfortunately, I’m stuck at “ImportError: No module named task”. I’ve installed aubio from their github and also installed python-aubio with no luck.
Seems that’s is a bug, and you can get some workaround changing your release version number, but i didn’t tried yet and really don’t need it just now.
Hi!
This code is obsolete now, aubio.task has been removed in the latest versions of aubio.
I have added an example based on this one to illustrate how to use alsaaudio with the latest version of aubio:
https://github.com/aubio/aubio/blob/master/python/demos/demo_alsa.py
let us know how it works for you!
cheers, piem
Hi piem,
Thanks for this update! I–like Joe–was puzzled regarding the missing aubio.task module.
When I run your code I get the following error:
File “demo_alsa.py”, line 39, in
freq = pitcher(samples)[0]
ValueError: input size of pitch should be 1024, not 940
Any thoughts on what’s going on?
Thanks for your contribution!
Hi Haig,
Not sure what’s going on here. Could you please open a bug report about it?
https://github.com/aubio/aubio/issues/new
Also, check out my comment below about the pyaudio version.
Best, piem
Hi!
This code is obsolete now, aubio.task has been removed in the latest versions of aubio.
I have added an example program based on this one to illustrate how to use alsaaudio with the latest version of aubio:
https://github.com/aubio/aubio/blob/master/python/demos/demo_alsa.py
Let us know how it works for you!
cheers, piem
Hi,
I just added another demo that uses pyaudio to do a something similar. This should work not only on linux, but also on windows and (untested) osx, since pyaudio is based on portaudio.
https://github.com/aubio/aubio/blob/master/python/demos/demo_pyaudio.py
Best, piem