midi-audio-player 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,8 +7,8 @@
7
7
  ██║ ╚═╝ ██║██║██████╔╝██║██║ ██║╚██████╔╝██████╔╝██║╚██████╔╝██║ ███████╗██║ ██║ ██║ ███████╗██║ ██║
8
8
  ╚═╝ ╚═╝╚═╝╚═════╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝
9
9
 
10
- Version: 2.0.1
11
- Build: 2026-05-31 02:44:14
10
+ Version: 2.0.2
11
+ Build: 2026-06-02 12:19:59
12
12
  Author: Maxime Larrivée-Roy <mlarriveeroy@gmail.com>
13
13
  Github: https://github.com/webaudiofonts/midi-audio-player/
14
14
  Website: https://webaudiofonts.com/midiaudioplayer/
@@ -1252,9 +1252,10 @@
1252
1252
  const player = new _WebAudioFontPlayer(preset, audioCtx, compressor, () => resolve(player));
1253
1253
  });
1254
1254
  }
1255
- async setPreset(preset) {
1255
+ async setPreset(preset, nonblocking = false) {
1256
1256
  this.#preset = preset;
1257
- await Promise.all(this.#preset.zones.map((zone) => this.#adjustZone(zone)));
1257
+ if (nonblocking) this.#preset.zones.map((zone) => this.#adjustZone(zone));
1258
+ else await Promise.all(this.#preset.zones.map((zone) => this.#adjustZone(zone)));
1258
1259
  }
1259
1260
  close() {
1260
1261
  const now = this.#audioCtx.currentTime;
@@ -1959,13 +1960,16 @@
1959
1960
  throw new Error("Invalid preset: ".concat(id));
1960
1961
  }
1961
1962
  }
1962
- async loadPreset(presetId, channel) {
1963
+ async loadPreset(presetId, channel, nonblocking = false) {
1963
1964
  const presetInfo = await this.findPreset(presetId);
1964
1965
  if (!presetInfo) throw new Error("Invalid preset: ".concat(presetId));
1965
1966
  this.#presetMap[presetInfo.program] = presetInfo;
1966
1967
  const preset = await this.getPreset(presetId);
1967
- await this.#players[channel].setPreset(preset);
1968
- this.#setupChange();
1968
+ if (nonblocking) this.#players[channel].setPreset(preset, nonblocking).then(() => this.#setupChange());
1969
+ else {
1970
+ await this.#players[channel].setPreset(preset, nonblocking);
1971
+ this.#setupChange();
1972
+ }
1969
1973
  }
1970
1974
  async load(content, setup) {
1971
1975
  if (typeof content === "string") {
@@ -1993,6 +1997,15 @@
1993
1997
  } catch (e) {
1994
1998
  await this.loadArrayBuffer(await this.#repairMidi(content));
1995
1999
  }
2000
+ if (this.#opts.karaoke) {
2001
+ this.#log("Generating karaoke frames...");
2002
+ this.#lyrics = null;
2003
+ await this.#generateKaraokeFrames();
2004
+ if (this.#title) this.#sendKaraokeFrame("title", this.#title);
2005
+ }
2006
+ this.#log("Trim midi events...");
2007
+ this.#trimMidiEvents();
2008
+ queueMicrotask(() => this.triggerPlayerEvent("computed"));
1996
2009
  this.#log("Loading instruments...");
1997
2010
  this.#channels = await this.#getInstruments();
1998
2011
  this.#channelStates = Object.keys(this.#channels).reduce((acc, key) => ({ ...acc, [key]: false }), {});
@@ -2003,8 +2016,8 @@
2003
2016
  this.#channelVolumes[channel] = setup.volumes[channel];
2004
2017
  }));
2005
2018
  }
2006
- const setupPrograms = /* @__PURE__ */ new Set();
2007
2019
  const setupPresets = {};
2020
+ const setupPrograms = /* @__PURE__ */ new Set();
2008
2021
  if (setup?.presets !== void 0) {
2009
2022
  await Promise.all(Object.keys(setup.presets).map(async (channel) => {
2010
2023
  const presetInfo = await this.findPreset(setup.presets[channel]);
@@ -2015,7 +2028,7 @@
2015
2028
  }
2016
2029
  const uniqueInstruments = await this.#getUniqueInstruments();
2017
2030
  if (!Object.values(this.#channels).length) this.#log("Error: no instrument found");
2018
- const presets = Promise.all([...uniqueInstruments].map(async (program) => {
2031
+ await Promise.all([...uniqueInstruments].map(async (program) => {
2019
2032
  if (setupPrograms.has(program)) return;
2020
2033
  let preset = null;
2021
2034
  if (this.#presetMap[program] !== void 0) preset = await this.getPreset(this.#presetMap[program].id);
@@ -2023,16 +2036,6 @@
2023
2036
  else preset = await this.#getAutoPreset(program);
2024
2037
  this.#instruments[program] = preset;
2025
2038
  }));
2026
- if (this.#opts.karaoke) {
2027
- this.#log("Generating karaoke frames...");
2028
- this.#lyrics = null;
2029
- await this.#generateKaraokeFrames();
2030
- if (this.#title) this.#sendKaraokeFrame("title", this.#title);
2031
- }
2032
- this.#log("Trim midi events...");
2033
- this.#trimMidiEvents();
2034
- queueMicrotask(() => this.triggerPlayerEvent("computed"));
2035
- await presets;
2036
2039
  await Promise.all(Object.keys(this.#channels).map(async (channel) => {
2037
2040
  if (this.#players[channel]) this.#players[channel].close();
2038
2041
  if (setupPresets[channel] !== void 0) this.#players[channel] = await this.#createPlayer(setupPresets[channel]);
@@ -2487,8 +2490,8 @@
2487
2490
  this.#presetMap[program] = preset;
2488
2491
  return await this.getPreset(preset.id);
2489
2492
  }
2490
- async #createPlayer(preset) {
2491
- return new index_default(preset, this.#audioCtx, this.#compressor);
2493
+ #createPlayer(preset) {
2494
+ return index_default.load(preset, this.#audioCtx, this.#compressor);
2492
2495
  }
2493
2496
  async #handleMidiPipeline(event) {
2494
2497
  if (!this.isPlaying()) return;
@@ -7,11 +7,11 @@
7
7
  ██║ ╚═╝ ██║██║██████╔╝██║██║ ██║╚██████╔╝██████╔╝██║╚██████╔╝██║ ███████╗██║ ██║ ██║ ███████╗██║ ██║
8
8
  ╚═╝ ╚═╝╚═╝╚═════╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝
9
9
 
10
- Version: 2.0.1
11
- Build: 2026-05-31 02:44:14
10
+ Version: 2.0.2
11
+ Build: 2026-06-02 12:19:59
12
12
  Author: Maxime Larrivée-Roy <mlarriveeroy@gmail.com>
13
13
  Github: https://github.com/webaudiofonts/midi-audio-player/
14
14
  Website: https://webaudiofonts.com/midiaudioplayer/
15
15
 
16
16
  */
17
- (()=>{function B(f,e){if(!(f instanceof e))throw new TypeError("Cannot call a class as a function")}function j(f,e){for(var t=0;t<e.length;t++){var s=e[t];s.enumerable=s.enumerable||!1,s.configurable=!0,"value"in s&&(s.writable=!0),Object.defineProperty(f,s.key,s)}}function V(f,e,t){return e&&j(f.prototype,e),t&&j(f,t),Object.defineProperty(f,"prototype",{writable:!1}),f}var P={VERSION:"2.0.17",NOTES:[],HEADER_CHUNK_LENGTH:14,CIRCLE_OF_FOURTHS:["C","F","Bb","Eb","Ab","Db","Gb","Cb","Fb","Bbb","Ebb","Abb"],CIRCLE_OF_FIFTHS:["C","G","D","A","E","B","F#","C#","G#","D#","A#","E#"]},W=[["C"],["C#","Db"],["D"],["D#","Eb"],["E"],["F"],["F#","Gb"],["G"],["G#","Ab"],["A"],["A#","Bb"],["B"]],H=0,G=function(e){W.forEach(function(t){t.forEach(function(s){return P.NOTES[H]=s+e}),H++})};for(R=-1;R<=9;R++)G(R);var R,w=(function(){function f(){B(this,f)}return V(f,null,[{key:"byteToHex",value:function(t){return("0"+t.toString(16)).slice(-2)}},{key:"bytesToHex",value:function(t){var s=[];return t.forEach(function(i){return s.push(f.byteToHex(i))}),s.join("")}},{key:"hexToNumber",value:function(t){return parseInt(t,16)}},{key:"bytesToNumber",value:function(t){return f.hexToNumber(f.bytesToHex(t))}},{key:"bytesToLetters",value:function(t){var s=[];return t.forEach(function(i){return s.push(String.fromCharCode(i))}),s.join("")}},{key:"decToBinary",value:function(t){return(t>>>0).toString(2)}},{key:"getVarIntLength",value:function(t){for(var s=t[0],i=1;s>=128;)s=t[i],i++;return i}},{key:"readVarInt",value:function(t){var s=0;return t.forEach(function(i){var a=i;a&128?(s+=a&127,s<<=7):s+=a}),s}},{key:"atob",value:(function(e){function t(s){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t})(function(e){return typeof atob=="function"?atob(e):Buffer.from(e,"base64").toString("binary")})}]),f})(),Q=(function(){function f(e,t){B(this,f),this.enabled=!0,this.eventIndex=0,this.pointer=0,this.lastTick=0,this.lastStatus=null,this.index=e,this.data=t,this.delta=0,this.runningDelta=0,this.events=[];var s=this.data.subarray(this.data.length-3,this.data.length);if(!(s[0]===255&&s[1]===47&&s[2]===0))throw"Invalid MIDI file; Last three bytes of track "+this.index+"must be FF 2F 00 to mark end of track"}return V(f,[{key:"reset",value:function(){return this.enabled=!0,this.eventIndex=0,this.pointer=0,this.lastTick=0,this.lastStatus=null,this.delta=0,this.runningDelta=0,this}},{key:"enable",value:function(){return this.enabled=!0,this}},{key:"disable",value:function(){return this.enabled=!1,this}},{key:"setEventIndexByTick",value:function(t){t=t||0;for(var s=0;s<this.events.length;s++)if(this.events[s].tick>=t)return this.eventIndex=s,this}},{key:"getCurrentByte",value:function(){return this.data[this.pointer]}},{key:"getDeltaByteCount",value:function(){return w.getVarIntLength(this.data.subarray(this.pointer))}},{key:"getDelta",value:function(){return w.readVarInt(this.data.subarray(this.pointer,this.pointer+this.getDeltaByteCount()))}},{key:"handleEvent",value:function(t,s){if(s=s||!1,s){var i=t-this.lastTick,a=this.getDelta(),o=i>=a;if(this.pointer<this.data.length&&(s||o)){var n=this.parseEvent();if(this.enabled)return n}}else{for(var r=[];this.events[this.eventIndex]&&this.events[this.eventIndex].tick<=t;)this.enabled&&r.push(this.events[this.eventIndex]),this.eventIndex++;if(r.length>0)return r}return null}},{key:"getStringData",value:function(t){var s=w.getVarIntLength(this.data.subarray(t+2)),i=w.readVarInt(this.data.subarray(t+2,t+2+s)),a=w.bytesToLetters(this.data.subarray(t+2+s,t+2+s+i));return a}},{key:"parseEvent",value:function(){var t=this.pointer+this.getDeltaByteCount(),s={},i=this.getDeltaByteCount();if(s.track=this.index+1,s.delta=this.getDelta(),this.lastTick=this.lastTick+s.delta,this.runningDelta+=s.delta,s.tick=this.runningDelta,s.byteIndex=this.pointer,this.data[t]==255){switch(this.data[t+1]){case 0:s.name="Sequence Number";break;case 1:s.name="Text Event",s.string=this.getStringData(t);break;case 2:s.name="Copyright Notice";break;case 3:s.name="Sequence/Track Name",s.string=this.getStringData(t);break;case 4:s.name="Instrument Name",s.string=this.getStringData(t);break;case 5:s.name="Lyric",s.string=this.getStringData(t);break;case 6:s.name="Marker",s.string=this.getStringData(t);break;case 7:s.name="Cue Point",s.string=this.getStringData(t);break;case 9:s.name="Device Name",s.string=this.getStringData(t);break;case 32:s.name="MIDI Channel Prefix";break;case 33:s.name="MIDI Port",s.data=w.bytesToNumber([this.data[t+3]]);break;case 47:s.name="End of Track";break;case 81:s.name="Set Tempo",s.data=Math.round(6e7/w.bytesToNumber(this.data.subarray(t+3,t+6))),this.tempo=s.data;break;case 84:s.name="SMTPE Offset";break;case 88:s.name="Time Signature",s.data=this.data.subarray(t+3,t+7),s.timeSignature=""+s.data[0]+"/"+Math.pow(2,s.data[1]);break;case 89:s.name="Key Signature",s.data=this.data.subarray(t+3,t+5);var a=s.data[0]>127?s.data[0]-256:s.data[0];a>=0?s.keySignature=P.CIRCLE_OF_FIFTHS[a]:s.keySignature=P.CIRCLE_OF_FOURTHS[Math.abs(a)],s.data[1]==0?s.keySignature+=" Major":s.data[1]==1&&(s.keySignature+=" Minor");break;case 127:s.name="Sequencer-Specific Meta-event";break;default:s.name="Unknown: "+this.data[t+1].toString(16);break}var o=w.getVarIntLength(this.data.subarray(t+2)),n=w.readVarInt(this.data.subarray(t+2,t+2+o));this.pointer+=i+2+o+n}else if(this.data[t]===240){s.name="Sysex";var r=w.getVarIntLength(this.data.subarray(t+1)),c=w.readVarInt(this.data.subarray(t+1,t+1+r));s.data=this.data.subarray(t+1+r,t+1+r+c),this.pointer+=i+1+r+c}else if(this.data[t]===247){s.name="Sysex (escape)";var h=w.getVarIntLength(this.data.subarray(t+1)),l=w.readVarInt(this.data.subarray(t+1,t+1+h));s.data=this.data.subarray(t+1+h,t+1+h+l),this.pointer+=i+1+h+l}else if(this.data[t]<128)if(s.running=!0,s.noteNumber=this.data[t],s.noteName=P.NOTES[this.data[t]],s.velocity=this.data[t+1],this.lastStatus<=143)s.name="Note off",s.channel=this.lastStatus-128+1,this.pointer+=i+2;else if(this.lastStatus<=159)s.name="Note on",s.channel=this.lastStatus-144+1,this.pointer+=i+2;else if(this.lastStatus<=175)s.name="Polyphonic Key Pressure",s.channel=this.lastStatus-160+1,s.note=P.NOTES[this.data[t]],s.pressure=this.data[t+1],this.pointer+=i+2;else if(this.lastStatus<=191)s.name="Controller Change",s.channel=this.lastStatus-176+1,s.number=this.data[t],s.value=this.data[t+1],this.pointer+=i+2;else if(this.lastStatus<=207)s.name="Program Change",s.channel=this.lastStatus-192+1,s.value=this.data[t+1],this.pointer+=i+1;else if(this.lastStatus<=223)s.name="Channel Key Pressure",s.channel=this.lastStatus-208+1,this.pointer+=i+1;else if(this.lastStatus<=239)s.name="Pitch Bend",s.channel=this.lastStatus-224+1,s.value=(this.data[t+1]&127)<<7|this.data[t]&127,this.pointer+=i+2;else throw"Unknown event (running): ".concat(this.lastStatus);else if(this.lastStatus=this.data[t],this.data[t]<=143)s.name="Note off",s.channel=this.lastStatus-128+1,s.noteNumber=this.data[t+1],s.noteName=P.NOTES[this.data[t+1]],s.velocity=Math.round(this.data[t+2]/127*100),this.pointer+=i+3;else if(this.data[t]<=159)s.name="Note on",s.channel=this.lastStatus-144+1,s.noteNumber=this.data[t+1],s.noteName=P.NOTES[this.data[t+1]],s.velocity=Math.round(this.data[t+2]/127*100),this.pointer+=i+3;else if(this.data[t]<=175)s.name="Polyphonic Key Pressure",s.channel=this.lastStatus-160+1,s.note=P.NOTES[this.data[t+1]],s.pressure=this.data[t+2],this.pointer+=i+3;else if(this.data[t]<=191)s.name="Controller Change",s.channel=this.lastStatus-176+1,s.number=this.data[t+1],s.value=this.data[t+2],this.pointer+=i+3;else if(this.data[t]<=207)s.name="Program Change",s.channel=this.lastStatus-192+1,s.value=this.data[t+1],this.pointer+=i+2;else if(this.data[t]<=223)s.name="Channel Key Pressure",s.channel=this.lastStatus-208+1,this.pointer+=i+2;else if(this.data[t]<=239)s.name="Pitch Bend",s.channel=this.lastStatus-224+1,s.value=(this.data[t+2]&127)<<7|this.data[t+1]&127,this.pointer+=i+3;else throw"Unknown event: ".concat(this.data[t]);return this.delta+=s.delta,this.events.push(s),s}},{key:"endOfTrack",value:function(){return this.data[this.pointer+1]==255&&this.data[this.pointer+2]==47&&this.data[this.pointer+3]==0}}]),f})();Uint8Array.prototype.forEach||Object.defineProperty(Uint8Array.prototype,"forEach",{value:Array.prototype.forEach});var Z=(function(){function f(e,t){B(this,f),this.sampleRate=5,this.startTime=0,this.buffer=t||null,this.midiChunksByteLength=null,this.division,this.format,this.setTimeoutId=!1,this.scheduledTime=0,this.tracks=[],this.instruments=[],this.defaultTempo=120,this.tempo=null,this.startTick=0,this.tick=0,this.lastTick=null,this.inLoop=!1,this.totalTicks=0,this.events=[],this.totalEvents=0,this.tempoMap=[],this.eventListeners={},typeof e=="function"&&this.on("midiEvent",e)}return V(f,[{key:"loadFile",value:function(t){throw"loadFile is only supported on Node.js"}},{key:"loadArrayBuffer",value:function(t){return this.buffer=new Uint8Array(t),this.fileLoaded()}},{key:"loadDataUri",value:function(t){for(var s=w.atob(t.split(",")[1]),i=new Uint8Array(s.length),a=0;a<s.length;a++)i[a]=s.charCodeAt(a);return this.buffer=i,this.fileLoaded()}},{key:"getFilesize",value:function(){return this.buffer?this.buffer.length:0}},{key:"fileLoaded",value:function(){if(!this.validate())throw"Invalid MIDI file; should start with MThd";return this.defaultTempo=120,this.setTempo(this.defaultTempo).getDivision().getFormat().getTracks().dryRun()}},{key:"validate",value:function(){return w.bytesToLetters(this.buffer.subarray(0,4))==="MThd"}},{key:"getFormat",value:function(){return this.format=w.bytesToNumber(this.buffer.subarray(8,10)),this}},{key:"getTracks",value:function(){this.tracks=[];for(var t=0;t<this.buffer.length;){if(w.bytesToLetters(this.buffer.subarray(t,t+4))=="MTrk"){var s=w.bytesToNumber(this.buffer.subarray(t+4,t+8));this.tracks.push(new Q(this.tracks.length,this.buffer.subarray(t+8,t+8+s)))}t+=w.bytesToNumber(this.buffer.subarray(t+4,t+8))+8}var i=0;return this.tracks.forEach(function(a){i+=8+a.data.length}),this.midiChunksByteLength=P.HEADER_CHUNK_LENGTH+i,this}},{key:"enableTrack",value:function(t){return this.tracks[t-1].enable(),this}},{key:"disableTrack",value:function(t){return this.tracks[t-1].disable(),this}},{key:"getDivision",value:function(){return this.division=w.bytesToNumber(this.buffer.subarray(12,P.HEADER_CHUNK_LENGTH)),this}},{key:"playLoop",value:function(t){this.inLoop||(this.inLoop=!0,this.tick=this.getCurrentTick(),this.tracks.forEach(function(s,i){if(!t&&this.endOfFile())this.stop(),this.triggerPlayerEvent("endOfFile");else{var a=s.handleEvent(this.tick,t);if(t&&a)a.hasOwnProperty("name")&&a.name==="Set Tempo"&&this.setTempo(a.data),a.hasOwnProperty("name")&&a.name==="Program Change"&&(this.instruments.includes(a.value)||this.instruments.push(a.value));else if(a){var o=Array.isArray(a)?a:[a];o.forEach(function(n){n.hasOwnProperty("name")&&n.name==="Set Tempo"&&this.setTempo(n.data),this.emitEvent(n)},this)}}},this),!t&&this.isPlaying()&&this.triggerPlayerEvent("playing",{tick:this.tick}),this.inLoop=!1)}},{key:"setTempo",value:function(t){return this.tempo=t,this}},{key:"setStartTime",value:function(t){return this.startTime=t,this}},{key:"play",value:function(){if(this.isPlaying())throw"Already playing...";return this.startTime||(this.startTime=new Date().getTime()),this.scheduledTime=Date.now(),this.schedulePlayLoop(this.sampleRate),this}},{key:"schedulePlayLoop",value:function(t){var s=this;this.setTimeoutId=setTimeout(function(){if(s.playLoop(),s.setTimeoutId!==!1){s.scheduledTime+=s.sampleRate;var i=Date.now()-s.scheduledTime;s.schedulePlayLoop(Math.max(0,s.sampleRate-i))}},t)}},{key:"pause",value:function(){return clearTimeout(this.setTimeoutId),this.setTimeoutId=!1,this.scheduledTime=0,this.startTick=this.tick,this.startTime=0,this}},{key:"stop",value:function(){return clearTimeout(this.setTimeoutId),this.setTimeoutId=!1,this.scheduledTime=0,this.startTick=0,this.startTime=0,this.resetTracks(),this}},{key:"skipToTick",value:function(t){this.stop(),this.startTick=t;for(var s=this.tempoMap.length-1;s>=0;s--)if(this.tempoMap[s].tick<=t){this.setTempo(this.tempoMap[s].tempo);break}return this.collectStateAtTick(t).forEach(function(i){this.emitEvent(i)},this),this.tracks.forEach(function(i){i.setEventIndexByTick(t)}),this}},{key:"collectStateAtTick",value:function(t){var s={};return this.events.forEach(function(i){i.forEach(function(a){if(!(a.tick>=t)){var o;a.name==="Program Change"?o="pc:"+a.channel:a.name==="Controller Change"?o="cc:"+a.channel+":"+a.number:a.name==="Pitch Bend"&&(o="pb:"+a.channel),o&&(s[o]=a)}})}),Object.keys(s).map(function(i){return s[i]})}},{key:"skipToPercent",value:function(t){if(t<0||t>100)throw"Percent must be number between 1 and 100.";return this.skipToTick(Math.round(t/100*this.totalTicks)),this}},{key:"skipToSeconds",value:function(t){var s=this.getSongTime();if(t<0||t>s)throw t+" seconds not within song time of "+s;return this.skipToTick(this.secondsToTicks(t)),this}},{key:"isPlaying",value:function(){return this.setTimeoutId!==!1}},{key:"dryRun",value:function(){for(this.resetTracks();!this.endOfFile();)this.playLoop(!0);return this.events=this.getEvents(),this.totalEvents=this.getTotalEvents(),this.totalTicks=this.getTotalTicks(),this.buildTempoMap(),this.startTick=0,this.startTime=0,this.resetTracks(),this.triggerPlayerEvent("fileLoaded",this),this}},{key:"resetTracks",value:function(){return this.tracks.forEach(function(t){return t.reset()}),this}},{key:"getEvents",value:function(){return this.tracks.map(function(t){return t.events})}},{key:"getTotalTicks",value:function(){return Math.max.apply(null,this.tracks.map(function(t){return t.delta}))}},{key:"getTotalEvents",value:function(){return this.tracks.reduce(function(t,s){return{events:{length:t.events.length+s.events.length}}},{events:{length:0}}).events.length}},{key:"buildTempoMap",value:function(){var t=[];return this.events.forEach(function(s){s.forEach(function(i){i.name==="Set Tempo"&&t.push({tick:i.tick,tempo:i.data})})}),t.sort(function(s,i){return s.tick-i.tick}),this.tempoMap=[{tick:0,tempo:this.defaultTempo}],t.forEach(function(s){var i=this.tempoMap[this.tempoMap.length-1];s.tick===i.tick?i.tempo=s.tempo:this.tempoMap.push({tick:s.tick,tempo:s.tempo})},this),this}},{key:"ticksToSeconds",value:function(t,s){for(var i=0,a=t,o=0;o<this.tempoMap.length;o++){var n=this.tempoMap[o],r=o+1<this.tempoMap.length?this.tempoMap[o+1].tick:s;if(!(r<=t)){var c=Math.max(n.tick,t),h=Math.min(r,s);if(c>=s)break;var l=h-c;i+=l/this.division/n.tempo*60,a=h}}if(a<s){var m=this.tempoMap[this.tempoMap.length-1];i+=(s-a)/this.division/m.tempo*60}return i}},{key:"secondsToTicks",value:function(t){for(var s=t,i=0,a=0;a<this.tempoMap.length;a++){var o=this.tempoMap[a],n=a+1<this.tempoMap.length?this.tempoMap[a+1].tick:1/0,r=n-o.tick,c=r/this.division/o.tempo*60;if(s<=c)return i=o.tick+Math.round(s/60*o.tempo*this.division),i;s-=c,i=n}return this.totalTicks}},{key:"getSongTime",value:function(){return this.ticksToSeconds(0,this.totalTicks)}},{key:"getSongTimeRemaining",value:function(){return Math.round(this.ticksToSeconds(this.getCurrentTick(),this.totalTicks))}},{key:"getSongPercentRemaining",value:function(){return Math.round(this.getSongTimeRemaining()/this.getSongTime()*100)}},{key:"bytesProcessed",value:function(){return P.HEADER_CHUNK_LENGTH+this.tracks.length*8+this.tracks.reduce(function(t,s){return{pointer:t.pointer+s.pointer}},{pointer:0}).pointer}},{key:"eventsPlayed",value:function(){return this.tracks.reduce(function(t,s){return{eventIndex:t.eventIndex+s.eventIndex}},{eventIndex:0}).eventIndex}},{key:"endOfFile",value:function(){return this.isPlaying()?this.totalTicks-this.tick<=0:this.bytesProcessed()>=this.midiChunksByteLength}},{key:"getCurrentTick",value:function(){if(!this.startTime)return this.startTick;var t=(new Date().getTime()-this.startTime)/1e3,s=this.ticksToSeconds(0,this.startTick);return this.secondsToTicks(s+t)}},{key:"emitEvent",value:function(t){return this.triggerPlayerEvent("midiEvent",t),this}},{key:"on",value:function(t,s){return this.eventListeners.hasOwnProperty(t)||(this.eventListeners[t]=[]),this.eventListeners[t].push(s),this}},{key:"triggerPlayerEvent",value:function(t,s){return this.eventListeners.hasOwnProperty(t)&&this.eventListeners[t].forEach(function(i){return i(s||{})}),this}}]),f})(),U={Player:Z,Utils:w,Constants:P};var _=class ${#s=null;#r=null;#t=null;#n=[];#a=.05;#h=1e-6;#o=2;#e=null;#l=.7;#u=1;#c=null;#m=!1;#d=8192;#p=new Set;constructor(e,t,s=null,i=null){this.#s=t,this.#r=s,this.#e=this.#s.createGain(),this.#e.gain.setValueAtTime(this.#l,this.#s.currentTime),this.#c=this.#s.createGain(),this.#c.gain.setValueAtTime(this.#u,this.#s.currentTime),this.#e.connect(this.#c),this.#c.connect(this.#r?this.#r.input:this.#s.destination),this.setPreset(e).then(()=>{typeof i=="function"&&i()})}get preset(){return this.#t}set preset(e){this.setPreset(e)}static load(e,t,s=null){return new Promise(i=>{let a=new $(e,t,s,()=>i(a))})}async setPreset(e){this.#t=e,await Promise.all(this.#t.zones.map(t=>this.#y(t)))}close(){let e=this.#s.currentTime;this.#n.forEach(t=>{try{t.gain.cancelScheduledValues(0),t.audioBufferSourceNode&&(t.audioBufferSourceNode.stop(e),t.audioBufferSourceNode.disconnect(),t.audioBufferSourceNode=null)}catch{}try{t.disconnect()}catch{}}),this.#n=[],this.#p.clear();try{this.#e.disconnect()}catch{}try{this.#c.disconnect()}catch{}this.#e=null,this.#c=null,this.#t=null,this.#r=null,this.#s=null}queueWaveTable(e,t,s,i,a){this.#s.state==="suspended"&&this.#s.resume().catch(()=>{});let o=this.#E(i),n=this.#x(Math.round(t));if(!n?.buffer)return null;let r=n.originalPitch-100*n.coarseTune-n.fineTune,c=t*100,h=(this.#d-8192)/8192*this.#o*100,l=c-r+h,m=Math.pow(2,l/1200),u=Math.max(e,this.#s.currentTime),d=s+this.#a,p=n.loopStart>=1&&n.loopStart<n.loopEnd;p||(d=Math.min(d,n.buffer.duration/m));let y=this.#i();this.#g(y,n,o,u,d,s);let k=this.#s.createBufferSource();if(k.buffer=n.buffer,k.playbackRate.setValueAtTime(m,0),a?.length>0&&(k.playbackRate.setValueAtTime(m,u),a.forEach(g=>{let S=(t+g.delta)*100-r+h,x=Math.pow(2,S/1200);k.playbackRate.linearRampToValueAtTime(x,u+g.when)})),k.loop=p,p){let g=n.delay??0;k.loopStart=n.loopStart/n.sampleRate+g,k.loopEnd=n.loopEnd/n.sampleRate+g}return k.connect(y),k.start(u,n.delay??0),k.stop(u+d),y.audioBufferSourceNode=k,y.when=u,y.duration=d,y.pitch=t,y.baseDetune=r,y}async cancelQueue(){this.#n.forEach(e=>{e.gain.cancelScheduledValues(0),e.gain.setValueAtTime(this.#h,this.#s.currentTime),e.when=-1;try{e.audioBufferSourceNode?.disconnect()}catch{}})}isSustainActive(){return this.#m}registerSustainNote(e){this.#p.add(e)}setPitchBend(e){this.#d=e;let t=e-8192,s=t>=0?t/8191*this.#o:t/8192*this.#o,i=this.#s.currentTime;this.#n.forEach(a=>{if(a.audioBufferSourceNode&&a.when+a.duration>i){let o=a.pitch*100,n=a.baseDetune,r=s*100,c=o-n+r,h=Math.pow(2,c/1200);a.audioBufferSourceNode.playbackRate.cancelScheduledValues(i),a.audioBufferSourceNode.playbackRate.setTargetAtTime(h,i,.015)}})}setController(e,t){let s=this.#s.currentTime,i=Math.max(0,Math.min(127,t))/127;switch(e){case 7:this.#l=i,this.#e.gain.setTargetAtTime(this.#l,s,.05);break;case 11:this.#u=i,this.#c.gain.setTargetAtTime(this.#u,s,.03);break;case 64:this.#m=t>=64,this.#m||(this.#p.forEach(a=>a()),this.#p.clear());break}}async#y(e){if(e.buffer)return e;if(e.delay=0,e.file){let t=atob(e.file),s=Uint8Array.from(t,i=>i.charCodeAt(0));try{e.buffer=await this.#s.decodeAudioData(s.buffer),this.#T(e)}catch(i){return console.error("Audio decoding error:",i),console.warn(this.#t),!1}}else this.#T(e);return e}#T(e){e.loopStart=this.#k(e.loopStart,0),e.loopEnd=this.#k(e.loopEnd,0),e.coarseTune=this.#k(e.coarseTune,0),e.fineTune=this.#k(e.fineTune,0),e.originalPitch=this.#k(e.originalPitch,6e3)}#g(e,t,s,i,a,o){e.gain.setValueAtTime(this.#h,this.#s.currentTime);let n=Math.min(o,a-this.#a),r=t.ahdsr&&t.ahdsr.length>0?t.ahdsr:[{duration:0,volume:1},{duration:n,volume:1}];e.gain.cancelScheduledValues(i);let c=(r[0]?.volume??1)*s;e.gain.linearRampToValueAtTime(this.#b(c),i+.002);let h=0,l=r[0]?.volume??1;for(let m of r){let{duration:u,volume:d}=m;if(u<=0)continue;let p=n-h;if(u>p){let y=p/u,k=l+y*(d-l);e.gain.exponentialRampToValueAtTime(this.#b(s*k),i+n);break}h+=u,l=d,e.gain.exponentialRampToValueAtTime(this.#b(s*l),i+h)}e.gain.exponentialRampToValueAtTime(this.#h,i+n+this.#a)}#i(e){let t=e||this.#e,s=this.#s.currentTime,i=this.#n.find(a=>a.target===t&&s>a.when+a.duration+.05);if(!i&&this.#n.length>=64){let a=this.#n.filter(o=>o.target===t);a.length>0&&(a.sort((o,n)=>o.when-n.when),i=a[0])}if(i){if(i.audioBufferSourceNode){try{i.audioBufferSourceNode.stop(0),i.audioBufferSourceNode.disconnect()}catch{}i.audioBufferSourceNode=null}i.gain.cancelScheduledValues(0),i.gain.setValueAtTime(this.#h,s)}else i=this.#s.createGain(),i.gain.value=0,i.target=t,i.connect(t),this.#n.push(i);return i.cancel=(a=!1)=>{let o=this.#s.currentTime;if(a&&i.audioBufferSourceNode){try{i.audioBufferSourceNode.stop(0),i.audioBufferSourceNode.disconnect()}catch{}i.audioBufferSourceNode=null}i.when+i.duration>o&&(i.gain.cancelScheduledValues(0),i.gain.setTargetAtTime(this.#h,o,a?.005:.02),i.when=o+1e-5,i.duration=0)},i}#x(e){return this.#t.zones.findLast(t=>e>=t.keyRangeLow&&e<=t.keyRangeHigh)}#E(e){let t=e?1*e:.5;return Math.min(t,.8)}#b(e){return e>this.#h?e:this.#h}#k(e,t){return typeof e=="number"?e:t}};typeof window<"u"&&(window.WebAudioFontPlayer=_);var q=_;var D=class f{#s=null;#r=null;#t=null;#n=null;#a=null;#h=null;#o=null;#e=0;#l=new Map;static#u=[32,64,128,256,512,1024,2048,4096,8192,16384];static#c=new Map([[32,.7],[64,.8],[128,.9],[256,1],[512,1.1],[1024,1.2],[2048,1.4],[4096,1.6],[8192,1.8],[16384,2]]);constructor(e,t,s){this.#t=e,this.#s=this.#t.createGain();let i=this.#s;[32,64,128,256,512,1024,2048,4096,8192,16384].forEach(o=>{i=this.#m(i,o);let n=o<1e3?o:o/1024+"k";this["band".concat(n)]=i}),this.#e=s,this.#h=this.#t.createConvolver(),this.#o=this.#t.createGain(),this.#o.gain.setValueAtTime(s,this.#t.currentTime),this.#d(1.5,2),this.#n=this.#t.createDynamicsCompressor(),this.#n.threshold.setValueAtTime(-10,this.#t.currentTime),this.#n.ratio.setValueAtTime(20,this.#t.currentTime),this.#n.attack.setValueAtTime(.001,this.#t.currentTime),this.#n.release.setValueAtTime(.1,this.#t.currentTime),this.#n.knee.setValueAtTime(0,this.#t.currentTime),this.#a=this.#t.createAnalyser(),this.#a.fftSize=256,this.#a.smoothingTimeConstant=.6,this.#r=this.#t.createGain(),this.#r.gain.setValueAtTime(t,this.#t.currentTime),i.connect(this.#r),this.#r.connect(this.#n),this.#r.connect(this.#h),this.#h.connect(this.#o),this.#n.connect(this.#a),this.#o.connect(this.#a),this.#a.connect(this.#t.destination)}get eqFrequencies(){return f.#u}get analyser(){return this.#a||null}get input(){return this.#s}get reverb(){return this.#e}set reverb(e){this.#e=Math.max(0,Math.min(1,e)),this.#o.gain.setTargetAtTime(this.#e,this.#t.currentTime,.1)}get masterVolume(){return this.#r.gain.value}set masterVolume(e){let t=Math.max(0,Math.min(1,e)),s=Math.pow(t,2);this.#r.gain.setTargetAtTime(s,this.#t.currentTime,.01)}killReverbTail(){let e=this.#t.currentTime;this.#o.gain.cancelScheduledValues(e),this.#o.gain.setValueAtTime(0,e)}restoreReverb(){this.reverb=this.#e}setEQ(e,t=.04){let s=this.#t.currentTime,i=12;for(let[a,o]of Object.entries(e)){let n=Number(a),r=this.#l.get(n);if(!r)continue;let c=Math.max(-i,Math.min(i,o));r.filter.gain.setTargetAtTime(c,s,t),r.gain=c}}getEQ(){let e={};for(let[t,s]of this.#l)e[t]=s.gain;return e}resetEQ(e=.04){let t={};for(let s of f.#u)t[s]=0;this.setEQ(t,e)}setEQPreset(e){let t={flat:{32:0,64:0,128:0,256:0,512:0,1024:0,2048:0,4096:0,8192:0,16384:0},bass:{32:7,64:6,128:4,256:2,512:0,1024:-1,2048:-1,4096:0,8192:0,16384:0},treble:{32:0,64:0,128:0,256:0,512:0,1024:1,2048:3,4096:5,8192:7,16384:8},vocal:{32:-3,64:-2,128:0,256:2,512:4,1024:5,2048:4,4096:2,8192:1,16384:0},loudness:{32:6,64:4,128:1,256:0,512:-1,1024:-1,2048:0,4096:2,8192:4,16384:5},classical:{32:4,64:3,128:2,256:0,512:0,1024:0,2048:0,4096:2,8192:3,16384:4},jazz:{32:4,64:3,128:1,256:0,512:-1,1024:-1,2048:0,4096:1,8192:3,16384:4},electronic:{32:6,64:5,128:2,256:-1,512:-2,1024:-1,2048:2,4096:4,8192:5,16384:6}},s=t[e];if(!s)throw new Error('Preset EQ unkown: "'.concat(e,'". Avaiables: ').concat(Object.keys(t).join(", ")));this.setEQ(s)}#m(e,t){let s=this.#t.createBiquadFilter();s.type="peaking",s.frequency.setValueAtTime(t,this.#t.currentTime),s.gain.setValueAtTime(0,this.#t.currentTime);let i=f.#c.get(t)??1;return s.Q.setValueAtTime(i,this.#t.currentTime),this.#l.set(t,{filter:s,gain:0}),e.connect(s),s}#d(e,t){let s=this.#t.sampleRate,i=s*e,a=this.#t.createBuffer(2,i,s),n=Math.floor(.015*s);for(let r=0;r<a.numberOfChannels;r++){let c=a.getChannelData(r),h=0,l=r===1?Math.floor(.002*s):0;for(let m=0;m<i;m++){if(m<n){c[m]=0;continue}let u=(m-n)/s,d=Math.exp(-u*(t/e)),p=Math.max(.01,.2*Math.exp(-u*2.5));h=(Math.random()*2-1)*p+h*(1-p);let k=h*d;u<.04&&(m%123===0||m%234===0)&&(k+=(Math.random()*2-1)*.2*(.04-u)/.04),m+l<i?c[m+l]=k:c[m]=k}}this.#h.buffer=a}};var J="MidiAudioPlayer",A="KeyValues";var M=null,F=1;async function O(f=F){return M&&f!==F&&(M.close(),M=null,F=f),M||new Promise((e,t)=>{let s=indexedDB.open(J,f);s.onupgradeneeded=i=>{let a=i.target.result;a.objectStoreNames.contains(A)||a.createObjectStore(A)},s.onsuccess=i=>{M=i.target.result,e(M)},s.onerror=i=>t(i.target.error)})}var X={async setVersion(f){await O(f)},async setItem(f,e,t=!1){let s=await O(),i=e,a=!1;if(t){let n=JSON.stringify(e),c=new Blob([n]).stream().pipeThrough(new CompressionStream("gzip"));i=await new Response(c).arrayBuffer(),a=!0}let o={data:i,isCompressed:a};return new Promise((n,r)=>{let l=s.transaction(A,"readwrite").objectStore(A).put(o,f);l.onsuccess=()=>n(),l.onerror=()=>r(l.error)})},async getItem(f){let e=await O(),t=await new Promise((s,i)=>{let n=e.transaction(A,"readonly").objectStore(A).get(f);n.onsuccess=()=>s(n.result),n.onerror=()=>i(n.error)});if(!t)return null;if(t.isCompressed){let i=new Blob([t.data]).stream().pipeThrough(new DecompressionStream("gzip")),o=await new Response(i).text();return JSON.parse(o)}return t.data},async removeItem(f){let e=await O();return new Promise((t,s)=>{let o=e.transaction(A,"readwrite").objectStore(A).delete(f);o.onsuccess=()=>t(),o.onerror=()=>s(o.error)})},async clear(){let f=await O();return new Promise((e,t)=>{let a=f.transaction(A,"readwrite").objectStore(A).clear();a.onsuccess=()=>e(),a.onerror=()=>t(a.error)})}},I=X;var z=(f,e,t)=>Math.min(Math.max(f,e),t),L=class f extends U.Player{static ENDPOINT="https://webaudiofonts.com/presets/";static DEFAULT_PRESET=-1;static REFERENCE_GAIN=.15;static KARAOKE_CHANNEL=0;#s=null;#r=null;#t=null;#n=null;#a={};#h={};#o={};#e={};#l={};#u={};#c={};#m=null;#d=null;#p=null;#y=null;#T=!1;#g="";#i={endpoint:f.ENDPOINT,volume:.6,reverb:.3,onEndFile:null,localCache:!0,presetRandom:!1,karaoke:!1,karaokeDelay:0,muteExpression:!1,maxCharPerLine:48,eqPreset:"flat",preferred:[],presets:[]};constructor(e={}){super(),this.#i={...this.#i,...e},this.#p=this.#x(),this.#r=new(window.AudioContext||window.webkitAudioContext),this.#t=new D(this.#r,this.#i.volume,this.#i.reverb),this.#t.setEQPreset(this.#i.eqPreset),this.#i.karaoke&&this.#C("intro")}get catalog(){return this.getCatalog()}get channels(){return this.#e}get channelStates(){return this.#h}get volume(){return this.#i.volume}set volume(e){this.#i.volume=z(e,0,1),this.#t.masterVolume=this.#i.volume}get volumes(){return this.#u}get reverb(){return this.#t.reverb}set reverb(e){this.#t.reverb=e}get muteExpression(){return this.#i.muteExpression}set muteExpression(e){this.#i.muteExpression=!!e}get eqFrequencies(){return this.#t.eqFrequencies}get eq(){return this.#t.getEQ()}getEQ(){return this.#t.getEQ()}setEQ(e){this.#t.setEQ(e)}setEQPreset(e){this.#t.setEQPreset(e)}setChannelVolume(e,t){this.#u[e]=t,this.#E()}async#x(){await Promise.all(this.#i.presets.map(async e=>{let t=await this.findPreset(e);t&&(this.#c[t.program]=t)}))}async findPreset(e){let t=null;return(await this.getCategories()).some(i=>{if(i.instruments.some(a=>{if(t=a.presets.find(o=>o.id==e),t)return t.category=i.name,t.instrument=a.name,t.program=a.program,!0}),t)return!0}),t}async close(){Object.keys(this.#e).forEach(e=>this.#e[e].close()),await this.#r.close()}async getCatalog(){if(this.#s)return this.#s;let e=this.#i.localCache?await sessionStorage.getItem("waf_catalog"):null;if(e)this.#s=JSON.parse(e);else{this.#f("Downloading catalog...");let i=await fetch("".concat(this.#i.endpoint,"catalog.json"));if(!i.ok)throw new Error("Impossible to download catalog: ".concat(i.status));this.#s=await i.json(),this.#i.localCache&&await sessionStorage.setItem("waf_catalog",JSON.stringify(this.#s))}let t=new Date(this.#s.updatedAt).getTime();return(await I.getItem("waf_catalog_version")||1)<t&&(await I.clear(),I.setItem("waf_catalog_version",t)),this.#s}async getCategories(){return(await this.getCatalog()).categories}async getProgramInstruments(e){let t=await this.getCategories(),s=[];return await Promise.all(t.map(async i=>i.instruments.filter(a=>a.program==e).forEach(a=>{a.presets.forEach(o=>{o.instrument=i.name+" / "+a.name,s.push(o)})}))),s}async getPreset(e){try{if(typeof e=="object")return e;let t="waf_preset_".concat(e),s=this.#i.localCache?await I.getItem(t):null;if(s)return JSON.parse(s);this.#f("Downloading preset ".concat(e,"..."));let a=await(await fetch("".concat(f.ENDPOINT).concat(e,".json"))).json();if(a.zones===void 0)throw console.error("Invalid preset: ".concat($id)),new Error("Invalid preset: ".concat($id));return this.#i.localCache&&await I.setItem(t,JSON.stringify(a),!0),a}catch{throw console.error("Invalid preset: ".concat(e)),new Error("Invalid preset: ".concat(e))}}async loadPreset(e,t){let s=await this.findPreset(e);if(!s)throw new Error("Invalid preset: ".concat(e));this.#c[s.program]=s;let i=await this.getPreset(e);await this.#e[t].setPreset(i),this.#E()}async load(e,t){typeof e=="string"&&(this.#f("Downloading song..."),e=await(await fetch(e)).arrayBuffer()),typeof t=="string"&&(this.#f("Downloading setup..."),t=await(await fetch(t)).json()),this.#m=await this.hashBuffer(e),await this.#p,this.isPlaying()&&this.stop(),this.#v(),await Promise.all(Object.values(this.#e).map(async n=>n.close())),this.#e={},this.#o={},this.#a={},this.#g="",this.#f("Loading buffer...");try{await this.loadArrayBuffer(e)}catch{await this.loadArrayBuffer(await this.#R(e))}this.#f("Loading instruments..."),this.#l=await this.#N(),this.#h=Object.keys(this.#l).reduce((n,r)=>({...n,[r]:!1}),{}),this.#u=Object.keys(this.#l).reduce((n,r)=>({...n,[r]:1}),{}),t?.volumes!==void 0&&await Promise.all(Object.keys(t.volumes).map(async n=>{this.#u[n]!==void 0&&(this.#u[n]=t.volumes[n])}));let s=new Set,i={};t?.presets!==void 0&&await Promise.all(Object.keys(t.presets).map(async n=>{let r=await this.findPreset(t.presets[n]);r&&(i[n]=await this.getPreset(r.id),s.add(r.program))}));let a=await this.#M();Object.values(this.#l).length||this.#f("Error: no instrument found");let o=Promise.all([...a].map(async n=>{if(s.has(n))return;let r=null;this.#c[n]!==void 0?r=await this.getPreset(this.#c[n].id):this.#i.presetRandom?r=await this.#I(n):r=await this.#L(n),this.#o[n]=r}));this.#i.karaoke&&(this.#f("Generating karaoke frames..."),this.#y=null,await this.#V(),this.#g&&this.#C("title",this.#g)),this.#f("Trim midi events..."),this.#B(),queueMicrotask(()=>this.triggerPlayerEvent("computed")),await o,await Promise.all(Object.keys(this.#l).map(async n=>{this.#e[n]&&this.#e[n].close(),i[n]!==void 0?this.#e[n]=await this.#P(i[n]):this.#e[n]=await this.#P(this.#o[this.#l[n]])})),this.#f("Initializing instrument states..."),await this.#k(),await this.triggerPlayerEvent("presetsLoaded",this.#o),await this.#E(),this.#f("Player ready")}async getSongSetup(){let e={hash:this.#m,presets:{},volumes:{}};return Object.keys(this.#e).map(async t=>e.presets[t]=this.#e[t].preset.id),e.volumes=this.#u,e}async getTrainingPresets(){return await Promise.all(Object.values(this.#c).map(async e=>e.id))}async play(e=null){if(this.#r.state==="suspended")try{await this.#r.resume()}catch{return!1}return e&&await this.load(e),await Promise.all(Object.keys(this.#e).map(async t=>await this.#e[t]?.cancelQueue())),this.#t.restoreReverb(),this.isPlaying()||(this.startTime||(this.startTime=new Date().getTime()),this.scheduledTime=Date.now(),this.schedulePlayLoop(this.sampleRate)),!0}async pause(){await super.pause(),this.#t.killReverbTail(),await this.#v(),await Promise.all(Object.keys(this.#e).map(async e=>await this.#e[e]?.cancelQueue()))}async stop(e=!1){return await super.stop(),this.setTimeoutId=!1,e||(this.#t.killReverbTail(),await Promise.all(Object.keys(this.#e).map(async t=>await this.#e[t]?.cancelQueue()))),await this.#v(),this.#i.karaoke&&this.#C("intro"),this}getRealTimeVolume(){let e=this.#t.analyser,t=new Uint8Array(e.frequencyBinCount);e.getByteFrequencyData(t);let s=0;for(let i=0;i<t.length;i++)s+=t[i];return s/(t.length*100)}getSongTimeRemaining(){return this.ticksToSeconds(this.getCurrentTick(),this.totalTicks)}async skipToSeconds(e){let t=this.getSongTime();if(e<0||e>t)throw e+" seconds not within song time of "+t;return await this.skipToTick(this.secondsToTicks(e)),this}async generateWaveformSVG(e=1e3){if(!this.totalTicks||!this.events)return"";let t=new Array(e).fill(0),s=this.totalTicks/e,i=this.events.flatMap((u,d)=>u.map(p=>({...p,computedChannel:p.channel!==void 0?p.channel:d}))).filter(u=>u.name==="Controller Change"||u.name==="Program Change"||u.name==="Note on"&&u.velocity>0).sort((u,d)=>u.tick-d.tick),a=new Map,o=new Map;i.forEach(u=>{let d=Math.floor(u.tick/s);if(d>=e)return;let p=u.computedChannel;if(a.has(p)||a.set(p,100),o.has(p)||o.set(p,127),u.name==="Controller Change")u.number===7?a.set(p,u.value):u.number===11&&o.set(p,u.value);else if(u.name==="Note on"){let y=a.get(p)/127,k=o.get(p)/127,g=u.velocity*y*k;t[d]+=g}});let n=t.reduce((u,d)=>isNaN(d)?u:d>u?d:u,0),r=n>0?t.map(u=>isNaN(u)?0:u/n):t.fill(0),c=e,h=c/5,l=r.map((u,d)=>{let p=d,y=Math.max(0,Math.min(h,h-u*h));return"".concat(p,",").concat(y.toFixed(2))}),m="M 0,".concat(h," L ").concat(l.join(" L ")," L ").concat(c,",").concat(h);return'<svg class="midiaudioplayer-waveform" viewBox="0 0 '.concat(c," ").concat(h,'" preserveAspectRatio="none"><path d="').concat(m,'" fill="none" stroke-linecap="round" stroke-linejoin="round" /></svg>')}async hashBuffer(e,t="SHA-256"){let s=await crypto.subtle.digest(t,e);return Array.from(new Uint8Array(s)).map(a=>a.toString(16).padStart(2,"0")).join("")}async#E(){this.#d&&clearTimeout(this.#d),this.#d=setTimeout(async()=>{let e=await this.getSongSetup();queueMicrotask(()=>this.triggerPlayerEvent("setupChange",e))},1e3)}async triggerPlayerEvent(e,t){e!="fileLoaded"&&(e=="computed"?(this.#n=await this.#F(),super.triggerPlayerEvent(e,{title:this.#g,karaoke:this.#T,vocalChannel:this.#n,tempo:this.tempo,division:this.division,duration:this.getSongTime(),sampleRate:this.sampleRate,totalTicks:this.totalTicks,totalEvents:this.totalEvents,channels:await this.#l})):e=="endOfFile"&&this.#i.karaoke?queueMicrotask(()=>super.triggerPlayerEvent(e,t)):super.triggerPlayerEvent(e,t))}async playLoop(e){if(this.inLoop)return;if(!e&&this.endOfFile()&&this.tick>0){await this.stop(!0),this.tick=0,this.triggerPlayerEvent("endOfFile");return}this.inLoop=!0,this.tick=this.getCurrentTick();let t=this.tracks.length;for(let s=0;s<t;s++){let i=this.tracks[s].handleEvent(this.tick,e);if(!i)continue;let a=i.constructor===Array,o=a?i.length:1;for(let n=0;n<o;n++){let r=a?i[n]:i,{name:c,data:h,value:l}=r;c==="Set Tempo"&&this.setTempo(h),e?c==="Program Change"&&!this.instruments.includes(l)&&this.instruments.push(l):this.emitEvent(r)}}!e&&this.isPlaying()&&this.triggerPlayerEvent("playing",{tick:this.tick}),this.inLoop=!1}schedulePlayLoop(e){this.setTimeoutId=setTimeout(()=>{if(this.setTimeoutId===!1)return;this.playLoop();let t=this.#r.currentTime;this._lastAudioTime||(this._lastAudioTime=t);let s=t-this._lastAudioTime;this._lastAudioTime=t;let i=this.sampleRate/1e3,a=s-i,o=Math.max(0,this.sampleRate-a*1e3);this.schedulePlayLoop(o)},e)}emitEvent(e){this.#D(e)}ticksToSeconds(e,t){if(t===void 0&&(t=e,e=0),e>=t)return 0;let s=0,i=this.tempoMap.length,a=60/this.division,o=0,n=i-1,r=0;for(;o<=n;){let h=o+n>>1;this.tempoMap[h].tick<=e?(r=h,o=h+1):n=h-1}let c=e;for(let h=r;h<i;h++){let l=this.tempoMap[h],m=h+1<i?this.tempoMap[h+1].tick:t;if(m<=e)continue;let u=Math.max(l.tick,e),d=Math.min(m,t);if(u>=t)break;s+=(d-u)/l.tempo*a,c=d}if(c<t){let h=this.tempoMap[i-1];s+=(t-c)/h.tempo*a}return s}secondsToTicks(e){let t=e,s=this.tempoMap.length,i=60/this.division;for(let a=0;a<s;a++){let o=this.tempoMap[a],c=((a+1<s?this.tempoMap[a+1].tick:1/0)-o.tick)/o.tempo*i;if(t<=c)return o.tick+Math.round(t*o.tempo/i);t-=c}return this.totalTicks}getTickBeforeSeconds(e,t){if(e<=0)return 0;let s=this.ticksToSeconds(0,e),i=Math.max(0,s-t);return this.secondsToTicks(i)}async skipToTick(e){let t=Math.max(0,Math.min(e,this.totalTicks||0)),s=this.isPlaying();if(this.#v(),Object.keys(this.channels).forEach(i=>this.channels[i]?.cancelQueue?.()),s&&super.pause(),this.startTick=t,this.tick=t,this.tempoMap&&this.tempoMap.length>0){for(let i=this.tempoMap.length-1;i>=0;i--)if(this.tempoMap[i].tick<=t){this.setTempo(this.tempoMap[i].tempo);break}}try{let i=[],a=[],o=[],n=[];this.#b(t).forEach(r=>{let c=r.channel;if(!((c===void 0||!this.channels[c])&&r.name!=="Karaoke Event"))switch(r.name){case"Controller Change":i[r.channel]=r;break;case"Program Change":a[r.channel]=r;break;case"Pitch Bend":o[r.channel]=r;break;case"Karaoke Event":n[r.channel]=r;break}}),i.forEach(r=>this.emitEvent(r)),a.forEach(r=>this.emitEvent(r)),o.forEach(r=>this.emitEvent(r)),n.forEach(r=>this.triggerPlayerEvent("karaoke",{type:r.type,tick:r.tick,html:r.text}))}catch(i){console.warn("Chase MIDI Error:",i),this.#f("Chase MIDI Error:",i)}return this.tracks&&this.tracks.length>0&&this.tracks.forEach((i,a)=>{let o=this.events[a];if(o&&o.length>0){let n=0,r=o.length-1,c=o.length;for(;n<=r;){let h=n+r>>1;o[h].tick>=t?(c=h,r=h-1):n=h+1}i.eventIndex=c}else typeof i.setEventIndexByTick=="function"&&i.setEventIndexByTick(t)}),s?this.play():this.triggerPlayerEvent("playing",{tick:t}),this}#b(e){let t={};if(!this.events)return[];for(let s=0;s<this.events.length;s++){let i=this.events[s];if(!i||i.length===0)continue;let a=0,o=i.length-1,n=i.length;for(;a<=o;){let r=a+o>>1;i[r].tick>=e?(n=r,o=r-1):a=r+1}for(let r=0;r<n;r++){let c=i[r],h;c.name==="Program Change"?h="pc:"+c.channel:c.name==="Controller Change"?h="cc:"+c.channel+":"+c.number:c.name==="Pitch Bend"?h="pb:"+c.channel:c.name==="Karaoke Event"&&(h="ke:"+c.channel),h&&(t[h]=c)}}return Object.keys(t).map(s=>t[s])}async#k(){this.events&&this.#b(1).forEach(e=>{let t=e.channel;if(this.#e[t])switch(e.name){case"Controller Change":this.#e[t].setController(e.number,e.value);break;case"Pitch Bend":this.#e[t].setPitchBend?.(e.value);break;case"Program Change":e.value>=0&&e.value<=127&&this.#o[e.value+1]!==void 0&&e.channel!=10&&this.#e[t].preset?.program!==e.value+1&&this.#e[t].setPreset(this.#o[e.value+1]);break}})}async#N(){let e={},t=new Set;return this.events.forEach(s=>{s.forEach(i=>{if(i.name==="Program Change"&&i.value>=0&&i.value<=127){if(e[i.channel])return;i.channel==10?e[i.channel]=-1:e[i.channel]=i.value+1}else i.name==="Note on"&&i.channel==10?(e[i.channel]=-1,t.add(10)):i.name==="Note on"&&t.add(i.channel)})}),Object.keys(e).forEach(s=>{t.has(Number(s))||delete e[s]}),e}async#M(){let e=new Set;return this.events.forEach(t=>{t.forEach(s=>{s.name==="Program Change"&&s.value>=0&&s.value<=127?e.add(s.channel==10?-1:s.value+1):s.name==="Note on"&&s.channel==10&&e.add(-1)})}),e}async#I(e){let t=await this.getProgramInstruments(e);if(!t.length)return null;let s=null;return this.#i.preferred.some(i=>{let a=new RegExp("_".concat(i,"$"),"i"),o=t.filter(n=>a.test(n.id));if(o.length)return s=o[Math.floor(Math.random()*o.length)],!0}),s||(s=t[Math.floor(Math.random()*t.length)]),this.#c[e]=s,await this.getPreset(s.id)}async#L(e){let t=await this.getProgramInstruments(e);if(!t.length)return null;let s=null;return this.#i.preferred.some(i=>{let a=new RegExp("_".concat(i,"$"),"i");if(s=t.find(o=>a.test(o.id)),s)return!0}),s||(s=t[0]),this.#c[e]=s,await this.getPreset(s.id)}async#P(e){return new q(e,this.#r,this.#t)}async#D(e){if(this.isPlaying())switch(e.name){case"Note on":if(e.tick<this.tick-100||e.noteNumber===void 0||e.channel==this.#n&&this.#i.muteExpression)return;if(e.velocity>0&&e.velocity<=127){if(this.#S(e.channel,e.noteNumber),this.#u[e.channel]==0)return;let t=e.velocity/127,s=f.REFERENCE_GAIN*Math.pow(t,2)*this.#u[e.channel],i=this.#e[e.channel]?.queueWaveTable(0,e.noteNumber,2,s);i&&this.#O(e.channel,e.noteNumber,i)}else this.#S(e.channel,e.noteNumber);break;case"Note off":if(e.noteNumber===void 0)return;this.#S(e.channel,e.noteNumber);break;case"Controller Change":this.#e[e.channel]?.setController(e.number,e.value);break;case"Pitch Bend":this.#e[e.channel]?.setPitchBend?.(e.value);break;case"Program Change":return;case"Karaoke Event":if(e.tick<this.tick-this.secondsToTicks(10))return;this.triggerPlayerEvent("karaoke",{type:e.type,tick:e.tick,html:e.text});break}}#O(e,t,s){this.#a[e]||(this.#a[e]=new Map),this.#a[e].set(t,s),this.#w();let i=(s.duration||0)*1e3;s.cleanupTimer=setTimeout(()=>{this.#a[e]?.get(t)===s&&(this.#a[e].delete(t),this.#w())},i+50)}#S(e,t){let s=this.#e[e],i=this.#a[e]?.get(t);if(i){i.cleanupTimer&&clearTimeout(i.cleanupTimer);let a=()=>{this.#a[e]?.delete(t),this.#w()};s&&s.isSustainActive()?s.registerSustainNote(()=>i.cancel(!1)):i.cancel(!1),a()}}#v(){Object.keys(this.#a).forEach(e=>{this.#a[e].forEach((t,s)=>{t&&(t.cleanupTimer&&clearTimeout(t.cleanupTimer),t.cancel&&t.cancel(!0)),this.#a[e]?.delete(s)})}),this.#w()}async#w(){let e=!1,t={};Object.keys(this.#e).forEach(s=>{let i=!!(this.#a[s]?.size&&this.#a[s].size>0);t[s]=i,this.#h[s]!==i&&(e=!0)}),e&&(this.#h=t,this.triggerPlayerEvent("channelState",this.#h))}async#R(e){let t=new Uint8Array(e),s=new DataView(e);if(String.fromCharCode(...t.slice(0,4))!=="MThd")throw new Error("Invalid MIDI file (MThd missing)");let a=s.getUint32(4),o=s.getUint16(8),n=s.getUint16(10),r=s.getUint16(12),c=[255,47,0],h=[],l=8+a;for(;l<t.length&&!(l+8>t.length);){let g=String.fromCharCode(...t.slice(l,l+4)),T=s.getUint32(l+4),S=l+8,x=S+T;if(g!=="MTrk"){let C=Math.min(x,t.length);h.push({tag:g,data:t.slice(l,C),repaired:!1}),l=x;continue}let E=h.filter(C=>C.tag==="MTrk").length+1,b=Math.min(T,t.length-S),v=t.slice(S,S+b),N=v.slice(-3);if(N[0]===255&&N[1]===47&&N[2]===0&&b===T)h.push({tag:g,data:v,repaired:!1});else{let C;if(b<T){let tt=T-b,K=v.slice(-2);K[0]===255&&K[1]===47?(C=new Uint8Array(v.length+1),C.set(v),C[v.length]=0):(C=new Uint8Array(v.length+3),C.set(v),C.set(c,v.length))}else C=new Uint8Array(v.length+3),C.set(v),C.set(c,v.length);h.push({tag:g,data:C,repaired:!0})}l=x}let m=h.filter(g=>g.tag==="MTrk").length,u=14+h.reduce((g,T)=>g+8+T.data.length,0),d=new Uint8Array(u),p=new DataView(d.buffer);d.set([77,84,104,100],0),p.setUint32(4,6),p.setUint16(8,o),p.setUint16(10,m),p.setUint16(12,r);let y=14;for(let g of h){let T=g.tag.split("").map(S=>S.charCodeAt(0));d.set(T,y),p.setUint32(y+4,g.data.length),d.set(g.data,y+8),y+=8+g.data.length}let k=h.filter(g=>g.repaired).length;return d.buffer}#B(){if(!this.events||this.events.length===0)return;let e=1/0,t=0;if(this.events.forEach(n=>{n.forEach(r=>{(r.name==="Note on"||r.name==="Note off")&&(r.tick<e&&(e=r.tick),r.tick>t&&(t=r.tick))})}),e===1/0)return;let s=[];this.events.forEach((n,r)=>{n.forEach(c=>{let h=c.name==="Program Change"||c.name==="Controller Change"||c.name==="Pitch Bend"||c.name==="Set Tempo";c.tick<e&&h&&s.push({event:c,trackIdx:r})})});let i=Object.fromEntries(this.events.map((n,r)=>[r,[]])),a=new Set;for(let n=s.length-1;n>=0;n--){let{event:r,trackIdx:c}=s[n],h=r.channel!==void 0?r.channel:"track-".concat(c),l=null;if(r.name==="Program Change"?l="pc:".concat(h):r.name==="Controller Change"?l="cc:".concat(h,":").concat(r.number):r.name==="Pitch Bend"?l="pb:".concat(h):r.name==="Set Tempo"&&(l="tempo"),l&&!a.has(l)){a.add(l);let m={...r,tick:0};i[c].push(m)}}let o=this.events.map((n,r)=>{let c=[];return n.forEach(l=>{let m=l.name==="Program Change"||l.name==="Controller Change"||l.name==="Pitch Bend"||l.name==="Set Tempo",u=l.name==="Text Event"||l.name==="Lyric Event"||l.name==="Track Name"||l.name==="Karaoke Event";if(l.tick<e)!m&&(u||r===0)&&(l.tick=0,c.push(l));else{l.tick=l.tick-e;let d=t-e;l.tick>d&&(l.tick=d),c.push(l)}}),[...i[r]||[],...c].sort((l,m)=>l.tick-m.tick)});this.events=o,this.totalTicks=t-e,typeof this.computeTempoMap=="function"&&this.computeTempoMap()}async#A(){if(this.#y)return this.#y;let e={language:"",title:"",paragraphs:[]},t=null,s=0;if(this.events.forEach(c=>{let h=c.filter(m=>m.name==="Text Event"||m.name==="Lyric Event"||m.name==="Cue Point"||m.name==="Marker"||m.name==="Track Name"),l=h.filter(m=>{let u=m.string||m.text||"";return u&&!u.startsWith("@")}).length;l>s&&(s=l,t=h)}),!t||t.length===0)return e;let i=t.sort((c,h)=>c.tick-h.tick),a=[],o=[],n=[],r=0;for(i.forEach(c=>{let h=this.#K(c.string||"");if(!h||/^Track-/i.test(h.trim())||/^Piste/i.test(h.trim())||h.trim()===""||c.tick===0&&h.length>20)return;if(h.startsWith("@L")){e.language=h.substring(2).trim();return}if(h.startsWith("@T")){e.title+=(e.title?" / ":"")+h.substring(2).trim();return}if(h.startsWith("@")||h.startsWith("(")||h.startsWith("PART")||/^\d+\s+\d+/.test(h.trim()))return;if(/^(Verse|Chorus|Bridge|Break|Intro|End\.)/i.test(h.trim())){let k=h.startsWith("\\")||h.startsWith("/"),g=n.length===0||c.tick-r>500;if((k||g)&&(n.length>0&&(o.push({tick:n[0].tick,blocks:n}),n=[]),o.length>0)){for(;o.length>4;){let T=o.splice(0,4);a.push({tick:T[0].tick,lines:T})}o.length>0&&(a.push({tick:o[0].tick,lines:o}),o=[])}return}let l=!1;if(n.length>0){let g=n[n.length-1].text,T=h.trimLeft();if(T.length>0){let S=/^[A-Z]/.test(T)||/^'[A-Z]/.test(T),x=/^[A-Z]/.test(g.trim())||/^'[A-Z]/.test(g.trim());S&&!g.endsWith(" ")&&g.trim()!="o"&&!x&&c.tick>r&&(l=!0),h.startsWith('"')&&g.endsWith('"')&&(l=!0),h.startsWith('"')&&(g.endsWith(")")||g.endsWith(')"'))&&(l=!0),T.startsWith('"')&&g.trimRight().endsWith(")")&&(l=!0)}}let m=h.startsWith("\\"),u=h.startsWith("/")||l;(m||u)&&(h.startsWith("\\")||h.startsWith("/"))&&(h=h.substring(1)),h=h.replace(/[\r\n]/g,"");let d=!1;r>0&&c.tick>r&&this.ticksToSeconds(r,c.tick)>2.5&&(d=!0);let y=n.reduce((k,g)=>k+g.text.length,0)+h.length>this.#i.maxCharPerLine;if((u||m||d||y)&&(n.length>0&&(o.push({tick:n[0].tick,blocks:n}),n=[]),o.length>0)){if(m||d){for(;o.length>4;){let k=o.splice(0,4);a.push({tick:k[0].tick,lines:k})}o.length>0&&(a.push({tick:o[0].tick,lines:o}),o=[])}else if(o.length>=6){let k=o.splice(0,4);a.push({tick:k[0].tick,lines:k})}}h.length>0&&(n.push({text:h,tick:c.tick}),r=c.tick)}),n.length>0&&o.push({tick:n[0].tick,blocks:n});o.length>4;){let c=o.splice(0,4);a.push({tick:c[0].tick,lines:c})}return o.length>0&&a.push({tick:o[0].tick,lines:o}),a=a.filter(c=>!(c.lines.length==1&&c.lines[0].blocks.length==1&&["intro","outro","sfx","solo","chorus","verse","bridge","break","end"].includes(c.lines[0].blocks[0].text.toLowerCase().trim()))),a.length<=2&&(a=[]),e.paragraphs=a,this.#y=e,e}async#V(){let e=await this.#A();if(!e.paragraphs.length){this.#T=!1,this.events[f.KARAOKE_CHANNEL].push({text:'<span class="karaoke-intro"></span>',name:"Karaoke Event",type:"intro",tick:0,channel:f.KARAOKE_CHANNEL}),this.events[f.KARAOKE_CHANNEL]=this.events[f.KARAOKE_CHANNEL].sort((l,m)=>l.tick-m.tick);return}this.#T=!0,this.#g=e.title;let t=0,s=this.secondsToTicks(this.#i.karaokeDelay),i=this.secondsToTicks(3),a=this.secondsToTicks(5),o=this.secondsToTicks(7),n=this.secondsToTicks(10),r=[];e.paragraphs.forEach((l,m)=>{l.lines.forEach((u,d)=>{u.blocks.forEach(p=>{r.push({block:p,lineIdx:d,paraIdx:m,paragraph:l,fastLinesText:l.lines.map(y=>y.blocks.map(k=>k.text).join(""))})})})});let c=[];e.paragraphs.forEach((l,m)=>{let u=this.getTickBeforeSeconds(l.tick,5);u<t&&(u=t+(l.tick-t)/2),m===0&&u<20&&(u=20),c[m]=u;let p=l.lines.map(y=>y.blocks.map(k=>k.text).join("")).map(y=>'<span class="karaoke-coming">'.concat(y,"</span>")).join("<br/>");if(this.events[f.KARAOKE_CHANNEL].push({text:p,name:"Karaoke Event",type:"lyric",tick:u,channel:f.KARAOKE_CHANNEL}),l.lines.length>0){let y=l.lines[l.lines.length-1];y.blocks.length>0&&(t=y.blocks[y.blocks.length-1].tick)}}),(c[0]||0)>25&&this.events[f.KARAOKE_CHANNEL].push({text:'<span class="karaoke-clear"></span>',name:"Karaoke Event",type:"clear",tick:5,channel:f.KARAOKE_CHANNEL}),r.forEach((l,m)=>{let u=l.block,d=l.lineIdx,p=l.paraIdx,y=l.paragraph,k=l.fastLinesText,g=(S=!1)=>y.lines.map((x,E)=>{if(E<d)return'<span class="karaoke-played">'.concat(k[E],"</span>");if(E>d)return'<span class="karaoke-coming">'.concat(k[E],"</span>");let b="";return x.blocks.forEach(v=>{let N="coming";S||v.tick<u.tick?N="played":v.tick===u.tick&&(N="playing"),b+='<span class="karaoke-'.concat(N,'">').concat(v.text,"</span>")}),b}).join("<br>");this.events[f.KARAOKE_CHANNEL].push({text:g(!1),name:"Karaoke Event",type:"lyric",tick:u.tick-s,channel:f.KARAOKE_CHANNEL});let T=r[m+1];if(T){let S=T.block.tick-u.tick;if(S>i){let x=u.tick+i,E=u.tick+o,b=S>n&&p>0;if(T.paraIdx!==p){let v=c[T.paraIdx];x>=v&&(x=v-1),b&&(E>=v||v-E<i)&&(b=!1)}x>u.tick&&this.events[f.KARAOKE_CHANNEL].push({text:g(!0),name:"Karaoke Event",type:"lyric",tick:x-s,channel:f.KARAOKE_CHANNEL}),b&&E>x&&this.events[f.KARAOKE_CHANNEL].push({text:'<span class="karaoke-clear"></span>',name:"Karaoke Event",type:"clear",tick:E-s,channel:f.KARAOKE_CHANNEL})}}t=u.tick}),this.totalTicks-t>this.secondsToTicks(5)?this.events[f.KARAOKE_CHANNEL].push({text:'<span class="karaoke-clear"></span>',name:"Karaoke Event",type:"clear",tick:t+this.secondsToTicks(5),channel:f.KARAOKE_CHANNEL}):this.events[f.KARAOKE_CHANNEL].push({text:'<span class="karaoke-clear"></span>',name:"Karaoke Event",type:"clear",tick:this.totalTicks-1,channel:f.KARAOKE_CHANNEL}),this.events[f.KARAOKE_CHANNEL]=this.events[f.KARAOKE_CHANNEL].sort((l,m)=>l.tick-m.tick)}async#F(){let e=await this.#A();if(!e?.paragraphs?.length)return null;let t=e.paragraphs.flatMap(c=>c.lines.flatMap(h=>h.blocks.map(l=>l.tick)));if(t.length===0)return null;let s=this.division?this.division/2:48,i=48,a=84,o=Object.keys(this.#l).map(Number).filter(c=>c!==10),n=null,r=-1/0;for(let c of o){let h=this.events.flatMap(E=>E.filter(b=>b.name==="Note on"&&b.velocity>0&&b.channel===c));if(h.length===0)continue;let m=t.filter(E=>h.some(b=>Math.abs(b.tick-E)<=s)).length/t.length,d=h.filter(E=>E.noteNumber>=i&&E.noteNumber<=a).length/h.length;if(d<.3)continue;let p=[...h].sort((E,b)=>E.tick-b.tick),y=this.division/8||6,g=1-p.filter((E,b)=>b>0&&Math.abs(E.tick-p[b-1].tick)<y).length/Math.max(h.length-1,1),T=h.length/Math.max(t.length,1),S=T<.3?T/.3:T>5?Math.max(0,1-(T-5)/10):1,x=m*.45+d*.35+g*.15+S*.05;x>r&&(r=x,n=c)}return r>=.4?n:null}#K(e){if(!e)return"";let t=new Uint8Array(e.length);for(let a=0;a<e.length;a++)t[a]=e.charCodeAt(a)&255;let i=new TextDecoder("windows-1252").decode(t);return i=i.replace(/ÿ/g,""),i=i.replace(/’/g,"'"),i=i.replace(/`/g,"'"),i}#C(e="clear",t=""){let s='<span class="karaoke-'.concat(e,'">').concat(t.replace(/\s\/\s/g,"<br>"),"</span>");this.#i.karaoke&&(e=="title"?queueMicrotask(()=>this.triggerPlayerEvent("karaoke",{type:e,title:t,html:s})):queueMicrotask(()=>this.triggerPlayerEvent("karaoke",{type:e,html:s})))}#f(e,t=!1){queueMicrotask(()=>this.triggerPlayerEvent("logs",e))}};typeof window<"u"&&(window.MidiAudioPlayer=L);var ut=L;})();
17
+ (()=>{function B(f,e){if(!(f instanceof e))throw new TypeError("Cannot call a class as a function")}function j(f,e){for(var t=0;t<e.length;t++){var s=e[t];s.enumerable=s.enumerable||!1,s.configurable=!0,"value"in s&&(s.writable=!0),Object.defineProperty(f,s.key,s)}}function V(f,e,t){return e&&j(f.prototype,e),t&&j(f,t),Object.defineProperty(f,"prototype",{writable:!1}),f}var P={VERSION:"2.0.17",NOTES:[],HEADER_CHUNK_LENGTH:14,CIRCLE_OF_FOURTHS:["C","F","Bb","Eb","Ab","Db","Gb","Cb","Fb","Bbb","Ebb","Abb"],CIRCLE_OF_FIFTHS:["C","G","D","A","E","B","F#","C#","G#","D#","A#","E#"]},W=[["C"],["C#","Db"],["D"],["D#","Eb"],["E"],["F"],["F#","Gb"],["G"],["G#","Ab"],["A"],["A#","Bb"],["B"]],H=0,G=function(e){W.forEach(function(t){t.forEach(function(s){return P.NOTES[H]=s+e}),H++})};for(R=-1;R<=9;R++)G(R);var R,w=(function(){function f(){B(this,f)}return V(f,null,[{key:"byteToHex",value:function(t){return("0"+t.toString(16)).slice(-2)}},{key:"bytesToHex",value:function(t){var s=[];return t.forEach(function(i){return s.push(f.byteToHex(i))}),s.join("")}},{key:"hexToNumber",value:function(t){return parseInt(t,16)}},{key:"bytesToNumber",value:function(t){return f.hexToNumber(f.bytesToHex(t))}},{key:"bytesToLetters",value:function(t){var s=[];return t.forEach(function(i){return s.push(String.fromCharCode(i))}),s.join("")}},{key:"decToBinary",value:function(t){return(t>>>0).toString(2)}},{key:"getVarIntLength",value:function(t){for(var s=t[0],i=1;s>=128;)s=t[i],i++;return i}},{key:"readVarInt",value:function(t){var s=0;return t.forEach(function(i){var a=i;a&128?(s+=a&127,s<<=7):s+=a}),s}},{key:"atob",value:(function(e){function t(s){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t})(function(e){return typeof atob=="function"?atob(e):Buffer.from(e,"base64").toString("binary")})}]),f})(),Q=(function(){function f(e,t){B(this,f),this.enabled=!0,this.eventIndex=0,this.pointer=0,this.lastTick=0,this.lastStatus=null,this.index=e,this.data=t,this.delta=0,this.runningDelta=0,this.events=[];var s=this.data.subarray(this.data.length-3,this.data.length);if(!(s[0]===255&&s[1]===47&&s[2]===0))throw"Invalid MIDI file; Last three bytes of track "+this.index+"must be FF 2F 00 to mark end of track"}return V(f,[{key:"reset",value:function(){return this.enabled=!0,this.eventIndex=0,this.pointer=0,this.lastTick=0,this.lastStatus=null,this.delta=0,this.runningDelta=0,this}},{key:"enable",value:function(){return this.enabled=!0,this}},{key:"disable",value:function(){return this.enabled=!1,this}},{key:"setEventIndexByTick",value:function(t){t=t||0;for(var s=0;s<this.events.length;s++)if(this.events[s].tick>=t)return this.eventIndex=s,this}},{key:"getCurrentByte",value:function(){return this.data[this.pointer]}},{key:"getDeltaByteCount",value:function(){return w.getVarIntLength(this.data.subarray(this.pointer))}},{key:"getDelta",value:function(){return w.readVarInt(this.data.subarray(this.pointer,this.pointer+this.getDeltaByteCount()))}},{key:"handleEvent",value:function(t,s){if(s=s||!1,s){var i=t-this.lastTick,a=this.getDelta(),n=i>=a;if(this.pointer<this.data.length&&(s||n)){var r=this.parseEvent();if(this.enabled)return r}}else{for(var o=[];this.events[this.eventIndex]&&this.events[this.eventIndex].tick<=t;)this.enabled&&o.push(this.events[this.eventIndex]),this.eventIndex++;if(o.length>0)return o}return null}},{key:"getStringData",value:function(t){var s=w.getVarIntLength(this.data.subarray(t+2)),i=w.readVarInt(this.data.subarray(t+2,t+2+s)),a=w.bytesToLetters(this.data.subarray(t+2+s,t+2+s+i));return a}},{key:"parseEvent",value:function(){var t=this.pointer+this.getDeltaByteCount(),s={},i=this.getDeltaByteCount();if(s.track=this.index+1,s.delta=this.getDelta(),this.lastTick=this.lastTick+s.delta,this.runningDelta+=s.delta,s.tick=this.runningDelta,s.byteIndex=this.pointer,this.data[t]==255){switch(this.data[t+1]){case 0:s.name="Sequence Number";break;case 1:s.name="Text Event",s.string=this.getStringData(t);break;case 2:s.name="Copyright Notice";break;case 3:s.name="Sequence/Track Name",s.string=this.getStringData(t);break;case 4:s.name="Instrument Name",s.string=this.getStringData(t);break;case 5:s.name="Lyric",s.string=this.getStringData(t);break;case 6:s.name="Marker",s.string=this.getStringData(t);break;case 7:s.name="Cue Point",s.string=this.getStringData(t);break;case 9:s.name="Device Name",s.string=this.getStringData(t);break;case 32:s.name="MIDI Channel Prefix";break;case 33:s.name="MIDI Port",s.data=w.bytesToNumber([this.data[t+3]]);break;case 47:s.name="End of Track";break;case 81:s.name="Set Tempo",s.data=Math.round(6e7/w.bytesToNumber(this.data.subarray(t+3,t+6))),this.tempo=s.data;break;case 84:s.name="SMTPE Offset";break;case 88:s.name="Time Signature",s.data=this.data.subarray(t+3,t+7),s.timeSignature=""+s.data[0]+"/"+Math.pow(2,s.data[1]);break;case 89:s.name="Key Signature",s.data=this.data.subarray(t+3,t+5);var a=s.data[0]>127?s.data[0]-256:s.data[0];a>=0?s.keySignature=P.CIRCLE_OF_FIFTHS[a]:s.keySignature=P.CIRCLE_OF_FOURTHS[Math.abs(a)],s.data[1]==0?s.keySignature+=" Major":s.data[1]==1&&(s.keySignature+=" Minor");break;case 127:s.name="Sequencer-Specific Meta-event";break;default:s.name="Unknown: "+this.data[t+1].toString(16);break}var n=w.getVarIntLength(this.data.subarray(t+2)),r=w.readVarInt(this.data.subarray(t+2,t+2+n));this.pointer+=i+2+n+r}else if(this.data[t]===240){s.name="Sysex";var o=w.getVarIntLength(this.data.subarray(t+1)),c=w.readVarInt(this.data.subarray(t+1,t+1+o));s.data=this.data.subarray(t+1+o,t+1+o+c),this.pointer+=i+1+o+c}else if(this.data[t]===247){s.name="Sysex (escape)";var h=w.getVarIntLength(this.data.subarray(t+1)),l=w.readVarInt(this.data.subarray(t+1,t+1+h));s.data=this.data.subarray(t+1+h,t+1+h+l),this.pointer+=i+1+h+l}else if(this.data[t]<128)if(s.running=!0,s.noteNumber=this.data[t],s.noteName=P.NOTES[this.data[t]],s.velocity=this.data[t+1],this.lastStatus<=143)s.name="Note off",s.channel=this.lastStatus-128+1,this.pointer+=i+2;else if(this.lastStatus<=159)s.name="Note on",s.channel=this.lastStatus-144+1,this.pointer+=i+2;else if(this.lastStatus<=175)s.name="Polyphonic Key Pressure",s.channel=this.lastStatus-160+1,s.note=P.NOTES[this.data[t]],s.pressure=this.data[t+1],this.pointer+=i+2;else if(this.lastStatus<=191)s.name="Controller Change",s.channel=this.lastStatus-176+1,s.number=this.data[t],s.value=this.data[t+1],this.pointer+=i+2;else if(this.lastStatus<=207)s.name="Program Change",s.channel=this.lastStatus-192+1,s.value=this.data[t+1],this.pointer+=i+1;else if(this.lastStatus<=223)s.name="Channel Key Pressure",s.channel=this.lastStatus-208+1,this.pointer+=i+1;else if(this.lastStatus<=239)s.name="Pitch Bend",s.channel=this.lastStatus-224+1,s.value=(this.data[t+1]&127)<<7|this.data[t]&127,this.pointer+=i+2;else throw"Unknown event (running): ".concat(this.lastStatus);else if(this.lastStatus=this.data[t],this.data[t]<=143)s.name="Note off",s.channel=this.lastStatus-128+1,s.noteNumber=this.data[t+1],s.noteName=P.NOTES[this.data[t+1]],s.velocity=Math.round(this.data[t+2]/127*100),this.pointer+=i+3;else if(this.data[t]<=159)s.name="Note on",s.channel=this.lastStatus-144+1,s.noteNumber=this.data[t+1],s.noteName=P.NOTES[this.data[t+1]],s.velocity=Math.round(this.data[t+2]/127*100),this.pointer+=i+3;else if(this.data[t]<=175)s.name="Polyphonic Key Pressure",s.channel=this.lastStatus-160+1,s.note=P.NOTES[this.data[t+1]],s.pressure=this.data[t+2],this.pointer+=i+3;else if(this.data[t]<=191)s.name="Controller Change",s.channel=this.lastStatus-176+1,s.number=this.data[t+1],s.value=this.data[t+2],this.pointer+=i+3;else if(this.data[t]<=207)s.name="Program Change",s.channel=this.lastStatus-192+1,s.value=this.data[t+1],this.pointer+=i+2;else if(this.data[t]<=223)s.name="Channel Key Pressure",s.channel=this.lastStatus-208+1,this.pointer+=i+2;else if(this.data[t]<=239)s.name="Pitch Bend",s.channel=this.lastStatus-224+1,s.value=(this.data[t+2]&127)<<7|this.data[t+1]&127,this.pointer+=i+3;else throw"Unknown event: ".concat(this.data[t]);return this.delta+=s.delta,this.events.push(s),s}},{key:"endOfTrack",value:function(){return this.data[this.pointer+1]==255&&this.data[this.pointer+2]==47&&this.data[this.pointer+3]==0}}]),f})();Uint8Array.prototype.forEach||Object.defineProperty(Uint8Array.prototype,"forEach",{value:Array.prototype.forEach});var Z=(function(){function f(e,t){B(this,f),this.sampleRate=5,this.startTime=0,this.buffer=t||null,this.midiChunksByteLength=null,this.division,this.format,this.setTimeoutId=!1,this.scheduledTime=0,this.tracks=[],this.instruments=[],this.defaultTempo=120,this.tempo=null,this.startTick=0,this.tick=0,this.lastTick=null,this.inLoop=!1,this.totalTicks=0,this.events=[],this.totalEvents=0,this.tempoMap=[],this.eventListeners={},typeof e=="function"&&this.on("midiEvent",e)}return V(f,[{key:"loadFile",value:function(t){throw"loadFile is only supported on Node.js"}},{key:"loadArrayBuffer",value:function(t){return this.buffer=new Uint8Array(t),this.fileLoaded()}},{key:"loadDataUri",value:function(t){for(var s=w.atob(t.split(",")[1]),i=new Uint8Array(s.length),a=0;a<s.length;a++)i[a]=s.charCodeAt(a);return this.buffer=i,this.fileLoaded()}},{key:"getFilesize",value:function(){return this.buffer?this.buffer.length:0}},{key:"fileLoaded",value:function(){if(!this.validate())throw"Invalid MIDI file; should start with MThd";return this.defaultTempo=120,this.setTempo(this.defaultTempo).getDivision().getFormat().getTracks().dryRun()}},{key:"validate",value:function(){return w.bytesToLetters(this.buffer.subarray(0,4))==="MThd"}},{key:"getFormat",value:function(){return this.format=w.bytesToNumber(this.buffer.subarray(8,10)),this}},{key:"getTracks",value:function(){this.tracks=[];for(var t=0;t<this.buffer.length;){if(w.bytesToLetters(this.buffer.subarray(t,t+4))=="MTrk"){var s=w.bytesToNumber(this.buffer.subarray(t+4,t+8));this.tracks.push(new Q(this.tracks.length,this.buffer.subarray(t+8,t+8+s)))}t+=w.bytesToNumber(this.buffer.subarray(t+4,t+8))+8}var i=0;return this.tracks.forEach(function(a){i+=8+a.data.length}),this.midiChunksByteLength=P.HEADER_CHUNK_LENGTH+i,this}},{key:"enableTrack",value:function(t){return this.tracks[t-1].enable(),this}},{key:"disableTrack",value:function(t){return this.tracks[t-1].disable(),this}},{key:"getDivision",value:function(){return this.division=w.bytesToNumber(this.buffer.subarray(12,P.HEADER_CHUNK_LENGTH)),this}},{key:"playLoop",value:function(t){this.inLoop||(this.inLoop=!0,this.tick=this.getCurrentTick(),this.tracks.forEach(function(s,i){if(!t&&this.endOfFile())this.stop(),this.triggerPlayerEvent("endOfFile");else{var a=s.handleEvent(this.tick,t);if(t&&a)a.hasOwnProperty("name")&&a.name==="Set Tempo"&&this.setTempo(a.data),a.hasOwnProperty("name")&&a.name==="Program Change"&&(this.instruments.includes(a.value)||this.instruments.push(a.value));else if(a){var n=Array.isArray(a)?a:[a];n.forEach(function(r){r.hasOwnProperty("name")&&r.name==="Set Tempo"&&this.setTempo(r.data),this.emitEvent(r)},this)}}},this),!t&&this.isPlaying()&&this.triggerPlayerEvent("playing",{tick:this.tick}),this.inLoop=!1)}},{key:"setTempo",value:function(t){return this.tempo=t,this}},{key:"setStartTime",value:function(t){return this.startTime=t,this}},{key:"play",value:function(){if(this.isPlaying())throw"Already playing...";return this.startTime||(this.startTime=new Date().getTime()),this.scheduledTime=Date.now(),this.schedulePlayLoop(this.sampleRate),this}},{key:"schedulePlayLoop",value:function(t){var s=this;this.setTimeoutId=setTimeout(function(){if(s.playLoop(),s.setTimeoutId!==!1){s.scheduledTime+=s.sampleRate;var i=Date.now()-s.scheduledTime;s.schedulePlayLoop(Math.max(0,s.sampleRate-i))}},t)}},{key:"pause",value:function(){return clearTimeout(this.setTimeoutId),this.setTimeoutId=!1,this.scheduledTime=0,this.startTick=this.tick,this.startTime=0,this}},{key:"stop",value:function(){return clearTimeout(this.setTimeoutId),this.setTimeoutId=!1,this.scheduledTime=0,this.startTick=0,this.startTime=0,this.resetTracks(),this}},{key:"skipToTick",value:function(t){this.stop(),this.startTick=t;for(var s=this.tempoMap.length-1;s>=0;s--)if(this.tempoMap[s].tick<=t){this.setTempo(this.tempoMap[s].tempo);break}return this.collectStateAtTick(t).forEach(function(i){this.emitEvent(i)},this),this.tracks.forEach(function(i){i.setEventIndexByTick(t)}),this}},{key:"collectStateAtTick",value:function(t){var s={};return this.events.forEach(function(i){i.forEach(function(a){if(!(a.tick>=t)){var n;a.name==="Program Change"?n="pc:"+a.channel:a.name==="Controller Change"?n="cc:"+a.channel+":"+a.number:a.name==="Pitch Bend"&&(n="pb:"+a.channel),n&&(s[n]=a)}})}),Object.keys(s).map(function(i){return s[i]})}},{key:"skipToPercent",value:function(t){if(t<0||t>100)throw"Percent must be number between 1 and 100.";return this.skipToTick(Math.round(t/100*this.totalTicks)),this}},{key:"skipToSeconds",value:function(t){var s=this.getSongTime();if(t<0||t>s)throw t+" seconds not within song time of "+s;return this.skipToTick(this.secondsToTicks(t)),this}},{key:"isPlaying",value:function(){return this.setTimeoutId!==!1}},{key:"dryRun",value:function(){for(this.resetTracks();!this.endOfFile();)this.playLoop(!0);return this.events=this.getEvents(),this.totalEvents=this.getTotalEvents(),this.totalTicks=this.getTotalTicks(),this.buildTempoMap(),this.startTick=0,this.startTime=0,this.resetTracks(),this.triggerPlayerEvent("fileLoaded",this),this}},{key:"resetTracks",value:function(){return this.tracks.forEach(function(t){return t.reset()}),this}},{key:"getEvents",value:function(){return this.tracks.map(function(t){return t.events})}},{key:"getTotalTicks",value:function(){return Math.max.apply(null,this.tracks.map(function(t){return t.delta}))}},{key:"getTotalEvents",value:function(){return this.tracks.reduce(function(t,s){return{events:{length:t.events.length+s.events.length}}},{events:{length:0}}).events.length}},{key:"buildTempoMap",value:function(){var t=[];return this.events.forEach(function(s){s.forEach(function(i){i.name==="Set Tempo"&&t.push({tick:i.tick,tempo:i.data})})}),t.sort(function(s,i){return s.tick-i.tick}),this.tempoMap=[{tick:0,tempo:this.defaultTempo}],t.forEach(function(s){var i=this.tempoMap[this.tempoMap.length-1];s.tick===i.tick?i.tempo=s.tempo:this.tempoMap.push({tick:s.tick,tempo:s.tempo})},this),this}},{key:"ticksToSeconds",value:function(t,s){for(var i=0,a=t,n=0;n<this.tempoMap.length;n++){var r=this.tempoMap[n],o=n+1<this.tempoMap.length?this.tempoMap[n+1].tick:s;if(!(o<=t)){var c=Math.max(r.tick,t),h=Math.min(o,s);if(c>=s)break;var l=h-c;i+=l/this.division/r.tempo*60,a=h}}if(a<s){var m=this.tempoMap[this.tempoMap.length-1];i+=(s-a)/this.division/m.tempo*60}return i}},{key:"secondsToTicks",value:function(t){for(var s=t,i=0,a=0;a<this.tempoMap.length;a++){var n=this.tempoMap[a],r=a+1<this.tempoMap.length?this.tempoMap[a+1].tick:1/0,o=r-n.tick,c=o/this.division/n.tempo*60;if(s<=c)return i=n.tick+Math.round(s/60*n.tempo*this.division),i;s-=c,i=r}return this.totalTicks}},{key:"getSongTime",value:function(){return this.ticksToSeconds(0,this.totalTicks)}},{key:"getSongTimeRemaining",value:function(){return Math.round(this.ticksToSeconds(this.getCurrentTick(),this.totalTicks))}},{key:"getSongPercentRemaining",value:function(){return Math.round(this.getSongTimeRemaining()/this.getSongTime()*100)}},{key:"bytesProcessed",value:function(){return P.HEADER_CHUNK_LENGTH+this.tracks.length*8+this.tracks.reduce(function(t,s){return{pointer:t.pointer+s.pointer}},{pointer:0}).pointer}},{key:"eventsPlayed",value:function(){return this.tracks.reduce(function(t,s){return{eventIndex:t.eventIndex+s.eventIndex}},{eventIndex:0}).eventIndex}},{key:"endOfFile",value:function(){return this.isPlaying()?this.totalTicks-this.tick<=0:this.bytesProcessed()>=this.midiChunksByteLength}},{key:"getCurrentTick",value:function(){if(!this.startTime)return this.startTick;var t=(new Date().getTime()-this.startTime)/1e3,s=this.ticksToSeconds(0,this.startTick);return this.secondsToTicks(s+t)}},{key:"emitEvent",value:function(t){return this.triggerPlayerEvent("midiEvent",t),this}},{key:"on",value:function(t,s){return this.eventListeners.hasOwnProperty(t)||(this.eventListeners[t]=[]),this.eventListeners[t].push(s),this}},{key:"triggerPlayerEvent",value:function(t,s){return this.eventListeners.hasOwnProperty(t)&&this.eventListeners[t].forEach(function(i){return i(s||{})}),this}}]),f})(),U={Player:Z,Utils:w,Constants:P};var _=class ${#s=null;#r=null;#t=null;#n=[];#a=.05;#h=1e-6;#o=2;#e=null;#l=.7;#u=1;#c=null;#m=!1;#d=8192;#p=new Set;constructor(e,t,s=null,i=null){this.#s=t,this.#r=s,this.#e=this.#s.createGain(),this.#e.gain.setValueAtTime(this.#l,this.#s.currentTime),this.#c=this.#s.createGain(),this.#c.gain.setValueAtTime(this.#u,this.#s.currentTime),this.#e.connect(this.#c),this.#c.connect(this.#r?this.#r.input:this.#s.destination),this.setPreset(e).then(()=>{typeof i=="function"&&i()})}get preset(){return this.#t}set preset(e){this.setPreset(e)}static load(e,t,s=null){return new Promise(i=>{let a=new $(e,t,s,()=>i(a))})}async setPreset(e,t=!1){this.#t=e,t?this.#t.zones.map(s=>this.#g(s)):await Promise.all(this.#t.zones.map(s=>this.#g(s)))}close(){let e=this.#s.currentTime;this.#n.forEach(t=>{try{t.gain.cancelScheduledValues(0),t.audioBufferSourceNode&&(t.audioBufferSourceNode.stop(e),t.audioBufferSourceNode.disconnect(),t.audioBufferSourceNode=null)}catch{}try{t.disconnect()}catch{}}),this.#n=[],this.#p.clear();try{this.#e.disconnect()}catch{}try{this.#c.disconnect()}catch{}this.#e=null,this.#c=null,this.#t=null,this.#r=null,this.#s=null}queueWaveTable(e,t,s,i,a){this.#s.state==="suspended"&&this.#s.resume().catch(()=>{});let n=this.#b(i),r=this.#x(Math.round(t));if(!r?.buffer)return null;let o=r.originalPitch-100*r.coarseTune-r.fineTune,c=t*100,h=(this.#d-8192)/8192*this.#o*100,l=c-o+h,m=Math.pow(2,l/1200),u=Math.max(e,this.#s.currentTime),d=s+this.#a,p=r.loopStart>=1&&r.loopStart<r.loopEnd;p||(d=Math.min(d,r.buffer.duration/m));let y=this.#i();this.#k(y,r,n,u,d,s);let k=this.#s.createBufferSource();if(k.buffer=r.buffer,k.playbackRate.setValueAtTime(m,0),a?.length>0&&(k.playbackRate.setValueAtTime(m,u),a.forEach(g=>{let S=(t+g.delta)*100-o+h,x=Math.pow(2,S/1200);k.playbackRate.linearRampToValueAtTime(x,u+g.when)})),k.loop=p,p){let g=r.delay??0;k.loopStart=r.loopStart/r.sampleRate+g,k.loopEnd=r.loopEnd/r.sampleRate+g}return k.connect(y),k.start(u,r.delay??0),k.stop(u+d),y.audioBufferSourceNode=k,y.when=u,y.duration=d,y.pitch=t,y.baseDetune=o,y}async cancelQueue(){this.#n.forEach(e=>{e.gain.cancelScheduledValues(0),e.gain.setValueAtTime(this.#h,this.#s.currentTime),e.when=-1;try{e.audioBufferSourceNode?.disconnect()}catch{}})}isSustainActive(){return this.#m}registerSustainNote(e){this.#p.add(e)}setPitchBend(e){this.#d=e;let t=e-8192,s=t>=0?t/8191*this.#o:t/8192*this.#o,i=this.#s.currentTime;this.#n.forEach(a=>{if(a.audioBufferSourceNode&&a.when+a.duration>i){let n=a.pitch*100,r=a.baseDetune,o=s*100,c=n-r+o,h=Math.pow(2,c/1200);a.audioBufferSourceNode.playbackRate.cancelScheduledValues(i),a.audioBufferSourceNode.playbackRate.setTargetAtTime(h,i,.015)}})}setController(e,t){let s=this.#s.currentTime,i=Math.max(0,Math.min(127,t))/127;switch(e){case 7:this.#l=i,this.#e.gain.setTargetAtTime(this.#l,s,.05);break;case 11:this.#u=i,this.#c.gain.setTargetAtTime(this.#u,s,.03);break;case 64:this.#m=t>=64,this.#m||(this.#p.forEach(a=>a()),this.#p.clear());break}}async#g(e){if(e.buffer)return e;if(e.delay=0,e.file){let t=atob(e.file),s=Uint8Array.from(t,i=>i.charCodeAt(0));try{e.buffer=await this.#s.decodeAudioData(s.buffer),this.#T(e)}catch(i){return console.error("Audio decoding error:",i),console.warn(this.#t),!1}}else this.#T(e);return e}#T(e){e.loopStart=this.#y(e.loopStart,0),e.loopEnd=this.#y(e.loopEnd,0),e.coarseTune=this.#y(e.coarseTune,0),e.fineTune=this.#y(e.fineTune,0),e.originalPitch=this.#y(e.originalPitch,6e3)}#k(e,t,s,i,a,n){e.gain.setValueAtTime(this.#h,this.#s.currentTime);let r=Math.min(n,a-this.#a),o=t.ahdsr&&t.ahdsr.length>0?t.ahdsr:[{duration:0,volume:1},{duration:r,volume:1}];e.gain.cancelScheduledValues(i);let c=(o[0]?.volume??1)*s;e.gain.linearRampToValueAtTime(this.#E(c),i+.002);let h=0,l=o[0]?.volume??1;for(let m of o){let{duration:u,volume:d}=m;if(u<=0)continue;let p=r-h;if(u>p){let y=p/u,k=l+y*(d-l);e.gain.exponentialRampToValueAtTime(this.#E(s*k),i+r);break}h+=u,l=d,e.gain.exponentialRampToValueAtTime(this.#E(s*l),i+h)}e.gain.exponentialRampToValueAtTime(this.#h,i+r+this.#a)}#i(e){let t=e||this.#e,s=this.#s.currentTime,i=this.#n.find(a=>a.target===t&&s>a.when+a.duration+.05);if(!i&&this.#n.length>=64){let a=this.#n.filter(n=>n.target===t);a.length>0&&(a.sort((n,r)=>n.when-r.when),i=a[0])}if(i){if(i.audioBufferSourceNode){try{i.audioBufferSourceNode.stop(0),i.audioBufferSourceNode.disconnect()}catch{}i.audioBufferSourceNode=null}i.gain.cancelScheduledValues(0),i.gain.setValueAtTime(this.#h,s)}else i=this.#s.createGain(),i.gain.value=0,i.target=t,i.connect(t),this.#n.push(i);return i.cancel=(a=!1)=>{let n=this.#s.currentTime;if(a&&i.audioBufferSourceNode){try{i.audioBufferSourceNode.stop(0),i.audioBufferSourceNode.disconnect()}catch{}i.audioBufferSourceNode=null}i.when+i.duration>n&&(i.gain.cancelScheduledValues(0),i.gain.setTargetAtTime(this.#h,n,a?.005:.02),i.when=n+1e-5,i.duration=0)},i}#x(e){return this.#t.zones.findLast(t=>e>=t.keyRangeLow&&e<=t.keyRangeHigh)}#b(e){let t=e?1*e:.5;return Math.min(t,.8)}#E(e){return e>this.#h?e:this.#h}#y(e,t){return typeof e=="number"?e:t}};typeof window<"u"&&(window.WebAudioFontPlayer=_);var q=_;var D=class f{#s=null;#r=null;#t=null;#n=null;#a=null;#h=null;#o=null;#e=0;#l=new Map;static#u=[32,64,128,256,512,1024,2048,4096,8192,16384];static#c=new Map([[32,.7],[64,.8],[128,.9],[256,1],[512,1.1],[1024,1.2],[2048,1.4],[4096,1.6],[8192,1.8],[16384,2]]);constructor(e,t,s){this.#t=e,this.#s=this.#t.createGain();let i=this.#s;[32,64,128,256,512,1024,2048,4096,8192,16384].forEach(n=>{i=this.#m(i,n);let r=n<1e3?n:n/1024+"k";this["band".concat(r)]=i}),this.#e=s,this.#h=this.#t.createConvolver(),this.#o=this.#t.createGain(),this.#o.gain.setValueAtTime(s,this.#t.currentTime),this.#d(1.5,2),this.#n=this.#t.createDynamicsCompressor(),this.#n.threshold.setValueAtTime(-10,this.#t.currentTime),this.#n.ratio.setValueAtTime(20,this.#t.currentTime),this.#n.attack.setValueAtTime(.001,this.#t.currentTime),this.#n.release.setValueAtTime(.1,this.#t.currentTime),this.#n.knee.setValueAtTime(0,this.#t.currentTime),this.#a=this.#t.createAnalyser(),this.#a.fftSize=256,this.#a.smoothingTimeConstant=.6,this.#r=this.#t.createGain(),this.#r.gain.setValueAtTime(t,this.#t.currentTime),i.connect(this.#r),this.#r.connect(this.#n),this.#r.connect(this.#h),this.#h.connect(this.#o),this.#n.connect(this.#a),this.#o.connect(this.#a),this.#a.connect(this.#t.destination)}get eqFrequencies(){return f.#u}get analyser(){return this.#a||null}get input(){return this.#s}get reverb(){return this.#e}set reverb(e){this.#e=Math.max(0,Math.min(1,e)),this.#o.gain.setTargetAtTime(this.#e,this.#t.currentTime,.1)}get masterVolume(){return this.#r.gain.value}set masterVolume(e){let t=Math.max(0,Math.min(1,e)),s=Math.pow(t,2);this.#r.gain.setTargetAtTime(s,this.#t.currentTime,.01)}killReverbTail(){let e=this.#t.currentTime;this.#o.gain.cancelScheduledValues(e),this.#o.gain.setValueAtTime(0,e)}restoreReverb(){this.reverb=this.#e}setEQ(e,t=.04){let s=this.#t.currentTime,i=12;for(let[a,n]of Object.entries(e)){let r=Number(a),o=this.#l.get(r);if(!o)continue;let c=Math.max(-i,Math.min(i,n));o.filter.gain.setTargetAtTime(c,s,t),o.gain=c}}getEQ(){let e={};for(let[t,s]of this.#l)e[t]=s.gain;return e}resetEQ(e=.04){let t={};for(let s of f.#u)t[s]=0;this.setEQ(t,e)}setEQPreset(e){let t={flat:{32:0,64:0,128:0,256:0,512:0,1024:0,2048:0,4096:0,8192:0,16384:0},bass:{32:7,64:6,128:4,256:2,512:0,1024:-1,2048:-1,4096:0,8192:0,16384:0},treble:{32:0,64:0,128:0,256:0,512:0,1024:1,2048:3,4096:5,8192:7,16384:8},vocal:{32:-3,64:-2,128:0,256:2,512:4,1024:5,2048:4,4096:2,8192:1,16384:0},loudness:{32:6,64:4,128:1,256:0,512:-1,1024:-1,2048:0,4096:2,8192:4,16384:5},classical:{32:4,64:3,128:2,256:0,512:0,1024:0,2048:0,4096:2,8192:3,16384:4},jazz:{32:4,64:3,128:1,256:0,512:-1,1024:-1,2048:0,4096:1,8192:3,16384:4},electronic:{32:6,64:5,128:2,256:-1,512:-2,1024:-1,2048:2,4096:4,8192:5,16384:6}},s=t[e];if(!s)throw new Error('Preset EQ unkown: "'.concat(e,'". Avaiables: ').concat(Object.keys(t).join(", ")));this.setEQ(s)}#m(e,t){let s=this.#t.createBiquadFilter();s.type="peaking",s.frequency.setValueAtTime(t,this.#t.currentTime),s.gain.setValueAtTime(0,this.#t.currentTime);let i=f.#c.get(t)??1;return s.Q.setValueAtTime(i,this.#t.currentTime),this.#l.set(t,{filter:s,gain:0}),e.connect(s),s}#d(e,t){let s=this.#t.sampleRate,i=s*e,a=this.#t.createBuffer(2,i,s),r=Math.floor(.015*s);for(let o=0;o<a.numberOfChannels;o++){let c=a.getChannelData(o),h=0,l=o===1?Math.floor(.002*s):0;for(let m=0;m<i;m++){if(m<r){c[m]=0;continue}let u=(m-r)/s,d=Math.exp(-u*(t/e)),p=Math.max(.01,.2*Math.exp(-u*2.5));h=(Math.random()*2-1)*p+h*(1-p);let k=h*d;u<.04&&(m%123===0||m%234===0)&&(k+=(Math.random()*2-1)*.2*(.04-u)/.04),m+l<i?c[m+l]=k:c[m]=k}}this.#h.buffer=a}};var J="MidiAudioPlayer",A="KeyValues";var M=null,F=1;async function O(f=F){return M&&f!==F&&(M.close(),M=null,F=f),M||new Promise((e,t)=>{let s=indexedDB.open(J,f);s.onupgradeneeded=i=>{let a=i.target.result;a.objectStoreNames.contains(A)||a.createObjectStore(A)},s.onsuccess=i=>{M=i.target.result,e(M)},s.onerror=i=>t(i.target.error)})}var z={async setVersion(f){await O(f)},async setItem(f,e,t=!1){let s=await O(),i=e,a=!1;if(t){let r=JSON.stringify(e),c=new Blob([r]).stream().pipeThrough(new CompressionStream("gzip"));i=await new Response(c).arrayBuffer(),a=!0}let n={data:i,isCompressed:a};return new Promise((r,o)=>{let l=s.transaction(A,"readwrite").objectStore(A).put(n,f);l.onsuccess=()=>r(),l.onerror=()=>o(l.error)})},async getItem(f){let e=await O(),t=await new Promise((s,i)=>{let r=e.transaction(A,"readonly").objectStore(A).get(f);r.onsuccess=()=>s(r.result),r.onerror=()=>i(r.error)});if(!t)return null;if(t.isCompressed){let i=new Blob([t.data]).stream().pipeThrough(new DecompressionStream("gzip")),n=await new Response(i).text();return JSON.parse(n)}return t.data},async removeItem(f){let e=await O();return new Promise((t,s)=>{let n=e.transaction(A,"readwrite").objectStore(A).delete(f);n.onsuccess=()=>t(),n.onerror=()=>s(n.error)})},async clear(){let f=await O();return new Promise((e,t)=>{let a=f.transaction(A,"readwrite").objectStore(A).clear();a.onsuccess=()=>e(),a.onerror=()=>t(a.error)})}},I=z;var X=(f,e,t)=>Math.min(Math.max(f,e),t),L=class f extends U.Player{static ENDPOINT="https://webaudiofonts.com/presets/";static DEFAULT_PRESET=-1;static REFERENCE_GAIN=.15;static KARAOKE_CHANNEL=0;#s=null;#r=null;#t=null;#n=null;#a={};#h={};#o={};#e={};#l={};#u={};#c={};#m=null;#d=null;#p=null;#g=null;#T=!1;#k="";#i={endpoint:f.ENDPOINT,volume:.6,reverb:.3,onEndFile:null,localCache:!0,presetRandom:!1,karaoke:!1,karaokeDelay:0,muteExpression:!1,maxCharPerLine:48,eqPreset:"flat",preferred:[],presets:[]};constructor(e={}){super(),this.#i={...this.#i,...e},this.#p=this.#x(),this.#r=new(window.AudioContext||window.webkitAudioContext),this.#t=new D(this.#r,this.#i.volume,this.#i.reverb),this.#t.setEQPreset(this.#i.eqPreset),this.#i.karaoke&&this.#C("intro")}get catalog(){return this.getCatalog()}get channels(){return this.#e}get channelStates(){return this.#h}get volume(){return this.#i.volume}set volume(e){this.#i.volume=X(e,0,1),this.#t.masterVolume=this.#i.volume}get volumes(){return this.#u}get reverb(){return this.#t.reverb}set reverb(e){this.#t.reverb=e}get muteExpression(){return this.#i.muteExpression}set muteExpression(e){this.#i.muteExpression=!!e}get eqFrequencies(){return this.#t.eqFrequencies}get eq(){return this.#t.getEQ()}getEQ(){return this.#t.getEQ()}setEQ(e){this.#t.setEQ(e)}setEQPreset(e){this.#t.setEQPreset(e)}setChannelVolume(e,t){this.#u[e]=t,this.#b()}async#x(){await Promise.all(this.#i.presets.map(async e=>{let t=await this.findPreset(e);t&&(this.#c[t.program]=t)}))}async findPreset(e){let t=null;return(await this.getCategories()).some(i=>{if(i.instruments.some(a=>{if(t=a.presets.find(n=>n.id==e),t)return t.category=i.name,t.instrument=a.name,t.program=a.program,!0}),t)return!0}),t}async close(){Object.keys(this.#e).forEach(e=>this.#e[e].close()),await this.#r.close()}async getCatalog(){if(this.#s)return this.#s;let e=this.#i.localCache?await sessionStorage.getItem("waf_catalog"):null;if(e)this.#s=JSON.parse(e);else{this.#f("Downloading catalog...");let i=await fetch("".concat(this.#i.endpoint,"catalog.json"));if(!i.ok)throw new Error("Impossible to download catalog: ".concat(i.status));this.#s=await i.json(),this.#i.localCache&&await sessionStorage.setItem("waf_catalog",JSON.stringify(this.#s))}let t=new Date(this.#s.updatedAt).getTime();return(await I.getItem("waf_catalog_version")||1)<t&&(await I.clear(),I.setItem("waf_catalog_version",t)),this.#s}async getCategories(){return(await this.getCatalog()).categories}async getProgramInstruments(e){let t=await this.getCategories(),s=[];return await Promise.all(t.map(async i=>i.instruments.filter(a=>a.program==e).forEach(a=>{a.presets.forEach(n=>{n.instrument=i.name+" / "+a.name,s.push(n)})}))),s}async getPreset(e){try{if(typeof e=="object")return e;let t="waf_preset_".concat(e),s=this.#i.localCache?await I.getItem(t):null;if(s)return JSON.parse(s);this.#f("Downloading preset ".concat(e,"..."));let a=await(await fetch("".concat(f.ENDPOINT).concat(e,".json"))).json();if(a.zones===void 0)throw console.error("Invalid preset: ".concat($id)),new Error("Invalid preset: ".concat($id));return this.#i.localCache&&await I.setItem(t,JSON.stringify(a),!0),a}catch{throw console.error("Invalid preset: ".concat(e)),new Error("Invalid preset: ".concat(e))}}async loadPreset(e,t,s=!1){let i=await this.findPreset(e);if(!i)throw new Error("Invalid preset: ".concat(e));this.#c[i.program]=i;let a=await this.getPreset(e);s?this.#e[t].setPreset(a,s).then(()=>this.#b()):(await this.#e[t].setPreset(a,s),this.#b())}async load(e,t){typeof e=="string"&&(this.#f("Downloading song..."),e=await(await fetch(e)).arrayBuffer()),typeof t=="string"&&(this.#f("Downloading setup..."),t=await(await fetch(t)).json()),this.#m=await this.hashBuffer(e),await this.#p,this.isPlaying()&&this.stop(),this.#v(),await Promise.all(Object.values(this.#e).map(async n=>n.close())),this.#e={},this.#o={},this.#a={},this.#k="",this.#f("Loading buffer...");try{await this.loadArrayBuffer(e)}catch{await this.loadArrayBuffer(await this.#R(e))}this.#i.karaoke&&(this.#f("Generating karaoke frames..."),this.#g=null,await this.#V(),this.#k&&this.#C("title",this.#k)),this.#f("Trim midi events..."),this.#B(),queueMicrotask(()=>this.triggerPlayerEvent("computed")),this.#f("Loading instruments..."),this.#l=await this.#N(),this.#h=Object.keys(this.#l).reduce((n,r)=>({...n,[r]:!1}),{}),this.#u=Object.keys(this.#l).reduce((n,r)=>({...n,[r]:1}),{}),t?.volumes!==void 0&&await Promise.all(Object.keys(t.volumes).map(async n=>{this.#u[n]!==void 0&&(this.#u[n]=t.volumes[n])}));let s={},i=new Set;t?.presets!==void 0&&await Promise.all(Object.keys(t.presets).map(async n=>{let r=await this.findPreset(t.presets[n]);r&&(s[n]=await this.getPreset(r.id),i.add(r.program))}));let a=await this.#M();Object.values(this.#l).length||this.#f("Error: no instrument found"),await Promise.all([...a].map(async n=>{if(i.has(n))return;let r=null;this.#c[n]!==void 0?r=await this.getPreset(this.#c[n].id):this.#i.presetRandom?r=await this.#I(n):r=await this.#L(n),this.#o[n]=r})),await Promise.all(Object.keys(this.#l).map(async n=>{this.#e[n]&&this.#e[n].close(),s[n]!==void 0?this.#e[n]=await this.#P(s[n]):this.#e[n]=await this.#P(this.#o[this.#l[n]])})),this.#f("Initializing instrument states..."),await this.#y(),await this.triggerPlayerEvent("presetsLoaded",this.#o),await this.#b(),this.#f("Player ready")}async getSongSetup(){let e={hash:this.#m,presets:{},volumes:{}};return Object.keys(this.#e).map(async t=>e.presets[t]=this.#e[t].preset.id),e.volumes=this.#u,e}async getTrainingPresets(){return await Promise.all(Object.values(this.#c).map(async e=>e.id))}async play(e=null){if(this.#r.state==="suspended")try{await this.#r.resume()}catch{return!1}return e&&await this.load(e),await Promise.all(Object.keys(this.#e).map(async t=>await this.#e[t]?.cancelQueue())),this.#t.restoreReverb(),this.isPlaying()||(this.startTime||(this.startTime=new Date().getTime()),this.scheduledTime=Date.now(),this.schedulePlayLoop(this.sampleRate)),!0}async pause(){await super.pause(),this.#t.killReverbTail(),await this.#v(),await Promise.all(Object.keys(this.#e).map(async e=>await this.#e[e]?.cancelQueue()))}async stop(e=!1){return await super.stop(),this.setTimeoutId=!1,e||(this.#t.killReverbTail(),await Promise.all(Object.keys(this.#e).map(async t=>await this.#e[t]?.cancelQueue()))),await this.#v(),this.#i.karaoke&&this.#C("intro"),this}getRealTimeVolume(){let e=this.#t.analyser,t=new Uint8Array(e.frequencyBinCount);e.getByteFrequencyData(t);let s=0;for(let i=0;i<t.length;i++)s+=t[i];return s/(t.length*100)}getSongTimeRemaining(){return this.ticksToSeconds(this.getCurrentTick(),this.totalTicks)}async skipToSeconds(e){let t=this.getSongTime();if(e<0||e>t)throw e+" seconds not within song time of "+t;return await this.skipToTick(this.secondsToTicks(e)),this}async generateWaveformSVG(e=1e3){if(!this.totalTicks||!this.events)return"";let t=new Array(e).fill(0),s=this.totalTicks/e,i=this.events.flatMap((u,d)=>u.map(p=>({...p,computedChannel:p.channel!==void 0?p.channel:d}))).filter(u=>u.name==="Controller Change"||u.name==="Program Change"||u.name==="Note on"&&u.velocity>0).sort((u,d)=>u.tick-d.tick),a=new Map,n=new Map;i.forEach(u=>{let d=Math.floor(u.tick/s);if(d>=e)return;let p=u.computedChannel;if(a.has(p)||a.set(p,100),n.has(p)||n.set(p,127),u.name==="Controller Change")u.number===7?a.set(p,u.value):u.number===11&&n.set(p,u.value);else if(u.name==="Note on"){let y=a.get(p)/127,k=n.get(p)/127,g=u.velocity*y*k;t[d]+=g}});let r=t.reduce((u,d)=>isNaN(d)?u:d>u?d:u,0),o=r>0?t.map(u=>isNaN(u)?0:u/r):t.fill(0),c=e,h=c/5,l=o.map((u,d)=>{let p=d,y=Math.max(0,Math.min(h,h-u*h));return"".concat(p,",").concat(y.toFixed(2))}),m="M 0,".concat(h," L ").concat(l.join(" L ")," L ").concat(c,",").concat(h);return'<svg class="midiaudioplayer-waveform" viewBox="0 0 '.concat(c," ").concat(h,'" preserveAspectRatio="none"><path d="').concat(m,'" fill="none" stroke-linecap="round" stroke-linejoin="round" /></svg>')}async hashBuffer(e,t="SHA-256"){let s=await crypto.subtle.digest(t,e);return Array.from(new Uint8Array(s)).map(a=>a.toString(16).padStart(2,"0")).join("")}async#b(){this.#d&&clearTimeout(this.#d),this.#d=setTimeout(async()=>{let e=await this.getSongSetup();queueMicrotask(()=>this.triggerPlayerEvent("setupChange",e))},1e3)}async triggerPlayerEvent(e,t){e!="fileLoaded"&&(e=="computed"?(this.#n=await this.#F(),super.triggerPlayerEvent(e,{title:this.#k,karaoke:this.#T,vocalChannel:this.#n,tempo:this.tempo,division:this.division,duration:this.getSongTime(),sampleRate:this.sampleRate,totalTicks:this.totalTicks,totalEvents:this.totalEvents,channels:await this.#l})):e=="endOfFile"&&this.#i.karaoke?queueMicrotask(()=>super.triggerPlayerEvent(e,t)):super.triggerPlayerEvent(e,t))}async playLoop(e){if(this.inLoop)return;if(!e&&this.endOfFile()&&this.tick>0){await this.stop(!0),this.tick=0,this.triggerPlayerEvent("endOfFile");return}this.inLoop=!0,this.tick=this.getCurrentTick();let t=this.tracks.length;for(let s=0;s<t;s++){let i=this.tracks[s].handleEvent(this.tick,e);if(!i)continue;let a=i.constructor===Array,n=a?i.length:1;for(let r=0;r<n;r++){let o=a?i[r]:i,{name:c,data:h,value:l}=o;c==="Set Tempo"&&this.setTempo(h),e?c==="Program Change"&&!this.instruments.includes(l)&&this.instruments.push(l):this.emitEvent(o)}}!e&&this.isPlaying()&&this.triggerPlayerEvent("playing",{tick:this.tick}),this.inLoop=!1}schedulePlayLoop(e){this.setTimeoutId=setTimeout(()=>{if(this.setTimeoutId===!1)return;this.playLoop();let t=this.#r.currentTime;this._lastAudioTime||(this._lastAudioTime=t);let s=t-this._lastAudioTime;this._lastAudioTime=t;let i=this.sampleRate/1e3,a=s-i,n=Math.max(0,this.sampleRate-a*1e3);this.schedulePlayLoop(n)},e)}emitEvent(e){this.#D(e)}ticksToSeconds(e,t){if(t===void 0&&(t=e,e=0),e>=t)return 0;let s=0,i=this.tempoMap.length,a=60/this.division,n=0,r=i-1,o=0;for(;n<=r;){let h=n+r>>1;this.tempoMap[h].tick<=e?(o=h,n=h+1):r=h-1}let c=e;for(let h=o;h<i;h++){let l=this.tempoMap[h],m=h+1<i?this.tempoMap[h+1].tick:t;if(m<=e)continue;let u=Math.max(l.tick,e),d=Math.min(m,t);if(u>=t)break;s+=(d-u)/l.tempo*a,c=d}if(c<t){let h=this.tempoMap[i-1];s+=(t-c)/h.tempo*a}return s}secondsToTicks(e){let t=e,s=this.tempoMap.length,i=60/this.division;for(let a=0;a<s;a++){let n=this.tempoMap[a],c=((a+1<s?this.tempoMap[a+1].tick:1/0)-n.tick)/n.tempo*i;if(t<=c)return n.tick+Math.round(t*n.tempo/i);t-=c}return this.totalTicks}getTickBeforeSeconds(e,t){if(e<=0)return 0;let s=this.ticksToSeconds(0,e),i=Math.max(0,s-t);return this.secondsToTicks(i)}async skipToTick(e){let t=Math.max(0,Math.min(e,this.totalTicks||0)),s=this.isPlaying();if(this.#v(),Object.keys(this.channels).forEach(i=>this.channels[i]?.cancelQueue?.()),s&&super.pause(),this.startTick=t,this.tick=t,this.tempoMap&&this.tempoMap.length>0){for(let i=this.tempoMap.length-1;i>=0;i--)if(this.tempoMap[i].tick<=t){this.setTempo(this.tempoMap[i].tempo);break}}try{let i=[],a=[],n=[],r=[];this.#E(t).forEach(o=>{let c=o.channel;if(!((c===void 0||!this.channels[c])&&o.name!=="Karaoke Event"))switch(o.name){case"Controller Change":i[o.channel]=o;break;case"Program Change":a[o.channel]=o;break;case"Pitch Bend":n[o.channel]=o;break;case"Karaoke Event":r[o.channel]=o;break}}),i.forEach(o=>this.emitEvent(o)),a.forEach(o=>this.emitEvent(o)),n.forEach(o=>this.emitEvent(o)),r.forEach(o=>this.triggerPlayerEvent("karaoke",{type:o.type,tick:o.tick,html:o.text}))}catch(i){console.warn("Chase MIDI Error:",i),this.#f("Chase MIDI Error:",i)}return this.tracks&&this.tracks.length>0&&this.tracks.forEach((i,a)=>{let n=this.events[a];if(n&&n.length>0){let r=0,o=n.length-1,c=n.length;for(;r<=o;){let h=r+o>>1;n[h].tick>=t?(c=h,o=h-1):r=h+1}i.eventIndex=c}else typeof i.setEventIndexByTick=="function"&&i.setEventIndexByTick(t)}),s?this.play():this.triggerPlayerEvent("playing",{tick:t}),this}#E(e){let t={};if(!this.events)return[];for(let s=0;s<this.events.length;s++){let i=this.events[s];if(!i||i.length===0)continue;let a=0,n=i.length-1,r=i.length;for(;a<=n;){let o=a+n>>1;i[o].tick>=e?(r=o,n=o-1):a=o+1}for(let o=0;o<r;o++){let c=i[o],h;c.name==="Program Change"?h="pc:"+c.channel:c.name==="Controller Change"?h="cc:"+c.channel+":"+c.number:c.name==="Pitch Bend"?h="pb:"+c.channel:c.name==="Karaoke Event"&&(h="ke:"+c.channel),h&&(t[h]=c)}}return Object.keys(t).map(s=>t[s])}async#y(){this.events&&this.#E(1).forEach(e=>{let t=e.channel;if(this.#e[t])switch(e.name){case"Controller Change":this.#e[t].setController(e.number,e.value);break;case"Pitch Bend":this.#e[t].setPitchBend?.(e.value);break;case"Program Change":e.value>=0&&e.value<=127&&this.#o[e.value+1]!==void 0&&e.channel!=10&&this.#e[t].preset?.program!==e.value+1&&this.#e[t].setPreset(this.#o[e.value+1]);break}})}async#N(){let e={},t=new Set;return this.events.forEach(s=>{s.forEach(i=>{if(i.name==="Program Change"&&i.value>=0&&i.value<=127){if(e[i.channel])return;i.channel==10?e[i.channel]=-1:e[i.channel]=i.value+1}else i.name==="Note on"&&i.channel==10?(e[i.channel]=-1,t.add(10)):i.name==="Note on"&&t.add(i.channel)})}),Object.keys(e).forEach(s=>{t.has(Number(s))||delete e[s]}),e}async#M(){let e=new Set;return this.events.forEach(t=>{t.forEach(s=>{s.name==="Program Change"&&s.value>=0&&s.value<=127?e.add(s.channel==10?-1:s.value+1):s.name==="Note on"&&s.channel==10&&e.add(-1)})}),e}async#I(e){let t=await this.getProgramInstruments(e);if(!t.length)return null;let s=null;return this.#i.preferred.some(i=>{let a=new RegExp("_".concat(i,"$"),"i"),n=t.filter(r=>a.test(r.id));if(n.length)return s=n[Math.floor(Math.random()*n.length)],!0}),s||(s=t[Math.floor(Math.random()*t.length)]),this.#c[e]=s,await this.getPreset(s.id)}async#L(e){let t=await this.getProgramInstruments(e);if(!t.length)return null;let s=null;return this.#i.preferred.some(i=>{let a=new RegExp("_".concat(i,"$"),"i");if(s=t.find(n=>a.test(n.id)),s)return!0}),s||(s=t[0]),this.#c[e]=s,await this.getPreset(s.id)}#P(e){return q.load(e,this.#r,this.#t)}async#D(e){if(this.isPlaying())switch(e.name){case"Note on":if(e.tick<this.tick-100||e.noteNumber===void 0||e.channel==this.#n&&this.#i.muteExpression)return;if(e.velocity>0&&e.velocity<=127){if(this.#S(e.channel,e.noteNumber),this.#u[e.channel]==0)return;let t=e.velocity/127,s=f.REFERENCE_GAIN*Math.pow(t,2)*this.#u[e.channel],i=this.#e[e.channel]?.queueWaveTable(0,e.noteNumber,2,s);i&&this.#O(e.channel,e.noteNumber,i)}else this.#S(e.channel,e.noteNumber);break;case"Note off":if(e.noteNumber===void 0)return;this.#S(e.channel,e.noteNumber);break;case"Controller Change":this.#e[e.channel]?.setController(e.number,e.value);break;case"Pitch Bend":this.#e[e.channel]?.setPitchBend?.(e.value);break;case"Program Change":return;case"Karaoke Event":if(e.tick<this.tick-this.secondsToTicks(10))return;this.triggerPlayerEvent("karaoke",{type:e.type,tick:e.tick,html:e.text});break}}#O(e,t,s){this.#a[e]||(this.#a[e]=new Map),this.#a[e].set(t,s),this.#w();let i=(s.duration||0)*1e3;s.cleanupTimer=setTimeout(()=>{this.#a[e]?.get(t)===s&&(this.#a[e].delete(t),this.#w())},i+50)}#S(e,t){let s=this.#e[e],i=this.#a[e]?.get(t);if(i){i.cleanupTimer&&clearTimeout(i.cleanupTimer);let a=()=>{this.#a[e]?.delete(t),this.#w()};s&&s.isSustainActive()?s.registerSustainNote(()=>i.cancel(!1)):i.cancel(!1),a()}}#v(){Object.keys(this.#a).forEach(e=>{this.#a[e].forEach((t,s)=>{t&&(t.cleanupTimer&&clearTimeout(t.cleanupTimer),t.cancel&&t.cancel(!0)),this.#a[e]?.delete(s)})}),this.#w()}async#w(){let e=!1,t={};Object.keys(this.#e).forEach(s=>{let i=!!(this.#a[s]?.size&&this.#a[s].size>0);t[s]=i,this.#h[s]!==i&&(e=!0)}),e&&(this.#h=t,this.triggerPlayerEvent("channelState",this.#h))}async#R(e){let t=new Uint8Array(e),s=new DataView(e);if(String.fromCharCode(...t.slice(0,4))!=="MThd")throw new Error("Invalid MIDI file (MThd missing)");let a=s.getUint32(4),n=s.getUint16(8),r=s.getUint16(10),o=s.getUint16(12),c=[255,47,0],h=[],l=8+a;for(;l<t.length&&!(l+8>t.length);){let g=String.fromCharCode(...t.slice(l,l+4)),T=s.getUint32(l+4),S=l+8,x=S+T;if(g!=="MTrk"){let C=Math.min(x,t.length);h.push({tag:g,data:t.slice(l,C),repaired:!1}),l=x;continue}let E=h.filter(C=>C.tag==="MTrk").length+1,b=Math.min(T,t.length-S),v=t.slice(S,S+b),N=v.slice(-3);if(N[0]===255&&N[1]===47&&N[2]===0&&b===T)h.push({tag:g,data:v,repaired:!1});else{let C;if(b<T){let tt=T-b,K=v.slice(-2);K[0]===255&&K[1]===47?(C=new Uint8Array(v.length+1),C.set(v),C[v.length]=0):(C=new Uint8Array(v.length+3),C.set(v),C.set(c,v.length))}else C=new Uint8Array(v.length+3),C.set(v),C.set(c,v.length);h.push({tag:g,data:C,repaired:!0})}l=x}let m=h.filter(g=>g.tag==="MTrk").length,u=14+h.reduce((g,T)=>g+8+T.data.length,0),d=new Uint8Array(u),p=new DataView(d.buffer);d.set([77,84,104,100],0),p.setUint32(4,6),p.setUint16(8,n),p.setUint16(10,m),p.setUint16(12,o);let y=14;for(let g of h){let T=g.tag.split("").map(S=>S.charCodeAt(0));d.set(T,y),p.setUint32(y+4,g.data.length),d.set(g.data,y+8),y+=8+g.data.length}let k=h.filter(g=>g.repaired).length;return d.buffer}#B(){if(!this.events||this.events.length===0)return;let e=1/0,t=0;if(this.events.forEach(r=>{r.forEach(o=>{(o.name==="Note on"||o.name==="Note off")&&(o.tick<e&&(e=o.tick),o.tick>t&&(t=o.tick))})}),e===1/0)return;let s=[];this.events.forEach((r,o)=>{r.forEach(c=>{let h=c.name==="Program Change"||c.name==="Controller Change"||c.name==="Pitch Bend"||c.name==="Set Tempo";c.tick<e&&h&&s.push({event:c,trackIdx:o})})});let i=Object.fromEntries(this.events.map((r,o)=>[o,[]])),a=new Set;for(let r=s.length-1;r>=0;r--){let{event:o,trackIdx:c}=s[r],h=o.channel!==void 0?o.channel:"track-".concat(c),l=null;if(o.name==="Program Change"?l="pc:".concat(h):o.name==="Controller Change"?l="cc:".concat(h,":").concat(o.number):o.name==="Pitch Bend"?l="pb:".concat(h):o.name==="Set Tempo"&&(l="tempo"),l&&!a.has(l)){a.add(l);let m={...o,tick:0};i[c].push(m)}}let n=this.events.map((r,o)=>{let c=[];return r.forEach(l=>{let m=l.name==="Program Change"||l.name==="Controller Change"||l.name==="Pitch Bend"||l.name==="Set Tempo",u=l.name==="Text Event"||l.name==="Lyric Event"||l.name==="Track Name"||l.name==="Karaoke Event";if(l.tick<e)!m&&(u||o===0)&&(l.tick=0,c.push(l));else{l.tick=l.tick-e;let d=t-e;l.tick>d&&(l.tick=d),c.push(l)}}),[...i[o]||[],...c].sort((l,m)=>l.tick-m.tick)});this.events=n,this.totalTicks=t-e,typeof this.computeTempoMap=="function"&&this.computeTempoMap()}async#A(){if(this.#g)return this.#g;let e={language:"",title:"",paragraphs:[]},t=null,s=0;if(this.events.forEach(c=>{let h=c.filter(m=>m.name==="Text Event"||m.name==="Lyric Event"||m.name==="Cue Point"||m.name==="Marker"||m.name==="Track Name"),l=h.filter(m=>{let u=m.string||m.text||"";return u&&!u.startsWith("@")}).length;l>s&&(s=l,t=h)}),!t||t.length===0)return e;let i=t.sort((c,h)=>c.tick-h.tick),a=[],n=[],r=[],o=0;for(i.forEach(c=>{let h=this.#K(c.string||"");if(!h||/^Track-/i.test(h.trim())||/^Piste/i.test(h.trim())||h.trim()===""||c.tick===0&&h.length>20)return;if(h.startsWith("@L")){e.language=h.substring(2).trim();return}if(h.startsWith("@T")){e.title+=(e.title?" / ":"")+h.substring(2).trim();return}if(h.startsWith("@")||h.startsWith("(")||h.startsWith("PART")||/^\d+\s+\d+/.test(h.trim()))return;if(/^(Verse|Chorus|Bridge|Break|Intro|End\.)/i.test(h.trim())){let k=h.startsWith("\\")||h.startsWith("/"),g=r.length===0||c.tick-o>500;if((k||g)&&(r.length>0&&(n.push({tick:r[0].tick,blocks:r}),r=[]),n.length>0)){for(;n.length>4;){let T=n.splice(0,4);a.push({tick:T[0].tick,lines:T})}n.length>0&&(a.push({tick:n[0].tick,lines:n}),n=[])}return}let l=!1;if(r.length>0){let g=r[r.length-1].text,T=h.trimLeft();if(T.length>0){let S=/^[A-Z]/.test(T)||/^'[A-Z]/.test(T),x=/^[A-Z]/.test(g.trim())||/^'[A-Z]/.test(g.trim());S&&!g.endsWith(" ")&&g.trim()!="o"&&!x&&c.tick>o&&(l=!0),h.startsWith('"')&&g.endsWith('"')&&(l=!0),h.startsWith('"')&&(g.endsWith(")")||g.endsWith(')"'))&&(l=!0),T.startsWith('"')&&g.trimRight().endsWith(")")&&(l=!0)}}let m=h.startsWith("\\"),u=h.startsWith("/")||l;(m||u)&&(h.startsWith("\\")||h.startsWith("/"))&&(h=h.substring(1)),h=h.replace(/[\r\n]/g,"");let d=!1;o>0&&c.tick>o&&this.ticksToSeconds(o,c.tick)>2.5&&(d=!0);let y=r.reduce((k,g)=>k+g.text.length,0)+h.length>this.#i.maxCharPerLine;if((u||m||d||y)&&(r.length>0&&(n.push({tick:r[0].tick,blocks:r}),r=[]),n.length>0)){if(m||d){for(;n.length>4;){let k=n.splice(0,4);a.push({tick:k[0].tick,lines:k})}n.length>0&&(a.push({tick:n[0].tick,lines:n}),n=[])}else if(n.length>=6){let k=n.splice(0,4);a.push({tick:k[0].tick,lines:k})}}h.length>0&&(r.push({text:h,tick:c.tick}),o=c.tick)}),r.length>0&&n.push({tick:r[0].tick,blocks:r});n.length>4;){let c=n.splice(0,4);a.push({tick:c[0].tick,lines:c})}return n.length>0&&a.push({tick:n[0].tick,lines:n}),a=a.filter(c=>!(c.lines.length==1&&c.lines[0].blocks.length==1&&["intro","outro","sfx","solo","chorus","verse","bridge","break","end"].includes(c.lines[0].blocks[0].text.toLowerCase().trim()))),a.length<=2&&(a=[]),e.paragraphs=a,this.#g=e,e}async#V(){let e=await this.#A();if(!e.paragraphs.length){this.#T=!1,this.events[f.KARAOKE_CHANNEL].push({text:'<span class="karaoke-intro"></span>',name:"Karaoke Event",type:"intro",tick:0,channel:f.KARAOKE_CHANNEL}),this.events[f.KARAOKE_CHANNEL]=this.events[f.KARAOKE_CHANNEL].sort((l,m)=>l.tick-m.tick);return}this.#T=!0,this.#k=e.title;let t=0,s=this.secondsToTicks(this.#i.karaokeDelay),i=this.secondsToTicks(3),a=this.secondsToTicks(5),n=this.secondsToTicks(7),r=this.secondsToTicks(10),o=[];e.paragraphs.forEach((l,m)=>{l.lines.forEach((u,d)=>{u.blocks.forEach(p=>{o.push({block:p,lineIdx:d,paraIdx:m,paragraph:l,fastLinesText:l.lines.map(y=>y.blocks.map(k=>k.text).join(""))})})})});let c=[];e.paragraphs.forEach((l,m)=>{let u=this.getTickBeforeSeconds(l.tick,5);u<t&&(u=t+(l.tick-t)/2),m===0&&u<20&&(u=20),c[m]=u;let p=l.lines.map(y=>y.blocks.map(k=>k.text).join("")).map(y=>'<span class="karaoke-coming">'.concat(y,"</span>")).join("<br/>");if(this.events[f.KARAOKE_CHANNEL].push({text:p,name:"Karaoke Event",type:"lyric",tick:u,channel:f.KARAOKE_CHANNEL}),l.lines.length>0){let y=l.lines[l.lines.length-1];y.blocks.length>0&&(t=y.blocks[y.blocks.length-1].tick)}}),(c[0]||0)>25&&this.events[f.KARAOKE_CHANNEL].push({text:'<span class="karaoke-clear"></span>',name:"Karaoke Event",type:"clear",tick:5,channel:f.KARAOKE_CHANNEL}),o.forEach((l,m)=>{let u=l.block,d=l.lineIdx,p=l.paraIdx,y=l.paragraph,k=l.fastLinesText,g=(S=!1)=>y.lines.map((x,E)=>{if(E<d)return'<span class="karaoke-played">'.concat(k[E],"</span>");if(E>d)return'<span class="karaoke-coming">'.concat(k[E],"</span>");let b="";return x.blocks.forEach(v=>{let N="coming";S||v.tick<u.tick?N="played":v.tick===u.tick&&(N="playing"),b+='<span class="karaoke-'.concat(N,'">').concat(v.text,"</span>")}),b}).join("<br>");this.events[f.KARAOKE_CHANNEL].push({text:g(!1),name:"Karaoke Event",type:"lyric",tick:u.tick-s,channel:f.KARAOKE_CHANNEL});let T=o[m+1];if(T){let S=T.block.tick-u.tick;if(S>i){let x=u.tick+i,E=u.tick+n,b=S>r&&p>0;if(T.paraIdx!==p){let v=c[T.paraIdx];x>=v&&(x=v-1),b&&(E>=v||v-E<i)&&(b=!1)}x>u.tick&&this.events[f.KARAOKE_CHANNEL].push({text:g(!0),name:"Karaoke Event",type:"lyric",tick:x-s,channel:f.KARAOKE_CHANNEL}),b&&E>x&&this.events[f.KARAOKE_CHANNEL].push({text:'<span class="karaoke-clear"></span>',name:"Karaoke Event",type:"clear",tick:E-s,channel:f.KARAOKE_CHANNEL})}}t=u.tick}),this.totalTicks-t>this.secondsToTicks(5)?this.events[f.KARAOKE_CHANNEL].push({text:'<span class="karaoke-clear"></span>',name:"Karaoke Event",type:"clear",tick:t+this.secondsToTicks(5),channel:f.KARAOKE_CHANNEL}):this.events[f.KARAOKE_CHANNEL].push({text:'<span class="karaoke-clear"></span>',name:"Karaoke Event",type:"clear",tick:this.totalTicks-1,channel:f.KARAOKE_CHANNEL}),this.events[f.KARAOKE_CHANNEL]=this.events[f.KARAOKE_CHANNEL].sort((l,m)=>l.tick-m.tick)}async#F(){let e=await this.#A();if(!e?.paragraphs?.length)return null;let t=e.paragraphs.flatMap(c=>c.lines.flatMap(h=>h.blocks.map(l=>l.tick)));if(t.length===0)return null;let s=this.division?this.division/2:48,i=48,a=84,n=Object.keys(this.#l).map(Number).filter(c=>c!==10),r=null,o=-1/0;for(let c of n){let h=this.events.flatMap(E=>E.filter(b=>b.name==="Note on"&&b.velocity>0&&b.channel===c));if(h.length===0)continue;let m=t.filter(E=>h.some(b=>Math.abs(b.tick-E)<=s)).length/t.length,d=h.filter(E=>E.noteNumber>=i&&E.noteNumber<=a).length/h.length;if(d<.3)continue;let p=[...h].sort((E,b)=>E.tick-b.tick),y=this.division/8||6,g=1-p.filter((E,b)=>b>0&&Math.abs(E.tick-p[b-1].tick)<y).length/Math.max(h.length-1,1),T=h.length/Math.max(t.length,1),S=T<.3?T/.3:T>5?Math.max(0,1-(T-5)/10):1,x=m*.45+d*.35+g*.15+S*.05;x>o&&(o=x,r=c)}return o>=.4?r:null}#K(e){if(!e)return"";let t=new Uint8Array(e.length);for(let a=0;a<e.length;a++)t[a]=e.charCodeAt(a)&255;let i=new TextDecoder("windows-1252").decode(t);return i=i.replace(/ÿ/g,""),i=i.replace(/’/g,"'"),i=i.replace(/`/g,"'"),i}#C(e="clear",t=""){let s='<span class="karaoke-'.concat(e,'">').concat(t.replace(/\s\/\s/g,"<br>"),"</span>");this.#i.karaoke&&(e=="title"?queueMicrotask(()=>this.triggerPlayerEvent("karaoke",{type:e,title:t,html:s})):queueMicrotask(()=>this.triggerPlayerEvent("karaoke",{type:e,html:s})))}#f(e,t=!1){queueMicrotask(()=>this.triggerPlayerEvent("logs",e))}};typeof window<"u"&&(window.MidiAudioPlayer=L);var ut=L;})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "midi-audio-player",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "Real MIDI playback in the browser — powered by Web Audio API and WebAudioFont.",
5
5
  "keywords": [
6
6
  "midi",
@@ -55,7 +55,7 @@
55
55
  },
56
56
  "dependencies": {
57
57
  "midi-player-js": "^2.0.17",
58
- "webaudiofontplayer": "^1.0.2"
58
+ "webaudiofontplayer": "^1.0.3"
59
59
  },
60
60
  "devDependencies": {
61
61
  "esbuild": "^0.28.0"
@@ -170,13 +170,18 @@ export default class MidiAudioPlayer extends MidiPlayer.Player {
170
170
  }
171
171
 
172
172
 
173
- async loadPreset(presetId, channel) {
173
+ async loadPreset(presetId, channel, nonblocking = false) {
174
174
  const presetInfo = await this.findPreset(presetId);
175
175
  if(!presetInfo) throw new Error(`Invalid preset: ${presetId}`);
176
176
  this.#presetMap[presetInfo.program] = presetInfo;
177
177
  const preset = await this.getPreset(presetId);
178
- await this.#players[channel].setPreset(preset);
179
- this.#setupChange();
178
+ // this.#players[channel].setPreset(preset).then(() => this.#setupChange());
179
+ if(nonblocking) this.#players[channel].setPreset(preset, nonblocking).then(() => this.#setupChange());
180
+ else {
181
+ await this.#players[channel].setPreset(preset, nonblocking);
182
+ this.#setupChange();
183
+ }
184
+
180
185
  }
181
186
 
182
187
 
@@ -207,6 +212,17 @@ export default class MidiAudioPlayer extends MidiPlayer.Player {
207
212
  await this.loadArrayBuffer(await this.#repairMidi(content));
208
213
  }
209
214
 
215
+ if(this.#opts.karaoke) {
216
+ this.#log('Generating karaoke frames...');
217
+ this.#lyrics = null;
218
+ await this.#generateKaraokeFrames();
219
+ if(this.#title) this.#sendKaraokeFrame('title', this.#title);
220
+ }
221
+
222
+ this.#log(`Trim midi events...`);
223
+ this.#trimMidiEvents();
224
+ queueMicrotask(() => this.triggerPlayerEvent('computed'));
225
+
210
226
  this.#log('Loading instruments...');
211
227
  this.#channels = await this.#getInstruments();
212
228
  this.#channelStates = Object.keys(this.#channels).reduce((acc, key) => ({ ...acc, [key]: false }), {});
@@ -218,8 +234,8 @@ export default class MidiAudioPlayer extends MidiPlayer.Player {
218
234
  }));
219
235
  }
220
236
 
221
- const setupPrograms = new Set();
222
237
  const setupPresets = {};
238
+ const setupPrograms = new Set();
223
239
  if(setup?.presets !== undefined) {
224
240
  await Promise.all(Object.keys(setup.presets).map(async channel => {
225
241
  const presetInfo = await this.findPreset(setup.presets[channel]);
@@ -231,7 +247,7 @@ export default class MidiAudioPlayer extends MidiPlayer.Player {
231
247
 
232
248
  const uniqueInstruments = await this.#getUniqueInstruments();
233
249
  if(!Object.values(this.#channels).length) this.#log("Error: no instrument found");
234
- const presets = Promise.all([...uniqueInstruments].map(async program => {
250
+ await Promise.all([...uniqueInstruments].map(async program => {
235
251
  if(setupPrograms.has(program)) return;
236
252
  let preset = null;
237
253
  if(this.#presetMap[program] !== undefined) preset = await this.getPreset(this.#presetMap[program].id);
@@ -240,18 +256,6 @@ export default class MidiAudioPlayer extends MidiPlayer.Player {
240
256
  this.#instruments[program] = preset;
241
257
  }));
242
258
 
243
- if(this.#opts.karaoke) {
244
- this.#log('Generating karaoke frames...');
245
- this.#lyrics = null;
246
- await this.#generateKaraokeFrames();
247
- if(this.#title) this.#sendKaraokeFrame('title', this.#title);
248
- }
249
-
250
- this.#log(`Trim midi events...`);
251
- this.#trimMidiEvents();
252
- queueMicrotask(() => this.triggerPlayerEvent('computed'));
253
-
254
- await presets;
255
259
  await Promise.all(Object.keys(this.#channels).map(async channel => {
256
260
  if(this.#players[channel]) this.#players[channel].close();
257
261
  if(setupPresets[channel] !== undefined) this.#players[channel] = await this.#createPlayer(setupPresets[channel]);
@@ -263,7 +267,6 @@ export default class MidiAudioPlayer extends MidiPlayer.Player {
263
267
  await this.triggerPlayerEvent('presetsLoaded', this.#instruments);
264
268
  await this.#setupChange();
265
269
  this.#log("Player ready");
266
-
267
270
  }
268
271
 
269
272
 
@@ -760,8 +763,8 @@ export default class MidiAudioPlayer extends MidiPlayer.Player {
760
763
  }
761
764
 
762
765
 
763
- async #createPlayer(preset) {
764
- return new WebAudioFontPlayer(preset, this.#audioCtx, this.#compressor);
766
+ #createPlayer(preset) {
767
+ return WebAudioFontPlayer.load(preset, this.#audioCtx, this.#compressor);
765
768
  }
766
769
 
767
770