Web Audio och 3D Soundscapes Introduktion

I denna handledning tar vi en närmare titt på de grundläggande Web Audio-elementen som används för att konstruera 3D-ljudbilder för immersiva interaktiva applikationer inklusive, men inte begränsat till, 3D-spel.

Web Audio API och den terminologi som den använder kan ibland vara förvirrande men den här handledningen syftar till att ta bort komplexiteten och ge en enklare förklaring av Web Audio-elementen och hur de fungerar tillsammans för att bilda en 3D-ljudbild.

Demonstration

Denna demonstration innehåller tre ljud som roterar runt en lyssnare, Lyttarens riktning indikeras av pilen. Om du kan tänka dig att titta på ett speltecken (lyssnaren), kan de roterande ljuden enkelt representera vänner eller fiender som cirklar karaktären.

Demonstrationskällkoden och resurserna bifogas denna handledning.

AudioContext

De AudioContext gränssnittet är hjärtan och själen i Web Audio, det ger de funktioner som krävs för att skapa olika Web Audio-element samt tillhandahålla ett sätt att skicka allt ljud till hårdvara och framåt till någons högtalare eller hörlurar.

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

Det är viktigt att se till att AudioContext gränssnittet är tillgängligt eftersom webbljudet fortfarande är ganska nytt och det kanske inte är tillgängligt i vissa webbläsare.

Förutom att de funktioner som krävs för att skapa olika Web Audio-element, ska AudioContext gränssnittet har två viktiga egenskaper; destination och lyssnare vilka båda är skrivskyddade. De destination egendom kan ses som en anslutning till ljudhårdvara, det är där allt det genererade ljudet kommer att hamna i slutändan. De lyssnare egendom (vi kommer att se ut så här mer i detalj senare) representerar sak som lyssnar på allt ljud, t.ex. ett tecken, eller mer exakt en kamera, i ett spel.

buffertar

De AudioBuffer och AudioBufferSourceNode gränssnitt tillåter oss att spela ljud. AudioBuffer Objekt innehåller de råa ljuden (ljudprover) som är tweaked, crunched och krossade när de går igenom Web Audio innan de når någons högtalare eller hörlurar. AudioBufferSourceNode objekt används för att starta och stoppa ljudet som finns i AudioBuffer objekt.

Det vanliga sättet att ladda ljud till en AudioBuffer objektet är att använda a XMLHttpRequest objekt med dess responseType satt till arraybuffer. När ljudfilen har laddats skickas matrisbufferten sedan till AudioContext objekt för avkodning och, om avkodningen är framgångsrik, kommer vi att förses med en AudioBuffer objekt.

