Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read realtime microphone audio volume in python and ffmpeg or similar

Tags:

I'm trying to read, in near-realtime, the volume coming from the audio of a USB microphone in Python.

I have the pieces, but can't figure out how to put it together.

If I already have a .wav file, I can pretty simply read it using wavefile:

from wavefile import WaveReader  with WaveReader("/Users/rmartin/audio.wav") as r:     for data in r.read_iter(size=512):         left_channel = data[0]         volume = np.linalg.norm(left_channel)         print volume 

This works great, but I want to process the audio from the microphone in real-time, not from a file.

So my thought was to use something like ffmpeg to PIPE the real-time output into WaveReader, but my Byte knowledge is somewhat lacking.

import subprocess import numpy as np  command = ["/usr/local/bin/ffmpeg",             '-f', 'avfoundation',             '-i', ':2',             '-t', '5',             '-ar', '11025',             '-ac', '1',             '-acodec','aac', '-']  pipe = subprocess.Popen(command, stdout=subprocess.PIPE, bufsize=10**8) stdout_data = pipe.stdout.read() audio_array = np.fromstring(stdout_data, dtype="int16")  print audio_array 

That looks pretty, but it doesn't do much. It fails with a [NULL @ 0x7ff640016600] Unable to find a suitable output format for 'pipe:' error.

I assume this is a fairly simple thing to do given that I only need to check the audio for volume levels.

Anyone know how to accomplish this simply? FFMPEG isn't a requirement, but it does need to work on OSX & Linux.

like image 792
Ryan Martin Avatar asked Oct 19 '16 17:10

Ryan Martin


People also ask

How to record system sound in Python?

The python-sounddevice and pyaudio libraries provide ways to record audio with Python. python-sounddevice records to NumPy arrays and pyaudio records to bytes objects. Both of these can be stored as WAV files using the scipy and wave libraries, respectively.


2 Answers

Thanks to @Matthias for the suggestion to use the sounddevice module. It's exactly what I need.

For posterity, here is a working example that prints real-time audio levels to the shell:

# Print out realtime audio volume as ascii bars  import sounddevice as sd import numpy as np  def print_sound(indata, outdata, frames, time, status):     volume_norm = np.linalg.norm(indata)*10     print ("|" * int(volume_norm))  with sd.Stream(callback=print_sound):     sd.sleep(10000) 

enter image description here

like image 65
Ryan Martin Avatar answered Oct 17 '22 05:10

Ryan Martin


Python 3 user here
I had few problems to make that work so I used: https://python-sounddevice.readthedocs.io/en/0.3.3/examples.html#plot-microphone-signal-s-in-real-time
And I need to install sudo apt-get install python3-tk for python 3.6 look Tkinter module not found on Ubuntu
Then I modified script:

#!/usr/bin/env python3 import numpy as np import sounddevice as sd  duration = 10 #in seconds  def audio_callback(indata, frames, time, status):    volume_norm = np.linalg.norm(indata) * 10    print("|" * int(volume_norm))   stream = sd.InputStream(callback=audio_callback) with stream:    sd.sleep(duration * 1000) 

And yes it working :)

like image 41
pbaranski Avatar answered Oct 17 '22 05:10

pbaranski