2010-05-21 35 views
12

Digamos que tengo un archivo WAV. En este archivo, hay una serie de tonos sinusoidales a intervalos precisos de 1 segundo. Quiero usar la biblioteca FFTW para extraer estos tonos en secuencia. ¿Es esto particularmente difícil de hacer? ¿Cómo voy a hacer esto?Cómo extraer frecuencias semi-precisas de un archivo WAV usando transformadas de Fourier

Además, ¿cuál es la mejor manera de escribir tonos de este tipo en un archivo WAV? Supongo que solo necesitaría una biblioteca de audio simple para la salida.

Mi idioma de su elección es C

Respuesta

1

archivos WAV contienen linear pulse code modulated (LPCM) datos. Eso solo significa que es una secuencia de valores de amplitud a una tasa de muestreo fija. Un RIFF header está contenido al principio del archivo para transportar información como sampling rate y bits por muestra (por ejemplo, 8 kHz con signo de 16 bits).

El formato es muy simple y puede hacer fácilmente el suyo propio. Sin embargo, hay varias bibliotecas disponibles para acelerar el proceso, como libsndfile. Simple Direct-media Layer (SDL)/SDL_mixer y PortAudio son dos geniales bibliotecas para reproducción.

En cuanto a alimentar los datos en FFTW, necesitaría almacenar en un buffer trozos de 1 segundo (determine el tamaño por la frecuencia de muestreo y los bits por muestra). A continuación, convierta todas las muestras al punto flotante IEEE (es decir, float o double dependiendo de la configuración de FFTW-- libsndfile puede hacer esto por usted). A continuación, cree otra matriz para contener la salida del dominio de frecuencia. Finalmente, cree y ejecute un plan FFTW pasando ambos buffers a fftw_plan_dft_r2c_1d y llamando al fftw_execute with the returned fftw_plan handle.

+0

No es realmente la versión 'fftw', pero si se compiló o no con soporte flotante, ¿no? –

+0

Es cierto, es una cuestión de la configuración de construcción IIRC. No he usado FFTW en muchos años. Tal vez "versión" no es la palabra más precisa que podría haber elegido? –

+0

Gran parte del software DSP de audio para Linux (y otras plataformas) que utiliza FFTW requiere FFTW con soporte de flotación, y habiendo pasado mucho tiempo construyendo esto desde el origen, puedo decir que Debian al menos tiene paquetes para las diferentes compilaciones opciones de FFTW que pueden instalarse todas simultáneamente. Espero que esto también se aplique a la mayoría de las otras distribuciones de Linux. –

22

Para obtener el power spectrum de una sección de su archivo:

  • recogen N muestras, donde N es una potencia de 2 - si su frecuencia de muestreo es de 44,1 kHz, por ejemplo, y que desea muestrear aproximadamente cada en segundo lugar ir por decir N = 32768 muestras.

  • aplicar un adecuado window function a las muestras, p. Hanning

  • pasan las muestras de ventana a una rutina de FFT - Lo ideal sería tener una FFT-real a complejo pero si todo lo que tiene a es complejo a-FFT compleja luego pase 0 para todas las partes de entrada imaginarios

  • calcular la magnitud al cuadrado de sus bandejas de salida FFT (re re * + im * im)

  • (opcional) calculan 10 * log10 de cada magnitud elevada al cuadrado bandeja de salida para obtener un valor de magnitud en dB

Ahora que tiene su espectro de potencia, solo necesita identificar el (los) pico (s), lo que debería ser bastante sencillo si tiene una relación S/N razonable. Tenga en cuenta que la resolución de frecuencia mejora con una mayor N. Para el ejemplo anterior de frecuencia de muestreo de 44.1 kHz y N = 32768, la resolución de frecuencia de cada contenedor es 44100/32768 = 1.35 Hz.

+0

Tenga en cuenta que la función de ventana 'Hanning' difuminará la entrada en varias ubicaciones; el 1,35 Hz sugerido es bastante optimista. [Como notas de Wikipedia] (http://en.wikipedia.org/wiki/Window_function#Comparison_of_windows), de hecho podría tener sentido no abrir ventana. – MSalters

+0

Las ventanas de Hann o Hamming tienden a ser las funciones de ventana de propósito general más útiles. Ambas dan un compromiso razonable en el sentido de que la magnitud y la frecuencia de un pico serán bastante confiables (a diferencia del caso sin ventana) y el pico también será razonablemente agudo. Sin embargo, si busca identificar picos separados que están muy juntos, probablemente haya mejores opciones para la función de ventana. El uso de ninguna ventana (es decir, la función de ventana rectangular) generalmente solo tiene sentido si se buscan componentes que se alinean exactamente con las frecuencias de la bandeja. –

2

Básicamente está interesado en estimating a Spectrum, suponiendo que ya ha pasado la etapa de lectura de WAV y convirtiéndola en una señal de tiempo discreta.

Entre los diversos métodos, el más básico es el Periodograma, que equivale a tomar una Transformada de Fourier Discreta con ventana (con una FFT) y mantener su magnitud al cuadrado. Esto corresponde a la respuesta de Pablo. Necesita una ventana que abarca varios periodos de la frecuencia más baja que desea detectar. Ejemplo: si sus sinusoides pueden ser tan bajas como 10 Hz (período = 100 ms), debe tomar una ventana de 200 ms o 300 ms o más (o más). Sin embargo, el periodograma tiene alguna disadvantages, aunque es fácil de calcular y es más que suficiente si la alta precisión no es necesaria:

El periodograma prima no es una buena estimación espectral debido espectral sesgo y el hecho de que la varianza a una frecuencia determinada no disminuye a medida que aumenta el número de muestras utilizadas en el cálculo .

El periodogram puede funcionar mejor al promediar varias ventanas, con una elección acertada de los anchos(). Y hay muchos otros métodos para estimar el espectro (modelado AR).

En realidad, no está exactamente interesado en estimar un espectro completo, sino solo la ubicación de una sola frecuencia. Esto se puede hacer buscando un pico de un espectro estimado (hecho como se explicó), pero también por un más específico y poderoso (y complicado) methods (Pisarenko, algoritmo de MÚSICA). Probablemente sean exagerados en su caso.

Cuestiones relacionadas