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

PC-98のロマンをあえてぶち壊しにしてみるテスト

FM音源風?
実際やってみてあの刻みの意味がよくわかった。
耳がもげそう
// forked from nemu90kWw's PC-98のBEEP音のアレ forked from: TinySiOPM MML workbench
// forked from keim_at_Si's TinySiOPM MML workbench
// MML Editor
// - shift+Enter で play/stop
// - 最下段で再生開始ポジションを指定
//------------------------------------------------------------

// BGMLIBを移植してみた。でもなんか違う・・・。
// 本物はBio_100%のサイトで聴けるよ。
package {
    import flash.media.*;
    import flash.display.*;
    import flash.events.*;
    import flash.text.*;

    [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]  
    public class MMLEditor extends Sprite
    {
        private var _sound:Sound;
        private var _channel:SoundChannel;
        private var _module:Beep;
        private var _sequencer:Sequencer;
        
        private var _textField:TextField;
        private var _statusField:TextField;
        private var _position:TextField;
        private var _track:TextField;
        
        function MMLEditor() {
            var format:TextFormat = new TextFormat("MS Gothic", 12, 0x80f0c0);
            _textField = new TextField();
            _textField.width = 465;
            _textField.height = 449;
            _textField.multiline = true;
            _textField.type = "input";
            _textField.defaultTextFormat = format;
            addChild(_textField);
            format.color = 0;
            _statusField= new TextField();
            _statusField.x = 0;
            _statusField.y = 449;
            _statusField.width = 465;
            _statusField.height = 16;
            _statusField.background = true;
            _statusField.backgroundColor = 0x80f0c0;
            _statusField.defaultTextFormat = format;
            _statusField.text = "position:";
            addChild(_statusField);
            _position = new TextField();
            _position.x = 60;
            _position.y = 449;
            _position.type = "input";
            _position.defaultTextFormat = format;
            _position.text = "0";
            addChild(_position);
            stage.addEventListener("keyDown", _onKeyDown);
            
            var mml:String = "";
            mml += ";=======================================\n";
            mml += ";=        爆笑超深どんとこい           =\n";
            mml += ";=        --------------------         =\n";
            mml += ";=        1991 (C) T.Ichikawa          =\n";
            mml += ";=        ALL RIGHTS RESERVED.         =\n";
            mml += ";=======================================\n";
            mml += "T150O2L16N0     ,O2L16N0     ,O3L16N0\n";
            mml += "ERERERERERERERERERERERERERERERER     ,R2GRGRGRGRGRGRGRGRBRBRBRBR     ,R1BRBRBRBR>ERERERER<\n";
            mml += "ERERERERERERERERERERERERERERERERERERERERERERERER     ,BRBRBRBR>ERERERERGRGRGRGRBRBRBRBRBRBRBRBRBRBRBRBR<     ,>GRGRGRGRBRBRBRBR>ERERERERERERERERERERERERERERERER<<\n";
            mml += "L8O2E>E<E>E<E>E<EF4>F<F>F<F>F<F>F<     ,L8N1O5E2.EFF2G.F.D     ,L8N1O4B2.B>CC2D.C.<A\n";
            mml += "E>E<E>E<E>E<EF4>F<F>F<F>F<F>F<     ,E2.EDD1     ,B2.BAA2>>C<B>C16D.<<\n";
            mml += "E>E<E>E<E>E<EF4>F<F>F<F>F<F>F<     ,>E2.EFF2G.F.D<     ,B2.B>CC2D.C.<A\n";
            mml += "E>E<E>E<E>E<EF4>F<F>F<F>F<F>F<     ,>E2.EDD1<     ,B2.BAA1\n";
            mml += "E>E<E>E<E>E<EF4>F<F>F<F>F<F>F<     ,L16GAGF+L8E2REF.A.>CC<B>CD<     ,R1R1\n";
            mml += "E>E<E>E<E>E<EF4>F<F>F<F>F<F>F<     ,>E1E2D4.<A     ,R1R1\n";
            mml += "E>E<E>E<E>E<EF4>F<F>F<F>F<F>F<     ,B2.B>CC1<     ,O4L16GAGF+L8E2REF.A.>CC<B>CD<\n";
            mml += "E>E<E>E<E>E<EF4>F<F>F<F>F<F>F<     ,B1B2A2     ,>E1E2D2<\n";
            mml += "E>E<E>E<G>G<G>G<F+>F+<F+>F+<F>F<F>F<     ,E2G2F+4.F4.G4     ,R1R1\n";
            mml += "E>E<E>E<G>G<G>G<F+>F+<F+>F+<F>F<F>F<     ,E2G2F+4.A4.D4     ,R1R1\n";
            mml += "E>E<E>E<G>G<G>G<F+>F+<F+>F+<F>F<F>F<     ,E2G2F+4.F4.G4     ,B2>E2D4.C4.D4<\n";
            mml += "E>E<E>E<G>G<G>G<A>A<A>A<<B>B<B>B     ,E2G2A4.B4RB4     ,B2>D2E4.E-4R<B4\n";
            mml += "C>C<C>C<C>C<C>C<C>C<C>C<C>C<C>C<     ,>C.<B.E2.>EREREDC<     ,>C.<B.E2.>E2EDC<\n";
            mml += "G>G<G>G<G>G<G>G<G>G<G>G<G>G<G>G<     ,B.A.GG1GRG4     ,B.A.GG1GRG4\n";
            mml += "F>F<F>F<F>F<F>F<F>F<F>F<F>F<F>F<     ,A.G.F2.>CRCRC<BA     ,A.G.F2.>C2C<BA\n";
            mml += "B>B<B>B<B>B<B>B<B>B<B>B<B>B<B>B<     ,B1B2BRB4     ,B1B2BRB4\n";
            mml += "C>C<C>C<C>C<C>C<C>C<C>C<C>C<C>C<     ,>C.<B.E2.>EREREDC<     ,>C.<B.E2.>E2EDC<\n";
            mml += "G>G<G>G<G>G<G>G<G>G<G>G<G>G<G>G<     ,B.A.GG1GRG4     ,B.A.GG1GRG4\n";
            mml += "F+>F+<F+>F+<F+>F+<F+>F+<F+>F+<F+>F+<F+>F+<F+>F+<     ,A.G.F+2.>CRCRCDE<     ,A.G.F+2.>C2CDE<\n";
            mml += "B>B<B>B<B>B<B>B<B>B<B>B<B>B<B>B<     ,>E-2E-<B>E-F+F+1<     ,>E-2E-<B>E-F+F+1<\n";
            mml += "L8O2E>E<E>E<E>E<EF4>F<F>F<F>F<F>F<     ,L8N1O5E2.EFF2G.F.D     ,L8N1O4B2.B>CC2D.C.<A\n";
            mml += "E>E<E>E<E>E<EF4>F<F>F<F>F<F>F<     ,E2.EDD1     ,B2.BAA2>>C<B>C16D.<<\n";
            mml += "E>E<E>E<E>E<EF4>F<F>F<F>F<F>F<     ,>E2.EFF2G.F.D<     ,B2.B>CC2D.C.<A\n";
            mml += "E>E<E>E<E>E<EF4>F<F>F<F>F<F>F<     ,>E2.EDD1<     ,B2.BAA1\n";
            mml += ";<END FLAG>--------------------------------------------------------------------\n";
            _textField.text = mml;
            
            _module = new Beep(2048, _onSoundFrame);
            _sequencer = new Sequencer(_textField.text);
            _sound = new Sound();
            _sound.addEventListener("sampleData", _onStream);
            
            _channel = _sound.play();
        }
        
        private function _onKeyDown(e:KeyboardEvent) : void {
            if (e.shiftKey && e.keyCode == 13) {
                if (_channel) {
                    _channel.stop();
                    _channel = null;
                } else {
                    _module.reset();
                    _sequencer.mml = _textField.text;
                    _sequencer.pos = int(_position.text);
                    _channel = _sound.play();
                }
            }
        }
        
        private function _onSoundFrame() : void {
            _sequencer.onSoundFrame();
        }
        
        private function _onStream(e:SampleDataEvent) : void {
            var moduleOut:Vector.<Number> = _module.render();
            for (var i:int = 0; i<4096; i++) {
                e.data.writeFloat(moduleOut[i]);
            }
        }
    }
}

