python audio fft frequency

Detección de frecuencia de Python



subplot title python (3)

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 tono que incluyen 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()

Ok, lo que estoy tratando de 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.

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-10 bps) pero también estoy muy limitado en el extremo transmisor, por lo que el software receptor deberá poder ser 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.


Si bien no he probado anteriormente el procesamiento de audio con Python, ¿tal vez podrías construir algo basado en SciPy (o su subproyecto NumPy), un marco para una computación numérica científica / de ingeniería eficiente? Puede comenzar mirando en scipy.fftpack para su FFT.