Chrome ha migliorato costantemente e silenziosamente il supporto dell'API Web Audio. In Chrome 49 (beta da febbraio 2016 e dovrebbe essere stabile a marzo 2016) abbiamo aggiornato diverse funzionalità per monitorare la specifica e abbiamo anche aggiunto un nuovo nodo.
decodeAudioData() ora restituisce una promessa
Il metodo
decodeAudioData()
su AudioContext
ora restituisce un Promise
, consentendo la gestione di pattern asincroni basati su promesse. Il metodo decodeAudioData()
ha sempre accettato come parametri le funzioni di callback di successo ed errore:
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 possa sembrare più verboso, le promesse semplificano e rendono più coerente la programmazione asincrona. Per motivi di compatibilità, le funzioni di callback Success e Error sono ancora supportate, come da specifica.
OfflineAudioContext ora supporta suspend() e resume()
A prima vista, potrebbe sembrare strano avere la chiamata suspend() su un OfflineAudioContext.
Dopotutto, suspend()
è stato aggiunto a AudioContext
per consentire di mettere l'hardware audio in modalità standby, il che sembra inutile negli scenari in cui esegui il rendering in un buffer (ovviamente, è lo scopo di OfflineAudioContext
).
Tuttavia, lo scopo di questa funzionalità è poter costruire solo una parte di un "punteggio" alla volta, per ridurre al minimo l'utilizzo della memoria. Puoi creare altri nodi mentre il rendering è sospeso.
Ad esempio, la Sonata al chiaro di luna di Beethoven contiene circa 6500 note.
È probabile che ogni "nota" venga decostruita in almeno un paio di nodi del grafico audio
(ad es. un AudioBuffer e un nodo Gain). Se vuoi eseguire il rendering dell'intero
minuto e mezzo in un buffer con OfflineAudioContext
, probabilmente
non vuoi creare tutti questi nodi contemporaneamente. In alternativa, puoi 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();
}
In questo modo, potrai ridurre al minimo il numero di nodi che devono essere pre-creati all'inizio del rendering e diminuire le richieste di memoria.
IIRFilterNode
La specifica ha aggiunto un nodo per gli audiofili che vogliono creare il proprio filtro a risposta infinita specificato con precisione: il IIRFilterNode.
Questo filtro completa il BiquadFilterNode, ma consente di specifiche complete
dei parametri di risposta del filtro (anziché l'intuitivo AudioParams
di BiquadFilterNode
per tipo, frequenza, Q e simili). IIRFilterNode
consente di specificare con precisione i filtri che non potevano essere creati in precedenza, come i filtri di ordine singolo. Tuttavia, l'utilizzo di IIRFilterNode richiede una conoscenza approfondita del funzionamento dei filtri IIR e non sono nemmeno pianificabili come BiquadFilterNode.
Modifiche precedenti
Voglio anche menzionare un paio di miglioramenti apportati in precedenza: in Chrome 48, l'automazione dei nodi BiquadFilter
ha iniziato a funzionare alla frequenza audio. L'API
non è cambiata per questo, ma significa che le scansioni dei filtri avranno un suono
ancora più fluido. Inoltre, in Chrome 48 abbiamo aggiunto il collegamento al metodo AudioNode.connect()
retornando il nodo a cui ci stiamo connettendo. In questo modo è più semplice creare catene di nodi, come in questo esempio:
sourceNode.connect(gainNode).connect(filterNode).connect(context.destination);
Per il momento è tutto. Continua a farti sentire.