Webaudio en 3D-soundscapes introductie

In deze tutorial zullen we de fundamentele Web Audio-elementen bekijken die worden gebruikt om 3D-soundscapes te construeren voor meeslepende interactieve toepassingen, inclusief maar niet beperkt tot, 3D-games.

De Web Audio API en de gebruikte terminologie kunnen soms verwarrend zijn, maar deze zelfstudie is bedoeld om de complexiteit weg te nemen en een eenvoudiger uitleg te geven van de Web Audio-elementen en hoe ze samenwerken om een ​​3D-soundscape te vormen.

Demonstratie

Deze demonstratie bevat drie geluiden die rond een draaien luisteraar, de richting van de luisteraar wordt aangegeven door de pijl. Als je je voorstelt neer te kijken op een gamekarakter (de luisteraar), zouden de roterende geluiden gemakkelijk vrienden of vijanden kunnen vertegenwoordigen die om het personage cirkelen.

De demonstratiebroncode en bronnen zijn aan deze zelfstudie gekoppeld.

AudioContext

De AudioContext interface is het hart en de ziel van Web Audio, het biedt de functies die nodig zijn om verschillende Web Audio-elementen te creëren en biedt een manier om alle audio naar hardware en verder naar iemands luidsprekers of koptelefoons te sturen.

var audioContext = null if (window.AudioContext! == undefined) audioContext = new AudioContext ()

Het is belangrijk om ervoor te zorgen dat de AudioContext interface is beschikbaar omdat Web Audio nog steeds vrij nieuw is en mogelijk niet beschikbaar in sommige webbrowsers.

Naast het bieden van de functies die nodig zijn om verschillende Web Audio-elementen te creëren, is de AudioContext interface heeft twee belangrijke eigenschappen; bestemming en luisteraar die beide alleen-lezen zijn. De bestemming eigenschap kan worden gezien als de verbinding met audio-hardware, het is waar alle gegenereerde audio uiteindelijk terecht zal komen. De luisteraar property (we zullen dit later gedetailleerder bekijken) vertegenwoordigt de ding dat is luisteren naar alle audio, b.v. een personage, of beter gezegd een camera, in een game.

buffers

De AudioBuffer en AudioBufferSourceNode interfaces stellen ons in staat om audio af te spelen. AudioBuffer objecten bevatten de onbewerkte audio (geluidsfragmenten) die worden geknepen, gemalen en verpletterd terwijl ze zich een weg banen door Web Audio voordat ze iemands luidsprekers of hoofdtelefoons bereiken. AudioBufferSourceNode objecten worden gebruikt om de audio te starten en te stoppen AudioBuffer voorwerpen.

De standaardmanier om audio in een te laden AudioBuffer object is om een ​​te gebruiken XMLHttpRequest object met zijn responseType ingesteld op arraybuffer. Wanneer het audiobestand is geladen, wordt de arraybuffer vervolgens verzonden naar de AudioContext object voor decodering en als de decodering succesvol is, krijgen we een AudioBuffer voorwerp.

var loader = nieuw XMLHttpRequest () loader.open ("GET", "massive-explosion.ogg") loader.responseType = "arraybuffer" loader.onload = whenLoaded loader.send () function whenLoaded (event) var data = loader .response if (data === null) // Er was een probleem bij het laden van het bestand. return // Decodeer de data. audioContext.decodeAudioData (data, whenDecoded) function whenDecoded (audioBuffer) // "audioBuffer" is een AudioBuffer-object. 

De decodeAudioData () functie heeft ook een derde parameter die een tweede callback accepteert, die callback wordt aangeroepen wanneer het geladen audiobestand niet kan worden gedecodeerd.

decodeAudioData (data, whenDecoded, whenFailed)

