es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo interpretar los datos FFT para crear un visualizador de espectro.

Estoy tratando de visualizar un espectro donde el rango de frecuencia se divide en N barras, ya sea de forma lineal o logarítmica. La FFT parece funcionar bien, pero no estoy seguro de cómo interpretar los valores para decidir la altura máxima de la visualización.
Estoy utilizando FMODAudio, un envoltorio para C#. Está configurado correctamente.

En el caso de un espectro lineal, las barras se definen de la siguiente manera:

public int InitializeSpectrum(int windowSize = 1024, int maxBars = 16)
{
    numSamplesPerBar_Linear.Clear();
    int barSamples = (windowSize / 2) / maxBars;

    for (int i = 0; i < maxBars; ++i)
    {
        numSamplesPerBar_Linear.Add(barSamples);
    }
    IsInitialized = true;
    Data = new float[numSamplesPerBar_Linear.Count];
    return numSamplesPerBar_Linear.Count;
}

Data es el arreglo que contiene los valores del espectro recibidos del bucle de actualización.

La actualización se ve así:

public unsafe void UpdateSpectrum(ref ParameterFFT* fftData)
{
    int length = fftData->Length / 2;
    if (length > 0)
    {
        int indexFFT = 0;
        for (int index = 0; index < numSamplesPerBar_Linear.Count; ++index)
        {
            for (int frec = 0; frec < numSamplesPerBar_Linear[index]; ++frec)
            {
                for (int channel = 0; channel < fftData->ChannelCount; ++channel)
                {
                    var floatspectrum = fftData->GetSpectrum(channel); // esto es un ReadOnlySpan<float> por defecto.
                    Data[index] += floatspectrum[indexFFT];
                }
                ++indexFFT;
            }

            Data[index] /= (float)(numSamplesPerBar_Linear[index] * fftData->ChannelCount); // promedio de ambos canales para obtener valores más significativos.
        }       
    }
}

Los valores que obtengo al probar una canción son muy bajos en todas las bandas.
Un momento elegido al azar al reproducir una canción da estos valores:
16 barras = 0,0326 0,0031 0,001 0,0003 0,0004 0,0003 0,0001 0,0002 0,0001 0,0001 0,0001 0 0 0 0 0

Me doy cuenta de que en muchos casos es más útil utilizar un espectro logarítmico, y tengo la intención de hacerlo, pero aún necesito saber cómo encontrar los valores máximos para cada barra para poder configurar la visualización en una escala adecuada.

P: ¿Cómo puedo conocer los valores máximos posibles para cada barra en función de esta configuración (que no es 1.0)?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para determinar el valor máximo de cada barra en el espectro lineal, necesitarías calcular el valor más alto posible para una barra específica, dado el número de muestras por barra y la tasa de muestreo. Esto se puede hacer utilizando la frecuencia de Nyquist, que es la mitad de la tasa de muestreo.

    Por ejemplo, si la tasa de muestreo es de 44.1 kHz y hay 16 barras, cada barra correspondería a un rango de frecuencia de 1378 Hz (21900 Hz / 16). Si cada barra contiene 64 muestras, entonces la resolución de frecuencia sería de aproximadamente 22 Hz (1378 Hz / 64). El valor máximo para una barra específica se puede calcular sumando las magnitudes de todos los coeficientes de la FFT dentro del rango de frecuencia correspondiente a esa barra y dividiendo por el número de muestras por barra.

    Ten en cuenta que los valores que estás obteniendo actualmente pueden ser bajos porque la señal de audio no está normalizada o puede haber otros factores que afecten los resultados. Puede que quieras normalizar la señal de audio para asegurar resultados consistentes.

Comments are closed.