Bach Chorale Dataset PNG

by yonatan
Extracted from http://www.jsbchorales.net MIDI files.
MIDI data © 1996-2011 Margaret Greentree, some rights reserved, non-commercial use is ok.
♥2 | Line 77 | Modified 2013-03-09 18:20:57 | MIT License | (replaced)
play

Related images

ActionScript3 source code

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

package {
    import flash.display.*;
    import flash.filters.*;
    import flash.net.*;
    import flash.system.*;
    import flash.events.*;
    import com.bit101.components.*;
    import org.si.sion.*;
    import org.si.sion.events.*;
    import org.si.utils.*;

    [SWF(width="465", height="465")]
    public class main extends Sprite {
        private var bae:ByteArrayExt = new ByteArrayExt;
        private var log:TextArea;
        private var chorales:Vector.<Vector.<int>> = new Vector.<Vector.<int>>();
        private var sion:SiONDriver = new SiONDriver;
        private var stepper:NumericStepper;

        function main() {
            // Data extracted from http://www.jsbchorales.net MIDI files.
            // (c) Copyright 1996-2011 Margaret Greentree, some rights reserved, non-commercial use is allowed.
            // NOTE_OFF events are not included (i.e. no rests)
            var url:String = "http://assets.wonderfl.net/images/related_images/f/fe/fe7f/fe7f67dd23761eab779792993fe971976c13e3b5";
            var loader:Loader = new Loader;
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoad);
            loader.load(new URLRequest(url), new LoaderContext(true));
        }

        private function pr(...a):void { log.text += a.join(", ") + "\n"; }
        private function cls():void { log.text = ""; }

        private function onLoad(e:Event):void {
            log = new TextArea(this, 0, 0);
            log.setSize(465, 465);
            var bae:ByteArrayExt = new ByteArrayExt;
            bae.fromBitmapData(Bitmap(e.target.content).bitmapData);
            bae.endian="bigEndian";

            var choraleCnt:int = bae.readInt();
            for(var i:int = 0; i < choraleCnt; i++) {
                var chords:Vector.<int> = chorales[i] = new Vector.<int>();
                var chordCnt:int = bae.readInt();
                pr("Reading chorale " + i, chordCnt + " chords");
                for(var j:int = 0; j < chordCnt; j++) chords[j] = bae.readInt();
            }

            stepper = new NumericStepper(this, 250, 30, onChange);
            stepper.filters = [new DropShadowFilter(6, 45, Style.DROPSHADOW, 1, 6, 6, .3, 1, false)];
            stepper.scaleX = stepper.scaleY = 2;
            stepper.minimum = 0;
            stepper.maximum = choraleCnt - 1;
            onChange(null);
        }

        private function onChange(e:Event):void {
            sion.stop();
            cls();
            var mml:String = toMml(chorales[stepper.value]);
            pr(mml);
            sion.play(sion.compile(mml));
        }

        private function mmlNote(midiNote:int):String {
            var names:Array = ["c","c+","d","d+","e","f","f+","g","g+","a","a+","b"];
            return "o" + int(midiNote/12) + names[midiNote%12];
        }

        private function toMml(chords:Vector.<int>, root:int = 45):String {
            var voices:Vector.<String> = new <String> ["A","A","A","A"];
            var j:int, note:int;
            for(var i:int = 0; i < chords.length; i++) {
                if(i) for(j=0; j<4; j++) voices[j] += "&";
                var c:int = chords[i];
                // The lowest byte is bass motion (difference from bass on previous chord),
                // the high ones are tenor, alto and soprano intervals.
                note = (root += (c << 24 >> 24)); voices[0] += mmlNote(note);
                note += (c << 16 >> 24);          voices[1] += mmlNote(note);
                note += (c << 8 >> 24);           voices[2] += mmlNote(note);
                note += (c >> 24);                voices[3] += mmlNote(note);
            }
            for(j=0; j<4; j++) voices[j] += ";\n";
            return mmlPrelude + voices.join("");
        }
    }
}

var mmlPrelude:String = String(<mml><![CDATA[#EFFECT0{reverb 123,34,85,40};
#OPN@0{6 7 31 00 00 06 09 33 0 04 7 0 31 00 00 06 09 00 0 04 3 0 31 00 00 06 09 00 0 02 3 0 31 00 00 06 09 00 0 01 7 0};
#A=%6 @f60 l16;
t80
]]></mml>);

Forked