Chrome ha migliorato in modo costante e discreto il supporto dell'API Web Audio. In Chrome 49 (beta a partire da febbraio 2016, che dovrebbe essere stabile a marzo 2016) abbiamo aggiornato diverse funzionalità per monitorare la specifica e abbiamo aggiunto un nuovo nodo.
decodeAudioData() ora restituisce una promessa
Il metodo decodeAudioData() su AudioContext
ora restituisce Promise
, consentendo la gestione asincrona dei pattern basata su Promise. Il metodo decodeAudioData()
ha sempre assunto funzioni di callback di successo ed errore come parametri:
context.decodeAudioData( arraybufferData, onSuccess, onError);
Ora però puoi utilizzare il metodo Promise standard per gestire la natura asincrona della decodifica dei dati audio:
context.decodeAudioData( arraybufferData ).then(
(buffer) => { /* store the buffer */ },
(reason) => { console.log("decode failed! " + reason) });
Sebbene in un singolo esempio sembri più dettagliato, Promises rende più semplice e coerente la programmazione asincrona. Per motivi di compatibilità, le funzioni di callback Successo ed Errore sono ancora supportate, in base alla specifica.
OfflineAudioContext ora supporta sospendi() e resume()
A prima vista, potrebbe sembrare strano l'uso della funzione Pause() in OfflineAudioContext.
Dopotutto, l'elemento suspend()
è stato aggiunto a AudioContext
per consentire l'attivazione della modalità standby dell'hardware audio, il che sembra inutile negli scenari in cui esegui il rendering in un buffer (il che è ovviamente OfflineAudioContext
).
Tuttavia, lo scopo di questa funzionalità è poter creare solo una parte di un "punteggio" alla volta, per ridurre al minimo l'utilizzo della memoria. Puoi creare più nodi
mentre la sospensione è in corso al centro di un rendering.
Ad esempio, la sonata al chiaro di luna di Beethoven contiene circa 6500 note.
Ogni "nota" probabilmente si scompone in almeno un paio di nodi di grafici audio
(ad es. un nodo AudioBuffer e Gain). Se volessi eseguire il rendering di tutti i sette minuti e mezzo in un buffer con OfflineAudioContext
, probabilmente non vorrai creare tutti quei nodi contemporaneamente. Puoi invece crearli in blocchi di tempo:
var context = new OfflineAudioContext(2, length, sampleRate);
scheduleNextBlock();
context.startRendering().then( (buffer) => { /* store the buffer */ } );
function scheduleNextBlock() {
// create any notes for the next blockSize number of seconds here
// ...
// make sure to tell the context to suspend again after this block;
context.suspend(context.currentTime + blockSize).then( scheduleNextBlock );
context.resume();
}
Ciò ti consentirà di ridurre al minimo il numero di nodi che devono essere precreati all'inizio del rendering e la richiesta di memoria.
IIRFilterNode
Le specifiche hanno aggiunto un nodo per gli audiofili che vogliono creare una propria risposta
infinita-impulse-response
esattamente specificata:
l'IIRFilterNode.
Questo filtro completa il BiquadFilterNode, ma consente la specifica completa
dei parametri di risposta del filtro (anziché l'AudioParams
facile da usare di BiquadFilterNode
per tipo, frequenza, Q e simili). IIRFilterNode
consente di specificare con precisione i filtri che non è stato possibile creare prima, come i filtri per ordine singolo. Tuttavia, l'utilizzo di IIRFilterNode richiede una conoscenza approfondita di come funzionano i filtri IIR e non sono pianificabili come BiquadFilterNodes.
Modifiche precedenti
Vorrei anche citare un paio di miglioramenti apportati in precedenza: in
Chrome 48, l'automazione dei nodi BiquadFilter
ha iniziato a funzionare alla velocità audio. L'API
non è cambiata per fare questo, ma questo significa che la ricerca dei filtri sarà ancora più fluida. Sempre in Chrome 48, abbiamo aggiunto il concatenamento al metodo AudioNode.connect()
restituendo il nodo a cui ci stiamo connettendo. Ciò semplifica la creazione di catene di nodi, come in questo esempio:
sourceNode.connect(gainNode).connect(filterNode).connect(context.destination);
Per il momento è tutto. Continua così!