import flash.events.*;
import flash.utils.*;
import flash.media.*;

class Sequencer
{
    public static var tracks:Array;
    public static var freq:int = 44100;
    public static var tempo:Number = 120;
    public static function get tick():Number {return 7.5 / tempo * freq;}
    public static var tck:Number  = 1;
    
    function Sequencer(mml:String = null)
    {
        this.mml = mml;
    }
    
    public function onSoundFrame() : void {
        for each (var tr:Track in tracks) tr.execute();
        return;
    }
    
    public function set pos(p:int) : void {
        for (var i:int=0; i<p; i++) {
            for each (var tr:Track in tracks) tr.execute();
        }
    }
    
    public function set mml(seq:String) : void
    {
        seq = seq.replace(/[ \t]|;.*$/gm, "");
        
        var list:Array = seq.split("\r");
        var res:Array = new Array("", "", "");
        
        for(var i:int = 0; i < list.length; i++)
        {
            var temp:Array = list[i].split(",");
            for(var t:int = 0; t < temp.length; t++)
            {
                if(t == 3) {break;}
                res[t] += temp[t];
            }
        }
        
        tracks = new Array();
        tracks.push(new Track(res[0]));
        tracks.push(new Track(res[1]));
        tracks.push(new Track(res[2]));
        tck = 1;
        for(var i:int = 0; i < tracks.length; i++)
        {
                if(tracks[i].currentNote.oct == 0xFF) {break;}
             var pitch:Number = freq / (Math.pow(2, tracks[i].currentNote.key / 12) * Math.pow(2, tracks[i].currentNote.oct+5));
                 tck *= pitch;
        }

    }
}

