【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にすると直線が描画されます。
コメント 0