2010-04-15 13 views
29

Ok, quello che sto cercando di fare è un tipo di software di elaborazione audio in grado di rilevare una frequenza prevalente e se la frequenza viene riprodotta abbastanza a lungo (pochi ms) so di avere una corrispondenza positiva. so che avrei bisogno di usare FFT o qualcosa di simile ma in questo campo della matematica faccio schifo, ho fatto ricerche su internet ma non ho trovato un codice che potesse fare solo questo.Rilevazione di frequenza Python

L'obiettivo che sto provando ad accedere è quello di creare un protocollo personalizzato per inviare dati tramite audio, richiedere un bitrate per secondo molto basso (5-10bps) ma è anche molto limitato sul terminale di trasmissione in modo che il software di ricezione debba essere in grado di personalizzare (non può utilizzare un vero modem hardware/software) anch'io voglio che questo sia solo software (nessun hardware aggiuntivo eccetto la scheda audio)

grazie mille per l'aiuto.

+1

Questo può essere utile (assicurarsi di leggere le risposte): http://www.keyongtech.com/5003865-frequency-analysis-without-numpy – ChristopheD

risposta

37

Le librerie aubio sono state incapsulate con SWIG e possono quindi essere utilizzate da Python. Tra le loro molte caratteristiche vi sono diversi metodi per il rilevamento/stima del pitch, tra cui l'algoritmo YIN e alcuni algoritmi a pettine armonico.

Tuttavia, se vuoi qualcosa di più semplice, ho scritto del codice per la stima del passo qualche tempo fa e puoi prenderlo o lasciarlo. Non sarà accurato come usare gli algoritmi di aubio, ma potrebbe essere abbastanza buono per le tue esigenze. Fondamentalmente ho appena preso la FFT dei dati volte una finestra (una finestra Blackman in questo caso), ha quadrato i valori FFT, trovato il bin che aveva il valore più alto e ho usato un'interpolazione quadratica attorno al picco usando il log del valore massimo e i suoi due valori vicini per trovare la frequenza fondamentale. L'interpolazione quadratica che ho preso da un foglio che ho trovato.

Funziona abbastanza bene sui toni di prova, ma non sarà così robusto o preciso come gli altri metodi menzionati sopra. L'accuratezza può essere aumentata aumentando la dimensione del blocco (o ridotta diminuendola). La dimensione del blocco dovrebbe essere un multiplo di 2 per sfruttare appieno la FFT. Inoltre, sto solo determinando la tonalità fondamentale per ogni blocco senza sovrapposizioni. Ho usato PyAudio per riprodurre il suono mentre scrivevo la tonalità stimata. Codice

Fonte:

# Read in a WAV and find the freq's 
import pyaudio 
import wave 
import numpy as np 

chunk = 2048 

# open up a wave 
wf = wave.open('test-tones/440hz.wav', 'rb') 
swidth = wf.getsampwidth() 
RATE = wf.getframerate() 
# use a Blackman window 
window = np.blackman(chunk) 
# open stream 
p = pyaudio.PyAudio() 
stream = p.open(format = 
       p.get_format_from_width(wf.getsampwidth()), 
       channels = wf.getnchannels(), 
       rate = RATE, 
       output = True) 

# read some data 
data = wf.readframes(chunk) 
# play stream and find the frequency of each chunk 
while len(data) == chunk*swidth: 
    # write data out to the audio stream 
    stream.write(data) 
    # unpack the data and times by the hamming window 
    indata = np.array(wave.struct.unpack("%dh"%(len(data)/swidth),\ 
             data))*window 
    # Take the fft and square each value 
    fftData=abs(np.fft.rfft(indata))**2 
    # find the maximum 
    which = fftData[1:].argmax() + 1 
    # use quadratic interpolation around the max 
    if which != len(fftData)-1: 
     y0,y1,y2 = np.log(fftData[which-1:which+2:]) 
     x1 = (y2 - y0) * .5/(2 * y1 - y2 - y0) 
     # find the frequency and output it 
     thefreq = (which+x1)*RATE/chunk 
     print "The freq is %f Hz." % (thefreq) 
    else: 
     thefreq = which*RATE/chunk 
     print "The freq is %f Hz." % (thefreq) 
    # read some more data 
    data = wf.readframes(chunk) 
if data: 
    stream.write(data) 
stream.close() 
p.terminate() 
+0

wow grazie, questo sembra che lo farò ora ho solo la figura gota come leggere l'audio in tempo reale da input auido (microfono) – MatijaG

+2

Vai al sito PyAudio http://people.csail.mit.edu/hubert/pyaudio/ e scorri la pagina verso gli esempi, ne vedrai alcuni che prendono input dal microfono. –

+0

uhm puoi aiutarmi a capire perché si verifica questo errore: " è necessario più di 0 valori per decomprimere " sulla riga seguente " y0, y1, y2 = np.log (fftData [which-1: which + 2:]) " – MatijaG

0

Mentre non ho ancora provato l'elaborazione audio con Python, forse potresti creare qualcosa basato su SciPy (o sul suo sottoprogetto NumPy), una struttura per un calcolo numerico scientifico/ingegneristico efficiente? Potresti iniziare osservando scipy.fftpack per il tuo FFT.

+1

ok ho trovato questo http://www.swharden.com/ blog/2010-03-05-realtime-fft-graph-of-audio-wav-file-o-microphone-input-with-python-scipy-and-wckgraph/ora mi chiedo come troverò la gamma freq che è al massimo (anche la SciPy ci ha aiutato un po 'grazie – MatijaG

+0

così hai capito come fare? –