Înainte de API-ul Web Audio, HTML5 ne-a dat element. Ar putea părea greu să-ți amintești acum, dar înainte de
element, cea mai bună opțiune pentru sunet într-un browser a fost un plugin!
elementul a fost într-adevăr interesant, dar a avut un accent destul de singular. Acesta a fost în esență un player video fără video, bun pentru un sunet lung, cum ar fi muzică sau un podcast, dar necorespunzător pentru cerințele jocurilor. Ne-am supus (sau am găsit soluții pentru) chestiuni legate de buclă, limite de sunet concurente, erori și lipsa totală a accesului la datele sonore.
Din fericire, răbdarea noastră sa răsplătit. Unde element poate fi lipsit, API Web Audio oferă. Ne dă un control fără precedent asupra sunetului și este perfect pentru orice, de la jocuri la editare sofisticată a sunetului. Toate acestea cu un API îngrijit care este foarte distractiv de utilizat și bine susținut.
Să fim puțin mai specifici: Web Audio vă oferă acces la datele de undă brute ale unui sunet și vă permite să le manipulați, să le analizați, să le deformați sau să le modificați în alt mod. Este vorba de audio ce este API-ul de panza la pixeli. Aveți acces profund și în cea mai mare parte liber la datele de sunet. Este foarte puternic!
Acest tutorial este al doilea dintr-o serie pe Flight Arcade construit pentru a demonstra ce este posibil pe platforma web și în noul browser Microsoft Edge și motorul de redare EdgeHTML. Codul interactiv și exemplele pentru acest articol sunt de asemenea localizate la Flight Arcade / Learn.
Chiar și cele mai vechi versiuni ale Flight Simulator au făcut eforturi pentru a recrea simțul zborului folosind sunetul. Unul dintre cele mai importante sunete este pasul dinamic al motorului care schimbă pasul cu accelerația. Știam că, așa cum am reimaginat jocul pentru web, un zgomot static al motorului ar părea chiar neted, astfel încât pasul dinamic al zgomotului motorului era un candidat evident pentru Web Audio.
Mai puțin evident (dar posibil mai interesant) a fost vocea instructorului nostru de zbor. În replicile timpurii ale Flight Arcade, am jucat vocea instructorului exact așa cum a fost înregistrată și suna ca și cum ar fi ieșit dintr-o cabină de sunet! Am observat că am început să ne referim la voce ca "narator" în locul "instructorului".
Cumva, acel sunet curat a spart iluzia jocului. Nu mi sa părut bine ca un sunet atât de perfect să vină peste sunetele zgomotoase ale cockpitului. Deci, în acest caz, am folosit Web Audio pentru a aplica câteva distorsiuni simple la instrucțiunile vocale și pentru a spori realismul învățării să zboare!
În secțiunile de mai jos, vă vom oferi o imagine detaliată a modului în care am folosit Web Audio API pentru a crea aceste sunete.
Primul pas în orice proiect Web Audio este crearea unui AudioContext
obiect. Unele browsere (inclusiv Chrome) necesită încă acest prefix API, astfel încât codul să arate astfel:
var AudioContext = fereastra.AudioContext || window.webkitAudioContext; var audioCtx = noul AudioContext ();
Apoi ai nevoie de un sunet. De fapt, puteți genera sunete de la zero cu API Web Audio, dar pentru scopurile noastre am vrut să încărcăm o sursă audio preîncărcată. Dacă ați avut deja un cod HTML element, ați putea folosi acest lucru, dar de multe ori nu veți. La urma urmei, cine are nevoie de unul
element dacă aveți Web Audio? Cel mai frecvent, veți descărca direct sunetul într-un tampon cu o solicitare HTTP:
var request = nou XMLHttpRequest (); request.open ("GET", url, true); request.responseType = "arraybuffer"; var loader = acest lucru; request.onload = function () loader.context.decodeAudioData (request.response, function (buffer) if (! buffer) console.log ('decodare fisier date fisier:' + url ') returner loader.bufferList [loader.urlList.length) loader.onload (loader.bufferList);, funcția (eroare) console.error ('error decodeAudioData', eroare );); ;
Acum avem un AudioContext și câteva date audio. Următorul pas este să obțineți aceste lucruri împreună. Pentru asta, avem nevoie ...
Aproape tot ceea ce faci cu Web Audio se întâmplă prin intermediul unui tip de AudioNode și vin în multe arome diferite: unele noduri sunt folosite ca surse audio, unele ca ieșiri audio și altele ca procesoare audio sau analizoare. Le puteți alătura împreună pentru a face lucruri interesante.
S-ar putea să vă gândiți la AudioContext ca la un fel de scenă de sunet. Diferitele instrumente, amplificatoare și difuzoare pe care le conține vor fi diferite tipuri de AudioNodes. Lucrul cu API-ul Web Audio este foarte asemănător cu conectarea tuturor acestor lucruri împreună (instrumente, de exemplu, pedale de efecte și pedale într-un amplificator și apoi un difuzor etc.).
Ei bine, pentru a face ceva interesant cu noile noastre surse audio AudioContext, trebuie să încapăm mai întâi datele audio ca o sursă AudioNode.
var sursaNode = audioContext.createBufferSource ();
Asta e. Avem o sursă. Dar înainte de ao putea juca, trebuie să o conectăm la un nod de destinație. Pentru confort, AudioContext expune un nod de destinație implicit (de obicei, căștile sau difuzoarele). Odată conectat, este doar o chestiune de a apela start
și Stop
.
sourceNode.connect (audioContext.destination); sourceNode.start (0); sourceNode.stop ();
Merită remarcat faptul că puteți apela doar start()
o dată pe fiecare nod sursă. Aceasta înseamnă că "pauza" nu este direct susținută. Odată ce o sursă este oprită, este expirată. Din fericire, nodurile sursă sunt obiecte necostisitoare, concepute pentru a fi create cu ușurință (datele audio în sine, amintiți-vă, se află într-un buffer separat). Deci, dacă doriți să reluați un sunet pauzat, puteți crea un nou nod sursă și apelați start()
cu un parametru de timbru. AudioContext are un ceas intern pe care îl puteți utiliza pentru a gestiona marcajele de timp.
Asta e pentru elementele de bază, dar tot ce am făcut până acum (redare audio simplă) s-ar fi putut face cu vechiul element. Pentru Flight Arcade, trebuia să facem ceva mai dinamic. Vrem ca pitch-ul să se schimbe cu viteza motorului.
Aceasta este de fapt destul de simplă cu Web Audio (și ar fi fost aproape imposibil fără ea)! Nodul sursă are o proprietate rata care afectează viteza de redare. Pentru a mări pitch, creștem doar rata de redare:
throttleSlider.onMove = funcția (val) sourceNode.source.playbackRate.value = val; ;
Sunetul motorului trebuie, de asemenea, să circule. Este, de asemenea, foarte ușor (există și o proprietate pentru ea):
sourceNode.source.loop = true;
Dar există o captură. Multe formate audio (în special audio comprimat) stochează datele audio în cadre de mărime fixă și, mai des, datele audio în sine nu vor "umple" cadrul final. Acest lucru poate lăsa un decalaj mic la sfârșitul fișierului audio și poate duce la clicuri sau glitches atunci când aceste fișiere audio se bucure. Elementele audio standard HTML nu oferă nici un fel de control asupra acestui decalaj și poate fi o mare provocare pentru jocurile web care se bazează pe looping audio.
Din fericire, redarea audio fără goluri cu API-ul Web Audio este foarte simplă. Este doar o chestiune de a seta o marcă de timp pentru începutul și sfârșitul porțiunii de buclă audio (rețineți că aceste valori sunt relative la sursa audio în sine și nu la ceasul AudioContext).
engineAudioSource.source.loopStart = 0.5; engineAudioSource.source.loopEnd = 1.5;
Până acum, tot ceea ce am făcut a fost cu un nod sursă (fișierul nostru audio) și un nod de ieșire (destinația sunetului pe care am stabilit-o mai devreme, probabil difuzoarele), dar AudioNodes pot fi folosite pentru mult mai mult, inclusiv manipularea sunetului analiză. În Flight Arcade, am folosit două tipuri de noduri (un ConvolverNode și un WaveShaperNode) pentru a face vocea instructorului să sune ca și cum ar veni printr-un difuzor.
Din spec. W3C:
Convoluția este un proces matematic care poate fi aplicat unui semnal audio pentru a obține multe efecte liniare de înaltă calitate. Foarte des, efectul este folosit pentru a simula un spațiu acustic, cum ar fi o sală de concerte, o catedrală sau un amfiteatru în aer liber. Poate fi folosit și pentru efecte complexe ale filtrului, cum ar fi un sunet amovibil care vine din interiorul unui dulap, sunet sub apă, sunet care vine prin telefon sau joc printr-un cabinet de difuzoare de epocă. Această tehnică este foarte frecvent utilizată în producția cinematografică și muzică și este considerată extrem de versatilă și de înaltă calitate.
Convoluția combină în esență două sunete: un sunet care trebuie procesat (vocea instructorului) și un sunet numit răspuns impuls. Răspunsul la impuls este, într-adevăr, un fișier de sunet, dar este într-adevăr util doar pentru acest tip de proces de convoluție. Vă puteți gândi la acesta ca la un filtru audio de tip, conceput pentru a produce un efect specific atunci când se convoacă cu alt sunet. Rezultatul este de obicei mult mai realist decât manipularea matematică simplă a sunetului.
Pentru ao folosi, vom crea un nod convolver, vom încărca sunetul care conține răspunsul la impuls și apoi vom conecta nodurile.
// creați convolverul var convolverNode = audioContext.createConvolver (); // presupuneți că am descărcat deja sunetul telefonului într-un buffer convolver.buffer = telephponeBuffer; // conectați nodurile sourceNode.connect (convolverNode); convolverNode.connect (audioContext.destination);
Pentru a spori distorsiunea, am folosit și un nod WaveShaper. Acest tip de nod vă permite să aplicați distorsiuni matematice semnalului audio pentru a obține unele efecte dramatice. Distorsiunea este definită ca o funcție a curbei. Aceste funcții pot necesita unele matematică complexă. Pentru exemplul de mai jos, am împrumutat unul bun de la prietenii noștri de la MDN.
// creați waveviserul var waveShaper = audioContext.createWaveShaper (); // funcția funcției de curbă a distorsiunii makeDistortionCurve (suma) var k = suma de tip === 'numărul'? suma: 50, n_samples = 44100, curve = float32Array nou (n_samples), deg = Math.PI / 180, i = 0, x; pentru (i < n_samples; ++i ) x = i * 2 / n_samples - 1; curve[i] = ( 3 + k ) * x * 20 * deg / (Math.PI + k * Math.abs(x)); return curve; // connect the nodes sourceNode.connect(convolver); convolver.connectwaveShaper); waveShaper.connect(audioContext.destination); // vary the amount of distortion with the slider distortionSlider.onMove = function(val) waveShaper.curve = makeDistortionCurve(val); ;
Observați diferența strictă între forma de undă originală și forma de undă cu aplicația WaveShaper.
Exemplul de mai sus este o reprezentare dramatică a cât de mult puteți face cu API-ul Web Audio. Nu numai că facem niște schimbări destul de dramatice ale sunetului din browser, dar analizăm, de asemenea, forma de undă și transformăm-o într-un element de panza! Aplicația Web Audio API este incredibil de puternică și versatilă și, sincer, o mulțime de distracție!
Microsoft are o grămadă de învățare gratuită pe multe subiecte JavaScript open-source și suntem în misiunea de a crea mult mai mult cu Microsoft Edge. Iată câteva pentru a verifica:
Și câteva instrumente gratuite pentru a începe: Visual Studio Code, Azure Trial și instrumente de testare cross-browser - toate disponibile pentru Mac, Linux sau Windows.
Acest articol face parte din seriile de tehnologie web dev din Microsoft. Suntem încântați să împărtășim Microsoft Edge și noul EdgeHTML motor de randare cu tine. Obțineți mașini virtuale gratuite sau testați de la distanță pe dispozitivele Mac, iOS, Android sau Windows @ http://dev.modern.ie/.