2011-08-07 51 views
6

Esto es lo que me gustaría hacer. Me gustaría encontrar la frecuencia de audio y la amplitud de un archivo .wav en cada digamos 1ms de ese archivo .wav y guardarlo en un archivo. He graficado la frecuencia contra la amplitud y he graficado la amplitud con el tiempo, pero no puedo calcular la frecuencia de las horas extras. Mi objetivo final es poder leer el archivo y usar la amplitud para ajustar las variables y la frecuencia para activar qué variables se usan, esa parece ser la parte fácil. He estado usando numpy, audiolab, matplotlib, etc ... usando FFT pero no puedo entender esto, ¡cualquier ayuda es apreciada! ¡Gracias!Python encuentra frecuencia de audio y amplitud en el tiempo

+2

Un archivo de sonido no tiene un solo "frecuencia" en un momento dado, a menos que sea simplemente una grabación de un tono sinusoidal pura. Lo que probablemente necesite hacer es capturar el * espectro de potencia * a intervalos regulares y almacenar eso, o posiblemente hacer algún tipo de procesamiento en el espectro de potencia, como identificar los picos N más grandes y almacenarlos. –

+0

http://stackoverflow.com/questions/604453/analyze-audio-using-fast-fourier-transform – sylvanaar

Respuesta

7

Use una STFT con ventanas superpuestas para estimar el espectrograma. Para ahorrarse la molestia de enrollar el suyo, puede usar el specgram method de Matlabotlib's mlab. Es importante usar una ventana lo suficientemente pequeña para la cual el audio sea aproximadamente estacionario, y el tamaño del búfer debe ser una potencia de 2 para usar de manera eficiente un radix-2 fft común. 512 muestras (aproximadamente 10,67 ms a 48 ksps, o 93,75 Hz por contenedor) deberían ser suficientes. Para una velocidad de muestreo de 48 ksps, superponga por 464 muestras para evaluar una ventana deslizante a cada 1 ms (es decir, cambie por 48 muestras).

Editar:

He aquí un ejemplo que utiliza mlab.specgram en una señal de 8 segundos que tiene 1 tono por segundo desde 2 kHz hasta 16 kHz. Tenga en cuenta la respuesta en los transitorios. He ampliado la imagen en 4 segundos para mostrar la respuesta con más detalle. La frecuencia cambia exactamente a 4 segundos, pero se necesita una longitud de búfer (512 muestras, aproximadamente +/- 5 ms) para que pase el transitorio. Esto ilustra el tipo de manchas espectrales/temporales causadas por transiciones no estacionarias a medida que pasan a través del buffer. Además, puede ver que incluso cuando la señal es estacionaria existe el problema de la fuga espectral causada por la ventana de los datos. Se utilizó un Hamming window function para minimizar los lóbulos laterales de la fuga, pero esto también ensancha el lóbulo principal.

spectrogram

import numpy as np 
from matplotlib import mlab, pyplot 

#Python 2.x: 
#from __future__ import division 

Fs = 48000 
N = 512 
f = np.arange(1, 9) * 2000 
t = np.arange(8 * Fs)/Fs 
x = np.empty(t.shape) 
for i in range(8): 
    x[i*Fs:(i+1)*Fs] = np.cos(2*np.pi * f[i] * t[i*Fs:(i+1)*Fs]) 

w = np.hamming(N) 
ov = N - Fs // 1000 # e.g. 512 - 48000 // 1000 == 464 
Pxx, freqs, bins = mlab.specgram(x, NFFT=N, Fs=Fs, window=w, 
           noverlap=ov) 

#plot the spectrogram in dB 

Pxx_dB = np.log10(Pxx) 
pyplot.subplots_adjust(hspace=0.4) 

pyplot.subplot(211) 
ex1 = bins[0], bins[-1], freqs[0], freqs[-1] 
pyplot.imshow(np.flipud(Pxx_dB), extent=ex1) 
pyplot.axis('auto') 
pyplot.axis(ex1) 
pyplot.xlabel('time (s)') 
pyplot.ylabel('freq (Hz)') 

#zoom in at t=4s to show transient 

pyplot.subplot(212) 
n1, n2 = int(3.991/8*len(bins)), int(4.009/8*len(bins)) 
ex2 = bins[n1], bins[n2], freqs[0], freqs[-1] 
pyplot.imshow(np.flipud(Pxx_dB[:,n1:n2]), extent=ex2) 
pyplot.axis('auto') 
pyplot.axis(ex2) 
pyplot.xlabel('time (s)') 
pyplot.ylabel('freq (Hz)') 

pyplot.show() 
Cuestiones relacionadas