In questo tutorial esamineremo da vicino gli elementi fondamentali di Web Audio che sono utilizzati per costruire paesaggi sonori 3D per applicazioni interattive coinvolgenti inclusi, ma non limitati a, i giochi 3D.
Le API Web Audio e la terminologia che utilizza a volte possono confondere, ma questo tutorial mira a rimuovere la complessità e fornire una spiegazione più semplice degli elementi Web Audio e di come lavorano insieme per formare un soundscape 3D.
Questa dimostrazione contiene tre suoni che ruotano attorno a a ascoltatore, la direzione dell'ascoltatore è indicata dalla freccia. Se immagini di guardare in basso un personaggio del gioco (l'ascoltatore), i suoni rotanti potrebbero facilmente rappresentare amici o nemici che circondano il personaggio.
Il codice sorgente e le risorse di dimostrazione sono allegati a questo tutorial.
Il AudioContext
l'interfaccia è il cuore e l'anima di Web Audio, fornisce le funzioni necessarie per creare vari elementi Web Audio e fornisce un modo per inviare tutto l'audio all'hardware e in avanti agli altoparlanti o alle cuffie di qualcuno.
var audioContext = null if (window.AudioContext! == undefined) audioContext = new AudioContext ()
È importante assicurarsi che il AudioContext
l'interfaccia è disponibile perché Web Audio è ancora abbastanza nuovo e potrebbe non essere disponibile in alcuni browser web.
Oltre a fornire le funzioni necessarie per creare vari elementi Web Audio, il AudioContext
l'interfaccia ha due importanti proprietà; destinazione
e ascoltatore
che sono entrambi di sola lettura. Il destinazione
la proprietà può essere pensata come la connessione all'hardware audio, è dove finirà tutto l'audio generato. Il ascoltatore
proprietà (lo vedremo più avanti in dettaglio) rappresenta il cosa che sta ascoltando tutto l'audio, ad es. un personaggio, o più precisamente una macchina fotografica, in un gioco.
Il AudioBuffer
e AudioBufferSourceNode
le interfacce ci permettono di riprodurre l'audio. AudioBuffer
gli oggetti contengono l'audio non elaborato (campioni sonori) che vengono ritoccati, scricchiolanti e schiacciati mentre si fanno strada attraverso Web Audio prima di raggiungere gli altoparlanti o le cuffie di qualcuno. AudioBufferSourceNode
gli oggetti sono utilizzati per avviare e interrompere l'audio contenuto in AudioBuffer
oggetti.
Il modo standard per caricare l'audio in un file AudioBuffer
l'oggetto è usare a XMLHttpRequest
oggetto con il suo responseType
impostato ArrayBuffer
. Quando il file audio è stato caricato, il buffer dell'array viene quindi inviato a AudioContext
oggetto di decodifica e, se la decodifica ha esito positivo, ci verrà fornito un AudioBuffer
oggetto.
var loader = new XMLHttpRequest () loader.open ("GET", "massive-explosion.ogg") loader.responseType = "arraybuffer" loader.onload = whenLoaded funzione loader.send () whenLoaded (event) var data = loader .response if (data === null) // Si è verificato un problema durante il caricamento del file. return // Decodifica i dati. audioContext.decodeAudioData (data, whenDecoded) function whenDecoded (audioBuffer) // "audioBuffer" è un oggetto AudioBuffer.
Il decodeAudioData ()
la funzione ha anche un terzo parametro che accetta un secondo callback, che viene richiamato quando il file audio caricato non può essere decodificato.
decodeAudioData (data, whenDecoded, whenFailed)
Non tutti i browser Web supportano gli stessi formati audio, una buona tabella di formati supportati può essere trovata qui, quindi potresti voler usare il secondo callback per fallback su un formato audio alternativo se necessario. Ad esempio, Internet Explorer non supporta OGG Vorbis ma supporta MP3. L'unico vero problema con l'MP3 è che non consente l'audio in loop continuo come fa OGG Vorbis.
Quando hai un AudioBuffer
oggetto disponibile puoi giocarlo usando un AudioBufferSourceNode
oggetto.
var source = audioContext.createBufferSource () // Allegare un oggetto AudioBuffer. source.buffer = audioBuffer // Connetti l'oggetto "sorgente" all'oggetto "destinazione". source.connect (audioContext.destination) // Facoltativamente, dire a "source" di eseguire continuamente il loop dell'audio. source.loop = false // Avvia l'audio. source.start ()
È importante ricordare AudioBufferSourceNode
gli oggetti sono lettori audio a scatto singolo, in altre parole è possibile utilizzare solo il inizio()
funzione una volta. Dovrai creare un AudioBufferSourceNode
oggetto e collegarlo (direttamente o indirettamente) al destinazione
oggetto esposto dal AudioContext
oggetto ogni volta che si desidera riprodurre l'audio da un AudioBuffer
oggetto.
Potresti rendere la vita un po 'più semplice creando una piccola funzione di utilità che crea, connette e avvia un AudioBufferSourceNode
oggetto per te.
funzione play (audioBuffer, audioContext) var source = audioContext.createSourceBuffer () source.buffer = audioBuffer source.connect (audioContext.destination) source.start () play (audioBuffer01, audioContext) play (audioBuffer02, audioContext) play (audioBuffer03) , audioContext)
Quando un AudioBufferSourceCode
Finisce l'esecuzione di oggetti, e se non si hanno riferimenti all'oggetto da nessuna parte (ad esempio non li si ha memorizzati in una matrice), Web Audio scollegherà automaticamente l'oggetto automaticamente. Ciò è estremamente utile quando hai solo bisogno di accendere e dimenticare effetti sonori brevi ecc.
Se decidi di effettuare il loop dell'audio, usa il AudioBufferSourceNode
ciclo continuo
proprietà, sarà necessario mantenere un riferimento al AudioBufferSourceNode
oggetto da qualche parte così puoi Stop()
la riproduzione audio.
source.stop ()
Quindi, a questo punto, utilizziamo i buffer per riprodurre l'audio, ma l'audio viene riprodotto direttamente senza alcuna panoramica o spazializzazione applicata. Qui è dove PannerNode
gli oggetti entrano in gioco.
PannerNode
oggetti ci permettono di posizionare l'audio nello spazio 3D, all'interno di un sistema di coordinate cartesiane. Questo è dove la maggior parte della magia 3D accade.
UN PannerNode
object ha alcune proprietà che ci permettono di mettere a punto il comportamento dell'audio ma per questo tutorial ci interessano solo due di esse; maxDistance
e panningModel
. Il maxDistance
la proprietà è la distanza dal ascoltatore a quel punto il volume dell'audio sarà zero. Questo è un valore arbitrario e avrà solo un significato all'interno dell'applicazione, ma per impostazione predefinita è 10000. Il panningModel
dice a Web Audio come elaborare l'audio che passa attraverso a PannerNode
oggetto. Per i paesaggi sonori 3D probabilmente vorrai impostare il valore su HRTF
(funzione di trasferimento relativa alla testa).
Per impostare la posizione di a AudioBufferSourceNode
noi usiamo il setPosition ()
funzione esposta da a PannerNode
oggetto.
var panner = audioContext.createPanner () panner.panningModel = "HRTF" // Imposta la posizione 3D (x, y, z). panner.setPosition (1, 2, 3) // Connette l'oggetto "sorgente" all'oggetto "panner". source.connect (panner) // Connette l'oggetto "panner" all'oggetto "destinazione". panner.connect (audioContext.destination) // Avvia l'audio. source.start ()
Per rendere le cose un po 'più chiare, aggiorniamo la funzione di utilità che abbiamo creato in precedenza.
funzione play (audioBuffer, x, y, z, audioContext) var source = audioContext.createSourceBuffer () source.buffer = audioBuffer var panner = audioContext.createPanner () panner.panningModel = "HRTF" panner.setPosition (x, y, z) source.connect (panner) panner.connect (audioContext.destination) source.start () play (audioBuffer01, 1, 2, 3, audioContext) play (audioBuffer02, 4, 5, 6, audioContext) play (audioBuffer03, 7, 8, 9, audioContext)
A questo punto stiamo riproducendo audio e posizionandolo nello spazio 3D, ma c'è un altro elemento importante che dobbiamo guardare; l'ascoltatore audio.
Ogni AudioContext
l'oggetto espone a ascoltatore
oggetto che rappresenta la posizione e l'orientamento del cosa sta ascoltando l'audio. Di solito il cosa sarebbe una macchina fotografica virtuale attaccata alla testa di un personaggio del gioco, il paraurti di un'auto, la coda di un aereo o qualsiasi altra cosa che abbia senso per lo spettatore dal loro punto di vista.
Il ascoltatore
l'oggetto ha un setPosition ()
funzione e a setOrientation ()
funzione. Il setPosition ()
funzione pone l'ascoltatore da qualche parte all'interno dello spazio 3D, e il setOrientation ()
ruota l'ascoltatore (immagina una telecamera panoramica e inclinazione).
Il setPosition ()
la funzione funziona esattamente allo stesso modo di PannerNode
setPosition ()
funzione e accetta tre coordinate.
audioContext.listener.setPosition (x, y, z)
Il setOrientation ()
la funzione è un po 'più complessa, accetta due vettori di unità. Il primo vettore rappresenta la rotazione dell'ascoltatore (la direzione verso cui punta la telecamera) e il secondo vettore rappresenta quello dell'ascoltatore su direzione (indica la parte superiore della telecamera).
audioContext.listener.setOrientation (x1, y1, z1, x2, y2, z2)
Se hai solo bisogno di ruotare l'ascoltatore attorno ad un asse, i calcoli vettoriali sono relativamente semplici. Ad esempio, se si utilizza lo stesso sistema di coordinate utilizzato da WebGL dove positivo X
punta a destra dello schermo, positivo y
punta alla parte superiore dello schermo e positivo z
punta fuori dallo schermo, quindi puoi ruotare l'ascoltatore attorno al y
asse (pan the camera) usando uno cos ()
chiamata di funzione e uno peccato()
chiamata di funzione.
// La posizione dell'ascoltatore (potrebbe essere qualsiasi cosa). var x = 50 var y = 100 var z = 0 audioContext.listener.setPosition (x, y, z) // Calcola il vettore di rotazione. // rad = rotazione, in radianti var rad = 0.10 var v1 = Math.cos (rad) // x var v2 = 0 // y var v3 = Math.sin (rad) // z // Il vettore "su" var v4 = 0 // x var v5 = 1 // y var v6 = 0 // z audioContext.listener.setOrientation (v1, v2, v3, v4, v5, v6)
La dimostrazione per questo tutorial (il codice sorgente è allegato) fa una cosa simile e ruota il PannerNode
oggetti attorno a un singolo asse.
In questo tutorial abbiamo dato uno sguardo agli elementi fondamentali di Web Audio che sono usati per costruire paesaggi sonori 3D per applicazioni interattive coinvolgenti inclusi, ma non limitati a, giochi 3D. Speriamo che questo tutorial ti sia stato utile e ti ha fornito informazioni sufficienti per capire come i buffer audio, i panner e gli ascoltatori lavorano insieme per produrre paesaggi sonori 3D.
Se avete commenti o domande non esitate a postare un commento qui sotto.
Nel prossimo tutorial, Web Audio e paesaggi sonori 3D: Implementazione, prenderemo tutto quanto sopra (e altro) e avvolgerlo in un'API semplificata. L'obiettivo principale del prossimo tutorial saranno i giochi 3D, ma l'API sarà abbastanza generica da poter essere utilizzata in varie applicazioni interattive immersive.