In diesem Lernprogramm werden Web Audio in eine einfache API eingebunden, die sich auf das Spielen von Klängen innerhalb eines 3D-Koordinatenraums konzentriert und für interaktive interaktive Anwendungen einschließlich 3D-Spielen verwendet werden kann.
Dieses Tutorial ist das zweite in einer zweiteiligen Serie. Wenn Sie das erste Tutorial der Serie nicht gelesen haben, sollten Sie dies vor dem Lesen dieses Tutorials tun, da Sie hier die verschiedenen Web-Audio-Elemente kennenlernen, die wir hier verwenden werden.
Bevor wir loslegen, hier eine kleine Demonstration, die die vereinfachte API verwendet, die wir in diesem Tutorial behandeln werden. Sounds (dargestellt durch die weißen Quadrate) werden zufällig in einem 3D-Koordinatenraum mit der kopfbezogenen Übertragungsfunktion (HRTF), die Web Audio für uns bereitstellt, positioniert und abgespielt.
Die Quelldateien für die Demonstration sind an dieses Tutorial angehängt.
Da die vereinfachte API (AudioPlayer) bereits für dieses Lernprogramm erstellt wurde und zum Download zur Verfügung steht, werfen wir einen Blick auf die AudioPlayer-API und den dazugehörigen Code.
Bevor Sie dieses Tutorial fortsetzen, lesen Sie bitte Das vorherige Tutorial dieser Serie, falls Sie dies noch nicht getan haben und in der Welt von Web Audio noch nicht bekannt sind.
Das Musikplayer
Klasse enthält unsere vereinfachte API und ist auf der Fenster
Objekt neben den Standard-Web-Audioklassen, wenn und nur wenn Web-Audio vom Webbrowser unterstützt wird. Das bedeutet, dass wir die Existenz der Klasse prüfen sollten, bevor wir versuchen, sie zu verwenden.
if (window.AudioPlayer! == undefined) audioPlayer = neuer AudioPlayer ()
(Wir hätten versuchen können, ein neues zu schaffen Musikplayer
Objekt innerhalb eines versuche es… fangen
Anweisung, aber eine einfache bedingte Prüfung funktioniert einwandfrei.)
Hinter den Kulissen der Musikplayer
schafft ein neues AudioContext
Objekt und ein neues AudioGainNode
Objekt für uns und verbindet das GainNode
Einwände gegen die Ziel
Knoten von der freigelegt AudioContext
Objekt.
var m_context = new AudioContext () var m_gain = m_context.createGain ()… m_gain.connect (m_context.destination)
Wenn Sounds erzeugt und abgespielt werden, werden sie mit dem verbunden m_gain
Knoten, ermöglicht dies die einfache Steuerung der Lautstärke (Amplitude) aller Sounds.
Das Musikplayer
konfiguriert auch das Audio Hörer
, ausgesetzt durch m_context
, Daher stimmt es mit dem üblichen 3D-Koordinatensystem überein, das mit WebGL verwendet wird. Das Positive z
Achse zeigt auf den Betrachter (mit anderen Worten, er zeigt aus dem 2D-Bildschirm heraus), das Positive y
Achse zeigt nach oben und das Positive x
Achse zeigt nach rechts.
m_context.listener.setOrientation (0, 0, -1, 0, 1, 0)
Die Position der Hörer
ist immer Null; Es befindet sich in der Mitte des Audiokoordinatensystems.
Bevor wir Sounds erstellen oder abspielen können, müssen wir die Sounddateien laden. zum glück genug Musikplayer
kümmert sich um all die harte Arbeit für uns. Es legt ein Belastung(… )
Funktion, mit der wir die Sounds laden können, und drei Event-Handler, mit denen wir den Ladungsfortschritt verfolgen können.
audioPlayer.onloadstart = function () … audioPlayer.onloaderror = function () … audioPlayer.onloadcomplete = function () … audioPlayer.load ("sound-01.ogg") audioPlayer.load ("sound-02.) .ogg ") audioPlayer.load (" sound-03.ogg ")
Die unterstützten Soundformate sind vom Browser abhängig. Zum Beispiel unterstützen Chrome und Firefox OGG Vorbis, Internet Explorer jedoch nicht. Alle drei Browser unterstützen MP3, was praktisch ist, aber das Problem bei MP3 ist das Fehlen von nahtlosem Sound-Looping. Das MP3-Format ist einfach nicht dafür ausgelegt. OGG Vorbis ist jedoch und kann Sounds perfekt schleifen.
Beim Anrufen der Belastung(… )
Funktion mehrmals, Musikplayer
Die Anforderungen werden in eine Warteschlange verschoben und nacheinander geladen. Wenn alle in der Warteschlange befindlichen Sounds geladen (und decodiert) wurden, wird der onloadcomplete
Eventhandler wird aufgerufen.
Hinter den Kulissen, Musikplayer
verwendet eine einzelne XMLHttpRequest
Objekt zum Laden der Sounds. Das responseType
der Anfrage ist auf gesetzt "arraybuffer"
, und wenn die Datei geladen ist, wird der Array-Puffer gesendet m_context
zum Dekodieren.
// vereinfachtes Beispiel m_loader = new XMLHttpRequest () m_queue = [] Funktion load () m_loader.open ("GET", m_queue [0]) m_loader.responseType = "arraybuffer" m_loader.onload = onLoad m_loader.send () Funktion onLoad (Ereignis) var data = m_loader.response var status = m_loader.status m_loader.abort () // setzt den Loader if (status < 400) m_context.decodeAudioData(data, onDecode)
Wenn das Laden und Dekodieren einer Datei erfolgreich ist, Musikplayer
wird entweder die nächste Datei in die Warteschlange laden (wenn die Warteschlange nicht leer ist) oder uns mitteilen, dass alle Dateien geladen wurden.
Nachdem wir nun einige Sounddateien geladen haben, können wir unsere Sounds erstellen und abspielen. Wir müssen zuerst erzählen Musikplayer
um die Sounds zu erzeugen, und dies geschieht mit der erstellen(… )
Funktion ausgesetzt durch Musikplayer
.
var sound1 = audioPlayer.create ("sound-01.ogg") var sound2 = audioPlayer.create ("sound-02.ogg") var sound3 = audioPlayer.create ("sound-03.ogg")
Wir können beliebig viele Sounds erstellen, auch wenn wir nur eine einzige Sounddatei geladen haben.
var a = audioPlayer.create ("beep.ogg") var b = audioPlayer.create ("beep.ogg") var c = audioPlayer.create ("beep.ogg")
Der Sounddateipfad, der an den übertragen wurde erstellen(… )
Funktion erzählt einfach Musikplayer
welche Datei der erstellte Sound verwenden soll. Wenn die angegebene Audiodatei beim Laden nicht geladen wurde erstellen(… )
Funktion aufgerufen wird, wird ein Laufzeitfehler ausgelöst.
Wenn wir einen oder mehrere Sounds erstellt haben, können wir diese Sounds jederzeit wiedergeben. Um einen Sound abzuspielen, verwenden wir den passend benannten abspielen(… )
Funktion ausgesetzt durch Musikplayer
.
audioPlayer.play (sound1)
Um zu bestimmen, ob Sie ein spielen möchten geschlungen Sound, wir können auch einen Boolean an den übergeben abspielen(… )
Funktion. Wenn der Boolean ist wahr
, Der Ton wird so lange wiederholt, bis er gestoppt wird.
audioPlayer.play (sound1, true)
Um einen Ton zu stoppen, können wir die verwenden halt(… )
Funktion.
audioPlayer.stop (sound1)
Das spielt(… )
Mit dieser Funktion können Sie wissen, ob gerade ein Sound abgespielt wird.
if (audioPlayer.isPlaying (sound1)) …
Hinter den Kulissen der Musikplayer
Es muss erstaunlich viel Arbeit geleistet werden, um einen Sound zu erzeugen, da Web Audio modular aufgebaut ist. Wann immer ein Ton abgespielt werden muss,Musikplayer
muss neu schaffen AudioSourceBufferNode
und PannerNode
Objekte, konfigurieren und verbinden sie und verbinden Sie den Sound mit dem m_gain
Knoten. Glücklicherweise ist Web Audio stark optimiert, sodass die Erstellung und Konfiguration neuer Audio-Nodes selten einen spürbaren Aufwand verursacht.
sound.source = m_context.createBufferSource () sound.panner = m_context.createPanner () sound.source.buffer = sound.buffer sound.source.loop = loop sound.source.onended = onSoundEnded // Dies ist ein bisschen Hack Wir müssen jedoch das // Sound-Objekt im onSoundEnded-Ereignishandler referenzieren, und dies tun // ist auf diese Weise optimaler als das Binden des Handlers. sound.source.sound = sound sound.panner.panningModel = "HRTF" sound.panner.distanceModel = "linear" sound.panner.setPosition (sound.x, sound.y, sound.z) sound.source.connect (sound .panner) sound.panner.connect (m_gain) sound.source.start ()
Klänge zu spielen ist offensichtlich nützlich, aber der Zweck von Musikplayer
ist es, Sounds innerhalb eines 3D-Koordinatensystems abzuspielen, daher sollten wir die Klangpositionen wahrscheinlich vor dem Abspielen einstellen. Musikplayer
macht einige Funktionen verfügbar, mit denen wir genau das tun können.
setX (…)
und getX (…)
Funktionen ausgesetzt durch Musikplayer
kann verwendet werden, um die Position eines Sounds entlang des Koordinatensystems festzulegen und abzurufen x
Achse.setY (…)
und getY (…)
Funktionen können verwendet werden, um die Position eines Sounds entlang des Koordinatensystems festzulegen und abzurufen y
Achse.setZ (…)
und getZ (…)
Funktionen können verwendet werden, um die Position eines Sounds entlang des Koordinatensystems festzulegen und abzurufen z
Achse.Position setzen(… )
Mit dieser Funktion können Sie die Position eines Sounds entlang des Koordinatensystems einstellen x
, y
, und z
Achsen.audioPlayer.setX (sound1, 100) audioPlayer.setZ (sound1, 200) console.log (audioPlayer.getX (sound1)) // 100 console.log (audioPlayer.getZ (sound1)) // 200 audioPlayer.setPosition (sound1, 300, 0, 400) console.log (audioPlayer.getX (sound1)) // 300 console.log (audioPlayer.getZ (sound1)) // 400
Je weiter ein Klang von der Mitte des Koordinatensystems entfernt ist, desto leiser ist der Klang. In einer Entfernung von 10000
(Standardeinstellung für Web-Audio) Ein Ton ist völlig stumm.
Wir können die globale (Master-) Lautstärke der Sounds mit Hilfe von steuern setVolume (…)
und getVolume (…)
Funktionen ausgesetzt durch Musikplayer
.
audioPlayer.setVolume (0.5) // 50% console.log (audioPlayer.getVolume ()) // 0.5
Das setVolume (…)
Funktion hat auch einen zweiten Parameter, mit dem die Lautstärke über einen bestimmten Zeitraum ausgeblendet werden kann. Um beispielsweise das Volumen über einen Zeitraum von zwei Sekunden auf null zu bringen, können Sie Folgendes tun:
audioPlayer.setVolume (0.0, 2.0)
Die Tutorial-Demo nutzt dies, um die Sounds sanft einzublenden.
Hinter den Kulissen der Musikplayer
sagt einfach das m_gain
Knoten, um den Verstärkungswert linear zu ändern, wenn die Lautstärke geändert werden muss.
var currentTime = m_context.currentTime var currentVolume = m_gain.gain.value m_gain.gain.cancelScheduledValues (0.0) m_gain.gain.setValueTime (currentVolume, currentTime)
Musikplayer
erzwingt eine minimale Überblendzeit von 0,01
Sekunden, um sicherzustellen, dass starke Lautstärkeänderungen keine hörbaren Klicks oder Knacks verursachen.
In diesem Lernprogramm haben wir einen Blick auf eine Möglichkeit zum Einschließen von Web Audio in eine einfache API gerichtet, die sich auf das Spielen von Sounds innerhalb eines 3D-Koordinatenraums für die Verwendung in (neben anderen Anwendungen) 3D-Spielen konzentriert.
Aufgrund des modularen Charakters von Web Audio können Programme, die Web Audio verwenden, sehr schnell komplex werden. Daher hoffe ich, dass dieses Tutorial für Sie von Nutzen war. Wenn Sie verstehen, wie Web Audio funktioniert und wie mächtig es ist, werden Sie sicher viel Spaß daran haben.
Vergessen Sie nicht, dass die AudioPlayer- und Demo-Quelldateien auf GitHub zur Verfügung stehen und zum Download bereitstehen. Der Quellcode ist ziemlich gut kommentiert, daher lohnt es sich, sich die Zeit zu nehmen, um einen kurzen Blick darauf zu werfen.
Wenn Sie Feedback oder Fragen haben, können Sie untenstehend einen Kommentar posten.