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.

Interpretación inexacta de FFT de audio en tiempo real con Python.

Estoy tratando de usar Python para crear una visualización de música en tiempo real. Las bibliotecas que estoy utilizando son SoundCard (para la captura de audio en vivo) y Librosa (para la transformada de Fourier en tiempo corto).

Sin embargo, sospecho que no estoy interpretando correctamente los datos de audio. Al observar el rango de frecuencia de 100Hz a 200Hz, obtengo un flujo constante de sonido incluso cuando la canción no contiene tanto bajo (o en realidad, ninguno en absoluto). Admito que estoy un poco por encima de mi nivel con todo el procesamiento de audio y la transformada de Fourier, ya que no es realmente mi especialidad y las matemáticas me confunden la mayor parte del tiempo.

Esta es la función que captura y analiza el audio. “Ib” está configurado en los altavoces y funciona correctamente. “Fs” está configurado en 48000 y grabo 1000 cuadros en un intento de mantener 48FPS. “fftwindowsize” está configurado en 2048*8 porque… no estoy seguro. Aumenté el número hasta que Librosa dejó de mostrar advertencias.

def audioanalysis():
    with lb.recorder(samplerate=Fs) as mic:
        rawdata = mic.record(numframes=1000)
        datalen: int = int(rawdata.size/2)
        monodata = numpy.empty(datalen)
        for x in range(0, datalen):
            monodata[x] = max(rawdata[x][0], rawdata[x][1])
        data = numpy.abs(librosa.stft(monodata, n_fft=fftwindowsize, hop_length=1024))
        return librosa.amplitude_to_db(data, ref=numpy.max)

Y el código para crear los “buckets”:

frequencies = librosa.core.fft_frequencies(n_fft=fftwindowsize)
freq_index_ratio = len(frequencies)/frequencies[len(frequencies)-1] / 2

[...]

for i in range(0, buckets):
            avg = 0
            for j in range (i * bucketsize, (i+1)*bucketsize):
                avg += amp(spectrogram=spectrogram, freq=j)
            amps[i] = avg/bucketsize

def amp(spectrogram, freq) -> float:
    return spectrogram[int(freq*freq_index_ratio)]

A lo largo de una canción, amps[1] (es decir, de 100Hz a 200Hz) permanece en el rango de -50dB a -30dB, lo cual no es realmente útil ni representativo de la canción que se está reproduciendo.

¿Está mal mi análisis de la transformada de Fourier? ¿No hay forma de interpretar de manera más precisa muestras cortas de sonido?

P.D. Sé que mi código en Python no es excelente. Este es mi primer proyecto en Python 🙂

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema podría estar en el paso de análisis de frecuencia de tu código. Específicamente, cuando calculas la amplitud de un bin de frecuencia dado utilizando la función amp, estás utilizando la entrada spectrogram y la entrada freq para seleccionar un índice específico en el array spectrogram. Sin embargo, parece que estás utilizando freq_index_ratio para realizar esta selección, lo cual no te dará el índice correcto para la frecuencia en la que estás interesado.

    En lugar de utilizar freq_index_ratio, prueba utilizando la función librosa.core.fft_frequencies para obtener el índice de frecuencia correcto para una frecuencia dada. Por ejemplo, podrías modificar la función amp de la siguiente manera:

    def amp(spectrogram, freq):
        freq_bins = librosa.core.fft_frequencies(n_fft=spectrogram.shape[0])
        freq_index = (numpy.abs(freq_bins - freq)).argmin()
        return numpy.mean(spectrogram[freq_index])
    

    Esto encontrará el bin de frecuencia más cercano a la frecuencia deseada, en lugar de utilizar una aproximación como freq_index_ratio.

    Además, puede que quieras considerar el uso de un tamaño de ventana más largo para la STFT (por ejemplo, 4096 o 8192) para obtener una mejor resolución de frecuencia. Esto te permitirá capturar con mayor precisión el contenido de baja frecuencia de la señal de audio, que podría ser la causa de la corriente constante de sonido a 100-200 Hz que estás observando.

    Finalmente, ten en cuenta que incluso con el mejor procesamiento posible, crear una visualización de música “en vivo” puede ser desafiante debido a la complejidad inherente y la variabilidad de la música. Es posible que algunas canciones simplemente no se presten bien a la visualización, independientemente de las técnicas de análisis utilizadas.

Comments are closed.