Pregunta

Intentando entender una rutina Fft (Fast Fourier Transform) que estoy usando (robando) (reciclando)

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 el dominio de la frecuencia. Intentando comprender la relación entre frecuencia, período, frecuencia de muestreo y posición en la matriz FFT. Ilustraré con ejemplos:

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

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

La matriz de entrada tiene valores máximos en arr (28), arr (128), arr (228) ... período = 100 puntos de muestra

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

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

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

Los valores pico de la matriz de entrada incluyen arr (7), arr (25), arr (43), arr (61) ... período = 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?

¿Fue útil?

Solución

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

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. Dado que su entrada fue de 10Hz, supongo que el contenedor 5 (9.7Hz) también tenía un componente grande. Para obtener una mayor precisión, debe tomar más muestras, para obtener contenedores más pequeños.

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

Otros consejos

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

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

Siempre debes asegurarte de que el valor promedio en tus datos de entrada sea cero: encuentra el promedio y restalo 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 último punto de datos estén cerca de cero porque, de lo contrario, el paso " " Desde fuera hacia dentro, la ventana de muestreo tiene el efecto de inyectar una gran cantidad de energía en diferentes frecuencias.

La conclusión es que hacer un análisis de pies por segundo requiere más cuidado que simplemente reciclar una rutina de pies por hora 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 muestrear artefactos

> 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

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

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

los intervalos de 0 a 449 son frecuencias positivas de 0 Hz a 500 Hz. los intervalos de 500 a 1000 son frecuencias negativas y deberían ser iguales a las positivas para una señal real. Si procesa un búfer cada segundo, las frecuencias y los índices de matriz se alinean muy bien. Así que el pico en el índice 6 se corresponde con 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 obtener un pico esperado en el índice 10. Las frecuencias deben asignarse linealmente a los contenedores.

Los picos en 0 indican un desplazamiento de CC.

Ha pasado algún tiempo desde que hice FFT, pero esto es lo que recuerdo

FFT generalmente toma números complejos como entrada y salida. Así que no estoy realmente seguro de cómo la parte real e imaginaria de la entrada y salida se asigna a los arreglos.

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

Por lo general, la primera mitad del búfer de salida son intervalos de frecuencia de 0 frecuencia (= dc offset) a 1/2 frecuencia de muestreo. 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.

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

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

Menciona un contenedor con un gran valor en 0: este es el contenedor con frecuencia 0, es decir, el componente de CC. Si esto es grande, entonces 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 frecuencia.

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

Las muestras están, como han dicho otros, espaciadas por igual en el dominio de la frecuencia (no logarítmica).

Para el 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

Por lo tanto, ambas respuestas parecen ser correctas con respecto a la ubicación máxima.

Lo que no estoy obteniendo es el componente de CC grande. ¿Estás seguro de que estás generando una onda sinusoidal como entrada? ¿La entrada va negativa? Para una onda sinusoidal, el CD debe estar cerca de cero, siempre y cuando tengas suficientes ciclos.

Otra vía es crear un Algoritmo de Goertzel de cada frecuencia de centro de notas que esté buscando .

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

El algoritmo de Goertzel es básicamente un FFT de un solo contenedor. Usando este método, puedes colocar tus bandejas de forma logarítmica, ya que las notas musicales van de manera natural.

Algunos pseudo códigos 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 puede ser utilizado en una aplicación de transmisión. Pienso que quizás el cálculo de la potencia debería estar también dentro del bucle. (Sin embargo, no se muestra como tal en el artículo de Wiki).

En el caso de detección de tono, habría 88 coeficientes diferentes, 88 pares de muestras previas y daría lugar a 88 muestras de salida de potencia que indican el nivel relativo en esa bandeja de frecuencia.

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 cero. Esto suena como un problema con el hardware. DEBE SER centrado en cero.

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

-Rick

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top