2012-01-13 11 views
12

He estado buscando en aurioTouch 2 del código de ejemplo de Apple (found here). Al final del día, quiero analizar las frecuencias yo mismo. Por ahora estoy tratando de entender algo de lo que está sucediendo aquí. Mis disculpas si esto es trivial, solo trato de entender algunos de los números mágicos no comentados que flotan en alguna parte de la fuente. Mis principales puntos de confusión en este momento son:Comprender FFT en aurioTouch2

  1. ¿Por qué ponen a cero el valor de nyquist en FFTBufferManager :: ComputeFFT? ¿Puede este valor realmente ser desechado? (~ línea 112 de FFTBufferManager.cpp).
  2. Escalan todo por -128db, así que supongo que los resultados están por lo tanto en el rango de (-128, 0). Sin embargo, más adelante en aurioTouchAppDelegate.mm (~ línea 807), convierten esto a un valor entre 0 y 1 agregando 80 y dividiendo por 64, luego ajustando a 0 y 1. ¿Por qué la falta de claridad? Además, ¿tengo razón al suponer que los valores estarán en las cercanías de (-128, 0)?

Respuesta

13

Bueno, tampoco es trivial para mí, pero así es como lo entiendo. Si lo simplifiqué en exceso es solo para mi beneficio, no pretendo ser condescendiente.

Poner a cero el resultado correspondiente a la frecuencia de Nyquist:

Voy a suponer que estamos calculando la FFT directa de 1024 muestras de entrada. Con 44100hz de entrada, esto suele ser cierto en mi caso (pero no es lo que AurioTouch está haciendo, lo que me parece un poco extraño, pero no soy un experto). Es más fácil para mí entender con valores específicos.

Dadas 1024 (n) muestras de entrada, dispuestas según sea necesario (incluso índices 'primero y luego índices impares' {en [0], en [2], en [4], ..., en 1, en [3], en [5], ...}) (utilizar vDSP_ctoz() para ordenar su entrada)

La salida del FFT 1024 muestras (n) de entrada es ((N/2) +1) valores complejos. es decir 513 componentes reales y 513 componentes imaginarios, un total de valores.

Sin embargo, imaginario [0] y imaginario [512] (n/2) son siempre, necesariamente, cero. Así que al colocar real [512] (el componente real de la bandeja de frecuencia Nyquist) en imaginario [0] y olvidando imaginario [512] - que siempre es cero y se puede inferir, los resultados se empaquetan en una (n) buffer de longitud.

Por lo tanto, para que los resultados devueltos sean válidos, al menos debe establecer imaginary [0] de vuelta a cero. Si necesita todos los ((n/2) 1) intervalos de frecuencia que es necesario añadir otro valor complejo para el resultado y lo puso de este modo ..

unpackedVal = imaginary[0] 
real[512]=unpackedVal, imaginary[512]=0 
imaginary[0] = 0 

En AurioTouch i se supone siempre que sólo don' Te moleston/2 resultados es obviamente más conveniente trabajar con y apenas se puede decir que desde el visualizador: - "Oh, mira, le falta una magnitud a la frecuencia de Nyquist"

The UsingFourierTransforms docs explain the packing

NB los valores específicos 1024, 513, 512, etc. son ejemplos, no los valores reales de n, (n/2) +1, n/2 de AurioTouch.

escalan todo abajo por -128db

No del todo, el intervalo de los valores de salida es en relación con el número de muestras de entrada Así que tiene que ser normalizado. La escala es 1.0/(2 * enNumberFrames).

Después de escalar el rango es -1.0 -> +1.0. se toma entonces la magnitud del vector complejo (la fase se ignora), dando un valor escalar para cada bin de frecuencia entre 0 y 1,0

Este valor se interpreta entonces como un valor de decibelios entre -128 y 0

El material de dibujo ... +80/64. ... * 120 ... ... no estoy seguro. Puedo estar completamente equivocado o puede ser ... ¿licencia artística?

+0

Muchas gracias por tomarse el tiempo para explicarme esto. –