tutorial the play objeto new examples abstracting javascript html5 webkit fft html5-audio

javascript - the - Interpretación de los resultados de la API de audio web FFT



web audio api play mp3 (3)

La Web Audio API tiene un nodo analizador que le permite obtener datos de FFT en el audio con el que está trabajando y tiene formas de byte y flotación de obtener los datos. La versión de bytes tiene un poco de sentido, devolviendo lo que parece un espectro de intensidad normalizado (dependiendo de los valores de decibeles máximo y mínimo) con 0 como componente del audio en una bandeja de frecuencia específica y 255 como máximo.

Pero me gustaría un poco más de detalle que 8 bits, sin embargo, usar la versión flotante da resultados extraños.

freqData = new Float32Array(analyser.frequencyBinCount); analyser.getFloatFrequencyData(freqData);

Esto me da valores entre -891.048828125 y 0. -891 aparece correspondiente al silencio, por lo que de alguna manera es el valor mínimo, mientras que supongo que 0 es equivalente al valor máximo.

¿Que esta pasando? ¿Por qué es -891.048828125 significativo en absoluto? ¿Por qué un gran negativo es el silencio y el cero es el máximo? ¿Estoy utilizando el FloatArray incorrecto o hay una configuración incorrecta? Float64 da 0 valores.


Como parece que no hay documentación sobre lo que realmente representan los datos, busqué en el código fuente relevante de webkit: RealtimeAnalyser.cpp

Respuesta corta : reste analyser.minDecibels de cada valor de Float32Array para obtener números positivos y multiplíquelos con (analyser.maxDecibels - analyser.minDecibels) para obtener una representación similar a la de getByteFrequencyData, solo con más resolución.

Respuesta larga :

Tanto getByteFrequencyData como getFloatFrequencyData le dan la magnitud en decibelios. Simplemente se escala de forma diferente y para getByteFrequencyData se resta una constante minDecibels:

Código relevante en webkit para getByteFrequencyData:

const double rangeScaleFactor = m_maxDecibels == m_minDecibels ? 1 : 1 / (m_maxDecibels - m_minDecibels); float linearValue = source[i]; double dbMag = !linearValue ? minDecibels : AudioUtilities::linearToDecibels(linearValue); // The range m_minDecibels to m_maxDecibels will be scaled to byte values from 0 to UCHAR_MAX. double scaledValue = UCHAR_MAX * (dbMag - minDecibels) * rangeScaleFactor;

Código relevante en webkit para getFloatFrequencyData:

float linearValue = source[i]; double dbMag = !linearValue ? minDecibels : AudioUtilities::linearToDecibels(linearValue); destination[i] = float(dbMag);

Entonces, para obtener valores positivos, simplemente puede restar minDecibels usted mismo, que está expuesto en el nodo del analizador :

//The minimum power value in the scaling range for the FFT analysis data for conversion to unsigned byte values. attribute double minDecibels;

Otro detalle es que, de forma predeterminada, el nodo del analizador realiza el suavizado de tiempo, que se puede desactivar estableciendo smoothingTimeConstant en cero.

Los valores por defecto en webkit son:

const double RealtimeAnalyser::DefaultSmoothingTimeConstant = 0.8; const double RealtimeAnalyser::DefaultMinDecibels = -100; const double RealtimeAnalyser::DefaultMaxDecibels = -30;

Lamentablemente, a pesar de que el nodo analizador computa un pie complejo, no da acceso a las representaciones complejas, solo las magnitudes de este.


Corrija en ambos puntos en la respuesta anterior y en los comentarios: los números están en decibelios, por lo que 0 es el máximo y el infinito es el mínimo (silencio absoluto). -891.0 ... es, creo, solo una rareza de conversión de punto flotante.


Tienes razón al usar un Float32Array. Encontré un interesante tutorial sobre el uso de la API de datos de audio, que, si bien es diferente de la API de audio de la web, me dio una idea útil sobre lo que está intentando hacer here . Eché un vistazo rápido para ver por qué los números son negativos y no noté nada obvio, pero me pregunté si estos números podrían estar en decibelios, dB , que comúnmente se dan en números negativos, y cero es el pico. El único problema con esa teoría es que -891 parece ser un número realmente pequeño para dB.