Cambios de audio web en m36

Cristian Rodríguez
Chris Wilson

Cambios en el audio web

En Google, nos encantan los estándares. Nuestra misión es crear una plataforma web definida por estándares. Una de las pequeñas verrugas que hay durante un tiempo ha sido la implementación de la Web Audio API con el prefijo webkit (en particular, el objeto webkitAudioContext) y algunas de las partes obsoletas de Web Audio que seguimos admitiendo.

Originalmente, se planificó que Chrome 36 quitara la compatibilidad con el prefijo webkitAudioContext, ya que habíamos comenzado a admitir el objeto AudioContext sin prefijo. Esto resultó ser más problemático de lo esperado, por lo que Chrome 36 admite tanto los prefijos como los sin prefijo. Sin embargo, incluso en el nuevo webkitAudioContext, se quitaron varios métodos y atributos heredados, como createGainNode y createJavaScriptNode. En resumen, en Chrome 36, webkitAudioContext y AudioContext son alias entre sí. No hay diferencia en la funcionalidad entre ambos.

Después de Chrome 36, probablemente quitaremos la compatibilidad con el prefijo por completo después de Chrome 36, en algunas versiones. Haremos un anuncio aquí cuando el cambio sea inminente y seguimos comunicándonos con los autores para que corrijan sus aplicaciones de audio web.

¿Por qué hicimos esto en lugar de volver a la implementación anterior? Bueno, en parte, tuvimos que retroceder demasiado; ya quitamos esas API y, como efecto secundario agradable de esta asignación de alias, las aplicaciones pueden funcionar bien en Firefox, que nunca ha admitido un objeto AudioContext con prefijo (y bastante bien) en su compatibilidad para audio web que se lanzó inicialmente el otoño pasado.

El resto de esta actualización proporciona una guía para corregir los errores que podrían estar dañados en tu código debido a este cambio. Lo bueno de solucionar estos problemas es que es muy probable que el código también funcione en Firefox. (Durante mucho tiempo, pensé que mi aplicación de Vocoder estaba dañada debido a la implementación de Firefox, pero resultó ser uno de esos problemas).

Si quieres comenzar a usarla, te recomendamos que consultes la biblioteca monkey-patch que escribí para las aplicaciones que se escribieron en el código de audio web anterior. Esta información puede ayudarte a comenzar a utilizar el servicio en un período mínimo de tiempo, ya que asignará un alias a los objetos y métodos de manera adecuada. De hecho, los parches que enumera la biblioteca son una buena guía para los aspectos que cambiaron.

En primer lugar,

Todas las referencias a window.webkitAudioContext se deben hacer como window.AudioContext en su lugar. Con frecuencia, esto se corrige con el siguiente comando:

window.AudioContext = window.AudioContext || window.webkitAudioContext;

Si la app responde, por ejemplo, se muestra lo siguiente: "Lamentablemente, el navegador no admite Web Audio. Usa Chrome o Safari". Es muy probable que se busque explícitamente webkitAudioContext. Mal desarrollador. Podrías haber usado Firefox durante meses.

Sin embargo, hay otras eliminaciones de código más sutiles, algunas de las cuales pueden ser menos evidentes.

  • Las constantes de tipo enumeradas de BiquadFilter para el atributo .type (que ahora es una string) ya no aparecen en el objeto BiquadFilterNode y no las admitimos en el atributo .type. Por lo tanto, ya no usas .LOWPASS (o 0), sino que lo configuras como "lowpass".
  • Además, el atributo Oscillator.type ahora es un tipo enumerado de string de manera similar: ya no se usa .SAWTOOTH.
  • PannerNode.type ahora también es un tipo enumerado de string.
  • PannerNode.distanceModel ahora también es un tipo enumerado de string.
  • Se cambió el nombre de createGainNode por createGain
  • Se cambió el nombre de createDelayNode por createDelay
  • Se cambió el nombre de createJavaScriptNode por createScriptProcessor
  • Se reemplazó AudioBufferSourceNode.noteOn() por start()
  • Ahora también se reemplazó AudioBufferSourceNode.noteGrainOn() por start()
  • Se cambió el nombre de AudioBufferSourceNode.noteOff() por stop().
  • Se cambió el nombre de OscillatorNode.noteOn() por start().
  • Se cambió el nombre de OscillatorNode.noteOff() por stop().
  • Se cambió el nombre de AudioParam.setTargetValueAtTime() por setTargetAtTime().
  • AudioContext.createWaveTable() y OscillatorNode.setWaveTable() ahora se llaman createPeriodicWave() andsetPeriodicWave()`.
  • Se quitó AudioBufferSourceNode.looping y se reemplazó por .loop
  • Se quitó AudioContext.createBuffer(ArrayBuffer, boolean) para decodificar de forma síncrona un BLOB de datos de audio codificados. Las llamadas síncronas que tardan mucho tiempo en completarse son una práctica de programación deficiente. En su lugar, usa la llamada de decodeAudioData asíncrona. Este es uno de los cambios más desafiantes: en realidad hay que cambiar el flujo lógico, pero es una práctica mucho mejor. Ehsan Angkari de Mozilla escribió un buen ejemplo de cómo hacer esto en su publicación sobre la conversión al audio web estándar.

Muchos de estos elementos (como el cambio de nombre de createGainNode y la eliminación de la decodificación síncrona en createBuffer) se mostrarán como un error en la consola de herramientas para desarrolladores, pero otros, como este uso:

MULTI_LINE_CODE_PLACEHOLDER_1

no se mostrará y fallará silenciosamente (myFilterNode.BANDPASS ahora se resolverá como indefinido, y el intento de configurar .type como indefinido simplemente no producirá ningún efecto). Esto, por cierto, era la causa del fallo del vocoder). Del mismo modo, si asignas filter.type a un número que funciona, haz lo siguiente:

myFilterNode.type = 2;

Pero ahora, debes usar la enumeración de string:

myFilterNode.type = “bandpass”;

Por lo tanto, tal vez quieras usar grep en tu código para cumplir con las siguientes condiciones:

  • webkitAudioContext
  • .LOWPASS
  • .HIGHPASS
  • .BANDPASS
  • .LOWSHELF
  • .HIGHSHELF
  • .PEAKING
  • .NOTCH
  • .ALLPASS
  • .SINE
  • .SQUARE
  • .SAWTOOTH
  • .TRIANGLE
  • .noteOn
  • .noteGrainOn
  • .noteOff
  • .setWaveTable
  • .createWaveTable
  • .looping
  • .EQUALPOWER
  • .HRTF
  • .LINEAR
  • .INVERSE
  • .EXPONENTIAL
  • createGainNode
  • createDelayNode
  • .type (sí, esto tendrá muchos falsos positivos, pero es la única manera de captar el último ejemplo anterior)

Una vez más, si tienes prisa y quieres ponerte en marcha, simplemente haz una copia de mi biblioteca monkeypatch webkitAudioContext e inclúyela en tu aplicación. ¡Feliz hackeo de audio!