-
Notifications
You must be signed in to change notification settings - Fork 12
/
midi-writer-js.js
1 lines (1 loc) · 19.6 KB
/
midi-writer-js.js
1
;'use strict';var tonalMidi=require('tonal-midi');var Constants={VERSION:"2.0.1",HEADER_CHUNK_TYPE:[0x4d,0x54,0x68,0x64],HEADER_CHUNK_LENGTH:[0x00,0x00,0x00,0x06],HEADER_CHUNK_FORMAT0:[0x00,0x00],HEADER_CHUNK_FORMAT1:[0x00,0x01],HEADER_CHUNK_DIVISION:[0x00,0x80],TRACK_CHUNK_TYPE:[0x4d,0x54,0x72,0x6b],META_EVENT_ID:0xFF,META_TEXT_ID:0x01,META_COPYRIGHT_ID:0x02,META_TRACK_NAME_ID:0x03,META_INSTRUMENT_NAME_ID:0x04,META_LYRIC_ID:0x05,META_MARKER_ID:0x06,META_CUE_POINT:0x07,META_TEMPO_ID:0x51,META_SMTPE_OFFSET:0x54,META_TIME_SIGNATURE_ID:0x58,META_KEY_SIGNATURE_ID:0x59,META_END_OF_TRACK_ID:[0x2F,0x00],CONTROLLER_CHANGE_STATUS:0xB0,PROGRAM_CHANGE_STATUS:0xC0,PITCH_BEND_STATUS:0xE0};function _typeof(b){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(b)}function _wrapRegExp(){_wrapRegExp=function(a,b){return new i(a,void 0,b)};var g=RegExp.prototype,h=new WeakMap();function i(a,b,c){var e=new RegExp(a,b);return h.set(e,c||h.get(a)),_setPrototypeOf(e,i.prototype)}function k(c,e){var d=h.get(e);return Object.keys(d).reduce(function(a,b){return a[b]=c[d[b]],a},Object.create(null))}return _inherits(i,RegExp),i.prototype.exec=function(a){var b=g.exec.call(this,a);return b&&(b.groups=k(b,this)),b},i.prototype[Symbol.replace]=function(c,e){if("string"==typeof e){var d=h.get(this);return g[Symbol.replace].call(this,c,e.replace(/\$<([^>]+)>/g,function(a,b){return"$"+d[b]}))}if("function"==typeof e){var f=this;return g[Symbol.replace].call(this,c,function(){var a=arguments;return"object"!=typeof a[a.length-1]&&(a=[].slice.call(a)).push(k(a,f)),e.apply(this,a)})}return g[Symbol.replace].call(this,c,e)},_wrapRegExp.apply(this,arguments)}function _classCallCheck(a,b){if(!(a instanceof b)){throw new TypeError("Cannot call a class as a function");}}function _defineProperties(a,b){for(var c=0;c<b.length;c++){var e=b[c];e.enumerable=e.enumerable||false;e.configurable=true;if("value"in e)e.writable=true;Object.defineProperty(a,e.key,e)}}function _createClass(a,b,c){if(b)_defineProperties(a.prototype,b);if(c)_defineProperties(a,c);Object.defineProperty(a,"prototype",{writable:false});return a}function _inherits(a,b){if(typeof b!=="function"&&b!==null){throw new TypeError("Super expression must either be null or a function");}a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,writable:true,configurable:true}});Object.defineProperty(a,"prototype",{writable:false});if(b)_setPrototypeOf(a,b)}function _setPrototypeOf(c,e){d=Object.setPrototypeOf||function d(a,b){a.__proto__=b;return a};return d(c,e)}var Utils=function(){function j(){_classCallCheck(this,j)}_createClass(j,null,[{key:"version",value:function o(){return Constants.VERSION}},{key:"stringToBytes",value:function p(b){return b.split('').map(function(a){return a.charCodeAt()})}},{key:"isNumeric",value:function q(a){return!isNaN(parseFloat(a))&&isFinite(a)}},{key:"getPitch",value:function r(a){return tonalMidi.toMidi(a)}},{key:"numberToVariableLength",value:function s(a){a=Math.round(a);var b=a&0x7F;while(a=a>>7){b<<=8;b|=a&0x7F|0x80}var c=[];while(true){c.push(b&0xff);if(b&0x80)b>>=8;else{break}}return c}},{key:"stringByteCount",value:function t(a){return encodeURI(a).split(/%..|./).length-1}},{key:"numberFromBytes",value:function u(b){var c='';var e;b.forEach(function(a){e=a.toString(16);if(e.length==1)e="0"+e;c+=e});return parseInt(c,16)}},{key:"numberToBytes",value:function v(b,c){c=c||1;var e=b.toString(16);if(e.length&1){e='0'+e}var d=e.match(/.{2}/g);d=d.map(function(a){return parseInt(a,16)});if(d.length<c){while(c-d.length>0){d.unshift(0)}}return d}},{key:"toArray",value:function w(a){if(Array.isArray(a))return a;return[a]}},{key:"convertVelocity",value:function x(a){a=a>100?100:a;return Math.round(a/100*127)}},{key:"getTickDuration",value:function y(c){if(Array.isArray(c)){return c.map(function(a){return j.getTickDuration(a)}).reduce(function(a,b){return a+b},0)}c=c.toString();if(c.toLowerCase().charAt(0)==='t'){return parseInt(c.substring(1))}var e=j.numberFromBytes(Constants.HEADER_CHUNK_DIVISION);var d=e*j.getDurationMultiplier(c);return j.getRoundedIfClose(d)}},{key:"getRoundedIfClose",value:function z(a){var b=Math.round(a);return Math.abs(b-a)<0.000001?b:a}},{key:"getPrecisionLoss",value:function A(a){var b=Math.round(a);return b-a}},{key:"getDurationMultiplier",value:function B(a){if(a==='0')return 0;var b=a.match(_wrapRegExp(/^(d+)?(\d+)(?:t(\d*))?/,{dotted:1,base:2,tuplet:3}));if(b){var c=Number(b.groups.base);var e=c===1||(c&c-1)===0;if(e){var d=c/4;var f=1/d;var g=b.groups,h=g.dotted,i=g.tuplet;if(h){var k=h.length;var l=Math.pow(2,k);f=f+f*((l-1)/l)}if(typeof i==='string'){var m=f*2;var n=Number(i||'3');f=m/n}return f}}throw new Error(a+' is not a valid duration.');}}]);return j}();var NoteOnEvent=function(){function c(a){_classCallCheck(this,c);a=Object.assign({channel:1,startTick:null,velocity:50,wait:0},a);this.type='note-on';this.channel=a.channel;this.pitch=a.pitch;this.wait=a.wait;this.velocity=a.velocity;this.startTick=a.startTick;this.midiNumber=Utils.getPitch(this.pitch);this.tick=null;this.delta=null;this.data=a.data}_createClass(c,[{key:"buildData",value:function e(a,b){this.data=[];if(this.startTick){this.tick=Utils.getRoundedIfClose(this.startTick);if(a.tickPointer==0){this.delta=this.tick}}else{this.delta=Utils.getTickDuration(this.wait);this.tick=Utils.getRoundedIfClose(a.tickPointer+this.delta)}this.deltaWithPrecisionCorrection=Utils.getRoundedIfClose(this.delta-b);this.data=Utils.numberToVariableLength(this.deltaWithPrecisionCorrection).concat(this.getStatusByte(),this.midiNumber,Utils.convertVelocity(this.velocity));return this}},{key:"getStatusByte",value:function d(){return 144+this.channel-1}}]);return c}();var NoteOffEvent=function(){function c(a){_classCallCheck(this,c);a=Object.assign({channel:1,velocity:50,tick:null},a);this.type='note-off';this.channel=a.channel;this.pitch=a.pitch;this.duration=a.duration;this.velocity=a.velocity;this.midiNumber=Utils.getPitch(this.pitch);this.tick=a.tick;this.delta=Utils.getTickDuration(this.duration);this.data=a.data}_createClass(c,[{key:"buildData",value:function e(a,b){if(this.tick===null){this.tick=Utils.getRoundedIfClose(this.delta+a.tickPointer)}this.deltaWithPrecisionCorrection=Utils.getRoundedIfClose(this.delta-b);this.data=Utils.numberToVariableLength(this.deltaWithPrecisionCorrection).concat(this.getStatusByte(),this.midiNumber,Utils.convertVelocity(this.velocity));return this}},{key:"getStatusByte",value:function d(){return 128+this.channel-1}}]);return c}();var NoteEvent=function(){function h(a){_classCallCheck(this,h);a=Object.assign({channel:1,repeat:1,sequential:false,startTick:null,velocity:50,wait:0},a);this.data=[];this.type='note';this.pitch=Utils.toArray(a.pitch);this.channel=a.channel;this.duration=a.duration;this.grace=a.grace;this.repeat=a.repeat;this.sequential=a.sequential;this.startTick=a.startTick;this.velocity=a.velocity;this.wait=a.wait;this.tickDuration=Utils.getTickDuration(this.duration);this.restDuration=Utils.getTickDuration(this.wait);this.events=[]}_createClass(h,[{key:"buildData",value:function i(){var d=this;this.data=[];this.tickDuration;this.restDuration;if(this.grace){var f=1;this.grace=Utils.toArray(this.grace);this.grace.forEach(function(a){var b=new h({pitch:d.grace,duration:'T'+f});d.data=d.data.concat(b.data)})}if(!this.sequential){for(var g=0;g<this.repeat;g++){this.pitch.forEach(function(a,b){if(b==0){var c=new NoteOnEvent({channel:d.channel,wait:d.wait,velocity:d.velocity,pitch:a,startTick:d.startTick})}else{var c=new NoteOnEvent({channel:d.channel,wait:0,velocity:d.velocity,pitch:a,startTick:d.startTick})}d.events.push(c)});this.pitch.forEach(function(a,b){if(b==0){var c=new NoteOffEvent({channel:d.channel,duration:d.duration,velocity:d.velocity,pitch:a,tick:d.startTick!==null?Utils.getTickDuration(d.duration)+d.startTick:null})}else{var c=new NoteOffEvent({channel:d.channel,duration:0,velocity:d.velocity,pitch:a,tick:d.startTick!==null?Utils.getTickDuration(d.duration)+d.startTick:null})}d.events.push(c)})}}else{for(var g=0;g<this.repeat;g++){this.pitch.forEach(function(a,b){var c=new NoteOnEvent({channel:d.channel,wait:b>0?0:d.wait,velocity:d.velocity,pitch:a,startTick:d.startTick});var e=new NoteOffEvent({channel:d.channel,duration:d.duration,velocity:d.velocity,pitch:a});d.events.push(c,e)})}}return this}}]);return h}();var scale14bits=function scale14bits(a){if(a<=0){return Math.floor(16384*(a+1)/2)}return Math.floor(16383*(a+1)/2)};var PitchBendEvent=_createClass(function PitchBendEvent(a){_classCallCheck(this,PitchBendEvent);a=Object.assign({delta:0x00},a);this.type='pitch-bend';var b=scale14bits(a.bend);var c=a.channel||0;var e=b&0x7f;var d=b>>7&0x7f;this.data=Utils.numberToVariableLength(a.delta).concat(Constants.PITCH_BEND_STATUS|c,e,d)});var ProgramChangeEvent=_createClass(function ProgramChangeEvent(a){_classCallCheck(this,ProgramChangeEvent);a=Object.assign({delta:0x00},a);this.type='program';this.data=Utils.numberToVariableLength(a.delta).concat(Constants.PROGRAM_CHANGE_STATUS,a.instrument)});var ControllerChangeEvent=_createClass(function ControllerChangeEvent(a){_classCallCheck(this,ControllerChangeEvent);a=Object.assign({delta:0x00},a);this.type='controller';this.data=Utils.numberToVariableLength(a.delta).concat(Constants.CONTROLLER_CHANGE_STATUS,a.controllerNumber,a.controllerValue)});var CopyrightEvent=_createClass(function CopyrightEvent(a){_classCallCheck(this,CopyrightEvent);a=Object.assign({delta:0x00},a);this.type='copyright';var b=Utils.stringToBytes(a.text);this.data=Utils.numberToVariableLength(a.delta).concat(Constants.META_EVENT_ID,Constants.META_COPYRIGHT_ID,Utils.numberToVariableLength(b.length),b)});var CuePointEvent=_createClass(function CuePointEvent(a){_classCallCheck(this,CuePointEvent);a=Object.assign({delta:0x00},a);this.type='cue-point';var b=Utils.stringToBytes(a.text);this.data=Utils.numberToVariableLength(a.delta).concat(Constants.META_EVENT_ID,Constants.META_CUE_POINT,Utils.numberToVariableLength(b.length),b)});var EndTrackEvent=_createClass(function EndTrackEvent(a){_classCallCheck(this,EndTrackEvent);a=Object.assign({delta:0x00},a);this.type='end-track';this.data=Utils.numberToVariableLength(a.delta).concat(Constants.META_EVENT_ID,Constants.META_END_OF_TRACK_ID)});var InstrumentNameEvent=_createClass(function InstrumentNameEvent(a){_classCallCheck(this,InstrumentNameEvent);a=Object.assign({delta:0x00},a);this.type='instrument-name';var b=Utils.stringToBytes(a.text);this.data=Utils.numberToVariableLength(a.delta).concat(Constants.META_EVENT_ID,Constants.META_INSTRUMENT_NAME_ID,Utils.numberToVariableLength(b.length),b)});var KeySignatureEvent=_createClass(function KeySignatureEvent(a,b){_classCallCheck(this,KeySignatureEvent);this.type='key-signature';var c=b||0;a=a||0;if(typeof b==='undefined'){var e=[['Cb','Gb','Db','Ab','Eb','Bb','F','C','G','D','A','E','B','F#','C#'],['ab','eb','bb','f','c','g','d','a','e','b','f#','c#','g#','d#','a#']];var d=a.length;var f=a||'C';if(a[0]===a[0].toLowerCase())c=1;if(d>1){switch(a.charAt(d-1)){case'm':c=1;f=a.charAt(0).toLowerCase();f=f.concat(a.substring(1,d-1));break;case'-':c=1;f=a.charAt(0).toLowerCase();f=f.concat(a.substring(1,d-1));break;case'M':c=0;f=a.charAt(0).toUpperCase();f=f.concat(a.substring(1,d-1));break;case'+':c=0;f=a.charAt(0).toUpperCase();f=f.concat(a.substring(1,d-1));break}}var g=e[c].indexOf(f);a=g===-1?0:g-7}this.data=Utils.numberToVariableLength(0x00).concat(Constants.META_EVENT_ID,Constants.META_KEY_SIGNATURE_ID,[0x02],Utils.numberToBytes(a,1),Utils.numberToBytes(c,1))});var LyricEvent=_createClass(function LyricEvent(a){_classCallCheck(this,LyricEvent);a=Object.assign({delta:0x00},a);this.type='lyric';var b=Utils.stringToBytes(a.text);this.data=Utils.numberToVariableLength(a.delta).concat(Constants.META_EVENT_ID,Constants.META_LYRIC_ID,Utils.numberToVariableLength(b.length),b)});var MarkerEvent=_createClass(function MarkerEvent(a){_classCallCheck(this,MarkerEvent);a=Object.assign({delta:0x00},a);this.type='marker';var b=Utils.stringToBytes(a.text);this.data=Utils.numberToVariableLength(a.delta).concat(Constants.META_EVENT_ID,Constants.META_MARKER_ID,Utils.numberToVariableLength(b.length),b)});var TempoEvent=_createClass(function TempoEvent(a){_classCallCheck(this,TempoEvent);a=Object.assign({delta:0x00},a);this.type='tempo';this.tick=a.tick;var b=Math.round(60000000/a.bpm);this.data=Utils.numberToVariableLength(a.delta).concat(Constants.META_EVENT_ID,Constants.META_TEMPO_ID,[0x03],Utils.numberToBytes(b,3))});var TextEvent=_createClass(function TextEvent(a){_classCallCheck(this,TextEvent);a=Object.assign({delta:0x00},a);this.type='text';var b=Utils.stringToBytes(a.text);this.data=Utils.numberToVariableLength(a.delta).concat(Constants.META_EVENT_ID,Constants.META_TEXT_ID,Utils.numberToVariableLength(b.length),b)});var TimeSignatureEvent=_createClass(function TimeSignatureEvent(a,b,c,e){_classCallCheck(this,TimeSignatureEvent);this.type='time-signature';this.data=Utils.numberToVariableLength(0x00).concat(Constants.META_EVENT_ID,Constants.META_TIME_SIGNATURE_ID,[0x04],Utils.numberToBytes(a,1),Utils.numberToBytes(Math.log2(b),1),Utils.numberToBytes(c||24,1),Utils.numberToBytes(e||8,1))});var TrackNameEvent=_createClass(function TrackNameEvent(a){_classCallCheck(this,TrackNameEvent);a=Object.assign({delta:0x00},a);this.type='track-name';var b=Utils.stringToBytes(a.text);this.data=Utils.numberToVariableLength(a.delta).concat(Constants.META_EVENT_ID,Constants.META_TRACK_NAME_ID,Utils.numberToVariableLength(b.length),b)});var Track=function(){function i(){_classCallCheck(this,i);this.type=Constants.TRACK_CHUNK_TYPE;this.data=[];this.size=[];this.events=[];this.explicitTickEvents=[];this.tickPointer=0}_createClass(i,[{key:"addEvent",value:function k(f,g){var h=this;Utils.toArray(f).forEach(function(b,c){if(b instanceof NoteEvent){if(typeof g==='function'){var e=g(c,b);if(_typeof(e)==='object'){for(var d in e){switch(d){case'channel':b.channel=e[d];break;case'duration':b.duration=e[d];break;case'sequential':b.sequential=e[d];break;case'velocity':b.velocity=Utils.convertVelocity(e[d]);break}}}}if(b.startTick!==null){h.explicitTickEvents.push(b)}else{b.buildData().events.forEach(function(a){return h.events.push(a)})}}else{h.events.push(b)}});return this}},{key:"buildData",value:function l(){var e=this;this.removeEventsByType('end-track').addEvent(new EndTrackEvent());this.data=[];this.size=[];this.tickPointer=0;var d=0;this.events.forEach(function(a,b){if(a instanceof NoteOnEvent||a instanceof NoteOffEvent){var c=a.buildData(e,d);d=Utils.getPrecisionLoss(a.deltaWithPrecisionCorrection||0);e.data=e.data.concat(c.data);e.tickPointer=Utils.getRoundedIfClose(a.tick)}else if(a instanceof TempoEvent){e.tickPointer=Utils.getRoundedIfClose(a.tick);e.data=e.data.concat(a.data)}else{e.data=e.data.concat(a.data)}});this.mergeExplicitTickEvents();this.size=Utils.numberToBytes(this.data.length,4);return this}},{key:"mergeExplicitTickEvents",value:function m(){var c=this;if(!this.explicitTickEvents.length)return;this.explicitTickEvents.sort(function(a,b){return a.startTick-b.startTick});this.explicitTickEvents.forEach(function(b){b.buildData().events.forEach(function(a){return a.buildData(c)});b.events.forEach(function(a){return c.mergeSingleEvent(a)})});this.explicitTickEvents=[];this.buildData()}},{key:"mergeTrack",value:function n(b){var c=this;this.buildData();b.buildData().events.forEach(function(a){return c.mergeSingleEvent(a)})}},{key:"mergeSingleEvent",value:function j(a){var b=0;for(var c=0;c<this.events.length;c++){if(this.events[c].tick>a.tick)break;b=c}var e=b+1;a.delta=a.tick-this.events[b].tick;this.events.splice(e,0,a);for(var c=e+1;c<this.events.length;c++){this.events[c].delta=this.events[c].tick-this.events[c-1].tick}}},{key:"removeEventsByType",value:function o(c){var e=this;this.events.forEach(function(a,b){if(a.type===c){e.events.splice(b,1)}});return this}},{key:"setTempo",value:function p(a){var b=arguments.length>1&&arguments[1]!==undefined?arguments[1]:0;return this.addEvent(new TempoEvent({bpm:a,tick:b}))}},{key:"setTimeSignature",value:function q(a,b,c,e){return this.addEvent(new TimeSignatureEvent(a,b,c,e))}},{key:"setKeySignature",value:function r(a,b){return this.addEvent(new KeySignatureEvent(a,b))}},{key:"addText",value:function s(a){return this.addEvent(new TextEvent({text:a}))}},{key:"addCopyright",value:function t(a){return this.addEvent(new CopyrightEvent({text:a}))}},{key:"addTrackName",value:function u(a){return this.addEvent(new TrackNameEvent({text:a}))}},{key:"addInstrumentName",value:function v(a){return this.addEvent(new InstrumentNameEvent({text:a}))}},{key:"addMarker",value:function w(a){return this.addEvent(new MarkerEvent({text:a}))}},{key:"addCuePoint",value:function x(a){return this.addEvent(new CuePointEvent({text:a}))}},{key:"addLyric",value:function y(a){return this.addEvent(new LyricEvent({text:a}))}},{key:"polyModeOn",value:function z(){var a=new NoteOnEvent({data:[0x00,0xB0,0x7E,0x00]});return this.addEvent(a)}},{key:"setPitchBend",value:function A(a){return this.addEvent(new PitchBendEvent({bend:a}))}},{key:"controllerChange",value:function B(a,b){return this.addEvent(new ControllerChangeEvent({controllerNumber:a,controllerValue:b}))}}]);return i}();var VexFlow=function(){function i(){_classCallCheck(this,i)}_createClass(i,[{key:"trackFromVoice",value:function k(e){var d=this;var f=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{addRenderedAccidentals:false};var g=new Track();var h=[];e.tickables.forEach(function(c){if(c.noteType==='n'){g.addEvent(new NoteEvent({pitch:c.keys.map(function(a,b){return d.convertPitch(a,b,c,f.addRenderedAccidentals)}),duration:d.convertDuration(c),wait:h}));h=[]}else if(c.noteType==='r'){h.push(d.convertDuration(c));return}});if(h.length>0){g.addEvent(new NoteEvent({pitch:'[c4]',duration:'0',wait:h,velocity:'0'}))}return g}},{key:"convertPitch",value:function l(b,c,e){var d=arguments.length>3&&arguments[3]!==undefined?arguments[3]:false;var f=b.split('/');var g=f[0].substring(1).replace('n','');if(d){var h;(h=e.getAccidentals())===null||h===void 0?void 0:h.forEach(function(a){if(a.index===c){if(a.type==='n'){g=''}else{g+=a.type}}})}return f[0][0]+g+f[1]}},{key:"convertDuration",value:function m(a){return'd'.repeat(a.dots)+this.convertBaseDuration(a.duration)+(a.tuplet?'t'+a.tuplet.num_notes:'')}},{key:"convertBaseDuration",value:function n(a){switch(a){case'w':return'1';case'h':return'2';case'q':return'4';default:return a}}}]);return i}();var HeaderChunk=_createClass(function HeaderChunk(a){_classCallCheck(this,HeaderChunk);this.type=Constants.HEADER_CHUNK_TYPE;var b=a>1?Constants.HEADER_CHUNK_FORMAT1:Constants.HEADER_CHUNK_FORMAT0;this.data=b.concat(Utils.numberToBytes(a,2),Constants.HEADER_CHUNK_DIVISION);this.size=[0,0,0,this.data.length]});var Writer=function(){function d(c){var e=this;_classCallCheck(this,d);c=Utils.toArray(c);this.data=[];this.data.push(new HeaderChunk(c.length));c.forEach(function(a,b){e.data.push(a.buildData())})}_createClass(d,[{key:"buildFile",value:function f(){var b=[];this.data.forEach(function(a){return b=b.concat(a.type,a.size,a.data)});return new Uint8Array(b)}},{key:"base64",value:function g(){if(typeof btoa==='function')return btoa(String.fromCharCode.apply(null,this.buildFile()));return Buffer.from(this.buildFile()).toString('base64')}},{key:"dataUri",value:function h(){return'data:audio/midi;base64,'+this.base64()}},{key:"stdout",value:function i(){return process.stdout.write(new Buffer(this.buildFile()))}}]);return d}();var main={Constants:Constants,NoteOnEvent:NoteOnEvent,NoteOffEvent:NoteOffEvent,NoteEvent:NoteEvent,PitchBendEvent:PitchBendEvent,ProgramChangeEvent:ProgramChangeEvent,Track:Track,Utils:Utils,VexFlow:VexFlow,Writer:Writer};module.exports=main;;