visual tutorial para for español applications aplicaciones vba audio signal-processing fft

vba - tutorial - visual basic for applications pdf



VB FFT: relación de comprensión atascada de los resultados con la frecuencia (8)

Tratando de entender una rutina fft (Fast Fourier Transform) que estoy usando (robo) (reciclaje)

La entrada es una matriz de 512 puntos de datos que son una forma de onda de muestra. Los datos de prueba se generan en esta matriz. fft transforma esta matriz en dominio de frecuencia. Intentando entender la relación entre la frecuencia, el período, la frecuencia de muestreo y la posición en la matriz fft. Ilustraré con ejemplos:

========================================

La frecuencia de muestreo es de 1000 muestras / s. Genera un conjunto de muestras a 10Hz.

La matriz de entrada tiene valores pico en arr (28), arr (128), arr (228) ... period = 100 puntos de muestra

el valor máximo en la matriz fft está en el índice 6 (excluyendo un valor enorme en 0)

========================================

La velocidad de muestreo es de 8000 muestras / s Generar un conjunto de muestras a 440 Hz

Los valores pico de la matriz de entrada incluyen arr (7), arr (25), arr (43), arr (61) ... periodo = 18 puntos de muestra

el valor máximo en la matriz fft está en el índice 29 (excluyendo un valor enorme en 0)

========================================

¿Cómo relaciono el índice del pico en la matriz fft con la frecuencia?


Ha pasado un tiempo desde que hice FFT, pero esto es lo que recuerdo

FFT usualmente toma números complejos como entrada y salida. Así que no estoy muy seguro de cómo la parte real e imaginaria del mapa de entrada y salida a las matrices.

Realmente no entiendo lo que estás haciendo. En el primer ejemplo, ¿dice que procesa buffers de muestra a 10 Hz para una frecuencia de muestreo de 1000 Hz? Por lo tanto, debe tener 10 búferes por segundo con 100 muestras cada uno. No entiendo cómo su matriz de entrada puede tener al menos 228 muestras de longitud.

Por lo general, la primera mitad del búfer de salida son contenedores de frecuencia desde la frecuencia 0 (= desplazamiento de cd) hasta la frecuencia de muestreo 1/2. y la segunda mitad son frecuencias negativas. si su entrada es solo datos reales con 0 para la señal imaginaria, las frecuencias positivas y negativas son las mismas. La relación de la señal real / imaginaria en la salida contiene información de fase de su señal de entrada.


También estoy un poco oxidado en matemáticas y procesamiento de señal, pero con la información adicional puedo darle una oportunidad.

Si desea conocer la energía de la señal por contenedor, necesita la magnitud de la salida compleja. Así que solo mirar el producto real no es suficiente. Incluso cuando la entrada es solo números reales. Para cada contenedor la magnitud de la salida es sqrt (real ^ 2 + imag ^ 2), al igual que pythagoras :-)

los receptáculos 0 a 449 son frecuencias positivas de 0 Hz a 500 Hz. los contenedores de 500 a 1000 son frecuencias negativas y deben ser los mismos que los positivos para una señal real. Si procesa un buffer cada segundo las frecuencias y los índices de matriz se alinean muy bien. Entonces, el pico en el índice 6 corresponde a 6Hz, por lo que es un poco extraño. Esto podría deberse a que solo está mirando los datos de salida reales y los datos reales e imaginarios se combinan para dar un pico esperado en el índice 10. Las frecuencias deben correlacionarse linealmente con los contenedores.

Los picos en 0 indican un desplazamiento de CC.


La frecuencia de bin i es i * (frecuencia de muestreo / n), donde n es el número de muestras en la ventana de entrada de la FFT.

Si está manejando audio, dado que el tono es proporcional al registro de frecuencia, la resolución de tono de los bins aumenta a medida que lo hace la frecuencia; es difícil resolver las señales de baja frecuencia con precisión. Para hacerlo, debes usar ventanas de FFT más grandes, lo que reduce la resolución del tiempo. Existe una compensación de la frecuencia frente a la resolución de tiempo para una frecuencia de muestreo determinada.

