2011-10-12 8 views
7

que tiene un reproductor de audio utilizando NAudio y me gustaría mostrar una intensidad en tiempo real para cada banda de frecuencia.frecuencia NAudio intensidad de la banda

tengo un evento disparado por cada bloque de 1024 muestras:

public void Update(Complex[] fftResults) 
{ 
    // ?? 
} 

lo que me gustaría tener es una serie de números que indican la intensidad de cada banda de frecuencia. Digamos que me gustaría dividir la ventana en 16 bandas.

Por ejemplo, cuando hay más frecuencias bajas que podría tener este aspecto:

░░░░░░░░░░░░░░░░ 
▓▓▓░░░░░░░░░░░░░ 
▓▓▓░░░░░░░░░░░░░ 
▓▓▓▓░░░░░░░░░░░░ 
▓▓▓▓▓░░░░░░░░░░░ 
▓▓▓▓▓▓▓▓░░░▓░░▓░ 

¿Qué debo poner en ese controlador de eventos si esto es posible con esos datos?

datos que vienen (Complejo []) ya ha sido transformada con la FFT. Es una transmisión estéreo.

primer intento:

double[] bandIntensity = new double[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 

    public void Update(Complex[] fftResults) 
    { 
     // using half fftResults because the others are just mirrored 
     int band = 0; 
     for (int n = 0; n < fftResults.Length/2; n++) 
     { 
      band = (int)((double)n/(fftResults.Length/2) * bandIntensity.Length); 
      bandIntensity[band] += Math.Sqrt(fftResults[n].X * fftResults[n].X + fftResults[n].Y * fftResults[n].Y); 
      bandIntensity[band] /= 2; 
     } 
    } 

Lo anterior se hace algo, pero pienso demasiado entra en las dos primeras bandas, y yo estoy jugando shakira que no tiene que muchos bajos.

Gracias!

Respuesta

8

Hay dos cuestiones distintas que es probable que desee abordar aquí:

(1) Función de ventana

Es necesario aplicar un window function a sus datos antes de la FFT, de lo contrario obtendrá spectral leakage cuales resultará en un espectro muy untado. Un efecto secundario desagradable de la fuga espectral es que si tiene algún tipo de componente de CC significativo (0 Hz), esto dará como resultado el tipo de forma 1/f que está viendo en su gráfico de barras.

(2) de amplitud de registro/frecuencia ejes

audición humana es esencialmente logarítmica en ambos ejes intensidad y frecuencia. No solo eso, sino que el habla y la música tienden a tener más energía en la parte de frecuencia más baja del espectro. Para obtener una visualización más agradable y significativa de la intensidad en función de la frecuencia, generalmente hacemos que tanto la magnitud como los ejes de frecuencia sean logarítmicos. En el caso de la magnitud eje esto normalmente es cuidado por el trazado dB re gran escala, es decir

magnitude_dB = 10 * log10(magnitude); 

en el caso de la frecuencia eje es probable que desee para agrupar los contenedores en bandas, lo que podría ser cada uno una octava (rango de frecuencia 2: 1), o más comúnmente para una resolución más alta, tercera octava. Así que si lo que desea es 10 "barras" entonces es posible utilizar las siguientes bandas de octava:

25 - 50 Hz 
    50 - 100 Hz 
    100 - 200 Hz 
    200 - 400 Hz 
    400 - 800 Hz 
    800 - 1600 Hz 
1600 - 3200 Hz 
3200 - 6400 Hz 
6400 - 12800 Hz 
12800 - 20000 Hz 

(suponiendo que tiene una frecuencia de muestreo de 44,1 kHz y un límite superior de su hardware de entrada de audio de 20 kHz).

Tenga en cuenta que aunque tener una escala de intensidad de magnitud (dB) es bastante obligatoria para este tipo de aplicación, el eje de frecuencia de registro es menos crítico, por lo que podría probar con su agrupación lineal existente por ahora, y solo ver qué efecto obtienes la aplicación de una función de ventana en el dominio del tiempo (suponiendo que aún no la tengas) y conviertes la escala de magnitud en dB.

+1

eres mi héroe. lol. –

+0

Para la ventana, veo que se utiliza BlackmannHarrisWindow. Sin embargo, no probé el 10xLog10() aún, veré cómo eso cambia el gráfico. Y eliminaré el bin DC de 0Hz. –

+0

incluso después de aplicar un bin de octava a la colección de bandas, todavía obtengo números extraños, demasiado en el lado izquierdo ... he convertido los números de la escala y a dBs –

Cuestiones relacionadas