Flash10でのサウンド作成機能を使ってみたよ。

Flash10でのサウンド作成機能を使ってみました。
こんな感じ。
http://moeten.info/flex/20081016_fp10Test/bin-release/test10.html
音出るのでボリューム絞ってからアクセスしてください(^−^)

将来的にはマウスを用いてユーザーとの対話ができると面白そう。
参考リンク

ソースはこちら

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    creationComplete="creationCompleteHandler(event)" width="700" height="800"
    backgroundGradientAlphas="[1.0, 1.0]" backgroundGradientColors="[#FFFFFF, #626262]">
<mx:Script>
<![CDATA[
import caurina.transitions.Tweener;
import flash.sampler.Sample;
import flash.display.Sprite;
import flash.events.SampleDataEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
private var phase:Number = 0;
private var freq:Number = 440;
private const PI2:Number = Math.PI * 2;
private var soundChannelObject:SoundChannel = new SoundChannel();
private var bd:BitmapData
private var bdA:BitmapData
private var bdB:BitmapData
private var bdF:BitmapData
//初期化
private function creationCompleteHandler(e:Event):void{
    //sin波描画用
    bd  = new BitmapData( myImage.width , myImage.height);
    bdA = new BitmapData( myImageA.width , myImageA.height);
    bdB = new BitmapData( myImageB.width , myImageB.height);
    bdF = new BitmapData( myImageF.width , myImageF.height);
    //サウンド作成
    var mySound:Sound = new Sound();
    mySound.addEventListener(SampleDataEvent.SAMPLE_DATA,onSampleData);
    soundChannelObject = mySound.play();
}
private var t:Number = 1;
private var bytes:ByteArray = new ByteArray();
private var spectrum:Array  = new Array(256);
private function onSampleData(e:SampleDataEvent):void
{
    var smpl:Number;
    var smplA:Number;
    var smplB:Number;
    var w:Number = PI2 * freq / 44100;
    var latency:Number = e.position / 44.1 - soundChannelObject.position;
    t = sliderT.value;
    bd.lock();
    bdA.lock();
    bdB.lock();
    bdF.lock();
    //sin波の作成
    for (var i:int = 0; i < 4096; ++i) {
        phase += w;
        if (phase > PI2) {
            phase -= PI2;
        }
        smplA = Math.sin( phase * t * sliderA.value ) * sliderAV.value;
        smplB = Math.sin( phase * t * sliderB.value ) * sliderBV.value;
        smpl = (smplA + smplB) * sliderV.value;
        bd.setPixel(  phase *100 +10 , smpl   *30 + 80 , 0xff0000 );
        bdA.setPixel( phase *100 +10 , smplA  *30 + 40 , 0x00ff00 );
        bdB.setPixel( phase *100 +10 , smplB  *30 + 40 , 0x0000ff );
        e.data.writeFloat(smpl);
        e.data.writeFloat(smpl);
    }
    //FFT用
    SoundMixer.computeSpectrum(bytes, true, 0);
    for (var i:int = 0; i < 256; ++i) {
        spectrum[i] = bytes.readFloat();
        bdF.setPixel( i*1 , bytes.readFloat()*100 , 0xff0000 );
    }
    //画像へ表示
    myImage.source  = new Bitmap( bd );
    myImageA.source = new Bitmap( bdA );
    myImageB.source = new Bitmap( bdB );
    myImageF.source = new Bitmap( bdF );
}
//キャンバスをクリア
private function onChange():void{
    bd  = new BitmapData( myImage.width , myImage.height);
    bdA = new BitmapData( myImageA.width , myImageA.height);
    bdB = new BitmapData( myImageB.width , myImageB.height);
    bdF = new BitmapData( myImageF.width , myImageF.height);
}
//Tweenerで音声を遊ぶ
private function startTween(num:int):void{
    if( num == 1 ){
        Tweener.addTween( sliderA ,{
                            value:10,
                            time:10,
                            transition:"easeInOutCubic"
                        });
        Tweener.addTween( sliderB ,{
                            value:5,
                            time:10,
                            transition:"easeInOutBounce"
                        });
        Tweener.addTween( sliderT ,{
                            value:10,
                            time:10,
                            transition:"easeInOutBounce"
                        });
    }
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%" verticalGap="3">
    <mx:Button label="Tween" click="startTween(1)"/>
    <!-- sin A -->
    <mx:HDividedBox>
        <mx:VBox>
            <mx:Label text="sinA Math.sin( 2pi * t * sliderA.value )" />
            <mx:HSlider id="sliderA" minimum="0" maximum="10" value="1" change="onChange()" showTrackHighlight="true" labels="{[0,10]}"/>
        </mx:VBox>
        <mx:VBox>
            <mx:Label text="sinA Volume" />
            <mx:HSlider id="sliderAV" minimum="0" maximum="1" value="0.5" change="onChange()" showTrackHighlight="true" labels="{[0,1]}"/>
        </mx:VBox>
    </mx:HDividedBox>
    <mx:Image id="myImageA" width="100%" height="80"/>
    <!-- sin B -->
    <mx:HDividedBox>
        <mx:VBox>
            <mx:Label text="sinB Math.sin( 2pi * t * sliderB.value )" />
            <mx:HSlider id="sliderB" minimum="0" maximum="10" value="1" change="onChange()" showTrackHighlight="true" labels="{[0,10]}"/>
        </mx:VBox>
        <mx:VBox>
            <mx:Label text="sinB Volume" />
            <mx:HSlider id="sliderBV" minimum="0" maximum="1" value="0.5" change="onChange()" showTrackHighlight="true" labels="{[0,1]}"/>
        </mx:VBox>
    </mx:HDividedBox>
    <mx:Image id="myImageB" width="100%" height="80"/>
    <!-- sin A + B -->
    <mx:HDividedBox>
        <mx:VBox>
            <mx:Label text="sinA + sinB" />
            <mx:HSlider id="sliderT" minimum="0" maximum="10" value="1" labels="周期T" change="onChange()" showTrackHighlight="true"/>
        </mx:VBox>
        <mx:VBox>
            <mx:Label text="sin Volume" />
            <mx:HSlider id="sliderV" minimum="0" maximum="1" value="0.5" change="onChange()" showTrackHighlight="true" labels="{[0,1]}"/>
        </mx:VBox>
    </mx:HDividedBox>
    <mx:Image id="myImage" width="100%" height="150"/>
    <!-- FFT -->
    <mx:Label text="FFT L R " />
    <mx:Image id="myImageF" width="100%" height="150"/>
</mx:VBox>
</mx:Application>