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.
Si va a usar FSK (modulación por desplazamiento de frecuencia) para codificar datos, probablemente sea mejor que use el algoritmo de Goertzel para poder verificar solo las frecuencias que desee, en lugar de una DFT / FFT completa.