Usted menciona un contenedor con un valor grande en 0 - este es el contenedor con la frecuencia 0, es decir, el componente de CC. Si esto es grande, entonces presumiblemente sus valores son generalmente positivos. Bin n / 2 (en su caso 256) es la frecuencia de Nyquist, la mitad de la frecuencia de muestreo, que es la frecuencia más alta que se puede resolver en la señal muestreada a esta velocidad.

Si la señal es real, entonces los contenedores n / 2 + 1 a n-1 contendrán los conjugados complejos de los contenedores n / 2-1 a 1, respectivamente. El valor de DC solo aparece una vez.


Si ignora la parte imaginaria, la distribución de frecuencia es lineal en los intervalos:

Frecuencia @ i = (Velocidad de muestreo / 2) * (i / Nbins).

Entonces, para su primer ejemplo, suponiendo que tenía 256 contenedores, el contenedor más grande corresponde a una frecuencia de 1000/2 * 6/256 = 11.7 Hz. Como tu entrada fue de 10Hz, supongo que bin 5 (9.7Hz) también tiene un gran componente. Para obtener una mejor precisión, necesita tomar más muestras, para obtener contenedores más pequeños.

Su segundo ejemplo da 8000/2 * 29/256 = 453Hz. De nuevo, cerca, pero necesitas más contenedores. Su resolución aquí es solo 4000/256 = 15.6Hz.


Las muestras son, como han dicho otros, igualmente espaciadas en el dominio de la frecuencia (no logarítmica).

Por ejemplo 1, deberías obtener esto:

texto alternativo http://home.comcast.net/~kootsoop/images/SINE1.jpg

Para el otro ejemplo, debes obtener

texto alternativo http://home.comcast.net/~kootsoop/images/SINE2.jpg

Entonces, sus respuestas parecen ser correctas con respecto a la ubicación máxima.

Lo que no obtendré es el gran componente DC. ¿Estás seguro de que estás generando una onda sinusoidal como entrada? ¿La entrada es negativa? Para una onda sinusoidal, el DC debe estar cerca de cero siempre que obtenga ciclos suficientes.


Sería útil si proporcionara su conjunto de datos de muestra.

Mi suposición sería que tienes lo que se llaman artefactos de muestreo. La señal fuerte en DC (frecuencia 0) sugiere que este es el caso.

Siempre debe asegurarse de que el valor promedio en sus datos de entrada sea cero: encuentre el promedio y restelo de cada punto de muestra antes de invocar el fft es una buena práctica.

En la misma línea, debe tener cuidado con el artefacto de la ventana de muestreo. Es importante que el primer y el último punto de datos estén cerca de cero porque, de lo contrario, el "paso" de afuera a dentro de la ventana de muestreo tiene el efecto de inyectar una gran cantidad de energía a diferentes frecuencias.

La conclusión es que hacer un análisis fft requiere más cuidado que simplemente reciclar una rutina FFT encontrada en alguna parte.

Aquí están los primeros 100 puntos de muestra de una señal de 10Hz como se describe en la pregunta, masajeados para evitar artefactos de muestreo

