【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