Domande frequenti su Web Audio

Boris Smus

Negli ultimi mesi, l'API Web Audio di WebKit si è rivelata un'interessante piattaforma per giochi e applicazioni audio sul web. Man mano che gli sviluppatori si familiarizzano con questo strumento, sento che si fanno ripetutamente domande simili. Questo rapido aggiornamento tenta di rispondere ad alcune delle domande più frequenti per rendere più piacevole la tua esperienza con l'API Web Audio.

D: Aiuto, non posso emettere suoni!

R: Se è la prima volta che utilizzi l'API Web Audio, dai un'occhiata al tutorial introduttivo o alla ricetta di Eric per riprodurre l'audio in base all'interazione utente.

D. Quanti contesti audio dovrei avere?

R: In genere, devi includere un AudioContext per pagina e un singolo contesto audio può supportare più nodi collegati. Anche se puoi includere più AudioContext in una singola pagina, ciò può portare a un calo delle prestazioni.

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

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

Sebbene ricreare il nodo di origine possa sembrare inefficiente, i nodi di origine sono fortemente ottimizzati per questo pattern. Inoltre, se mantieni un handle nell'AudioBuffer, non dovrai inviare un'altra richiesta alla risorsa per riprodurre di nuovo lo stesso suono. Se devi ripetere questo schema, racchiudi la riproduzione con una semplice funzione helper come playSound(buffer).

D: Quando riproduci un suono, perché devi creare un nuovo nodo di origine ogni volta?

R: L'idea di questa architettura è disaccoppiare l'asset audio dallo stato di riproduzione. Nell'analogia con i giradischi, i buffer sono analoghi ai record e alle sorgenti rispetto alle teste di riproduzione. Poiché molte applicazioni prevedono la riproduzione simultanea di più versioni dello stesso buffer, questo pattern è essenziale.

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

R: MediaElementAudioSourceNode è in fase di sviluppo. Se disponibile, funziona nel seguente modo (aggiunta di 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à viene monitorata in questo crbug. Tieni presente che in questa configurazione non è necessario chiamare mediaSourceNode.noteOn(), il tag audio controlla la riproduzione.

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

R. La parte dell'input audio sarà implementata come parte di WebRTC utilizzando getUserMedia e sarà disponibile come nodo di origine speciale nell'API Web Audio. Funziona insieme a createMediaElementSource.

D: Come faccio a controllare quando ha finito di giocare a AudioSourceNode?

R: Al momento devi utilizzare un timer JavaScript perché l'API Web Audio non supporta questa funzionalità. Lo snippet riportato di seguito del tutorial sull'API Web Audio ne è un esempio 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: Usa l'API decodeAudioData per il caricamento asincrono ed evitare di bloccare il thread principale. Vedi questo esempio.

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

R: Sì, stiamo lavorando a una soluzione. Ti terremo aggiornato!

D: Ho creato una fantastica applicazione API Web Audio, ma ogni volta che la scheda in cui è in esecuzione viene eseguita in background, i suoni diventano strani.

R: È probabile che tu stia utilizzando setTimeouts, che si comporta in modo diverso se la pagina viene riprodotta in background. In futuro, l'API Web Audio sarà in grado di richiamare a orari specifici utilizzando il timer interno dell'audio web (attributo context.currentTime). Per ulteriori informazioni, consulta questa richiesta di funzionalità.

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

D: Come faccio a cambiare la tonalità di un suono utilizzando l'API Web Audio?

R: Modifica playbackRate sul nodo di origine.

D: Posso cambiare il tono senza cambiare velocità?

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

  • algoritmi del dominio temporale, che causano artefatti eco ripetuti del segmento.
  • Tecniche con domini di frequenza, che causano artefatti del suono riverberante.

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

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

R: Al momento non c'è supporto per questa funzionalità, ma stiamo esaminando la tua richiesta. Consulta questa richiesta di funzionalità.

Se avete altre domande, non esitate a porle su StackOverflow utilizzando il tag web-audio.