Hvordan manipulere og visualisere nettlyd

Forfatter: John Stephens
Opprettelsesdato: 28 Januar 2021
Oppdater Dato: 19 Kan 2024
Anonim
The Internet: Packets, Routing & Reliability
Video: The Internet: Packets, Routing & Reliability

Innhold

Web Audio API er kraftig og kan brukes til lydmanipulering og analyse i sanntid, men dette kan gjøre det vanskelig å jobbe med. Ved å bruke et rutediagram for å pipe lyd fra node til node, er det forskjellig fra andre web-APIer - og det er litt skremmende første gang man nærmer seg spesifikasjonen. I dette stykket vil vi gå gjennom et eksempel på bare bein som manipulerer lyd i sanntid, og deretter visualisere lyddataene.

Plug and play

Tenk deg at du er gitarist for favorittbandet ditt: lyd kommer fra gitaren din, via effektpedaler (du vil høres tungt, ikke sant?) Og inn i forsterkeren din slik at den kan høres. Web Audio API fungerer på samme måte: data beveger seg fra en kildenode, via transformasjonsnoder og til slutt ut av datamaskinens lydkort.

Alt i nettlyd starter med å starte en AudioContext forekomst. De AudioContext kan betraktes som vårt lydmiljø, og fra konteksten lager vi alle våre lydnoder. På grunn av dette lever alle lydnoder inne i en AudioContext, som blir et nettverk av tilkoblede noder.


Først trenger vi en kildeknute der lyden kommer fra. Det er flere typer kildenoder, for eksempel MediaElementAudioSourceNode for å bruke en lyd> element, a MediaStreamAudioSourceNode for bruk av direkte mikrofoninngang med WebRTC, en OscillatorNode for firkantede og trekantbølger, eller en lydfil med en AudioBufferSourceNode. I dette tilfellet bruker vi a MediaElementAudioSourceNode for å utnytte de opprinnelige kontrollene lyd> element gir oss.

Her vil vi være forberedt på prefikset objektnavn og støtte forskjellige lydkodeker. Det kan hende du må servere denne siden fra en server, slik at passende overskrifter for lydfilene er angitt. La oss lage en lyd> element, instantiate an AudioContext og krok a MediaElementAudioSourceNode til vår lyd> element:

body> audio id = "audio-element" controls = "controls"> source src = "audio / augment.mp3" type = "audio / mpeg;"> source src = "audio / augment.ogg" type = "audio / ogg; codecs = vorbis; "> / audio> script> var ctx = new (window.AudioContext || window. webkitAudioContext) (); var audioEl = document.getElementById ("lydelement"); var elSource = ctx.createMediaElementSource (audioEl); / script> / body>

De lyd> elementets lyd blir pumpet inn i vår lydkontekst. Så hvorfor kan vi ikke høre sporet når vi klikker på play? Når vi omdirigerer lyden fra elementet til vår kontekst, må vi koble kilden vår til kontekstens destinasjon. Det er som om vi spiller en elektrisk gitar som ikke er koblet til en forsterker.


Hver AudioContext forekomst har en mål egenskap: en spesiell lydnode som representerer datamaskinens lydutgang, og alle lydnodene våre har en koble metode som gjør det mulig for oss å pipe lyddata fra en til en annen. La oss koble lydelementnoden vår til destinasjonsnoden, som en gitarkabel til en forsterker.

elSource.connect (ctx.destination);

Nå når vi treffer avspillingen, har vi lyd> elementknute som pumpes inn i destinasjonsknuten, og kan høre sangen. Men det er ikke annerledes enn å bruke lyd> tag på egenhånd. La oss legge til en filternode for å spille med lydsporets frekvenser. Først kontrollerer vi filteret med en glidebryter og en skjerm slik at vi kan se hvilken verdi som er:

input id = "glidebryter" type = "range" min = "100" max = "22000" value = "100" /> div id = "freq-display"> 100 / div>

Nå må vi lage en BiquadFilterNode: vårt filter og funksjoner, som en equalizer i nettlyd. Som med alle noder vi lager, instantierer vi filteret vårt fra AudioContext. Tidligere koblet vi sammen vår MediaElementAudioSourceNode direkte til vår kontekst mål. Nå vil vi at kildekoden vår først skal koble til filteret vårt, og filteret vårt til destinasjonen, slik at filternoden vår kan manipulere lyden som sendes gjennom den. Vi burde ha noe slikt nå:


var ctx = new (window.AudioContext || vindu.webkitAudioContext) (); var audioEl = document.getElementById ("lydelement"); var elSource = ctx.createMediaElementSource (audioEl); var filter = ctx.createBiquadFilter (); filter.type = "lowpass"; filter.frequency.value = 100; elSource.connect (filter); filter.connect (ctx.destination);

Filternoder har flere typer frekvensfiltrering, men vi bruker standard "lav passering"- bare frekvenser lavere enn Frekvens kan passere gjennom. Gi det en lytting: legg merke til hvordan det høres ut som om det er en fest ved siden av. Bare frekvenser under 100 Hz skal til destinasjonen, så vi hører bare bassen. La oss koble til glidebryteren vår slik at vi kan manipulere dette filteret.

var glidebryter = document.getElementById ("glidebryter"); var freqDisplay = document.getElementById ("freq-display"); // Hendelsehåndterer i tvers av nettlesere hvis (slider.addEventListener) {slider.addEventListener ("endre", onChange); } annet {slider.attachEvent ("onchange", onChange); } funksjon onChange () {// Oppdater filternodens frekvensverdi med skyveverdi filter.frequency.value = slider.value; freqDisplay.innerHTML = slider.value; }

