piano/js/lib/jasmid/jasmid.min.js

1 line
3.9 KiB
JavaScript

function Stream(e){function n(n){var r=e.substr(t,n);t+=n;return r}function r(){var n=(e.charCodeAt(t)<<24)+(e.charCodeAt(t+1)<<16)+(e.charCodeAt(t+2)<<8)+e.charCodeAt(t+3);t+=4;return n}function i(){var n=(e.charCodeAt(t)<<8)+e.charCodeAt(t+1);t+=2;return n}function s(n){var r=e.charCodeAt(t);if(n&&r>127)r-=256;t+=1;return r}function o(){return t>=e.length}function u(){var e=0;while(true){var t=s();if(t&128){e+=t&127;e<<=7}else{return e+t}}}var t=0;return{eof:o,read:n,readInt32:r,readInt16:i,readInt8:s,readVarInt:u}}function MidiFile(e){function t(e){var t=e.read(4);var n=e.readInt32();return{id:t,length:n,data:e.read(n)}}function r(e){var t={};t.deltaTime=e.readVarInt();var r=e.readInt8();if((r&240)==240){if(r==255){t.type="meta";var i=e.readInt8();var s=e.readVarInt();switch(i){case 0:t.subtype="sequenceNumber";if(s!=2)throw"Expected length for sequenceNumber event is 2, got "+s;t.number=e.readInt16();return t;case 1:t.subtype="text";t.text=e.read(s);return t;case 2:t.subtype="copyrightNotice";t.text=e.read(s);return t;case 3:t.subtype="trackName";t.text=e.read(s);return t;case 4:t.subtype="instrumentName";t.text=e.read(s);return t;case 5:t.subtype="lyrics";t.text=e.read(s);return t;case 6:t.subtype="marker";t.text=e.read(s);return t;case 7:t.subtype="cuePoint";t.text=e.read(s);return t;case 32:t.subtype="midiChannelPrefix";if(s!=1)throw"Expected length for midiChannelPrefix event is 1, got "+s;t.channel=e.readInt8();return t;case 47:t.subtype="endOfTrack";if(s!=0)throw"Expected length for endOfTrack event is 0, got "+s;return t;case 81:t.subtype="setTempo";if(s!=3)throw"Expected length for setTempo event is 3, got "+s;t.microsecondsPerBeat=(e.readInt8()<<16)+(e.readInt8()<<8)+e.readInt8();return t;case 84:t.subtype="smpteOffset";if(s!=5)throw"Expected length for smpteOffset event is 5, got "+s;var o=e.readInt8();t.frameRate={0:24,32:25,64:29,96:30}[o&96];t.hour=o&31;t.min=e.readInt8();t.sec=e.readInt8();t.frame=e.readInt8();t.subframe=e.readInt8();return t;case 88:t.subtype="timeSignature";if(s!=4)throw"Expected length for timeSignature event is 4, got "+s;t.numerator=e.readInt8();t.denominator=Math.pow(2,e.readInt8());t.metronome=e.readInt8();t.thirtyseconds=e.readInt8();return t;case 89:t.subtype="keySignature";if(s!=2)throw"Expected length for keySignature event is 2, got "+s;t.key=e.readInt8(true);t.scale=e.readInt8();return t;case 127:t.subtype="sequencerSpecific";t.data=e.read(s);return t;default:t.subtype="unknown";t.data=e.read(s);return t}t.data=e.read(s);return t}else if(r==240){t.type="sysEx";var s=e.readVarInt();t.data=e.read(s);return t}else if(r==247){t.type="dividedSysEx";var s=e.readVarInt();t.data=e.read(s);return t}else{throw"Unrecognised MIDI event type byte: "+r}}else{var u;if((r&128)==0){u=r;r=n}else{u=e.readInt8();n=r}var a=r>>4;t.channel=r&15;t.type="channel";switch(a){case 8:t.subtype="noteOff";t.noteNumber=u;t.velocity=e.readInt8();return t;case 9:t.noteNumber=u;t.velocity=e.readInt8();if(t.velocity==0){t.subtype="noteOff"}else{t.subtype="noteOn"}return t;case 10:t.subtype="noteAftertouch";t.noteNumber=u;t.amount=e.readInt8();return t;case 11:t.subtype="controller";t.controllerType=u;t.value=e.readInt8();return t;case 12:t.subtype="programChange";t.programNumber=u;return t;case 13:t.subtype="channelAftertouch";t.amount=u;return t;case 14:t.subtype="pitchBend";t.value=u+(e.readInt8()<<7);return t;default:throw"Unrecognised MIDI event type: "+a}}}var n;stream=Stream(e);var i=t(stream);if(i.id!="MThd"||i.length!=6){throw"Bad .mid file - header not found"}var s=Stream(i.data);var o=s.readInt16();var u=s.readInt16();var a=s.readInt16();if(a&32768){throw"Expressing time division in SMTPE frames is not supported yet"}else{ticksPerBeat=a}var f={formatType:o,trackCount:u,ticksPerBeat:ticksPerBeat};var l=[];for(var c=0;c<f.trackCount;c++){l[c]=[];var h=t(stream);if(h.id!="MTrk"){throw"Unexpected chunk - expected MTrk, got "+h.id}var p=Stream(h.data);while(!p.eof()){var d=r(p);l[c].push(d)}}return{header:f,tracks:l}}