class Track
{
    private var codeA:int="A".charCodeAt();
    private var nt:Array=[9,11,0,2,4,5,7];
    private var lentable:Array = new Array();
    private var notelist:Array;
    private var oct:int;
    private var len:int;
    private var tenuto:int;
    private var pos:int;
    private var cnt:Number;
    public var currentNote:Note;
    private var _rex:RegExp=/([A-GRTLON<>])([-+])?(-?\d+)?(\.*\.)?/gi;
    function Track(seq:String)
    {
        lentable[32] = 1;
        lentable[16] = 2;
        lentable[8] = 4;
        lentable[4] = 8;
        lentable[2] = 16;
        lentable[1] = 32;
        
        lentable[24] = 1.5;
        lentable[12] = 3;
        lentable[6] = 6;
        lentable[3] = 12;
        
        var note:Note;
        notelist = new Array();
        
        cnt = 0;
        pos = 0;
        oct = 5;
        len = 4;
        tenuto = 1;
        
        for (var res:* = _rex.exec(seq); res; res = _rex.exec(seq))
        {
            res[1] = res[1].toUpperCase();
            var cmd:int = res[1].charCodeAt();
            if (cmd>=codeA && cmd<=codeA+6)
            {
                note = new Note();
                note.key = nt[cmd-codeA];
                if(res[2] == "-") {note.key--;}
                if(res[2] == "+") {note.key++;}
                note.oct = oct;
                note.len = lentable[(res[3]) ? int(res[3]) : len] * Sequencer.tick;
                if(res[4]) {
                    var l:Number = note.len;
                    for(var i:int = 0; i < res[4].length; i++)
                    {
                        l /= 2;
                        note.len += l;
                    }
                }
                notelist.push(note);
            }
            else if (res[1] == 'R') {
                note = new Note();
                note.key = 0xFF;
                note.oct = 0xFF;
                note.len = lentable[(res[3]) ? int(res[3]) : len] * Sequencer.tick;
                if(res[4]) {
                    var l:Number = note.len;
                    for(var i:int = 0; i < res[4].length; i++)
                    {
                        l /= 2;
                        note.len += l;
                    }
                }
                notelist.push(note);
            }
            else {
                switch(res[1]){
                case 'T': Sequencer.tempo = int(res[3]); break;
                case 'L': len = int(res[3]); break;
                case 'O': oct = int(res[3]); break;
                case 'N': tenuto = int(res[3]); break;
                case '<': oct--; break;
                case '>': oct++; break;
                }
            }
        }
        currentNote = notelist[0];
    }
    
    public function execute() : void
    {
        cnt++;
        if (cnt >= currentNote.len)
        {
            cnt -= currentNote.len;
            pos++;
            if(pos == notelist.length) {
                pos = 0;
            }
            currentNote = notelist[pos];
        }
    }
}

class Note
{
    public var key:int;
    public var oct:int;
    public var len:int;
}

class Beep
{
    private var _output:Vector.<Number>;
    private var _bufferSize:int;
    private var _onSoundFrame:Function;
    
    private var phase:Number = 0;
    public var pitch:Number = 0;
    
    function Beep(bufferSize:int=2048, onSoundFrame:Function=null)
    {
        _bufferSize = bufferSize;
        _onSoundFrame = onSoundFrame;
        
        _output = new Vector.<Number>(bufferSize*2, true);
    }
    
    public function reset() : void {
        phase = 0;
    }
    
    public function render():Vector.<Number>
    {
        for (var i:int=0; i < _bufferSize; i++)
        {
            if(_onSoundFrame != null) _onSoundFrame();
            
            var track:Track;
            var num:int;
            if(phase % Sequencer.tck*3 < Sequencer.tck) {
                num = 0;
            }
            else if(phase % Sequencer.tck*3 < Sequencer.tck*2){
                num = 1;
            }
            else {
                num = 2;
            }
            for (var j:int = 0; j < 3; j++)
            {
                track = Sequencer.tracks[num];
                if(track.currentNote.oct != 0xFF) {break;}
                num--;
                if(num == -1) {num = 2;}
            }
            
            if(j==3)
            {
                _output[i*2] = 0;
                _output[i*2+1] = 0;
                phase++;
                continue;
            }
            
            pitch = Math.pow(2, track.currentNote.key / 12) * Math.pow(2, track.currentNote.oct+5) / Sequencer.freq;
            
            _output[i*2] = Math.sin(Math.PI * pitch * phase) < 0 ? 0.1 : -0.1;
            _output[i*2+1] = Math.sin(Math.PI * pitch * phase) < 0 ? 0.1 : -0.1;
            phase++;
        }
        return _output;
    }
}