Med glidebryteren vår som kan kontrollere filternodens frekvens, kan vi manipulere lydavspilling i sanntid. For å få en bedre titt på dataene som sendes rundt, kan vi visualisere frekvensdataene til signalet. Mens filternoden vår endret lyden som kommer ut av høyttalerne våre, bruker vi to nye noder for å analysere signalet i stedet for å påvirke det. La oss lage en AnalyserNode og en ScriptProcessorNode:

var analysator = ctx.createAnalyser (); var proc = ctx.createScriptProcessor (1024, 1, 1);

De createScriptProcessor (tidligere createJavaScriptNode) -metoden tar tre argumenter. Den første er bufferstørrelsen, som må være en effekt på 2, og antall innganger og utganger er de gjenværende argumentene tilsvarende. Med en prosessorknute kan vi planlegge at en hendelse skal utløses når nok lyd behandles. Hvis bufferstørrelsen vår er 1024, betyr det at hver gang 1024 prøver blir behandlet, vil arrangementet avfyres.

Våre AudioContext samplingsfrekvensen er 44100Hz (44100 prøver å behandle per sekund), og arrangementet vil skyte hvert 1024 prøver - hvert .023 sekund, eller 43 ganger i sekundet. Ved å holde dette enkelt, kan prosessornoden vår gjøre det mulig å koble til en tilbakeringing når nye lyddata behandles. Vi bruker dette til å tegne på et lerret om kort tid.

Ved å bruke skriptprosessoren vår som en tilbakeringingskrok, trenger vi vår AnalyserNode for å få dataene. Men lydsignalet vårt må passere gjennom både analysatoren og prosessoren: la oss endre rutingen vår og sende det filtrerte signalets utgang til analysatoren, så kobler analysatoren til vårt lydmål og skriptprosessor:

elSource.connect (filter); filter.connect (analysator); analyser.connect (proc); filter.connect (ctx.destination); proc.connect (ctx.destination);

En WebKit-feil betyr at vi må koble prosessorens utgang tilbake til destinasjonen for å motta lydbehandlingshendelser, som vi vil bruke om et øyeblikk.

Frekvenskontroll

Nå er lydrutingen vår satt opp, la oss koble oss til den behandlingshendelsen jeg nevnte tidligere. Vi kan tilordne en funksjon til en ScriptProcessorNodes lydprosess eiendom som skal ringes når bufferen vår er full av behandlede prøver, og bruk vår AnalyserNodeEvne til å få signalets råfrekvensdata.

Analysatorens getByteFrequencyData befolker en Uint8Array med gjeldende buffers lyddata, i dette tilfellet, som verdier mellom 0 og 255. Vi bruker samme matrise på hver samtale, slik at vi ikke trenger å fortsette å lage nye matriser.

// Gjør at Uint8Array har samme størrelse som analysatorens bin telle var data = ny Uint8Array (analyser.frequencyBinCount); proc.onaudioprocess = onProcess; funksjon onProcess () {analyser.getByteFrequencyData (data); console.log (data [10]); }

For tiden skriver vi bare ut det tiende elementet i lyddataene på hver prosess (ikke veldig interessant), men vi kan se at prosessorhendelsen vår blir avfyrt med analysatoren vår som tolker dataene som sendes gjennom den. Dette ville være mye mer spennende å tegne på et lerret. Legg til en lerret> element med et id av "lerret", bredde på 1024 og høyde på 256 - la oss se på tegningskoden vi legger til i vår i prosessen funksjon.

var lerret = document.getElementById (’lerret’); var canvasCtx = canvas.getContext (’2d’); funksjon onProcess () {analyser.getByteFrequencyData (data); canvasCtx.clearRect (0, 0, canvas.width, canvas.height); for (var i = 0, l = data.length; i l; i ++) {canvasCtx.fillRect (i, - (canvas.height / 255) * data [i], 1, canvas.height); }}

Nå kalles det til en hendelse hver gang en lydbuffer behandles, takket være prosessornoden vår, ettersom analysatornoden vår fyller en Uint8Array med lyddata, og vi rydder lerretet og gjengir de nye dataene til det i form av frekvensbinger, som hver representerer et frekvensområde. Når vi skrubber filterkontrollene våre frem og tilbake, kan vi se på lerretet at vi fjerner høye frekvenser når vi beveger glidebryteren vår til venstre.

Vi kan se at når vi kobler til lydnoder, kan vi manipulere lyder vi hører og visualisere lyddataene. Dette eksemplet bruker en enkel biquad-filternode, men det er convolvors, gevinster, forsinkelser og andre måter å endre lyddata for musikere, spillutviklere eller synthesizer-entusiaster. Bli kreativ og spill med Web Audio API, ettersom linjene blir uskarpe mellom lydteknikere og webutviklere.

Ord: Jordan Santell

Denne artikkelen dukket opprinnelig opp i nettmagasinutgave 254.

Velg Administrasjon
Corel Painter 2017
Oppdage

Corel Painter 2017

ammen med de mange forbedringene om ikke kunne dekke her, gjør de nye verktøyene og funk jonene, pe ielt gradient-ek pre maling og tek turverktøy, 2017 til en verdig oppdatering, og de...
De beste USB-C-skjermene i 2021: Toppskjermer som også kan lade den bærbare datamaskinen
Oppdage

De beste USB-C-skjermene i 2021: Toppskjermer som også kan lade den bærbare datamaskinen

Å finne den be te U B-C- kjermen for deg handler om å balan ere enkelhet tilkoblingen bekvemmelighet med de andre funk jonene du trenger. År etter lan eringen er U B-C en tift for b...
John Foliot om de nye videoformatene
Oppdage

John Foliot om de nye videoformatene

Denne artikkelen dukket før t opp i nummer 224 av .net magazine - verden me t olgte maga in for webde ignere og utviklere.John Foliot jobber ved tanford Univer ity, hvor han driver tandard Online...