2010-04-15 28 views
29

Ok, lo que intento hacer es un tipo de software de procesamiento de audio que puede detectar una frecuencia frecuente y si la frecuencia se reproduce durante el tiempo suficiente (unos pocos minutos) sé que obtuve una coincidencia positiva. Sé que necesitaría usar FFT o algo similar, pero en este campo de las matemáticas no me gusta, busqué en Internet pero no encontré un código que pudiera hacer esto.Detección de frecuencia de Python

el objetivo que intento lograr es hacerme un protocolo personalizado para enviar datos a través del sonido, necesito una tasa de bits muy baja por segundo (5-10bps) pero también estoy muy limitado en el extremo transmisor, por lo que poder personalizado (no puedo usar un módem de hardware/software real) también quiero que esto sea solo software (sin hardware adicional excepto tarjeta de sonido)

muchas gracias por la ayuda.

+1

Esto puede ser útil (asegúrese de leer las respuestas): http://www.keyongtech.com/5003865-frequency-analysis-without-numpy – ChristopheD

Respuesta

37

Las bibliotecas aubio se han envuelto con SWIG y, por lo tanto, pueden ser utilizadas por Python. Entre sus muchas características se incluyen varios métodos para la detección/estimación de tonos, incluido el algoritmo YIN y algunos algoritmos de peine armónico.

Sin embargo, si quieres algo más simple, escribí un código para la estimación de tono hace algún tiempo y puedes tomarlo o dejarlo. No será tan preciso como usar los algoritmos en aubio, pero podría ser lo suficientemente bueno para sus necesidades. Básicamente, solo tomé FFT de los datos por una ventana (una ventana de Blackman en este caso), cuadre los valores de FFT, encontré el contenedor que tenía el valor más alto y usé una interpolación cuadrática alrededor del pico usando el registro del valor máximo y sus dos valores vecinos para encontrar la frecuencia fundamental. La interpolación cuadrática que tomé de un papel que encontré.

Funciona bastante bien en tonos de prueba, pero no será tan robusto ni tan preciso como los otros métodos mencionados anteriormente. La precisión se puede aumentar aumentando el tamaño del fragmento (o reduciéndolo disminuyéndolo). El tamaño del fragmento debe ser un múltiplo de 2 para hacer un uso completo de la FFT. Además, solo estoy determinando el tono fundamental para cada fragmento sin superposición. Utilicé PyAudio para reproducir el sonido mientras escribía el tono estimado. Código

Fuente:

# 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, gracias, esto parece que va a hacer ahora solo goto cómo leer el audio en tiempo real desde la entrada de auido (micrófono) – MatijaG

+2

Visite el sitio de PyAudio http://people.csail.mit.edu/hubert/pyaudio/ y desplácese por la página hasta encontrar los ejemplos. Verá algunos que reciben información del micrófono. –

+0

uhm me puede ayudar a entender ¿Por qué está ocurriendo este error? " necesita más de 0 valores para descomprimir " en la siguiente línea " y0, y1, y2 = np.log (fftData [which-1: which + 2:]) " – MatijaG

0

Si bien no he probado anteriormente el procesamiento de audio con Python, ¿podría construir algo basado en SciPy (o su subproyecto NumPy), un marco para el cálculo numérico científico/de ingeniería eficiente? Puede comenzar por mirar scipy.fftpack para su FFT.

+1

ok, encontré esto http://www.swharden.com/ blog/2010-03-05-realtime-fft-graph-of-audio-wav-file-or-microphone-input-with-python-scipy-and-wckgraph/tho ahora me pregunto cómo voy a encontrar el rango de frecuencia que está en lo más alto (también el SciPy ayudó un poco, gracias – MatijaG

+0

, ¿te diste cuenta cómo hacerlo? –

Cuestiones relacionadas