Using aubio and alsaaudio with Python

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)
Advertisement

14 thoughts on “Using aubio and alsaaudio with Python

  1. Xwö says:

    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?

  2. DJ says:

    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.

  3. Jay says:

    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.

  4. Jimbo says:

    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!

  5. Candice says:

    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.

  6. Jason says:

    Probably useful to mention that you can find your audio card names using: cat /proc/asound/cards

  7. Devin says:

    I am having a problem with the line: “PITCHALG = aubio_pitch_yin”
    it says that “aubio_pitch_yin is not defined.”

    Any ideas?

  8. joe says:

    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.

    • m3nda says:

      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.

  9. piem says:

    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

    • Haig says:

      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!

  10. piem says:

    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

  11. piem says:

    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

Leave a Reply

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

WordPress.com Logo

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

Facebook photo

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

Connecting to %s

%d bloggers like this: