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

dynamic sound generate. ランダムな音。

ランダムに音をならします。

ずっと聞いてたら気持ち悪くなった。
/**
 * Copyright sakef ( http://wonderfl.net/user/sakef )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/7op2
 */

package
{
    import flash.display.Graphics;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.SampleDataEvent;
    import flash.events.TimerEvent;
    import flash.media.Sound;
    import flash.media.SoundMixer;
    import flash.utils.ByteArray;
    import flash.utils.Timer;
    
    [SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="40")]
    public class Main extends Sprite
    {
        private static const SAMPLING:int = 2048;            // バッファ
        private static const SAMPLING_RATE:int = 44100;    // サンプリングレート
        private static const PI:Number = Math.PI * 2;        // 1周期
        private static const VOLUME:Number = 0.1;            // ボリューム
        private static const MAX:Number = 0.5;            // 音の最大値
        private var container:Array;
        
        public function Main()
        {
            // コンテナ
            container = [];
            
            // タイマーの初期化
            var t:Timer = new Timer(1000);
            t.addEventListener(TimerEvent.TIMER, addSound);
            t.start();
            
            // サウンドの再生
            var sound:Sound = new Sound;
            sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
            sound.play();
            addEventListener(Event.ENTER_FRAME, onFrame);
        }
        
        private function addSound(e:TimerEvent=null):void
        {
            // 周波数の計算
            // 2 の (1 / 12) 乗を乗算すると音程を1段階上げる。
            var freq:Number = 220 * Math.pow(2, (int(30*Math.random()))/12);
            var s:SoundData = new SoundData(freq, 0.05, 0.05, 40, 1);
            container.push(s);
        }
        
        // 波形を書き込む
        private function onSampleData(e:SampleDataEvent):void
        {
            var data:ByteArray = e.data;
            var pos:Number = e.position;
            var len:int = container.length;
            var s:SoundData;
            var i:int, n:int;    
            
            for(i=0 ; i<SAMPLING ; i++)
            {
                var d:Number = 0;
                n = len;
                
                // データを足し合わせていく。
                while(n--)
                {
                    s = container[n] as SoundData;
                    var w:Number = (PI * s.frequency / SAMPLING_RATE);
                    d += VOLUME * s.volume * Math.sin(((pos + i) * w) % PI) * 0.4;
                }
                
                // データを範囲内に丸める
                d = (d > -MAX)?(d):(MAX);
                d = (d < MAX)?(d):(MAX);
                
                // 書き込み
                data.writeFloat(d);
                data.writeFloat(d);
            }
            
            n = container.length;
            while(n--)
            {
                s = (container[n] as SoundData);
                s.renderSound();
                if(s.state == 3) container.splice(n,1);    
            }
        }
        
        // スペクトラムを描写
        private function onFrame(e:Event):void
        {
            var g:Graphics = graphics;
            g.clear();
            
            g.lineStyle(0.5, 0x555555);
            g.drawRect(50, 50, 350, 280);
            
            var bytes:ByteArray = new ByteArray();
            SoundMixer.computeSpectrum(bytes, true, 0);
            
            for (var i:int = 0; i < 50; i++)
            {
                var spec:Number = bytes.readFloat();
                var h:int = 250 * spec;
                g.moveTo(50 + 7*i, 330);
                g.lineTo(50 + 7*i, 330-h);
            }
        }
    }
}

// 音データを保持するクラス
class SoundData
{
    public var frequency:Number;
    public var volume:Number;
    public var state:int;
    
    private var fadeIn:Number;
    private var fadeOut:Number;
    private var show:Number;
    private var volMax:Number;
    private var count:int;
    
    public function SoundData(frequency:Number, fadeIn:Number, fadeOut:Number, show:int, volMax:Number)
    {
        this.frequency = frequency;
        this.fadeIn = fadeIn;
        this.fadeOut = fadeOut;
        this.show = show;
        this.volMax = volMax;
        this.volume = this.state = this.count = 0
    }
    
    public function renderSound():void
    {
        switch(state)
        {
            // 音をフェードインさせる
            case 0:
                volume += fadeIn;
                if(volume>=volMax)
                {
                    volume = volMax;
                    state = 1;
                }
                break;
            
            // 音を流す
            case 1:
                count ++;
                if(count == show) state = 2;
                break;
            
            // 音をフェードアウトさせる
            case 2:
                volume -= fadeOut;
                if(volume <= 0)
                {
                    state = 3;
                    volume = 0;
                }
                break;
        }
    }
}