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: 各種ソートアルゴリズムを可聴化

元祖 つhttp://0xcc.net/blog/archives/000160.html
// forked from kappaLab's 各種ソートアルゴリズムを可聴化
/*
    元祖 つhttp://0xcc.net/blog/archives/000160.html
*/
package 
{
    import flash.display.Sprite;
    import flash.events.*;
    import flash.utils.Timer;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.text.TextFieldAutoSize;

    [SWF(backgroundColor="#000000", frameRate=120)]
    public class Sort extends Sprite
    {
        private const STAGESIZE:int = 400;
        private const SIZE:int = 100;
        private const SORTSPEED:int = 100;
        private var data:Array;
        private var timer:Timer;
        private var tf:TextField;
        private var k:int, l:int; //あんまり使いたくない
        private var oscs:Vector.<OSC>
        
        public function Sort()
        {
            oscs = new Vector.<OSC>()
            for (var j:int = 0; j < 10; j++) 
            {
                oscs[j] = new SineOSC()
                oscs[j].frequency = 100
                var offset:Number = i*5
                oscs[j].generateEnvelop(0, 0, offset, .8, 10 + offset, 0, 50 + offset)
                //oscs[j].volume = .2// + (j * .03)
            }
            tf = new TextField();
            tf.y = stage.stageHeight - 50;
            tf.autoSize = TextFieldAutoSize.LEFT;
            var format:TextFormat = new TextFormat();
            format.font = "_sans";
            format.color = "0xFFFFFF";
            format.size = 23;
            tf.defaultTextFormat = format;
            addChild(tf);
            
            data = new Array(SIZE);
            for (var i:int = 0; i < SIZE; i++)
            {
                var d:Data = new Data(STAGESIZE / SIZE);
                d.x = i * STAGESIZE / SIZE;
                d.y = i * STAGESIZE / SIZE;
                addChild(d);
                data[i] = d;
            }
            
            bubbleSort();
        }
        
        private function random(data:Array):void
        {
            for (var i:int = 0; i < 100; i++)
            {
                var a:int = Math.floor(Math.random() * data.length);
                var b:int = Math.floor(Math.random() * data.length);

                var temp:int = data[a].y;
                data[a].y = data[b].y;
                data[b].y = temp;
            }
        }
        private function playSound():void
        {
            for (var i:int = 0; i < 10; i++) 
            {
                oscs[i].frequency = 60 * data[i * 5].y + 40;
                oscs[i].play()
            }
        }
        private function bubbleSort(event:TimerEvent = null):void
        {
            tf.text = "BubbleSort";
            random(data);
            timer = new Timer(SORTSPEED);
            timer.repeatCount = data.length - 1;
            timer.addEventListener(TimerEvent.TIMER, _bubbleSort);
            timer.addEventListener(TimerEvent.TIMER_COMPLETE, selectionSort);
            timer.start();
        }
        
        private function _bubbleSort(event:TimerEvent):void
        {
            for (var j:int = 0; j < data.length - event.target.currentCount; j++)
            {
                if (data[j].y > data[j + 1].y) swap(data[j], data[j + 1]);
            }
            playSound()
        }
        
        private function selectionSort(event:TimerEvent = null):void
        {
            tf.text = "SelectionSort";
            random(data);
            timer = new Timer(SORTSPEED);
            timer.repeatCount = data.length - 1;
            timer.addEventListener(TimerEvent.TIMER, _selectionSort);
            timer.addEventListener(TimerEvent.TIMER_COMPLETE, insertionSort);
            timer.start();
        }
        
        private function _selectionSort(event:TimerEvent):void
        {
            var i:int = event.target.currentCount - 1;
            var min:int = i;
            for (var j:int = i + 1; j < data.length; j++)
            {
                if (data[min].y > data[j].y) min = j;
            }
            swap(data[min], data[i]);
            playSound()
        }
        
        private function swap(a:Data, b:Data):void
        {
            var temp:int = a.y;
            a.y = b.y;
            b.y = temp;
        }
        
        private function insertionSort(event:TimerEvent = null):void
        {
            tf.text = "InsertionSort";
            random(data);
            timer= new Timer(SORTSPEED);
            timer.repeatCount = data.length - 1;
            timer.addEventListener(TimerEvent.TIMER, _insertionSort);
            timer.addEventListener(TimerEvent.TIMER_COMPLETE, shellSort);
            timer.start();
        }
        
        private function _insertionSort(event:TimerEvent):void
        {
            var i:int = event.target.currentCount;
            var tmp:int = data[i].y;
            for (var j:int = i; j > 0 && data[j - 1].y > tmp; j--)
            {
                data[j].y = data[j - 1].y;
            }
            data[j].y = tmp;
            playSound()
        }
        
        private function shellSort(event:TimerEvent = null):void
        {
            k = data.length / 2;
            l = k;
            tf.text = "ShellSort";
            random(data);
            timer = new Timer(SORTSPEED / 2);
            timer.repeatCount = 999; //適当
            timer.addEventListener(TimerEvent.TIMER, _shellSort);
            timer.start();
        }
        
        private function _shellSort(event:TimerEvent):void
        {
            if (l >= data.length)
            {
                k /= 2;
                l = k;
                
                if (k <= 0)
                {
                    timer.stop();
                    shakerSort();
                    return;
                }
            }
            
            var j:int;
            var temp:int = data[l].y;
            for (j = l - k; j >= 0 && data[j].y > temp; j -= k)
            {
                data[j + k].y = data[j].y;
            }
            data[j + k].y = temp;
            
            l++;
            playSound()
        }
        
        private function shakerSort(event:TimerEvent = null):void
        {
            tf.text = "ShakerSort";
            random(data);
            timer = new Timer(SORTSPEED);
            timer.repeatCount = data.length - 1;
            timer.addEventListener(TimerEvent.TIMER, _shakerSort);
            timer.addEventListener(TimerEvent.TIMER_COMPLETE, heapSort);
            timer.start();
        }
        
        private function _shakerSort(event:Event):void
        {
            var i:int = event.target.currentCount;
            for (var j:int = 0; j < data.length - i; j++)
            {
                if (data[j].y > data[j + 1].y) swap(data[j], data[j + 1]);
            }
            
            for (j = data.length - i; j > 0; j--)
            {
                if (data[j].y < data[j - 1].y) swap(data[j], data[j - 1]);
            }
            playSound()
        }

        private function heapSort(event:TimerEvent):void
        {
            tf.text = "HeapSort";
            random(data);
            timer = new Timer(SORTSPEED);
            timer.repeatCount = (data.length - 2) / 2 + 1;
            timer.addEventListener(TimerEvent.TIMER, _heapSort);
            timer.addEventListener(TimerEvent.TIMER_COMPLETE, _heapSort2);
            timer.start();
        }

        private function _heapSort(event:TimerEvent = null):void
        {
            var i:int = event.target.currentCount;
                
            _makeHeap((data.length - 2) / 2 - i + 1, data.length - 1);
            playSound()
        }
        
        private function _heapSort2(event:TimerEvent):void
        {
            timer = new Timer(SORTSPEED);
            timer.repeatCount = data.length - 1;
            timer.addEventListener(TimerEvent.TIMER, __heapSort2);
            timer.addEventListener(TimerEvent.TIMER_COMPLETE, gnomeSort);
            timer.start();
        }
        
        private function __heapSort2(event:TimerEvent):void
        {
            var i:int = event.target.currentCount;
            
            swap(data[0], data[data.length - i]);
            _makeHeap(0, data.length - i - 1);
            
        }
        
        private function _makeHeap(parent:int, r:int):void
        {
            var p:int = data[parent].y;
            while (true)
            {
                var left:int = parent * 2 + 1;
                if (left > r) break;
                if (left != r)
                {
                    if (data[left + 1].y > data[left].y) left++;
                }
                if (p >= data[left].y) break;
                data[parent].y = data[left].y;
                parent = left;
            }
            data[parent].y = p;
            playSound()
        }
        
        private function gnomeSort(event:TimerEvent = null):void
        {
            tf.text = "GnomeSort";
            random(data);
            
            k = 1, l = 2;
            timer = new Timer(SORTSPEED / 3);
            timer.repeatCount = 999; //適当
            timer.addEventListener(TimerEvent.TIMER, _gnomeSort);
            timer.start();
        }
        
        private function _gnomeSort(event:TimerEvent):void
        {
            if (k >= data.length)
            {
                timer.stop();
                end();
                return;
            }
            if (data[k - 1].y <= data[k].y)
            {
                k = l;
                l++;
            }
            else
            {
                swap(data[k - 1], data[k]);
                k--;
                if (k == 0) k = 1;
            }
            playSound()
        }
        
        private function end(event:TimerEvent = null):void
        {
            tf.text = "END";
        }
    }
}

import flash.display.Sprite;

class Data extends Sprite
{
    public function Data(size:int)
    {
        graphics.beginFill(0xFFFFFF);
        graphics.drawRect(0, 0, size, size);
        graphics.endFill();
    }
}

import flash.display.Sprite;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.SampleDataEvent;
import flash.media.Sound;
import flash.utils.ByteArray;

class Master extends EventDispatcher
{
    static public const PI2:Number = Math.PI * 2;
    static public const SAMPLE_RATE:uint = 44100;    
    static public const TIME_PER_BYTE:Number = 1000/44100;    
    
    static public var  LATENCY:uint = 2048 //2048~8192
    
    static private var instance:Master
    
    private const _LATENCY:uint = LATENCY
    private var oscs:Vector.<OSC>
    private var sound:Sound
    protected var phase:Number = 0
    
    static public function getInstance():Master
    {
        if (instance) {
            return instance
        }else {
            instance = new Master()
            return instance
        }
    }
    
    public function Master()
    {
        oscs = new Vector.<OSC>()
        sound = new Sound()
        sound.addEventListener(SampleDataEvent.SAMPLE_DATA, update)
        sound.play()
    }
    
    
    public function addOSC(osc:OSC):OSC
    {
        oscs.push(osc)
        return osc
    }
    
