В этом уроке я научу вас создавать визуальное представление звукового спектра звукового файла с помощью метода 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 .
Спасибо, что нашли время, чтобы прочитать эту статью, потому что это мой первый урок. Если у вас есть какие-либо вопросы, пожалуйста, оставьте их в комментарии.