Domande frequenti su Web Audio

Boris Smus

Negli ultimi mesi, l'API Web Audio di WebKit si è affermata come piattaforma interessante per giochi e applicazioni audio sul web. Man mano che gli sviluppatori acquisiscono familiarità con lo strumento, sento ripetutamente le stesse domande. Questo rapido aggiornamento ha lo scopo di rispondere ad alcune delle domande più frequenti per rendere più piacevole la tua esperienza con l'API Web Audio.

D: Aiuto, non riesco a emettere suoni.

R: Se non hai mai utilizzato l'API Web Audio, dai un'occhiata al tutorial introduttivo o alla ricetta di Eric per riprodurre audio in base all'interazione dell'utente.

D. Quanti contesti audio dovrei avere?

R. In genere, dovresti includere un solo AudioContext per pagina e un singolo contesto audio può supportare molti nodi collegati. Anche se puoi includere più AudioContext in una singola pagina, ciò può comportare un calo delle prestazioni.

D: Ho un AudioBufferSourceNode che ho appena riprodotto con noteOn() e voglio riprodurlo di nuovo, ma noteOn() non fa nulla. Aiuto!

R. Una volta terminata la riproduzione di un nodo di origine, non è possibile riprodurne altri. Per riprodurre di nuovo il buffer sottostante, devi creare un nuovo AudioBufferSourceNode e chiamare noteOn().

Anche se la ricreazione del nodo di origine può sembrare inefficiente, i nodi di origine sono fortemente ottimizzati per questo pattern. Inoltre, se mantieni un handle per AudioBuffer, non devi effettuare un'altra richiesta all'asset per riprodurre di nuovo lo stesso suono. Se ti accorgi di dover ripetere questo pattern, incapsula la riproduzione con una semplice funzione helper come playSound(buffer).

D: Durante la riproduzione di un suono, perché è necessario creare un nuovo nodo di origine ogni volta?

R: L'idea di questa architettura è di separare l'asset audio dallo stato di riproduzione. Prendendo come esempio un giradischi, i buffer sono analoghi ai dischi e le sorgenti alle testine di riproduzione. Poiché molte applicazioni prevedono la riproduzione simultanea di più versioni dello stesso buffer, questo pattern è essenziale.

D: Come posso elaborare l'audio dai tag audio e video?

R: MediaElementAudioSourceNode è in fase di sviluppo. Se disponibile, funzionerà all'incirca come segue (aggiungendo un effetto filtro a un campione riprodotto tramite il tag audio):

<audio src="sounds/sample.wav" controls>
var audioElement = document.querySelector('audio');
var mediaSourceNode = context.createMediaElementSource(audioElement);
mediaSourceNode.connect(filter);
filter.connect(context.destination);

Questa funzionalità è monitorata in questo crbug. Tieni presente che in questa configurazione non è necessario chiamare mediaSourceNode.noteOn(), in quanto la riproduzione è controllata dal tag audio.

D: Quando posso ottenere l'audio da un microfono?

R. La parte di input audio verrà implementata come parte di WebRTC utilizzando getUserMedia e sarà disponibile come nodo di origine speciale nell'API Web Audio. Funzionerà in combinazione con createMediaElementSource.

D: Come faccio a controllare quando la riproduzione di un AudioSourceNode è terminata?

R: Al momento devi utilizzare un timer JavaScript perché l'API Web Audio non supporta questa funzionalità. Il seguente snippet del tutorial Introduzione all'API Web Audio è un esempio di questo in azione:

// Assume source and buffer are previously defined.
source.noteOn(0);
var timer = setTimeout(function() {
    console.log('playback finished');
}, buffer.duration * 1000);

Esiste un bug aperto per fare in modo che l'API Web Audio implementi un callback più preciso.

D: Il caricamento dei suoni causa il blocco dell'intero thread dell'interfaccia utente e la mia UI non risponde. Aiuto!**

R. Utilizza l'API decodeAudioData per il caricamento asincrono per evitare di bloccare il thread principale. Vedi questo esempio.

D: L'API Web Audio può essere utilizzata per elaborare i suoni più velocemente del tempo reale?

R: Sì, stiamo lavorando a una soluzione. Resta in attesa di ulteriori aggiornamenti.

D. Ho creato un'applicazione API Web Audio fantastica, ma ogni volta che la scheda in cui è in esecuzione va in background, i suoni diventano strani.

R: Probabilmente perché utilizzi setTimeouts, che si comportano in modo diverso se la pagina viene eseguita in background. In futuro, l'API Web Audio sarà in grado di richiamare callback in momenti specifici utilizzando il timer interno di Web Audio (attributo context.currentTime). Per saperne di più, consulta questa richiesta di funzionalità.

In generale, potrebbe essere una buona idea interrompere la riproduzione quando l'app passa in background. Puoi rilevare quando una pagina passa in background utilizzando l'API Page Visibility.

D: Come posso modificare l'intonazione di un suono utilizzando l'API Web Audio?

R. Modifica playbackRate nel nodo di origine.

D: Posso modificare il tono senza modificare la velocità?

R: L'API Web Audio potrebbe avere un PitchNode nel contesto audio, ma è difficile da implementare. Questo perché nella community audio non esiste un algoritmo di trasposizione semplice. Le tecniche note creano artefatti, soprattutto nei casi in cui la variazione di intonazione è elevata. Esistono due tipi di approcci per affrontare questo problema:

  • Algoritmi del dominio del tempo, che causano artefatti di eco dei segmenti ripetuti.
  • Tecniche del dominio della frequenza, che causano artefatti sonori riverberanti.

Sebbene non esista un nodo nativo per eseguire queste tecniche, puoi farlo con un JavaScriptAudioNode. Questo snippet di codice può fungere da punto di partenza.

D: Come faccio a creare un AudioContext a una frequenza di campionamento a mia scelta?

R: Al momento non è supportata, ma stiamo esaminando la questione. Consulta questa richiesta di funzionalità.

Se hai altre domande, non esitare a porle su Stack Overflow utilizzando il tag web-audio.