2016-10-19 10 views
5

Próbuję przeczytać, w niemal w czasie rzeczywistym, głośność pochodzącą z audio z mikrofonu USB w Pythonie.Jak odczytywać głośność dźwięku w czasie rzeczywistym mikrofon w python i ffmpeg lub podobny

Mam części, ale nie mogę wymyślić, jak je złożyć.

Jeśli już mam pliku wav, mogę całkiem po prostu odczytać go za pomocą 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 

Działa to doskonale, ale chcę, aby przetwarzać dźwięk z mikrofonu w czasie rzeczywistym, nie z pliku.

Tak więc moim pomysłem było użycie czegoś takiego jak ffmpeg do PIPE wyjścia w czasie rzeczywistym do WaveReadera, ale moja wiedza na temat Bajtów jest nieco słaba.

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 

To wygląda ładnie, ale nie robi zbyt wiele. Nie powiedzie się z [NULL @ 0x7ff640016600] Nie można znaleźć odpowiedniego formatu wyjściowego dla błędu "pipe:".

Zakładam, że jest to dość prosta sprawa, ponieważ muszę tylko sprawdzić poziom głośności dźwięku.

Ktoś wie, jak to osiągnąć? FFMPEG nie jest wymogiem, ale musi działać na systemie Linux OSX &.

+0

mam używane [pyaudio] (https://people.csail.mit.edu/hubert/pyaudio/); jest dostępny na [pypi] (https://pypi.python.org/pypi/PyAudio). –

+1

Aby wyprowadzić do WAV, upuść '-acodec aac' i wstaw' -f wav' przed '-' – Mulvya

+2

Możesz użyć modułu [sounddevice] (http://python-sounddevice.readthedocs.io/). Istnieje [przykład do wykreślania sygnału mikrofonu w czasie rzeczywistym] (http://python-sounddevice.readthedocs.io/en/latest/examples.html#plot-microphone-signal-s-in-real-time), który mógłby łatwo zmienić, aby obliczyć poziom dźwięku zamiast kreślenia. – Matthias

Odpowiedz

8

Dzięki @Matthias za sugestię użycia modułu sounddevice. Dokładnie tego potrzebuję.

dla potomności, tutaj jest przykład roboczych, które drukuje poziomów dźwięku w czasie rzeczywistym do powłoki:

# Print out realtime audio volume as ascii bars 

import sounddevice as sd 

duration = 10 # seconds 

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(duration * 1000) 

enter image description here

+0

To działa ładnie, ale tylko jeśli dodasz 'import numpy jako np'. BTW, możesz użyć 'InputStream', ponieważ nie potrzebujesz' outdata'. Ale działa tak czy inaczej ... – Matthias

0

Python 3 użytkownika tutaj
miałem kilka problemów, aby tę pracę tak użyłem: https://python-sounddevice.readthedocs.io/en/0.3.3/examples.html#plot-microphone-signal-s-in-real-time
I muszę zainstalować sudo apt-get install python3-tk dla Pythona 3.6 przeglądowej Tkinter module not found on Ubuntu
Potem modyfi ed scenariusz:

#!/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) 

I tak to działa :)

Powiązane problemy