var loader.onload = närladdad loader.send () funktion whenLoaded (händelse) var data = loader.windows (open) (varas = loader.open ("GET", "massive-explosion.ogg") loader.responseType = "arraybuffer" .response if (data === null) // Det gick inte att ladda filen. returnera // Avkod data. audioContext.decodeAudioData (data, whenDecoded) funktion närDecoded (audioBuffer) // "audioBuffer" är ett AudioBuffer-objekt. 

De decodeAudioData () funktionen har också en tredje parameter som accepterar en andra återuppringning, den återkallas kallas när den laddade ljudfilen inte kan avkodas.

decodeAudioData (data, närDecoded, whenFailed)

Inte alla webbläsare stöder samma ljudformat. Ett bra tablett med stödformat finns här, så du kanske vill använda den andra återuppringningen till fallback till ett alternativt ljudformat om det behövs. Till exempel stöder Internet Explorer inte OGG Vorbis men det stöder MP3. Det enda verkliga problemet med MP3 är att det inte tillåter sömlöst loopat ljud som OGG Vorbis gör.

När du har en AudioBuffer objekt tillgängligt du kan spela det med en AudioBufferSourceNode objekt.

var source = audioContext.createBufferSource () // Bifoga ett AudioBuffer-objekt. source.buffer = audioBuffer // Anslut "source" -objektet till "destination" -objektet. source.connect (audioContext.destination) // Optionellt, berätta "source" för att slingra ljudet kontinuerligt. source.loop = false // Starta ljudet. source.start ()

Det är viktigt att komma ihåg AudioBufferSourceNode Objekt är enstaka ljudspelare, med andra ord kan du bara använda Start() funktion en gång. Du måste skapa en AudioBufferSourceNode objekt och anslut det (direkt eller indirekt) till destination föremål utsatt av AudioContext objekt när du vill spela ljud från en AudioBuffer objekt.

Du kan göra livet lite enklare genom att skapa en liten verktygsfunktion som skapar, ansluter och startar en AudioBufferSourceNode föremål för dig.

funktionsspel (audioBuffer01, audioContext) var source = audioContext.createSourceBuffer () source.buffer = audioBuffer source.connect (audioContext.destination) source.start () spela (audioBuffer01, audioContext) spela (audioBuffer02, audioContext) spela (audioBuffer03 , audioContext)

När en AudioBufferSourceCode objekt slutar spelas och om du inte har några referenser till objektet någonstans (t.ex. du inte har dem lagrade i en array), kopplar Web Audio automatiskt objektet till dig. Det här är väldigt användbart när du bara behöver elda och glömma korta ljudeffekter mm.

Om du bestämmer dig för att slinga ljudet med hjälp av AudioBufferSourceNode slinga egendom, måste du hänvisa till AudioBufferSourceNode objekt någonstans så du kan sluta() ljudspelet.

source.stop ()

Så vid denna tidpunkt använder vi buffertar för att spela ljud, men ljudet spelas direkt utan att panning eller spatialisering appliceras på den. Det är här PannerNode objekt kommer till spel.

  • W3C AudioBuffer-specifikation.
  • W3C AudioBufferSourceNode-specifikation.

panners

PannerNode objekt tillåter oss att placera ljud i 3D-rymden, inom ett kartesiskt koordinatsystem. Det här är där de flesta 3D-magikerna händer.

en PannerNode objektet har en hel del egenskaper som gör att vi kan finjustera ljudets beteende men för denna handledning är vi bara intresserade av två av dem; maxDistance och panningModel. De maxDistance egendom är avståndet från lyssnare vid vilken tidpunkt kommer ljudvolymen att vara noll. Detta är ett godtyckligt värde och kommer bara att innebära betydelse inom din ansökan men det är normalt 10000. Den panningModel berättar Web Audio hur man behandlar ljudet som passerar genom a PannerNode objekt. För 3D-ljudbilder kommer du förmodligen att ange värdet till HRTF (huvudrelaterad överföringsfunktion).

För att ange positionen för en AudioBufferSourceNode vi använder setPosition () funktion utsatt av a PannerNode objekt.

var panner = audioContext.createPanner () panner.panningModel = "HRTF" // Ställ in 3D-positionen (x, y, z). panner.setPosition (1, 2, 3) // Anslut "source" -objektet till "panner" -objektet. source.connect (panner) // Anslut "panner" -objektet till "destination" -objektet. panner.connect (audioContext.destination) // Starta ljudet. source.start ()

För att göra sakerna lite tydligare, låt oss uppdatera den funktion som vi skapade tidigare.

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

Vid denna tidpunkt spelar vi ljud och placerar det i 3D-utrymme, men det finns ytterligare ett viktigt element som vi behöver titta på; ljudlyssnaren.

  • W3C PannerNode specifikation.

Audio Listener

Varje AudioContext objektet avslöjar a lyssnare objekt som representerar positionen och orienteringen av sak det lyssnar på ljudet. Vanligtvis sak skulle vara en virtuell kamera som är kopplad till ett spel karaktärs huvud, bilens stötfångare, flygplanets svans eller något annat som är vettigt för betraktaren från deras perspektiv.

De lyssnare objektet har a setPosition () funktion och a setOrientation () fungera. De setPosition () funktion placerar lyssnaren någonstans inom 3D-rymden och setOrientation () roterar lyssnaren (föreställ dig en kamera panorering och lutning).

De setPosition () funktion fungerar på exakt samma sätt som PannerNode setPosition () funktion och accepterar tre koordinater.

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

De setOrientation () funktionen är lite mer komplex, det accepterar två enhetsvektorer. Den första vektorn representerar lyssnarens rotation (den riktning som kameran pekar), och den andra vektorn representerar lyssnarens upp riktning (den pekar ut över kamerans topp).

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

Om du bara behöver rotera lyssnaren runt en axel är vektorkalkylerna relativt enkla. Till exempel, om du använder samma koordinatsystem som WebGL använder var positiv x pekar till höger om skärmen, positiv y pekar på toppen av skärmen och positivt z pekar ut på skärmen, så kan du rotera lyssnaren runt y axel (panorera kameran) med en cos () funktionssamtal och en synd() funktionssamtal.

// Lyssnarens position (kan vara någonting). var x = 50 var y = 100 var z = 0 audioContext.listener.setPosition (x, y, z) // Beräkna rotationsvektorn. // rad = rotation, i radianer var rad = 0.10 var v1 = Math.cos (rad) // x var v2 = 0 // y var v3 = Math.sin (rad) // z // Den "upp" vektorn var v4 = 0 // x var v5 = 1 // y var v6 = 0 // z audioContext.listener.setOrientation (v1, v2, v3, v4, v5, v6)

Demonstrationen för denna handledning (källkod är bifogad) gör en liknande sak och roterar PannerNode objekt runt en enda axel.

  • W3C AudioListener specifikation.

Slutsats

I denna handledning tog vi en titt på de grundläggande Web Audio-elementen som används för att konstruera 3D-ljudbilder för immersiva interaktiva applikationer, inklusive, men inte begränsat till, 3D-spel. Förhoppningsvis har denna handledning varit till nytta för dig och har gett tillräckligt med information för att du ska kunna förstå hur ljudbuffertar, pannrar och lyssnare arbetar tillsammans för att producera 3D-ljudbilder.

Om du har några kommentarer eller frågor, var god och skriv en kommentar nedan.

Medel

  • W3C Web Audio Specification
  • MDN Web Audio Documentation
  • 3D (Euklidiska) vektorer

Nästa steg: Implementering

I nästa handledning, Web Audio och 3D Soundscapes: Implementation, kommer vi att ta alla ovanstående (och mer) och lägga in det i ett förenklat API. Huvudfokus för nästa handledning kommer att vara 3D-spel, men API: n kommer att vara generisk nog för användning i olika immersiva interaktiva applikationer.