Domande frequenti su Web Audio

Boris Smus

Negli ultimi mesi, l'API Web Audio di WebKit si è affermata come una piattaforma convincente per giochi e applicazioni audio sul web. Man mano che gli sviluppatori si familiarizzano con questa funzionalità, ricevo spesso domande simili. Questo breve aggiornamento è un tentativo di rispondere ad alcune delle domande più frequenti per rendere più piacevole la tua esperienza con l'API Web Audio.

D: Aiutami, non riesco a sentire i suoni.

R: se non hai mai utilizzato l'API Web Audio, consulta il tutorial introduttivo o la ricetta di Eric per la riproduzione di audio in base all'interazione dell'utente.

D. Quanti contesti audio devo avere?

A: in genere, devi includere un AudioContext per pagina e un singolo contesto audio può supportare molti nodi collegati. Sebbene sia possibile includere più AudioContext in una singola pagina, questa operazione 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, un nodo di origine non può più riprodurre. Per riprodurre di nuovo il buffer sottostante, devi creare un nuovo AudioBufferSourceNode e chiamare noteOn().

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

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

R: L'idea di questa architettura è disaccoppiare l'asset audio dallo stato di riproduzione. Facendo un paragone con un giradischi, i buffer sono simili ai dischi e le sorgenti alle testine di lettura. Poiché molte applicazioni richiedono 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, funzionerà approssimativamente come segue (aggiungendo un effetto filtro a un sample 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(), poiché il tag audio controlla la riproduzione.

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

R: la parte di input audio verrà implementata nell'ambito di WebRTC utilizzando getUserMedia e sarà disponibile come nodo sorgente speciale nell'API Web Audio. Funziona 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 Inizia a utilizzare l'API Web Audio è un esempio di questo approccio 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 l'interfaccia utente non risponde. Aiuto!**

R: utilizza l'API decodeAudioData per il caricamento asincrono per evitare di bloccare il thread principale. Guarda questo esempio.

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

R: Sì, è in corso la ricerca di 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 passa in background, i suoni diventano strani.

R: probabilmente perché utilizzi setTimeouts, che si comporta in modo diverso se la pagina è in background. In futuro, l'API Web Audio potrà eseguire il callback in momenti specifici utilizzando il timer interno di Web Audio (attributo context.currentTime). Per ulteriori informazioni, 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 faccio a modificare l'altezza di un suono utilizzando l'API Web Audio?

A: Modifica playbackRate sul nodo di origine.

D: Posso modificare l'intonazione senza modificare la velocità?

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

  • Algoritmi nel dominio del tempo, che causano artefatti di eco del segmento ripetuti.
  • Tecniche nel dominio di 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 potrebbe essere un buon punto di partenza.

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

R: al momento non è disponibile il supporto per questa operazione, ma stiamo esaminando la questione. Consulta questa richiesta di funzionalità.

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