    public function removeOSC(osc:OSC):OSC
    {
        var index:int = oscs.indexOf(osc)
        oscs.splice(index, 1);
        return osc;
    }
    
    private function update(e:SampleDataEvent):void
    {
        dispatchEvent(e)
        var oscs:Vector.<OSC> = this.oscs
        
        var n:int = _LATENCY
        var data:ByteArray = e.data
        for each(var osc:OSC in oscs)
            osc.update()
        
        for (var i:int = 0; i < n; i++) 
        {
            var s:Number = 0;
            for each(var osc1:OSC in oscs)
                s += osc1.sample[i];
    
            data.writeFloat(s)
            data.writeFloat(s)
        } 
    }
    
}

class OSC extends EventDispatcher
{
    protected const PI:Number   = Math.PI
    protected const PI2:Number  = Math.PI * 2;
    protected const LATENCY:int = Master.LATENCY
    protected const SAMPLE_RATE:uint = Master.SAMPLE_RATE;
    protected const TIME_PER_BYTE:Number = 1000.0 / SAMPLE_RATE;
    private var master:Master;
    private var _listen:Boolean;
    private var _frequency:Number;
    
    protected var _amplifier:Number; 
    protected var envelopTime:Number; 
    protected var envelop:Vector.<Number>
    protected var _filters:Vector.<SoundFilter>
    protected var phase:Number = 0;
    protected var deltPhase:Number;
    
    
    protected var initAmplifier:Number;
    protected var lastAmplifier:Number;
    protected var envelopValue:Vector.<Number>;
    protected var envelopInterval:Vector.<Number>;
    protected var envelopLength:int
    
    protected var _random:Function = Math.random

    public var volume:Number;
    public var sample:Vector.<Number>;
    public var isMute:Boolean 
    
    public function OSC()
    {
        init()
    }
    
    private function init():void
    {
        master = Master.getInstance();
        
        _frequency = 440;
        _listen    = true;
        deltPhase  = PI2 * _frequency / SAMPLE_RATE;
        volume = .2;
        generateEnvelop(0,1,50,0,100)
        sample  = new Vector.<Number>(LATENCY);
        _filters = new Vector.<SoundFilter>();
        master.addOSC(this)
        
    }

    public function generateEnvelop(init:Number, ...arg):void 
    {
        initAmplifier    = init;
        envelopValue     = new Vector.<Number>()
        envelopInterval  = new Vector.<Number>()
        var n:int = arg.length >> 1;//int(arg.length / 2)
        var previousValue:Number = initAmplifier
        var prevInterval:Number  = 0;
        for (var i:int = 0; i < n; i++) 
        {
            var ii:int = i << 1 // i*2
            envelopInterval[i] = arg[ii + 1]+prevInterval;
            envelopValue[i]    = (arg[ii] - previousValue) / ((arg[ii + 1]/1000)*SAMPLE_RATE);
            previousValue      = arg[ii]
            prevInterval       = envelopInterval[i]
        }
        lastAmplifier = previousValue;
        envelopTime   = prevInterval
        envelopLength = n
        trace("generateEnvelop")
        trace(arg)
        trace(envelopValue)
        trace(envelopInterval)
        trace("--------------")
        
    }
    
    public function update():void
    {
    }  
   
    public function play():void
    {
        //listen = true
        envelopTime = 0
        _amplifier = initAmplifier
    }
    
    public function get listen():Boolean { return _listen; }
    public function set listen(value:Boolean):void 
    {
        if (_listen == value) return;
        
        _listen = value;
        if (value) 
            master.addOSC(this);
        else
            master.removeOSC(this);
            
    }
    
    public function get frequency():Number { return _frequency; }
    public function set frequency(value:Number):void 
    {
        _frequency = value;
        deltPhase  = PI2 * _frequency / SAMPLE_RATE;
    }
    
    public function get amplifier():Number { return _amplifier; }
    
    public function get filters():Vector.<SoundFilter> { return _filters; }
    public function set filters(value:Vector.<SoundFilter>):void 
    {
        _filters = value;
    }
    
    
}

class SineOSC extends OSC
{
    override public function update():void
    {   
        var n:int = LATENCY
        var m:int = envelopLength-1;
        for (var i:int = 0; i < n; i++) 
        {
            phase = (phase + deltPhase) % PI2;
            envelopTime += TIME_PER_BYTE;
            for (var j:int = 0; j <= m; j++) {
                if (envelopTime <= envelopInterval[j]) 
                {
                    _amplifier += envelopValue[j];
                    break; 
                }
                else if (envelopTime > envelopInterval[m]) 
                {
                    _amplifier=lastAmplifier
                    break; 
                }
            };
            sample[i] = Math.sin(phase) * _amplifier * volume;
        }
        var nn:uint = _filters.length
        for (var ii:int = 0; ii < nn; ii++) _filters[0].process(sample);
    }
}

class SawOSC extends OSC
{
    override public function update():void
    {
        var envelopInterval:Vector.<Number> = this.envelopInterval
        var envelopValue:Vector.<Number> = this.envelopValue
        var n:int = LATENCY
        var m:int  = envelopLength-1;
        for (var i:int = 0; i < n; i++) 
        {
            phase = (phase + deltPhase) % PI2;
            envelopTime += TIME_PER_BYTE;
            for (var j:int = 0; j <= m; j++) {
                if (envelopTime <= envelopInterval[j]) 
                {
                    _amplifier += envelopValue[j];
                    break; 
                }
                else if (envelopTime > envelopInterval[m]) 
                {
                    _amplifier = lastAmplifier;
                    break; 
                }
            };
            sample[i] = (-phase / PI + 1) * _amplifier * volume;
        }
        var nn:uint = _filters.length
        for (var ii:int = 0; ii < nn; ii++) _filters[0].process(sample);
    }
}

class SquareOSC extends OSC
{
    override public function update():void
    {
        var envelopInterval:Vector.<Number> = this.envelopInterval
        var envelopValue:Vector.<Number> = this.envelopValue
        var n:int = LATENCY
        var m:int  = envelopLength-1;
        for (var i:int = 0; i < n; i++) 
        {
            phase = (phase + deltPhase) % PI2;
            envelopTime += TIME_PER_BYTE;
            for (var j:int = 0; j <= m; j++) {
                if (envelopTime <= envelopInterval[j]) 
                {
                    _amplifier += envelopValue[j];
                    break; 
                }
                else if (envelopTime > envelopInterval[m]) 
                {
                    _amplifier = lastAmplifier;
                    break; 
                }
            };
            sample[i] = ((phase > PI)?1: -1) * _amplifier * volume;
        }
        var nn:uint = _filters.length
        for (var ii:int = 0; ii < nn; ii++) _filters[0].process(sample);
    }
}

