Estoy tratando de crear un analizador de espectro gráfico en Python.
Actualmente estoy leyendo 1024 bytes de un flujo de audio de frecuencia de muestreo de 44,100 Hz de doble canal de 16 bits y promediando la amplitud de los 2 canales juntos. Así que ahora tengo una serie de 256 cortos firmados. Ahora quiero preformar un fft en esa matriz, usando un módulo como numpy, y usar el resultado para crear el analizador de espectro gráfico, que, para comenzar, será solo de 32 barras.
He leído los artículos de Wikipedia sobre Transformada rápida de Fourier y Transformada discreta de Fourier, pero todavía no tengo claro qué representa la matriz resultante. Así es como se ve la matriz después de realizar un fft en mi matriz usando numpy:
[ -3.37260500e+05 +0.00000000e+00j 7.11787022e+05 +1.70667403e+04j
4.10040193e+05 +3.28653370e+05j 9.90933073e+04 +1.60555003e+05j
2.28787050e+05 +3.24141951e+05j 2.09781047e+04 +2.31063376e+05j
-2.15941453e+05 +1.63773851e+05j -7.07833051e+04 +1.52467334e+05j
-1.37440802e+05 +6.28107674e+04j -7.07536614e+03 +5.55634993e+03j
-4.31009964e+04 -1.74891657e+05j 1.39384348e+05 +1.95956947e+04j
1.73613033e+05 +1.16883207e+05j 1.15610357e+05 -2.62619884e+04j
-2.05469722e+05 +1.71343186e+05j -1.56779748e+04 +1.51258101e+05j
-2.08639913e+05 +6.07372799e+04j -2.90623668e+05 -2.79550838e+05j
-1.68112214e+05 +4.47877871e+04j -1.21289916e+03 +1.18397979e+05j
-1.55779104e+05 +5.06852464e+04j 1.95309737e+05 +1.93876325e+04j
-2.80400414e+05 +6.90079265e+04j 1.25892113e+04 -1.39293422e+05j
3.10709174e+04 -1.35248953e+05j 1.31003438e+05 +1.90799303e+05j...
Me pregunto qué representan exactamente estos números y cómo convertiría estos números en un porcentaje de una altura para cada una de las 32 barras. Además, ¿debería promediar los 2 canales juntos?
Aunque este hilo tiene años, lo encontré muy útil. Solo quería dar mi opinión a cualquiera que encuentre esto y esté tratando de crear algo similar.
En cuanto a la división en barras, esto no debe hacerse como sugiere antti, dividiendo los datos por igual en función del número de barras. Lo más útil sería dividir los datos en partes de octavas, siendo cada octava el doble de la frecuencia de la anterior. (es decir, 100 Hz es una octava por encima de 50 Hz, que es una octava por encima de 25 Hz).
Dependiendo del número de compases que desee, divida todo el rango en rangos de octava de 1 / X. Basado en una frecuencia central dada de A en la barra, obtienes los límites superior e inferior de la barra de:
Para calcular la siguiente frecuencia central adyacente, utilice un cálculo similar:
Luego, promedia los datos que se ajustan a estos rangos para obtener la amplitud de cada barra.
Por ejemplo: Queremos dividir en rangos de 1/3 de octavas y comenzamos con una frecuencia central de 1 kHz.
Dadas 44100hz y 1024 muestras (43hz entre cada punto de datos) debemos promediar los valores de 21 a 26. (890.9 / 43 = 20.72 ~ 21 y 1122.5 / 43 = 26.10 ~ 26)
(Las barras de 1/3 de octava le darían alrededor de 30 barras entre ~ 40 Hz y ~ 20 kHz). Como puede deducir a estas alturas, a medida que subimos, promediaremos un rango mayor de números. Las barras bajas generalmente solo incluyen 1 o una pequeña cantidad de puntos de datos. Mientras que las barras más altas pueden ser el promedio de cientos de puntos. La razón es que 86 hz es una octava por encima de 43 hz ... mientras que 10086 hz suena casi igual que 10043 hz.
fuente
lo que tienes es una muestra cuya duración en el tiempo es 256/44100 = 0.00580499 segundos. Esto significa que su resolución de frecuencia es 1 / 0.00580499 = 172 Hz. Los 256 valores que obtienes de Python corresponden a las frecuencias, básicamente, de 86 Hz a 255 * 172 + 86 Hz = 43946 Hz. Los números que obtiene son números complejos (de ahí la "j" al final de cada segundo número).
EDITADO: INFORMACIÓN INCORRECTA CORREGIDA
Necesita convertir los números complejos en amplitud calculando la raíz cuadrada (i 2 + j 2 ) donde i y j son las partes real e imaginaria, resp.
Si desea tener 32 barras, por lo que tengo entendido, debería tomar el promedio de cuatro amplitudes sucesivas, obteniendo 256/4 = 32 barras como desee.
fuente
FFT devuelve N valores complejos, ¿cuál de ustedes puede calcular
module=sqrt(real_part^2+imaginary_part^2)
? Para obtener el valor de cada banda, debe sumar los módulos sobre todos los armónicos dentro de la banda. A continuación puede ver un ejemplo sobre un analizador de espectro de 10 barras. El código c debe ajustarse para obtener un módulo pyd python.Diseñé e hice un analizador de espectro completo de 10 barras LED de Python. En lugar de usar la biblioteca nunmpy (demasiado grande e inútil para obtener solo la FFT), se creó un módulo pyd de Python (solo 27 KB) para obtener la FFT y dividir todo el espectro de audio en bandas.
Además, para leer el audio de salida se creó un módulo pyd de WASapi portaudio de loopback. Puedes ver el proyecto (diagrama de bloques) en la imagen 10BarsSpectrumAnalyzerWithWASapi.jpg
Acabo de agregar un video tutorial en mi canal de YouTube: cómo diseñar y hacer una barra LED de Python Spectrum Analyzer 10 muy inteligente
fuente