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 la funzionalità di chaining 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.