Rendering di uno spettro audio MP3 in Flash con computeSpectrum ()

In questo tutorial, ti insegnerò come creare una rappresentazione visiva dello spettro audio di un file audio, utilizzando Flash SoundMixer.computeSpectrum metodo. Useremo quattro classi per questo effetto: Suono, SoundChannel, SoundMixer, e ByteArray. Spiegherò ogni lezione mentre le usiamo.


Anteprima del risultato finale

Diamo un'occhiata al risultato finale su cui lavoreremo:


Clicca per vedere la demo

Passaggio 1: impostare il file Flash

Avvia Flash Pro e crea un nuovo documento Flash. Imposta le dimensioni dello stage su 500x300px, il colore dello sfondo su # 000000 e la frequenza fotogrammi su 24 fps.

Nella timeline, seleziona il livello esistente e rinominalo "Pulsanti". Quindi fare clic Finestra> Librerie comuni> Pulsanti.

Seleziona il tuo set di pulsanti preferito, quindi trascina e rilascia i pulsanti "Play" e "Stop" nell'angolo in basso a destra dello stage.


Impostare i nomi di istanza di questi pulsanti su play_btn e stop_btn, rispettivamente.

Passaggio 2: creare la classe del documento

Crea un nuovo file AS e salvalo come Main.as. Aggiungi questo codice (leggi i commenti per maggiori dettagli):

Questo codice dovrebbe essere inserito nella nostra nuova classe:

 pacchetto import flash.display.Sprite; import flash.media.Sound; // La classe Sound è il primo passo per lavorare con il suono. Viene utilizzato per caricare un suono, riprodurre un suono e gestire le proprietà del suono di base. import flash.net.URLRequest; public class Main estende Sprite private var sound: Sound; funzione pubblica Main () sound = new Sound (new URLRequest ("sound.mp3")); // assegna la musica alla variabile sonora. sound.play (); // riproduce l'audio assegnato. 

Avrai bisogno di mettere un file MP3 chiamato sound.mp3 nella stessa directory della directory di output del FLA. Qualsiasi MP3 farà; on è incluso nel download del sorgente del tutorial.


Passaggio 3: Classe documento

Aggiungi il nome della classe al campo Classe nella sezione Pubblica del pannello Proprietà per associare il FLA alla classe del documento Principale.

Se non hai familiarità con il concetto di una classe di documenti, consulta questo suggerimento rapido prima di leggere ulteriormente.

Quindi premi Ctrl + Invio per testare la tua applicazione.


Passaggio 4: Gestione del suono mediante i pulsanti

Aggiungiamo un'istanza di una nuova classe: SoundChannel. Questa classe è utilizzata per mantenere suoni diversi in canali audio separati; ogni canale è creato da un'istanza di SoundChannel, e usiamo queste istanze per controllare i suoni.

 pacchetto import flash.display.Sprite; import flash.media.Sound; import flash.media.SoundChannel; import flash.net.URLRequest; import flash.events.MouseEvent; public class Main estende Sprite private var sound: Sound; canale var privato: SoundChannel; funzione pubblica Main () sound = new Sound (new URLRequest ("sound.mp3")); play_btn.addEventListener (MouseEvent.CLICK, onPlayHandler); stop_btn.addEventListener (MouseEvent.CLICK, onStopHandler);  funzione privata onPlayHandler (event: MouseEvent): void channel = sound.play ();  funzione privata onStopHandler (event: MouseEvent): void channel.stop (); 

Come puoi vedere, quando si fa clic su Play, non suoniamo solo l'MP3, ma lo assegniamo anche a un SoundChannel. Possiamo quindi controllare la riproduzione attraverso questa istanza di SoundChannel in seguito, in questo caso, facendola fermare.


Passaggio 5: crea un'animazione semplice

Ora creiamo delle semplici animazioni per questo suono, usando ancora la classe SoundChannel.

 pacchetto 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 estende Sprite private var sound: Sound; canale var privato: SoundChannel; funzione pubblica Main () sound = new Sound (new URLRequest ("sound.mp3")); play_btn.addEventListener (MouseEvent.CLICK, onPlayHandler); stop_btn.addEventListener (MouseEvent.CLICK, onStopHandler);  funzione privata onPlayHandler (event: MouseEvent): void channel = sound.play (); // assegna il suono alla classe del canale addEventListener (Event.ENTER_FRAME, animateBars); // renderizza l'animazione ogni frame funzione privata onStopHandler (event: MouseEvent): void channel.stop (); graphics.clear (); removeEventListener (Event.ENTER_FRAME, animateBars); // interruzione del rendering dell'animazione private function animateBars (event: Event): void graphics.clear (); graphics.beginFill (0xAB300C, 1); // Disegna un rettangolo la cui altezza corrisponde a channel.leftPeak graphics.drawRect (190,300,50, -channel.leftPeak * 160); graphics.endFill (); graphics.beginFill (0xAB300C, 1); // Disegna un rettangolo la cui altezza corrisponde a channel.rightPeak graphics.drawRect (250,300,50, -channel.rightPeak * 160); graphics.endFill (); 

Il leftPeak e rightPeak proprietà di a SoundChannel l'istanza corrisponde all'ampiezza corrente del suono, attraverso i canali sinistro e destro. Pensaci in questo modo: se hai altoparlanti stereo, allora leftPeak è il volume del suono che esce dall'altoparlante sinistro e rightPeak è il volume del suono che esce dall'altoparlante destro.

Puoi premere Ctrl + Invio per testare la tua applicazione:


Passaggio 6: cos'è SoundMixer?

Il SoundMixer class controlla tutti i suoni incorporati e in streaming nell'applicazione, per tutti i SoundChannel contemporaneamente.

