link body attribute javascript html5-canvas html5-audio web-audio requestanimationframe

javascript - body - meta html



Calcular el suavizadoTimeConstant de AnalyserNode (1)

Según mi lectura de la especificación, creo que lo descubrirías así:

var val = 255 , smooth = 0.6 , sampl = 48000 , i = 0 , ms; for ( ; val > 0.001; i++ ){ val = ( val + val * smooth ) / 2; } ms = ( i / sampl * 1000 );

El problema es que con este tipo de promediado, nunca se llega a cero, por lo que la condición de bucle es algo arbitraria. Puede hacer que ese número sea más pequeño y, como era de esperar, el valor de ms aumenta.

De todos modos, podría estar completamente fuera de base aquí. Pero una mirada rápida a través del código fuente actual de Chromium parece confirmar que así es como funciona. Aunque seré el primero en admitir que mi C ++ es bastante malo.

Estoy usando Web Audio API para mostrar una visualización del audio que se está reproduciendo. Tengo un elemento <audio> que controla la reproducción, luego lo conecto a la API de Web Audio con la creación de un nodo MediaElementSource del elemento <audio> . Luego se conecta a un GainNode y un AnalyserNode . El AnalyserNode de AnalyserNode se establece en 0.6 . El GainNode se conecta luego al AudioContext.destination .

Luego llamo a mi función de procesamiento de audio: onAudioProcess() . Esa función se llamará continuamente usando:

audioAnimation = requestAnimationFrame(onAudioProcess);

La función usa AnalyserNode para getByteFrequencyData del audio, luego realiza un bucle a través del Uint8Array (ahora poblado) y dibuja cada magnitud de frecuencia en el contexto 2d del elemento <canvas> . Todo esto funciona bien

Mi problema es que cuando pausas el elemento <audio> , mi función onAudioProcess continúa en bucle (solicitando cuadros de animación en sí mismo) que onAudioProcess innecesariamente ciclos de CPU. Puedo cancelAnimationFrame(audioAnimation) pero eso deja las últimas frecuencias dibujadas en el lienzo. Puedo resolverlo llamando también a clearRect en el clearRect contexto del lienzo, pero parece muy extraño en comparación con simplemente dejar que el bucle de procesamiento de audio continúe (lo que reduce lentamente cada barra a la parte inferior del lienzo debido a smoothingTimeConstant ).

Entonces, lo que terminé haciendo fue establecer un tiempo de espera cuando el <audio> está en pausa, antes de cancelar el cuadro de la animación. Al hacer esto, pude ahorrar ciclos de CPU cuando no se estaba reproduciendo audio Y aún pude mantener la bajada suave de las barras de frecuencia dibujadas en el <canvas> .

MI PREGUNTA: ¿Cómo puedo calcular con precisión el número de milisegundos que tarda una magnitud de frecuencia de 255 para golpear 0 (el rango es 0-255) en función del valor smoothingTimeConstant del AnalyserNode para que pueda establecer correctamente el tiempo de espera para cancelar el marco de animación?