forked from: SiON MIDI Player

by ohisama forked from SiON MIDI Player (diff: 167)
♥0 | Line 336 | Modified 2013-02-06 19:15:40 | MIT License
play

ActionScript3 source code

/**
 * Copyright ohisama ( http://wonderfl.net/user/ohisama )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/pmT7
 */

// forked from keim_at_Si's SiON MIDI Player
package 
{
    import flash.text.*;
    import flash.events.*;
    import flash.display.Sprite;
    import flash.utils.ByteArray;
    import org.si.sion.SiONDriver;
    import org.si.sion.midi.*;
    import org.si.sion.events.*;
    import org.si.utils.ByteArrayExt;
    import com.bit101.components.*;
    public class main extends Sprite 
    {
        public var driver : SiONDriver = new SiONDriver(4096);
        public var smfData : SMFData = new SMFData();
        private var _title : TextField;
        private var _midiMode : Label;
        private var _tempo : Label;
        private function _playMIDIFile(midiFile : ByteArray) : void
        {
            smfData.loadBytes(midiFile);
            driver.play(smfData);
        }
        function main() 
        {
            var i : int;
            Style.BACKGROUND = 0x404040;
            Style.BUTTON_FACE = 0x606060;
            Style.LABEL_TEXT = 0xaaaaaa;
            Style.INPUT_TEXT = 0xaaaaaa;
            Style.DROPSHADOW = 0;
            Style.PANEL = 0x303030;
            Style.PROGRESS_BAR = 0x404040;
            container = this;
            new PushButton(this, 0, 0, "Load SMF ...", function(e : Event) : void 
            {
                if (driver.isPlaying) driver.fadeOut(4);
                new ByteArrayExt().browse(function(ba : ByteArrayExt) : void 
                {
                    _playMIDIFile(ba);
                    _title.text = smfData.title;
                    _tempo.text = "T:" + smfData.bpm.toFixed(1);
                    reset();
                }, null, null, "Standard MIDI File", "*.mid;*.smf");
            });
            driver.addEventListener(SiONEvent.FADE_OUT_COMPLETE, _onFadeOut);
            driver.addEventListener(SiONTrackEvent.CHANGE_BPM, _onBPMChanged);
            driver.addEventListener(SiONTrackEvent.BEAT, _onBeat);
            //driver.addEventListener(SiONMIDIEvent.NOTE_ON,  _onNoteOn);
            //driver.addEventListener(SiONMIDIEvent.NOTE_OFF, _onNoteOff);
            driver.addEventListener(SiONMIDIEvent.CONTROL_CHANGE, _onControlChange);
            driver.addEventListener(SiONMIDIEvent.PROGRAM_CHANGE, _onProgramChange);
            driver.addEventListener(SiONMIDIEvent.PITCH_BEND, _onPitchBend);
            driver.midiModule.onSysEx = _onSystemExclusive;
            driver.midiModule.onFinishSequence = _onFinishSequence;
            setup();
            _title = new TextField();
            _title.defaultTextFormat = new TextFormat("_sans", 12, 0xffffff);
            _title.x = 120;
            _title.y = 0;
            _title.width = 300;
            _title.text = "SCC MIDI Player !! powered by SiON v0.65";
            addChild(_title);
            _midiMode = new Label(this, 420, 5);
            _tempo = new Label(this, 420, -4);
        }
        private function _onFadeOut(e : SiONEvent) : void
        {
            driver.stop();
        }
        private function _onBPMChanged(e : SiONTrackEvent) : void
        {
            _tempo.text = "T:" + driver.bpm.toFixed(1);
        }
        private function _onBeat(e : SiONTrackEvent) : void
        {
            tempoIndicatorAlpha = 1;
        }
        private function _onNoteOn(e : SiONMIDIEvent) : void 
        {
            noteOn[e.midiChannelNumber][e.note] = 1;
            release[e.midiChannelNumber][e.note] = 1;
        }
        private function _onNoteOff(e : SiONMIDIEvent) : void 
        {
            release[e.midiChannelNumber][e.note] = 0.84;
        }
        private function _onControlChange(e : SiONMIDIEvent) : void
        {
            switch(e.controllerNumber) 
            {
            case SMFEvent.CC_MODULATION:    
                updateModulation(e.midiChannelNumber, e.value); 
            break;
            case SMFEvent.CC_EXPRESSION:    
                updateExpression(e.midiChannelNumber, e.value); 
            break;
            case SMFEvent.CC_SUSTAIN_PEDAL: 
                updateSustain(e.midiChannelNumber, e.value); 
            break;
            case SMFEvent.CC_PANPOD:        
                updatePanpod(e.midiChannelNumber, e.value); 
            break;
            case SMFEvent.CC_VOLUME:        
                updateVolume(e.midiChannelNumber, e.value); 
            break;
            case SMFEvent.CC_REVERB_SEND:   
                updateReverb(e.midiChannelNumber, e.value); 
            break;
            case SMFEvent.CC_CHORUS_SEND:               
                updateChorus(e.midiChannelNumber, e.value); 
            break;
            case SMFEvent.CC_DELAY_SEND:    
                updateDelay(e.midiChannelNumber, e.value);  
            break;
            }
        }
        private function _onProgramChange(e : SiONMIDIEvent) : void 
        {
            updateVoiceInformation(e.midiModule, e.midiChannelNumber, e.value, e.midiChannel.drumMode);
        }
        private function _onPitchBend(e : SiONMIDIEvent) : void
        {
            updatePitchBend(e.midiChannelNumber, e.value);
        }
        private function _onSystemExclusive(channelNumber : int, bytes : ByteArray) : void 
        {
            if (driver.midiModule.systemExclusiveMode != "") _midiMode.text = driver.midiModule.systemExclusiveMode;
        }
        private function _onFinishSequence() : void
        {
            driver.fadeOut(4);
        }
    }
}
import flash.display.*;
import flash.geom.*;
import flash.events.*;
import org.si.sion.midi.*;
import com.bit101.components.*;
var noteOn : Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>(16);
var release : Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>(16);
var noteOnRect : Vector.<Vector.<Rectangle>> = new Vector.<Vector.<Rectangle>>(16);
var noteOnColor : Vector.<uint> = new Vector.<uint>(85);
var keyImage : BitmapData = new BitmapData(465, 445, false, 0);
var keyOnImage : BitmapData = new BitmapData(465, 445, true, 0);
var tempoIndicator : Shape = new Shape();
var keyShape : Shape = new Shape();
var lbl : Label = new Label();
var mat : Matrix = new Matrix();
var rc : Rectangle = new Rectangle();
var container : Sprite;
var tempoIndicatorAlpha : Number = 0;
function setup() : void 
{
    var tr : int, i : int, x : Number;
    var bw : Array = [0,1,0,1,0,0,1,0,1,0,1,0];
    var g : Graphics;
    for (i=0; i<16; i++) 
    {
        noteOn[i] = new Vector.<Number>(128);
        release[i] = new Vector.<Number>(128); 
        noteOnRect[i] = new Vector.<Rectangle>(85);
    }
    g = tempoIndicator.graphics
    g.beginFill(0xf06060);
    g.drawCircle(0, 0, 4);
    g.endFill();
    g = keyShape.graphics;
    g.lineStyle(1, 0x808080);
    g.drawPath(Vector.<int>([1,2,2]), Vector.<Number>([0,0, 0,24, 5,24]));
    g.lineStyle(1, 0xc0c0c0);
    g.drawPath(Vector.<int>([1,2,2]), Vector.<Number>([5,24, 5,-1, 0,-1]));
    for (tr=0; tr<16; tr++) 
    {
        rc.setTo(0,tr*28,300,25);
        keyImage.fillRect(rc, 0xf0f0f0);
        rc.setTo(375,tr*28,90,25);
        keyImage.fillRect(rc, 0x202038);
        for (i=0; i<9; i++) 
        {
            rc.setTo(302+i*8,tr*28,6,25);
            keyImage.fillRect(rc, 0x303030);
        }
        for (mat.setTo(1,0,0,1,0,tr*28); mat.tx<300; mat.tx+=6) 
        {
            keyImage.draw(keyShape, mat);
        }
        _drawText(keyImage, 375, tr*28-4, "[TRACK" + String(tr+1) + "]");
    }
    g.clear();
    g.beginFill(0x202020);
    g.lineStyle(1, 0x404040);
    g.drawPath(Vector.<int>([1,2,2,2]), Vector.<Number>([0,0, 0,14, 4,14, 4,0]));
    g.endFill();
    g.lineStyle(1, 0x808080);
    g.drawPath(Vector.<int>([1,2,2]), Vector.<Number>([1,0, 1,12, 2,12]));
    for (i=0,x=0; i<85; i++) 
    {
        var bwf : int = bw[i%12];
        noteOnColor[i] = (bwf) ? 0xffccaa : 0xff2222;
        for (tr=0; tr<16; tr++) 
        {
            noteOnRect[tr][i] = new Rectangle(x+bwf+1, tr*28, 4-bwf, 24-bwf*10);
            if (bwf) 
            {
                mat.ty = tr*28;
                mat.tx = x+1;
                keyImage.draw(keyShape, mat);
            }
        }
        x += (bwf == bw[(i+1)%12])?6:3;
    }
    with(container.addChild(new Bitmap(keyImage))) 
    { 
        x = 0; 
        y = 20; 
    }
    with(container.addChild(new Bitmap(keyOnImage))) 
    { 
        x = 0; 
        y = 20; 
    }
    tempoIndicator.x = 110;
    tempoIndicator.y = 10;
    container.addChild(tempoIndicator);
    container.addEventListener(Event.ENTER_FRAME, draw);
    container.graphics.beginFill(0x303050);
    container.graphics.drawRect(0,0,465,20);
    container.graphics.endFill();
}
function reset() : void 
{
    var tr : int, nt : int;
    keyOnImage.fillRect(keyOnImage.rect, 0);
    for (tr=0; tr<16; tr++) 
    {
        for (nt=0; nt<128; nt++) 
        {
            noteOn[tr][nt] = 0;
            release[tr][nt] = 0;
        }
        updatePitchBend(tr, 0);
        updateModulation(tr, 0);
        updateExpression(tr, 128);
        updateSustain(tr, 0);
        updatePanpod(tr, 64);
        updateVolume(tr, 128);
        updateReverb(tr, 0);
        updateChorus(tr, 0);
        updateDelay(tr, 0);
    }
}
function _drawText(img:BitmapData, x:Number, y:Number, str:String, scale:Number=1) : void 
{
    mat.setTo(scale,0,0,scale,x,y);
    lbl.text = str;
    lbl.draw();
    img.draw(lbl, mat);
}
function updateVoiceInformation(midiModule:MIDIModule, tr:int, pn:int, drumMode:int) : void 
{
    rc.setTo(375, tr*28+13, 90, 13);
    keyOnImage.fillRect(rc, 0);
    if (drumMode) 
    {
        _drawText(keyOnImage, 375, tr*28+8, String(pn) + ":[DRUM MODE]");
    } 
    else 
    {
        _drawText(keyOnImage, 375, tr*28+8, String(pn) + ":" + midiModule.voiceSet[pn].name);
    }
}
function updatePitchBend(tr:int, bend:int) : void 
{
    _updateBar(tr, 0, (bend>0) ? (-bend*12/8192) : 0, (bend<0) ? (-bend*12/8192) : 1, 13); 
}
function updateModulation(tr:int, mod:int) : void 
{ 
    _updateBar(tr, 1, -mod*25/128); 
}
function updateExpression(tr:int, exp:int) : void 
{ 
    _updateBar(tr, 2, -exp*25/128); 
}
function updateSustain(tr:int, sus:int) : void    
{ 
    _updateBar(tr, 3, -sus*25/128); 
}
function updatePanpod(tr:int, pan:int) : void     
{ 
    _updateBar(tr, 4, (pan>64) ? (-(pan-64)*12/64) : 0, (pan<64) ? (-(pan-64)*12/64) : 1, 13); 
}
function updateVolume(tr:int, vol:int) : void    
{ 
    _updateBar(tr, 5, -vol*25/128); 
}
function updateReverb(tr:int, rev:int) : void     
{ 
    _updateBar(tr, 6, -rev*25/128); 
}
function updateChorus(tr:int, cho:int) : void     
{ 
    _updateBar(tr, 7, -cho*25/128); 
}
function updateDelay(tr:int, dly:int) : void      
{ 
    _updateBar(tr, 8, -dly*25/128); 
}
function _updateBar(tr:int, index:int, y0:int, y1:int=0, c:int=25) : void 
{
    rc.setTo(302+index*8, tr*28, 6, 25);
    keyOnImage.fillRect(rc, 0);
    rc.setTo(302+index*8, tr*28+c+y0, 6, y1-y0);
    keyOnImage.fillRect(rc, 0xff8080a0);
}
function draw(e:Event) : void 
{
    rc.setTo(0, 0, 300, 450);
    keyOnImage.fillRect(rc, 0);
    for (var tr : int = 0; tr < 16; tr++) 
    {
        var n : Vector.<Number> = noteOn[tr],
            r : Vector.<Number> = release[tr],
            nr : Vector.<Rectangle> = noteOnRect[tr];
        for (var i : int = 0, j : int = 24; i < 85; i++, j++) 
        {
            if (n[j] > 0) 
            {
                n[j] *= r[j];
                if (n[j] < 0.01) n[j] = 0;
                keyOnImage.fillRect(nr[i], ((n[j]*255)<<24)|noteOnColor[i]);
            }
        }
    }
    tempoIndicator.alpha = tempoIndicatorAlpha;
    tempoIndicatorAlpha *= 0.9;
}