Niet alle webbrowsers ondersteunen dezelfde audioformaten, een goede tabel met ondersteunde indelingen is hier te vinden, dus misschien wilt u de tweede callback gebruiken om terug te vallen naar een alternatieve audioformaat als dat nodig is. Internet Explorer biedt bijvoorbeeld geen ondersteuning voor OGG Vorbis, maar ondersteunt wel MP3. Het enige echte probleem met MP3 is dat het geen naadloos geluide audio toestaat zoals OGG Vorbis dat doet.

Wanneer je een hebt AudioBuffer object beschikbaar, je kunt het spelen met een AudioBufferSourceNode voorwerp.

var source = audioContext.createBufferSource () // Voeg een AudioBuffer-object toe. source.buffer = audioBuffer // Verbind het "bron" -object met het "doel" -object. source.connect (audioContext.destination) // Zeg desgewenst "source" om de audio continu te herhalen. source.loop = false // Start de audio. source.start ()

Het is belangrijk om te onthouden AudioBufferSourceNode objecten zijn single-shot audiospelers, met andere woorden, u kunt alleen de begin() eenmaal functioneren. U moet een maken AudioBufferSourceNode object en verbind het (direct of indirect) met de bestemming object belicht door de AudioContext object wanneer u audio van een wilt afspelen AudioBuffer voorwerp.

U kunt het leven een beetje eenvoudiger maken door een kleine hulpprogramma-functie te maken waarmee u een maakt, verbindt en start AudioBufferSourceNode object voor jou.

function play (audioBuffer, audioContext) var source = audioContext.createSourceBuffer () source.buffer = audioBuffer source.connect (audioContext.destination) source.start () afspelen (audioBuffer01, audioContext) afspelen (audioBuffer02, audioContext) afspelen (audioBuffer03 , audioContext)

Wanneer een AudioBufferSourceCode het object is voltooid en als u nergens verwijzingen naar het object hebt (deze hebt u bijvoorbeeld niet in een array opgeslagen), wordt het object automatisch door Web Audio afgekoppeld. Dit is uitermate handig wanneer u alleen korte geluidseffecten, enz., Hoeft aan te vuren en te vergeten.

Als u besluit de audio af te spelen, gebruikt u de AudioBufferSourceNode lus eigendom, moet u een verwijzing naar de AudioBufferSourceNode object ergens, zodat je kunt hou op() het afspelen van audio.

source.stop ()

Dus op dit punt gebruiken we buffers om audio af te spelen, maar de audio wordt direct afgespeeld zonder dat er panning of spatialisatie op wordt toegepast. Dit is waar PannerNode voorwerpen komen om de hoek kijken.

  • W3C AudioBuffer-specificatie.
  • W3C AudioBufferSourceNode-specificatie.

panners

PannerNode Met objecten kunnen we audio in 3D-ruimte positioneren, in een cartesisch coördinatensysteem. Dit is waar de meeste 3D-magie gebeurt.

EEN PannerNode object heeft nogal wat eigenschappen die ons in staat stellen om het gedrag van de audio te verfijnen, maar voor deze tutorial zijn we alleen geïnteresseerd in twee van hen; maxDistance en panningModel. De maxDistance eigendom is de afstand tot de luisteraar op welk punt het geluidsvolume nul zal zijn. Dit is een willekeurige waarde en heeft alleen betekenis binnen uw applicatie, maar het is standaard 10000. Het panningModel vertelt Web Audio hoe de audio wordt verwerkt die door a gaat PannerNode voorwerp. Voor 3D-soundscapes wilt u waarschijnlijk de waarde instellen op HRTF (hoofd-gerelateerde overdrachtsfunctie).

Om de positie van een in te stellen AudioBufferSourceNode wij gebruiken de SetPosition () functie ontmaskerd door a PannerNode voorwerp.

var panner = audioContext.createPanner () panner.panningModel = "HRTF" // Stel de 3D-positie in (x, y, z). panner.setPosition (1, 2, 3) // Verbind het "source" -object met het "panner" -object. source.connect (panner) // Verbind het "panner" -object met het "destination" -object. panner.connect (audioContext.destination) // Start de audio. source.start ()

