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

各種ソートアルゴリズムを可聴化

元祖 つhttp://0xcc.net/blog/archives/000160.html
/*
    元祖 つ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=20)]
	public class Sort extends Sprite
	{
		private const STAGESIZE:int = 300;
		private const SIZE:int = 50;
		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 = "_typewriter";
			format.color = "0xCCCCCC";
			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 = "終わり";
		}
	}
}

import flash.display.Sprite;

class Data extends Sprite
{
	public function Data(size:int)
	{
		graphics.beginFill(0xFF33FF);
		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;
        }
    }
    
}