Ha tre metodi: areSoundsInaccessible (), che determina se alcuni suoni sono inaccessibili a causa di motivi di sicurezza; stopAll (), che interrompe la riproduzione di tutti i suoni; e computeSpectrum (), che è ciò che ci interessa per questo tutorial. Quest'ultimo metodo acquisisce una "istantanea" del suono corrente e lo inserisce in un oggetto ByteArray.


Passaggio 7: cos'è ByteArray?

La classe ByteArray fornisce metodi e proprietà per ottimizzare la lettura, la scrittura e il lavoro con i dati binari. Memorizza i dati come una matrice di byte, da cui il suo nome. Scopri di più con questa Introduzione a ByteArray.


Passaggio 8: Animazione più complessa

Quindi ora creiamo un'animazione più complessa usando il SoundMixer.computeSpectrum () metodo. Ancora una volta, leggi i commenti nel codice per comprendere appieno il comportamento:

 pacchetto 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 estende Sprite private var sound: Sound; canale var privato: 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 () // crea un effetto "glow" per l'animazione che renderizzeremo glow.color = 0x009900; glow.alpha = 1; glow.blurX = 10; glow.blurY = 10; // carica il tuo MP3 nell'oggetto Sound sound = new Sound (new URLRequest ("sound.mp3")); // applica l'effetto glow filterArr = new Array (glow); line.filters = filterArr; addChild (line); play_btn.addEventListener (MouseEvent.CLICK, onPlayHandler); stop_btn.addEventListener (MouseEvent.CLICK, onStopHandler);  funzione privata onPlayHandler (event: MouseEvent): void channel = sound.play (0,1000); addEventListener (Event.ENTER_FRAME, spectrumHandler);  funzione privata 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); // spinge i byte dello spettro in ByteArray SoundMixer.computeSpectrum (byteArr); per (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);    

Le parti più importanti di questo codice sono le linee 53 e 57. Qui, l'intera onda sonora viene tradotta in un ByteArray, che viene quindi letto, byte per byte e tradotto in un insieme di numeri.

ByteArray sarà lungo 512 float; nel per loop, leggiamo solo i primi 256 float, che corrispondono all'intera onda sonora del canale sinistro (il suono proveniente dall'altoparlante sinistro).

Premi Ctrl + Invio per testare la tua applicazione.


Passaggio 9: riempire gli spazi vuoti

Possiamo riempire l'area sotto la linea per darci un effetto diverso:

Tutto ciò che dobbiamo fare è disegnare una scatola e riempirla, usando grafica metodi. Il codice per questo è il seguente:

 pacchetto 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 estende Sprite private var sound: Sound; canale var privato: 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 () glow.color = 0xFF0000; glow.alpha = 1; glow.blurX = 10; glow.blurY = 10; sound = new Sound (new URLRequest ("sound.mp3")); filterArr = new Array (glow); line.filters = filterArr; addChild (line); addChild (play_btn); addChild (stop_btn); play_btn.addEventListener (MouseEvent.CLICK, onPlayHandler); stop_btn.addEventListener (MouseEvent.CLICK, onStopHandler);  funzione privata onPlayHandler (event: MouseEvent): void channel = sound.play (0,1000); addEventListener (Event.ENTER_FRAME, spectrumHandler);  funzione privata onStopHandler (event: MouseEvent): void channel.stop (); line.graphics.clear (); removeEventListener (Event.ENTER_FRAME, spectrumHandler);  private function spectrumHandler (event: Event): void // disegna un bordo della casella e specifica un riempimento line.graphics.clear (); line.graphics.beginFill (0xFF0000,1); line.graphics.lineStyle (1,0xFF0000); line.graphics.moveTo (-1150); SoundMixer.computeSpectrum (byteArr); per (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);   

Passaggio 10: prova qualcosa di diverso

Possiamo portare ulteriormente questa idea, per aggiungere effetti ancora più interessanti e complessi:

In questo caso, disegneremo due spettri uno sopra l'altro, uno per il canale sinistro e uno per quello destro. Per ottenere ciò, ne useremo due per cicli che ogni lettura in 256 fluttua, uno dopo l'altro.

 pacchetto 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 estende Sprite private var sound: Sound; canale var privato: 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; public const GRAFT_HEIGHT: int = 150; // imposta altezza animazione pubblico const CHANNEL_SIZE: int = 256; // imposta la dimensione del canale left / right public function Main () glow.color = 0x009900; glow.alpha = 1; glow.blurX = 10; glow.blurY = 10; sound = new Sound (new URLRequest ("sound.mp3")); filterArr = new Array (glow); // aggiungi bagliore all'animazione line.filters = filterArr; addChild (line); play_btn.addEventListener (MouseEvent.CLICK, onPlayHandler); stop_btn.addEventListener (MouseEvent.CLICK, onStopHandler);  funzione privata onPlayHandler (event: MouseEvent): void channel = sound.play (0,1000); // riproduce il suono 1000 volte addEventListener (Event.ENTER_FRAME, spectrumHandler);  funzione privata 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 (); // crea la grafica corrente line.graphics.lineStyle (0, 0x00FF00); line.graphics.beginFill (0x00FF00,0.5); line.graphics.moveTo (0, GRAFT_HEIGHT); SoundMixer.computeSpectrum (byteArr); // aggiungi byte al mixer audio per (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 - num);  line.graphics.lineTo (0, GRAFT_HEIGHT); line.graphics.endFill (); 

Conclusione

Quindi abbiamo imparato come usare le varie classi di suoni e come creare bellissime animazioni di disegni sonori usando SoundMixer.

Grazie per aver dedicato del tempo a leggere questo articolo, perché questo è il mio primo tutorial. Se avete domande, per favore lasciatele in un commento.