В этом уроке я научу вас создавать визуальное представление звукового спектра звукового файла с помощью метода Flash SoundMixer.computeSpectrum
. Для этого эффекта мы будем использовать четыре класса: Sound
, SoundChannel
, SoundMixer
и ByteArray
. Я объясню каждый класс, как мы их используем.
Окончательный результат предварительного просмотра
Давайте посмотрим на конечный результат, к которому мы будем стремиться:
Шаг 1: Настройте файл Flash
Запустите Flash Pro и создайте новый документ Flash. Установите размер сцены 500x300px, цвет фона # 000000 и частоту кадров 24 кадра в секунду.
В вашей временной шкале выберите существующий слой и переименуйте его в «Кнопки». Затем нажмите « Окно»> «Общие библиотеки»> «Кнопки» .
Выберите ваш любимый набор кнопок, затем перетащите кнопки «Play» и «Stop» в правый нижний угол сцены.
Установите имена экземпляров этих кнопок равными play_btn и stop_btn соответственно.
Шаг 2. Создайте класс документа
Создайте новый файл AS и сохраните его как Main.as. Добавьте этот код (читайте комментарии для более подробной информации):
Этот код должен быть помещен в наш новый класс:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
package {
import flash.display.Sprite;
import flash.media.Sound;
import flash.net.URLRequest;
public class Main extends Sprite {
private var sound:Sound;
public function Main() {
sound = new Sound(new URLRequest(«sound.mp3»));
sound.play();
}
}
}
|
Вам нужно будет поместить файл MP3 с именем sound.mp3 в тот же каталог, что и выходной каталог вашего FLA. Подойдет любой MP3; включен в исходную загрузку учебника.
Шаг 3: Класс документа
Добавьте имя класса в поле «Класс» в разделе «Публикация» на панели «Свойства», чтобы связать FLA с классом основного документа.
Если вы не знакомы с концепцией класса документа, ознакомьтесь с этим кратким советом, прежде чем читать дальше.
Затем нажмите Ctrl + Enter, чтобы протестировать ваше приложение.
Шаг 4: обработка звука с помощью кнопок
Давайте добавим экземпляр нового класса: SoundChannel
. Этот класс используется для хранения разных звуков в отдельных аудиоканалах; каждый канал создается экземпляром SoundChannel
, и мы используем эти экземпляры для управления звуками.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
package {
import flash.display.Sprite;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.URLRequest;
import flash.events.MouseEvent;
public class Main extends Sprite {
private var sound:Sound;
private var channel:SoundChannel;
public function Main() {
sound = new Sound(new 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();
}
}
}
|
Как видите, при нажатии кнопки «Воспроизведение» мы не просто воспроизводим MP3, мы также назначаем его для SoundChannel. Затем мы можем управлять воспроизведением через этот экземпляр SoundChannel позже — в этом случае, остановив его.
Шаг 5: создайте простую анимацию
Теперь давайте создадим простую анимацию для этого звука, снова используя класс SoundChannel.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
package {
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 extends Sprite {
private var sound:Sound;
private var channel:SoundChannel;
public function Main() {
sound = new Sound(new URLRequest(«sound.mp3»));
play_btn.addEventListener(MouseEvent.CLICK,onPlayHandler);
stop_btn.addEventListener(MouseEvent.CLICK,onStopHandler);
}
private function onPlayHandler(event:MouseEvent):void{
channel = sound.play();//assign sound to channel class
addEventListener(Event.ENTER_FRAME,animateBars);
}
private function onStopHandler(event:MouseEvent):void{
channel.stop();
graphics.clear();
removeEventListener(Event.ENTER_FRAME,animateBars);//stop rendering the animation
}
private function animateBars(event:Event):void{
graphics.clear();
graphics.beginFill(0xAB300C,1);
//Draw a rectangle whose height corresponds to channel.leftPeak
graphics.drawRect(190,300,50,-channel.leftPeak * 160 );
graphics.endFill();
graphics.beginFill(0xAB300C,1);
//Draw a rectangle whose height corresponds to channel.rightPeak
graphics.drawRect(250,300,50,-channel.rightPeak * 160 );
graphics.endFill();
}
}
}
|
leftPeak
и rightPeak
экземпляра SoundChannel
соответствуют текущей амплитуде звука через левый и правый каналы. Подумайте об этом так: если у вас есть стереодинамики, то leftPeak
— это громкость звука, выходящего из левого динамика, а rightPeak
— это громкость звука, выходящего из правого динамика.
Вы можете нажать Ctrl + Enter, чтобы протестировать ваше приложение:
Шаг 6: Что такое SoundMixer?
Класс SoundMixer
контролирует все встроенные и потоковые звуки в приложении для всех SoundChannels одновременно.
Он имеет три метода: areSoundsInaccessible()
, который определяет, являются ли какие-либо звуки недоступными по соображениям безопасности; stopAll()
, который останавливает воспроизведение всех звуков; и computeSpectrum()
, который нас интересует в этом уроке. Последний метод берет «снимок» текущего звука и помещает его в объект ByteArray.
Шаг 7: Что такое ByteArray?
Класс ByteArray предоставляет методы и свойства для оптимизации чтения, записи и работы с двоичными данными. Он хранит данные в виде массива байтов, отсюда и его имя. Узнайте больше с этим введением в ByteArray .
Шаг 8: более сложная анимация
Итак, теперь давайте создадим более сложную анимацию, используя метод SoundMixer.computeSpectrum()
. Снова, прочитайте комментарии в коде, чтобы полностью понять поведение:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
package {
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 extends Sprite{
private var sound:Sound;
private var channel: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(){
// create a «glow» effect for the animation we will render
glow.color = 0x009900;
glow.alpha = 1;
glow.blurX = 10;
glow.blurY = 10;
// load your MP3 in to the Sound object
sound = new Sound(new URLRequest(«sound.mp3»));
// apply the glow effect
filterArr = new Array(glow);
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(-1,150);
// push the spectrum’s bytes into the ByteArray
SoundMixer.computeSpectrum(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);
}
}
}
}
|
Наиболее важными частями этого кода являются строки 53 и 57. Здесь вся звуковая волна преобразуется в ByteArray, который затем читается, побайтно, и транслируется в набор чисел.
ByteArray будет длиной 512 операций с плавающей запятой; в цикле for
мы читаем только первые 256 значений с плавающей точкой, которые соответствуют всей звуковой волне левого канала (звук, проходящий через левый динамик)
Нажмите Ctrl + Enter, чтобы протестировать ваше приложение.
Шаг 9: Заполнить пробелы
Мы можем заполнить область под линией, чтобы получить другой эффект:
Все, что нам нужно сделать, это нарисовать прямоугольник и заполнить его, используя graphics
методы. Код для этого выглядит следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
package {
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 extends Sprite{
private var sound:Sound;
private var channel: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);
}
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{
// draw one edge of the box, and specify a fill
line.graphics.clear();
line.graphics.beginFill(0xFF0000,1);
line.graphics.lineStyle(1,0xFF0000);
line.graphics.moveTo(-1,150);
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);
}
}
}
|
Шаг 10: попробуй что-нибудь другое
Мы можем развить эту идею, добавив еще более интересные и сложные эффекты:
В этом случае мы нарисуем два спектра друг над другом, один для левого канала и один для правого. Чтобы достичь этого, мы будем использовать два цикла for
, каждый из которых читает 256 операций с плавающей запятой, один за другим.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
package {
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 extends Sprite{
private var sound:Sound;
private var channel: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;
public const CHANNEL_SIZE:int = 256;
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);
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{
num = 0;
line.graphics.clear();
line.graphics.lineStyle(0, 0x00FF00);
line.graphics.beginFill(0x00FF00,0.5);
line.graphics.moveTo(0,GRAFT_HEIGHT);
SoundMixer.computeSpectrum(byteArr);// add bytes to Sound mixer
for (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();
}
}
}
|
Вывод
Итак, мы узнали, как использовать различные классы Sound и как создавать красивые анимации рисования звука с помощью SoundMixer
.
Спасибо, что нашли время, чтобы прочитать эту статью, потому что это мой первый урок. Если у вас есть какие-либо вопросы, пожалуйста, оставьте их в комментарии.