2012-07-03 17 views
6

Me pregunto si estoy usando Fourier Transformation en MATLAB de la manera correcta. Quiero tener todas las amplitudes promedio para frecuencias en una canción. Para fines de prueba, estoy usando a free mp3 download of Beethovens "For Elise" que convertí en un archivo de onda única de 8 kHz usando Audacity.¿Estoy usando la transformación de Fourier de la manera correcta?

Mi código MATLAB es el siguiente:

clear all % be careful 

% load file 
% Für Elise Recording by Valentina Lisitsa 
% from http://www.forelise.com/recordings/valentina_lisitsa 
% Converted to 8 kHz mono using Audacity 
allSamples = wavread('fur_elise_valentina_lisitsa_8khz_mono.wav'); 


% apply windowing function 
w = hanning(length(allSamples)); 
allSamples = allSamples.*w; 


% FFT needs input of length 2^x 
NFFT = 2^nextpow2(length(allSamples)) 


% Apply FFT 
fftBuckets=fft(allSamples, NFFT); 
fftBuckets=fftBuckets(1:(NFFT/2+1)); % because of symetric/mirrored values 


% calculate single side amplitude spectrum, 
% normalize by dividing by NFFT to get the 
% popular way of displaying amplitudes 
% in a range of 0 to 1 
fftBuckets = (2*abs(fftBuckets))/NFFT; 

% plot it: max possible frequency is 4000, because sampling rate of input 
% is 8000 Hz 
x = linspace(1,4000,length(fftBuckets)); 
bar(x,fftBuckets); 

La salida tendrá el aspecto siguiente: enter image description here

  1. Puede alguien por favor dígame si mi código es correcto? Me pregunto especialmente sobre los picos alrededor de 0.
  2. Para normalizar, ¿tengo que dividir por NFFT o length(allSamples)?
  3. Para mí esto realmente no se ve como un gráfico de barras, pero supongo que esto se debe a los muchos valores que estoy trazando?

¡Gracias por cualquier pista!

+1

¿Has visto esta página: [Usando FFT para obtener gráficos sencillos de análisis espectral] (http://www.mathworks.com/support/tech-notes/1700/1702.html). Tiene un ejemplo con muchas explicaciones – Amro

Respuesta

6
  1. Depende de su definición de "correcto". Esto está haciendo lo que pretendía, creo, pero probablemente no sea muy útil. Sugeriría usar 2D spectrogram en su lugar, ya que obtendrá información localizada en el tiempo sobre el contenido de frecuencia.

  2. No hay una forma correcta de normalizar la salida FFT; hay varias convenciones diferentes (véase, por ejemplo, la discusión here). El comentario en tu código dice que quieres un rango de 0 a 1; si sus valores de entrada están en el rango de -1 a 1, entonces dividir por cantidad de contenedores lo logrará.

  3. Bueno, exactamente!

También recomendaría trazado el eje y en una escala logarítmica (decibels en), ya que eso es más o menos la forma en que el oído humano interpreta la intensidad.

2

Dos cosas que saltan a mí:

  1. no estoy seguro de por qué se está incluyendo el (1 = índice) componente de CC en su parcela. No es gran cosa, pero, por supuesto, ese contenedor no contiene datos de frecuencia
  2. Creo que es más probable que dividir por length(allSamples) sea correcto que dividir por NFFT. El motivo es que si desea que el componente de CC sea igual al promedio de los datos de entrada, dividir por length(allSamples) es lo correcto.

Sin embargo, como dijo Oli, no se puede decir cuál es la normalización "correcta" hasta que sepa exactamente lo que está tratando de calcular. Tiendo a usar FFT para estimar los espectros de potencia, por lo que quiero unidades como "DAC/rt-Hz", lo que daría lugar a una normalización diferente a la que usted deseaba con algo como "DAC/Hz".

En última instancia, no hay sustituto para pensar exactamente qué desea obtener de la FFT (incluidas las unidades), y averiguar cuál debería ser la normalización correcta (comenzando desde la definición de la FFT si es necesario).

También debe tener en cuenta que MATLAB fft no tiene la necesidad de utilizar una longitud de matriz que es una potencia de 2 (aunque al hacerlo presumiblemente conducirá a la FFT corriendo más rápido). Debido a que zero-padding introducirá algunos timbres, debe pensar si es lo correcto para su aplicación.

Por último, si un espectrograma/espectro de potencia es realmente lo que desea, MATLAB proporciona funciones como periodogram, pwelch y otras que pueden ser útiles.

Cuestiones relacionadas