Bach Chorale Dataset PNG
Extracted from http://www.jsbchorales.net MIDI files.
MIDI data © 1996-2011 Margaret Greentree, some rights reserved, non-commercial use is ok.
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>);