In deze zelfstudie leer ik je hoe je een visuele weergave van het geluidsspectrum van een geluidsbestand maakt met behulp van Flash's SoundMixer.computeSpectrum
methode. We gebruiken vier klassen voor dit effect: Geluid
, SoundChannel
, SoundMixer
, en ByteArray
. Ik zal elke les uitleggen terwijl we ze gebruiken.
Laten we eens kijken naar het eindresultaat waar we naartoe zullen werken:
Start Flash Pro en maak een nieuw Flash-document. Stel de stage in op 500x300 px, de achtergrondkleur op # 000000 en de framesnelheid op 24 fps.
Selecteer in je tijdlijn de bestaande laag en hernoem deze "Knoppen". Dan klikken Venster> Algemene bibliotheken> Knoppen.
Selecteer uw favoriete knoppenset en sleep de knoppen 'Afspelen' en 'Stoppen' naar de rechterbenedenhoek van het werkgebied.
Stel de instantienamen van deze knoppen in play_btn en stop_btn, respectievelijk.
Maak een nieuw AS-bestand en sla het op als Main.as. Voeg deze code toe (lees de opmerkingen voor meer details):
Deze code moet in onze nieuwe klas worden geplaatst:
pakket import flash.display.Sprite; import flash.media.Sound; // De klasse Sound is de eerste stap in het werken met geluid. Het wordt gebruikt om een geluid te laden, een geluid te spelen en elementaire geluidseigenschappen te beheren. import flash.net.URLRequest; public class Main breidt Sprite uit private var sound: Sound; openbare functie Main () sound = new Sound (nieuwe URLRequest ("sound.mp3")); // wijs muziek toe aan de geluidsvariabele. sound.play (); // speel toegewezen geluid.
U moet een MP3-bestand met de naam sound.mp3 in dezelfde map als de uitvoermap van uw FLA. Elke MP3 zal doen; Aan is opgenomen in de brondownload van de zelfstudie.
Voeg de klassenaam toe aan het veld Class in het gedeelte Publiceren van het venster Properties om de FLA te koppelen aan de klasse Main document.
Als u niet bekend bent met het concept van een documentklasse, bekijk dan deze Quick Tip voordat u verder leest.
Druk vervolgens op Ctrl + Enter om uw toepassing te testen.
Laten we een instantie van een nieuwe klasse toevoegen: SoundChannel
. Deze klasse wordt gebruikt om verschillende geluiden in afzonderlijke audiokanalen te houden; elk kanaal wordt gemaakt door een instantie van SoundChannel
, en we gebruiken deze instanties om de geluiden te besturen.
pakket import flash.display.Sprite; import flash.media.Sound; import flash.media.SoundChannel; import flash.net.URLRequest; import flash.events.MouseEvent; public class Main breidt Sprite uit private var sound: Sound; privé var-kanaal: SoundChannel; openbare functie Main () sound = new Sound (nieuwe URLRequest ("sound.mp3")); play_btn.addEventListener (MouseEvent.CLICK, onPlayHandler); stop_btn.addEventListener (MouseEvent.CLICK, onStopHandler); private function onPlayHandler (event: MouseEvent): void channel = sound.play (); private function onStopHandler (event: MouseEvent): void channel.stop ();
Zoals je kunt zien, spelen we niet alleen de MP3 op Play, maar ook aan een SoundChannel. We kunnen het afspelen vervolgens via deze SoundChannel-instantie regelen, in dit geval door het te laten stoppen.
Laten we nu een eenvoudige animatie voor dit geluid maken, opnieuw met behulp van de klasse SoundChannel.
pakket import flash.display.Sprite; import flash.media.Sound; import flash.media.SoundChannel; import flash.net.URLRequest; import flash.events.MouseEvent; import flash.events.Event; public class Main breidt Sprite uit private var sound: Sound; privé var-kanaal: SoundChannel; openbare functie Main () sound = new Sound (nieuwe URLRequest ("sound.mp3")); play_btn.addEventListener (MouseEvent.CLICK, onPlayHandler); stop_btn.addEventListener (MouseEvent.CLICK, onStopHandler); private function onPlayHandler (event: MouseEvent): void channel = sound.play (); // wijs geluid toe aan kanaalklasse addEventListener (Event.ENTER_FRAME, animateBars); // render de animatie elk frame persoonlijke functie onStopHandler (event: MouseEvent): void channel.stop (); graphics.clear (); removeEventListener (Event.ENTER_FRAME, animateBars); // stop rendering van de animatie private function animateBars (event: Event): void grafische.clear (); graphics.beginFill (0xAB300C, 1); // Teken een rechthoek waarvan de hoogte overeenkomt met channel.leftPeak graphics.drawRect (190.300,50, -channel.leftPeak * 160); graphics.endFill (); graphics.beginFill (0xAB300C, 1); // Teken een rechthoek waarvan de hoogte overeenkomt met channel.rightPeak graphics.drawRect (250.300,50, -channel.rightPeak * 160); graphics.endFill ();
De leftPeak
en rightPeak
eigenschappen van een SoundChannel
instantie komt overeen met de huidige amplitude van het geluid, via de linker- en rechterkanalen. Zie het op deze manier: als je stereoluidsprekers hebt, dan leftPeak
is het volume van het geluid dat uit de linkerluidspreker komt, en rightPeak
is het volume van het geluid dat uit de rechterluidspreker komt.
U kunt op Ctrl + Enter drukken om uw toepassing te testen:
De SoundMixer
class regelt alle ingesloten en gestreamde geluiden in de toepassing, voor alle SoundChannels tegelijk.
Het heeft drie methoden: areSoundsInaccessible ()
, die bepaalt of geluiden om veiligheidsredenen ontoegankelijk zijn; stop alles()
, die het afspelen van alle geluiden stopt; en computeSpectrum ()
, dat is waar we in geïnteresseerd zijn voor deze tutorial. De laatste methode neemt een "momentopname" van het huidige geluid en duwt het in een ByteArray-object.
De klasse ByteArray biedt methoden en eigenschappen om het lezen, schrijven en werken met binaire gegevens te optimaliseren. Het slaat gegevens op als een reeks bytes, vandaar de naam. Lees meer met deze Inleiding tot ByteArray.
Laten we nu een complexere animatie maken met behulp van de SoundMixer.computeSpectrum ()
methode. Lees nogmaals de opmerkingen in de code om het gedrag volledig te begrijpen:
pakket import flash.display.Sprite; import flash.media.Sound; import flash.utils.ByteArray; import flash.events.Event; import flash.media.SoundMixer; import flash.filters.GlowFilter; import flash.net.URLRequest; import flash.events.MouseEvent; import flash.media.SoundChannel; public class Main breidt Sprite uit private var sound: Sound; privé var-kanaal: SoundChannel; private var byteArr: ByteArray = new ByteArray (); private var glow: GlowFilter = new GlowFilter (); private var filterArr: Array; private var line: Sprite = new Sprite (); public function Main () // maak een "glow" -effect voor de animatie die we zullen genereren glow.color = 0x009900; glow.alpha = 1; glow.blurX = 10; glow.blurY = 10; // laad uw MP3 in het Sound-objectgeluid = new Sound (nieuwe URLRequest ("sound.mp3")); // pas het filter met gloedeffect toe AR = nieuwe array (gloed); line.filters = filterArr; addChild (line); play_btn.addEventListener (MouseEvent.CLICK, onPlayHandler); stop_btn.addEventListener (MouseEvent.CLICK, onStopHandler); private function onPlayHandler (event: MouseEvent): void channel = sound.play (0,1000); addEventListener (Event.ENTER_FRAME, spectrumHandler); private function onStopHandler (event: MouseEvent): void channel.stop (); line.graphics.clear (); removeEventListener (Event.ENTER_FRAME, spectrumHandler); private function spectrumHandler (event: Event): void line.graphics.clear (); line.graphics.lineStyle (1, Math.random () * 0xFFFFFF); line.graphics.moveTo (-1150); // duw de bytes van het spectrum naar de ByteArray SoundMixer.compute Spectrum (byteArr); for (var i: uint = 0; i<256; i++) // read bytes and translate to a number between 0 and +300 var num:Number = byteArr.readFloat() * 150 + 150; //use this number to draw a line line.graphics.lineTo(i*2,num);
De belangrijkste delen van deze code zijn regels 53 en 57. Hier wordt de hele geluidsgolf naar een ByteArray vertaald, die vervolgens wordt gelezen, byte voor byte en vertaald naar een reeks getallen.
De ByteArray zal 512 drijvers lang zijn; in de voor
loop, we lezen alleen de eerste 256 drijvers, die overeenkomen met de gehele geluidsgolf van het linkerkanaal (het geluid dat door de linkerluidspreker komt).
Druk op Ctrl + Enter om uw toepassing te testen.
We kunnen het gebied onder de lijn invullen om ons een ander effect te geven:
Alles wat we moeten doen is een doos tekenen en invullen, met behulp van grafiek
methoden. De code hiervoor is als volgt:
pakket import flash.display.Sprite; import flash.media.Sound; import flash.utils.ByteArray; import flash.events.Event; import flash.media.SoundMixer; import flash.filters.GlowFilter; import flash.net.URLRequest; import flash.events.MouseEvent; import flash.media.SoundChannel; public class Main breidt Sprite uit private var sound: Sound; privé var-kanaal: SoundChannel; private var byteArr: ByteArray = new ByteArray (); private var glow: GlowFilter = new GlowFilter (); private var filterArr: Array; private var line: Sprite = new Sprite (); openbare functie Hoofd () glow.color = 0xFF0000; glow.alpha = 1; glow.blurX = 10; glow.blurY = 10; sound = new Sound (nieuwe URLRequest ("sound.mp3")); filterArr = nieuwe array (gloed); line.filters = filterArr; addChild (line); addChild (play_btn); addChild (stop_btn); play_btn.addEventListener (MouseEvent.CLICK, onPlayHandler); stop_btn.addEventListener (MouseEvent.CLICK, onStopHandler); private function onPlayHandler (event: MouseEvent): void channel = sound.play (0,1000); addEventListener (Event.ENTER_FRAME, spectrumHandler); private function onStopHandler (event: MouseEvent): void channel.stop (); line.graphics.clear (); removeEventListener (Event.ENTER_FRAME, spectrumHandler); private function spectrumHandler (event: Event): void // teken één rand van het vak en geef een fill line.graphics.clear (); line.graphics.beginFill (0xFF0000,1); line.graphics.lineStyle (1,0xFF0000); line.graphics.moveTo (-1150); SoundMixer.computeSpectrum (byteArr); for (var i: uint = 0; i<256; i++) var num:Number = byteArr.readFloat() * 200 + 150; line.graphics.lineTo(i*2,num); //draw the rest of the box line.graphics.lineTo(512,300); line.graphics.lineTo(0,300); line.graphics.lineTo(-1,150);
We kunnen dit idee verder brengen om nog interessantere en complexere effecten toe te voegen:
In dit geval tekenen we twee spectra op elkaar, één voor het linkerkanaal en één voor het rechterkanaal. Om dit te bereiken, zullen we er twee gebruiken voor
loops die elk 256 dobbers achter elkaar lezen.
pakket import flash.display.Sprite; import flash.media.Sound; import flash.utils.ByteArray; import flash.events.Event; import flash.media.SoundMixer; import flash.filters.GlowFilter; import flash.net.URLRequest; import flash.events.MouseEvent; import flash.media.SoundChannel; public class Main breidt Sprite uit private var sound: Sound; privé var-kanaal: SoundChannel; private var byteArr: ByteArray = new ByteArray (); private var glow: GlowFilter = new GlowFilter (); private var filterArr: Array; private var line: Sprite = new Sprite (); private var num: Number; openbare const GRAFT_HEIGHT: int = 150; // stel de hoogte van de animatie in op public const CHANNEL_SIZE: int = 256; // stel linker- / rechterkanaalgrootte in publieke functie Hoofd () glow.color = 0x009900; glow.alpha = 1; glow.blurX = 10; glow.blurY = 10; sound = new Sound (nieuwe URLRequest ("sound.mp3")); filterArr = nieuwe array (gloed); // gloed toevoegen aan de animatielijn.filters = filterArr; addChild (line); play_btn.addEventListener (MouseEvent.CLICK, onPlayHandler); stop_btn.addEventListener (MouseEvent.CLICK, onStopHandler); private function onPlayHandler (event: MouseEvent): void channel = sound.play (0,1000); // speel geluid 1000 keer addEventListener (Event.ENTER_FRAME, spectrumHandler); private function onStopHandler (event: MouseEvent): void channel.stop (); line.graphics.clear (); removeEventListener (Event.ENTER_FRAME, spectrumHandler); private function spectrumHandler (event: Event): void num = 0; line.graphics.clear (); // maak de huidige grafische lijn.graphics.lineStyle (0, 0x00FF00); line.graphics.beginFill (0x00FF00,0.5); line.graphics.moveTo (0, GRAFT_HEIGHT); SoundMixer.computeSpectrum (byteArr); // bytes toevoegen aan Sound-mixer voor (var i: int = 0; i < CHANNEL_SIZE; i++) num = (byteArr.readFloat() * GRAFT_HEIGHT); line.graphics.lineTo(i * 2, GRAFT_HEIGHT - num); line.graphics.lineTo(CHANNEL_SIZE * 2, GRAFT_HEIGHT); line.graphics.endFill(); line.graphics.lineStyle(0, 0xFF0000); line.graphics.beginFill(0xFF0000, 0.5); line.graphics.moveTo(CHANNEL_SIZE * 2,GRAFT_HEIGHT); for (i = CHANNEL_SIZE; i > 0; i--) num = (byteArr.readFloat () * GRAFT_HEIGHT); line.graphics.lineTo (i * 2, GRAFT_HEIGHT - aantal); line.graphics.lineTo (0, GRAFT_HEIGHT); line.graphics.endFill ();
We hebben dus geleerd hoe we de verschillende geluidsklassen kunnen gebruiken en hoe we mooie geluidstekeninganimaties kunnen maken met SoundMixer
.
Bedankt dat je de tijd hebt genomen om dit artikel te lezen, want dit is mijn eerste zelfstudie. Als u vragen heeft, laat deze dan achter in een opmerking.