Om dingen een beetje duidelijker te maken, laten we de functie die we eerder hebben gemaakt bijwerken.

function 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 () afspelen (audioBuffer01, 1, 2, 3, audioContext) afspelen (audioBuffer02, 4, 5, 6, audioContext) afspelen (audioBuffer03, 7, 8, 9, audioContext)

Op dit punt spelen we audio en positioneren we het in 3D-ruimte, maar er is nog een belangrijk element waar we naar moeten kijken; de audio-luisteraar.

  • W3C PannerNode-specificatie.

De audio-luisteraar

elk AudioContext object onthult een luisteraar object dat de positie en oriëntatie van de ding dat is luisteren naar de audio. Meestal is het ding zou een virtuele camera zijn die is bevestigd aan het hoofd van een spelpersonage, de bumper van een auto, de staart van een vliegtuig of iets anders dat vanuit hun perspectief zinvol is voor de kijker.

De luisteraar object heeft een SetPosition () functie en a setOrientation () functie. De SetPosition () functie plaatst de luisteraar ergens in de 3D-ruimte en de setOrientation () roteert de luisteraar (stel je een panelen en kantelen van een camera voor).

De SetPosition () functie werkt op precies dezelfde manier als de PannerNode SetPosition () functie en accepteert drie coördinaten.

audioContext.listener.setPosition (x, y, z)

De setOrientation () De functie is iets complexer en accepteert twee eenheidsvectoren. De eerste vector vertegenwoordigt de rotatie van de luisteraar (de richting waarin de camera wijst) en de tweede vector geeft de luisteraar weer omhoog richting (deze wijst naar de bovenkant van de camera).

audioContext.listener.setOrientation (x1, y1, z1, x2, y2, z2)

Als u de luisteraar alleen rond één as hoeft te draaien, zijn de vectorberekeningen relatief eenvoudig. Als u bijvoorbeeld hetzelfde coördinatensysteem gebruikt dat WebGL positief gebruikt X wijst naar de rechterkant van het scherm, positief Y wijst naar de bovenkant van het scherm en positief z uit het scherm wijst, dan kunt u de luisteraar draaien rond de Y as (pan de camera) met behulp van een cos () functieaanroep en één zonde() functieaanroep.

// De positie van de luisteraar (kan van alles zijn). var x = 50 var y = 100 var z = 0 audioContext.listener.setPosition (x, y, z) // Bereken de rotatievector. // rad = rotatie, in radialen var rad = 0,10 var v1 = Math.cos (rad) // x var v2 = 0 // y var v3 = Math.sin (rad) // z // De "omhoog" vector var v4 = 0 // x var v5 = 1 // y var v6 = 0 // z audioContext.listener.setOrientation (v1, v2, v3, v4, v5, v6)

De demonstratie voor deze tutorial (broncode is bijgevoegd) doet iets soortgelijks en roteert het PannerNode objecten rond een enkele as.

  • W3C AudioListener-specificatie.

Conclusie

In deze tutorial hebben we de fundamentele Web Audio-elementen bekeken die worden gebruikt om 3D-soundscapes te construeren voor meeslepende interactieve toepassingen, inclusief maar niet beperkt tot, 3D-games. Hopelijk is deze tutorial je van dienst geweest en heb je voldoende informatie verzameld om te begrijpen hoe audiobuffers, panners en luisteraars samenwerken om 3D-soundscapes te maken..

Als je feedback of vragen hebt, kun je hieronder een reactie plaatsen.

Middelen

  • W3C Web Audio-specificatie
  • MDN Web Audio-documentatie
  • 3D (euclidische) vectoren

De volgende stap: implementatie

In de volgende zelfstudie, webaudio en 3D-soundscapes: implementatie, nemen we al het bovenstaande (en meer) en verpakken het in een vereenvoudigde API. De belangrijkste focus van de volgende tutorial zal 3D games zijn, maar de API zal generiek genoeg zijn voor gebruik in verschillende meeslepende interactieve applicaties.