> sinx[1:100] [1] 0.000000e+00 6.279052e-02 1.253332e-01 1.873813e-01 2.486899e-01 3.090170e-01 3.681246e-01 4.257793e-01 4.817537e-01 5.358268e-01 [11] 5.877853e-01 6.374240e-01 6.845471e-01 7.289686e-01 7.705132e-01 8.090170e-01 8.443279e-01 8.763067e-01 9.048271e-01 9.297765e-01 [21] 9.510565e-01 9.685832e-01 9.822873e-01 9.921147e-01 9.980267e-01 1.000000e+00 9.980267e-01 9.921147e-01 9.822873e-01 9.685832e-01 [31] 9.510565e-01 9.297765e-01 9.048271e-01 8.763067e-01 8.443279e-01 8.090170e-01 7.705132e-01 7.289686e-01 6.845471e-01 6.374240e-01 [41] 5.877853e-01 5.358268e-01 4.817537e-01 4.257793e-01 3.681246e-01 3.090170e-01 2.486899e-01 1.873813e-01 1.253332e-01 6.279052e-02 [51] -2.542075e-15 -6.279052e-02 -1.253332e-01 -1.873813e-01 -2.486899e-01 -3.090170e-01 -3.681246e-01 -4.257793e-01 -4.817537e-01 -5.358268e-01 [61] -5.877853e-01 -6.374240e-01 -6.845471e-01 -7.289686e-01 -7.705132e-01 -8.090170e-01 -8.443279e-01 -8.763067e-01 -9.048271e-01 -9.297765e-01 [71] -9.510565e-01 -9.685832e-01 -9.822873e-01 -9.921147e-01 -9.980267e-01 -1.000000e+00 -9.980267e-01 -9.921147e-01 -9.822873e-01 -9.685832e-01 [81] -9.510565e-01 -9.297765e-01 -9.048271e-01 -8.763067e-01 -8.443279e-01 -8.090170e-01 -7.705132e-01 -7.289686e-01 -6.845471e-01 -6.374240e-01 [91] -5.877853e-01 -5.358268e-01 -4.817537e-01 -4.257793e-01 -3.681246e-01 -3.090170e-01 -2.486899e-01 -1.873813e-01 -1.253332e-01 -6.279052e-02

Y aquí están los valores absolutos resultantes del dominio de frecuencia fft

[1] 7.160038e-13 1.008741e-01 2.080408e-01 3.291725e-01 4.753899e-01 6.653660e-01 9.352601e-01 1.368212e+00 2.211653e+00 4.691243e+00 5.001674e+02 [12] 5.293086e+00 2.742218e+00 1.891330e+00 1.462830e+00 1.203175e+00 1.028079e+00 9.014559e-01 8.052577e-01 7.294489e-01


WaveyDavey dice que está capturando el sonido de un micrófono, a través del hardware de audio de su computadora, PERO que sus resultados no están centrados en el cero. Esto suena como un problema con el hardware. DEBE ESTAR CENTRADO EN CERO.

Cuando la sala está en silencio, la corriente de valores provenientes del API de sonido debe estar muy cerca de la amplitud 0, con ligeras + variaciones para el ruido ambiental. Si hay un sonido vibratorio en la habitación (p. Ej., Un piano, una flauta, una voz), la secuencia de datos debe mostrar una onda fundamentalmente sinusoidal que es tanto positiva como negativa, y tiene promedios cercanos a cero. Si este no es el caso, ¡el sistema tiene algo de funk!

-Almiar


Otra vía es elaborar un algoritmo de Goertzel de cada frecuencia de centro de notas que está buscando.

Una vez que obtenga una implementación del algoritmo funcionando, puede hacer que tome parámetros para establecer su frecuencia central. Con eso, puede ejecutar fácilmente 88 de ellos o lo que necesite en una colección y escanear para obtener el valor máximo.

El algoritmo Goertzel es básicamente una FFT de un solo contenedor. Usando este método puedes colocar tus contenedores logarítmicamente como van naturalmente las notas musicales.

Algunos pseudo código de Wikipedia:

s_prev = 0 s_prev2 = 0 coeff = 2*cos(2*PI*normalized_frequency); for each sample, x[n], s = x[n] + coeff*s_prev - s_prev2; s_prev2 = s_prev; s_prev = s; end power = s_prev2*s_prev2 + s_prev*s_prev - coeff*s_prev2*s_prev;

Las dos variables que representan las dos muestras anteriores se mantienen para la siguiente iteración. Esto se puede usar luego en una aplicación de transmisión. Creo que quizás el cálculo de la potencia también debería estar dentro del ciclo. (Sin embargo, no se describe como tal en el artículo de Wiki).

En el caso de detección de tonos, habría 88 coeficientes diferentes, 88 pares de muestras previas, y se obtendrían 88 muestras de potencia de salida que indicarían el nivel relativo en ese intervalo de frecuencias.