【AS3】オーディオの動的生成と正弦波表示

このエントリーをはてなブックマークに追加

iyamaです。

なんか堅苦しいタイトルですが、ActionScriptでオーディオを
音声データやデバイスを使わず生成してみようということです。


 

前回の記事では、外部の音声データ(MP3ファイル)を呼び出して再生しましたが、
今回はActionScript上で生成して見ましょう。
また、昨日のchakemiさんみたく正弦波の波を描画してみたいと思います。
 

■環境
ActionScript 3.0
(※今回もFlashDevelopにてパブリッシュして検証しました)
 

■Main.as

package Main
{
        import flash.display.Graphics;
        import flash.display.Shape;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.SampleDataEvent;
        import flash.media.Sound;
        
        public class Main extends Sprite 
        {
                private var sound:Sound;
                private var sine:Shape;
                private var angle:Number;
                
                public function Main():void 
                {
                        if (stage) init();
                        else addEventListener(Event.ADDED_TO_STAGE, init);
                }
                
                private function init(e:Event = null):void 
                {
                        removeEventListener(Event.ADDED_TO_STAGE, init);

                        // sine
                        sine = new Shape();
                        sine.x = 0;
                        sine.y = stage.stageHeight / 2;
                        
                        // graphics
                        graphics.lineStyle(2, 0xFF00FF);
                        graphics.moveTo(sine.x, sine.y);
                        
                        // angle
                        angle = 0;
                        
                        // event
                        stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
                        
                        // sound
                        sound = new Sound();
                        sound.addEventListener(SampleDataEvent.SAMPLE_DATA, sineWaveGenerator);
                        sound.play();
                }
                
                /**
                 * sineWaveGenerator
                 * @param       event
                 */
                private function sineWaveGenerator(event:SampleDataEvent):void {
                        for (var i:int = 0; i < 8192; i++) {
                                var n:Number = Math.sin((i + event.position) / Math.PI / 4);
                                event.data.writeFloat(n);
                                event.data.writeFloat(n);
                        }
                }
                
                private function onEnterFrame(event:Event):void {
                        angle++;
                        sine.x++;
                        sine.y = (stage.stageHeight / 2) + Math.sin((angle) / Math.PI / 2) * 100;
                        graphics.lineTo(sine.x, sine.y);
                }
                
        }
        
}

 

■解説
動的に音声を生成することをFlashではダイナミックサウンドとも言うようです。
ダイナミックサウンドにするため、SampleDataEventを呼び出してください。
FlashPlayerの10以降からは新しく別の方法でも動的生成できるようですが、
とりあえずシンプルな方法にします。

オーディオ再生のためにSoundのインスタンスを作成し、
SampleDataEventのEventを登録してください。
サウンドのインスタンスをplay()するとSampleDataEventが実行されます。
オーディオを止めたいときはStop()を。
sineWaveGeneratorの中で同じ内容が2行書いてありますが、ステレオにするためです。
(右用、左用ということです。)
 

次に正弦波の表示ですが、ShapeとGraphicsを呼び出してください。
Shapeのインスタンスに、初期値(原点)を与え、表示する線の色とか指定しておきましょう。
描画にはEnterFrameを利用して表示させましょう。
わざわざangleでインクリメントしてますが、今回のような単純な表示の場合は
sine.xの値でもいいですね。後から気がつきました。
あと、sine.yの*100は*0.25にすると直線が描画されます。
 

■実行結果
正弦波
こんな感じになりますー。

return top