In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: forked from: 音声合成もどき

Get Adobe Flash player
by h_sakurai 01 Mar 2009
    Embed
// forked from Nully's forked from: 音声合成もどき
// forked from wanson's 音声合成もどき
package {
    import flash.display.*;
    import flash.events.*;
    import flash.media.*;
    import flash.geom.*;

    [SWF(width=465, height=465, backgroundColor=0x0, frameRate=30)]
    public class Voice extends Sprite {
        private var phase:Number = 0, time:Number = 0;
        private var tap:Array = [0, 0];
        private const FL:Array = [
            [800.,  0.8], // あ
           [250.,  1.4],// い
            [250.,  1.2],// う
           [450.,  0.9],// え
            [450.,  0.8]// お
];
        private var bitmap:BitmapData = new BitmapData(465,465,true,0);
        public function Voice() { 
            rect.width = 1; rect.height = 1;
            addChild(new Bitmap(bitmap));
            var sound:Sound = new Sound();
            sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
            sound.play();
        }
        private var rect:Rectangle = new Rectangle();
        private function setPixcel(x:int, y:int,c:int):void {
            rect.x = x;
            rect.y = y;
            
            bitmap.fillRect(rect, c);
        }
        private function onSampleData(event:SampleDataEvent):void {
            bitmap.fillRect(bitmap.rect,0);
            for (var i:int = 0; i < 8192; i++) {
                // params
                var time2:Number = time / 1.5 * 5;
                var time3:Number = time / 1.7 * 5;
                const vow1:int = Math.floor(time2) % FL.length;// あいうえおのうち1つ選択
                const vow2:int = (vow1 + 1) % FL.length;// vow1の次の母音選択
                const amp:Number = (.65);// 音の大きさ
                const freq:Number = 260;// + 100 * Math.cos(time /2* Math.PI );// 周波数

                // synthesize
                var s:Number = .4 * ((phase - Math.floor(phase)))
                     * FL[vow1][1] * amp;// 三角波を作る?
                
                setPixcel(i/2,-s*200+150, 0xffff0000);
                s = 0.2*(Math.sin(phase*8)+1)*FL[vow1][1]*amp;
                setPixcel(i/2,-s*200+150, 0xffff00ff);
                
                const ff:Number = FL[vow1][0];// たとえば"あ"と"い"の中間をとる。

/*
                // 指数関数を使っていいかんじにffを拡張する。
                //const r:Number  = Math.exp(
                //    -Math.PI * 50. * (1. + ff * ff * 1e-7 ) / 44100.);
                const r:Number = 0.99
                const a1:Number = 2. * r * 
                    Math.cos(2.0 * Math.PI * ff / 44100.);
                // tap[0]は1つ前
                // tap[1]は2つ前
                s = s
                      + (   a1 * (tap[0]-s)) 
                      - (r * r * (tap[1]-s))
*/
                const r:Number  = Math.exp(
                    -Math.PI * 50. * (1. + ff * ff * 1e-7 ) / 44100.);
                const a1:Number = 2. * r *
                    Math.cos(2.0 * Math.PI * ff / 44100.); 

                // tap[0]は1つ前
                // tap[1]は2つ前
                s = s
                      + (a1 * (tap[0]-s)) 
                      - (r*r* (tap[1]-s))

                setPixcel(i/2, -s*200+150, 0xff00ffff);
                tap[1] = tap[0]; tap[0] = s;

                // 音をステレオで出力
                event.data.writeFloat(s); event.data.writeFloat(s);
                // 周波数分進める。
                phase += freq / 44100.;
                // 時間を1フレーム分(1/44100秒)進める
                time  += 1.0 / 44100.;
            }
        }
    }
}