class TriangleOSC extends OSC
{
    override public function update():void
    {
        var envelopInterval:Vector.<Number> = this.envelopInterval
        var envelopValue:Vector.<Number> = this.envelopValue
        var n:int = LATENCY
        var m:int  = envelopLength-1;
        for (var i:int = 0; i < n; i++) 
        {
            phase = (phase + deltPhase) % PI2;
            envelopTime += TIME_PER_BYTE;
            for (var j:int = 0; j <= m; j++) {
                if (envelopTime <= envelopInterval[j]) 
                {
                    _amplifier += envelopValue[j];
                    break; 
                }
                else if (envelopTime > envelopInterval[m]) 
                {
                    _amplifier = lastAmplifier;
                    break; 
                }
            };
            var s:Number = (phase / PI - 1)
            
            if (s > 0) sample[i] = (s * 2 -1) * _amplifier * volume;
                else   sample[i] = (s * -2 -1) * _amplifier * volume;
        }
        var nn:uint = _filters.length
        for (var ii:int = 0; ii < nn; ii++) _filters[0].process(sample);
    }
}

class NoiseOSC extends OSC
{
    override public function update():void
    {
        
        var envelopInterval:Vector.<Number> = this.envelopInterval
        var envelopValue:Vector.<Number> = this.envelopValue
        var n:int = LATENCY
        var m:int  = envelopLength-1;
        for (var i:int = 0; i < n; i++) 
        {
            phase = (phase + deltPhase) % PI2;
            envelopTime += TIME_PER_BYTE;
            for (var j:int = 0; j <= m; j++) {
                if (envelopTime <= envelopInterval[j]) 
                {
                    _amplifier += envelopValue[j];
                    break; 
                }
                else if (envelopTime > envelopInterval[m]) 
                {
                    _amplifier = lastAmplifier;
                    break; 
                }
            };
            sample[i] = (Math.random() * 2 - 1) * _amplifier * volume;
        }
        
        var nn:uint = _filters.length
        for (var ii:int = 0; ii < nn; ii++) _filters[0].process(sample);
    }
}
class Bass extends OSC
{
    public var initFrequency:uint = 300
    public var endFrequency:uint  = 10
    public var length:uint = 2000
    
    override public function play():void
    {
        super.play()
        frequency = initFrequency
    }
    override public function update():void
    {
        var m:int  = envelopLength-1
        var n:int = LATENCY
        for (var i:int = 0; i < n; i++) 
        {
            
            this.frequency += (endFrequency - frequency) / length
            phase = (phase + deltPhase) % PI2;
            envelopTime += TIME_PER_BYTE;
            for (var j:int = 0; j <= m; j++) {
                if (envelopTime <= envelopInterval[j]) 
                {
                    _amplifier += envelopValue[j];
                    break; 
                }
                else if (envelopTime > envelopInterval[m]) 
                {
                    _amplifier = lastAmplifier;
                    break; 
                }
            };

            sample[i] = Math.sin(phase) * amplifier * volume;
        }
        var nn:uint = _filters.length
        for (var ii:int = 0; ii < nn; ii++) _filters[0].process(sample);
    }
}


class SoundFilter {
    protected var osc:OSC
    public function addOSC(osc:OSC):void
    {
        this.osc = osc
    }
    public function process(sample:Vector.<Number>):void
    {
    }
}
class ResonatFilter extends SoundFilter 
{
    private var buf0:Number = 0 ;
    private var buf1:Number = 0 ;
    private var cutoff:Number;    
    private var q:Number;    
    private var type:int;
    
    static public const LPF:uint = 0;
    static public const BPF:uint = 1;
    static public const HPF:uint = 2;
    
    
    
    public function ResonatFilter(type:int,cutoff:Number=440,q:Number=0.5) 
    {
        this.type = type;
        this.cutoff = cutoff
        this.q = q
    }
    
    override public function process(sample:Vector.<Number>):void
    {
        // f and fb calculation
        var f:Number = 2.0 * Math.sin(Math.PI * cutoff / Master.SAMPLE_RATE);
        var fb:Number = q + q/(1.0 - f);

        var n:int = Master.LATENCY;
        var hp:Number;
        var bp:Number;
        
        for (var i:int = 0; i < n; i++) 
        {
            hp = sample[i] - buf0;
            bp = buf0 - buf1;
            buf0 = buf0 + f * (hp + fb * bp);
            buf1 = buf1 + f * (buf0 - buf1);
            sample[i] = (type == 0)?buf1:(type == 1)?bp:hp;
        }
    }
    
}