Tengo un archivo de audio y estoy iterando a través del archivo y tomando 512 muestras en cada paso y luego pasándolas a través de una FFT.Convirtiendo una FFT a un spectogram
Tengo los datos como un bloque 514 flota de largo (usando ippsFFTFwd_RToCCS_32f_I de IPP) con componentes reales e imaginarios intercalados.
Mi problema es ¿qué hago con estos números complejos una vez que los tengo? En el momento que estoy haciendo para cada valor
const float realValue = buffer[(y * 2) + 0];
const float imagValue = buffer[(y * 2) + 1];
const float value = sqrt((realValue * realValue) + (imagValue * imagValue));
Esto da algo poco útil pero prefiero alguna manera de conseguir los valores en el rango de 0 a 1. El problema con él es que por encima de los picos terminan regresando como alrededor de 9 o más. Esto significa que las cosas se saturan brutalmente y luego hay otras partes del espectrograma que apenas aparecen a pesar del hecho de que parecen ser bastante fuertes cuando ejecuto el audio a través del espectrograma de la audición. Admito plenamente que no estoy 100% seguro de cuáles son los datos devueltos por la FFT (aparte de que representa los valores de frecuencia del bloque largo de 512 muestras que estoy pasando). Especialmente, mi entendimiento carece de lo que representa exactamente el número compex.
¡Cualquier consejo y ayuda sería muy apreciada!
Editar: Solo para aclarar. Mi gran problema es que los valores de FFT devueltos no tienen sentido sin una idea de lo que es la escala. ¿Alguien puede indicarme que trabaje en esa escala?
Edit2: Tengo muy buenos resultados en busca de la siguiente manera:
size_t count2 = 0;
size_t max2 = kFFTSize + 2;
while(count2 < max2)
{
const float realValue = buffer[(count2) + 0];
const float imagValue = buffer[(count2) + 1];
const float value = (log10f(sqrtf((realValue * realValue) + (imagValue * imagValue)) * rcpVerticalZoom) + 1.0f) * 0.5f;
buffer[count2 >> 1] = value;
count2 += 2;
}
Para mi ojo esto incluso se ve mejor que la mayoría de las otras implementaciones del espectrograma que he mirado.
¿Hay algo MAYORMENTE mal con lo que estoy haciendo?
Está haciendo lo correcto para obtener la magnitud del número complejo. Solo necesita averiguar la escala de estos números (complejos) (0-1, 0-255, ...), consulte los documentos de su función FFT para eso.Si el rango es demasiado grande para su gusto, tomar un registro() de la magnitud debería ayudar, como se sugiere a continuación. – Wim
Probablemente no sea importante para su uso, pero también podría normalizar los valores de dominio de frecuencia (es decir, los valores que obtiene de la FFT) dividiéndolos por el ancho de FFT. (es decir, cuanto más amplia sea su FFT, mayores serán los valores en los diferentes intervalos de frecuencia) –