PageSourceSearch

https://www.hamienet.com/assets/midiProcessor.worker-DJEo_dd6.js

js hamienet.com collected 2026-10-02 05:01:12 UTC 72,036 bytes, 2,258 lines download raw bytes

1(function() {
2  "use strict";
3  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
4  function getAugmentedNamespace(n) {
5    if (n.__esModule) return n;
6    var f = n.default;
7    if (typeof f == "function") {
8      var a = function a2() {
9        if (this instanceof a2) {
10          return Reflect.construct(f, arguments, this.constructor);
11        }
12        return f.apply(this, arguments);
13      };
14      a.prototype = f.prototype;
15    } else a = {};
16    Object.defineProperty(a, "__esModule", { value: true });
17    Object.keys(n).forEach(function(k) {
18      var d = Object.getOwnPropertyDescriptor(n, k);
19      Object.defineProperty(a, k, d.get ? d : {
20        enumerable: true,
21        get: function() {
22          return n[k];
23        }
24      });
25    });
26    return a;
27  }
28  var Midi = {};
29  var midiFile = {};
30  function parseMidi(data) {
31    var p = new Parser(data);
32    var headerChunk = p.readChunk();
33    if (headerChunk.id != "MThd")
34      throw "Bad MIDI file.  Expected 'MHdr', got: '" + headerChunk.id + "'";
35    var header = parseHeader(headerChunk.data);
36    var tracks = [];
37    for (var i = 0; !p.eof() && i < header.numTracks; i++) {
38      var trackChunk = p.readChunk();
39      if (trackChunk.id != "MTrk")
40        throw "Bad MIDI file.  Expected 'MTrk', got: '" + trackChunk.id + "'";
41      var track = parseTrack(trackChunk.data);
42      tracks.push(track);
43    }
44    return {
45      header,
46      tracks
47    };
48  }
49  function parseHeader(data) {
50    var p = new Parser(data);
51    var format = p.readUInt16();
52    var numTracks = p.readUInt16();
53    var result = {
54      format,
55      numTracks
56    };
57    var timeDivision = p.readUInt16();
58    if (timeDivision & 32768) {
59      result.framesPerSecond = 256 - (timeDivision >> 8);
60      result.ticksPerFrame = timeDivision & 255;
61    } else {
62      result.ticksPerBeat = timeDivision;
63    }
64    return result;
65  }
66  function parseTrack(data) {
67    var p = new Parser(data);
68    var events = [];
69    while (!p.eof()) {
70      var event = readEvent();
71      events.push(event);
72    }
73    return events;
74    var lastEventTypeByte = null;
75    function readEvent() {
76      var event2 = {};
77      event2.deltaTime = p.readVarInt();
78      var eventTypeByte = p.readUInt8();
79      if ((eventTypeByte & 240) === 240) {
80        if (eventTypeByte === 255) {
81          event2.meta = true;
82          var metatypeByte = p.readUInt8();
83          var length = p.readVarInt();
84          switch (metatypeByte) {
85            case 0:
86              event2.type = "sequenceNumber";
87              if (length !== 2) throw "Expected length for sequenceNumber event is 2, got " + length;
88              event2.number = p.readUInt16();
89              return event2;
90            case 1:
91              event2.type = "text";
92              event2.text = p.readString(length);
93              return event2;
94            case 2:
95              event2.type = "copyrightNotice";
96              event2.text = p.readString(length);
97              return event2;
98            case 3:
99              event2.type = "trackName";
100              event2.text = p.readString(length);
101              return event2;
102            case 4:
103              event2.type = "instrumentName";
104              event2.text = p.readString(length);
105              return event2;
106            case 5:
107              event2.type = "lyrics";
108              event2.text = p.readString(length);
109              return event2;
110            case 6:
111              event2.type = "marker";
112              event2.text = p.readString(length);
113              return event2;
114            case 7:
115              event2.type = "cuePoint";
116              event2.text = p.readString(length);
117              return event2;
118            case 32:
119              event2.type = "channelPrefix";
120              if (length != 1) throw "Expected length for channelPrefix event is 1, got " + length;
121              event2.channel = p.readUInt8();
122              return event2;
123            case 33:
124              event2.type = "portPrefix";
125              if (length != 1) throw "Expected length for portPrefix event is 1, got " + length;
126              event2.port = p.readUInt8();
127              return event2;
128            case 47:
129              event2.type = "endOfTrack";
130              if (length != 0) throw "Expected length for endOfTrack event is 0, got " + length;
131              return event2;
132            case 81:
133              event2.type = "setTempo";
134              if (length != 3) throw "Expected length for setTempo event is 3, got " + length;
135              event2.microsecondsPerBeat = p.readUInt24();
136              return event2;
137            case 84:
138              event2.type = "smpteOffset";
139              if (length != 5) throw "Expected length for smpteOffset event is 5, got " + length;
140              var hourByte = p.readUInt8();
141              var FRAME_RATES = { 0: 24, 32: 25, 64: 29, 96: 30 };
142              event2.frameRate = FRAME_RATES[hourByte & 96];
143              event2.hour = hourByte & 31;
144              event2.min = p.readUInt8();
145              event2.sec = p.readUInt8();
146              event2.frame = p.readUInt8();
147              event2.subFrame = p.readUInt8();
148              return event2;
149            case 88:
150              event2.type = "timeSignature";
151              if (length != 2 && length != 4) throw "Expected length for timeSignature event is 4 or 2, got " + length;
152              event2.numerator = p.readUInt8();
153              event2.denominator = 1 << p.readUInt8();
154              if (length === 4) {
155                event2.metronome = p.readUInt8();
156                event2.thirtyseconds = p.readUInt8();
157              } else {
158                event2.metronome = 36;
159                event2.thirtyseconds = 8;
160              }
161              return event2;
162            case 89:
163              event2.type = "keySignature";
164              if (length != 2) throw "Expected length for keySignature event is 2, got " + length;
165              event2.key = p.readInt8();
166              event2.scale = p.readUInt8();
167              return event2;
168            case 127:
169              event2.type = "sequencerSpecific";
170              event2.data = p.readBytes(length);
171              return event2;
172            default:
173              event2.type = "unknownMeta";
174              event2.data = p.readBytes(length);
175              event2.metatypeByte = metatypeByte;
176              return event2;
177          }
178        } else if (eventTypeByte == 240) {
179          event2.type = "sysEx";
180          var length = p.readVarInt();
181          event2.data = p.readBytes(length);
182          return event2;
183        } else if (eventTypeByte == 247) {
184          event2.type = "endSysEx";
185          var length = p.readVarInt();
186          event2.data = p.readBytes(length);
187          return event2;
188        } else {
189          throw "Unrecognised MIDI event type byte: " + eventTypeByte;
190        }
191      } else {
192        var param1;
193        if ((eventTypeByte & 128) === 0) {
194          if (lastEventTypeByte === null)
195            throw "Running status byte encountered before status byte";
196          param1 = eventTypeByte;
197          eventTypeByte = lastEventTypeByte;
198          event2.running = true;
199        } else {
200          param1 = p.readUInt8();
201          lastEventTypeByte = eventTypeByte;
202        }
203        var eventType = eventTypeByte >> 4;
204        event2.channel = eventTypeByte & 15;
205        switch (eventType) {
206          case 8:
207            event2.type = "noteOff";
208            event2.noteNumber = param1;
209            event2.velocity = p.readUInt8();
210            return event2;
211          case 9:
212            var velocity = p.readUInt8();
213            event2.type = velocity === 0 ? "noteOff" : "noteOn";
214            event2.noteNumber = param1;
215            event2.velocity = velocity;
216            if (velocity === 0) event2.byte9 = true;
217            return event2;
218          case 10:
219            event2.type = "noteAftertouch";
220            event2.noteNumber = param1;
221            event2.amount = p.readUInt8();
222            return event2;
223          case 11:
224            event2.type = "controller";
225            event2.controllerType = param1;
226            event2.value = p.readUInt8();
227            return event2;
228          case 12:
229            event2.type = "programChange";
230            event2.programNumber = param1;
231            return event2;
232          case 13:
233            event2.type = "channelAftertouch";
234            event2.amount = param1;
235            return event2;
236          case 14:
237            event2.type = "pitchBend";
238            event2.value = param1 + (p.readUInt8() << 7) - 8192;
239            return event2;
240          default:
241            throw "Unrecognised MIDI event type: " + eventType;
242        }
243      }
244    }
245  }
246  function Parser(data) {
247    this.buffer = data;
248    this.bufferLen = this.buffer.length;
249    this.pos = 0;
250  }
251  Parser.prototype.eof = function() {
252    return this.pos >= this.bufferLen;
253  };
254  Parser.prototype.readUInt8 = function() {
255    var result = this.buffer[this.pos];
256    this.pos += 1;
257    return result;
258  };
259  Parser.prototype.readInt8 = function() {
260    var u = this.readUInt8();
261    if (u & 128)
262      return u - 256;
263    else
264      return u;
265  };
266  Parser.prototype.readUInt16 = function() {
267    var b0 = this.readUInt8(), b1 = this.readUInt8();
268    return (b0 << 8) + b1;
269  };
270  Parser.prototype.readInt16 = function() {
271    var u = this.readUInt16();
272    if (u & 32768)
273      return u - 65536;
274    else
275      return u;
276  };
277  Parser.prototype.readUInt24 = function() {
278    var b0 = this.readUInt8(), b1 = this.readUInt8(), b2 = this.readUInt8();
279    return (b0 << 16) + (b1 << 8) + b2;
280  };
281  Parser.prototype.readInt24 = function() {
282    var u = this.readUInt24();
283    if (u & 8388608)
284      return u - 16777216;
285    else
286      return u;
287  };
288  Parser.prototype.readUInt32 = function() {
289    var b0 = this.readUInt8(), b1 = this.readUInt8(), b2 = this.readUInt8(), b3 = this.readUInt8();
290    return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3;
291  };
292  Parser.prototype.readBytes = function(len) {
293    var bytes = this.buffer.slice(this.pos, this.pos + len);
294    this.pos += len;
295    return bytes;
296  };
297  Parser.prototype.readString = function(len) {
298    var bytes = this.readBytes(len);
299    return String.fromCharCode.apply(null, bytes);
300  };
301  Parser.prototype.readVarInt = function() {
302    var result = 0;
303    while (!this.eof()) {
304      var b = this.readUInt8();
305      if (b & 128) {
306        result += b & 127;
307        result <<= 7;
308      } else {
309        return result + b;
310      }
311    }
312    return result;
313  };
314  Parser.prototype.readChunk = function() {
315    var id = this.readString(4);
316    var length = this.readUInt32();
317    var data = this.readBytes(length);
318    return {
319      id,
320      length,
321      data
322    };
323  };
324  var midiParser = parseMidi;
325  function writeMidi(data, opts) {
326    if (typeof data !== "object")
327      throw "Invalid MIDI data";
328    opts = opts || {};
329    var header = data.header || {};
330    var tracks = data.tracks || [];
331    var i, len = tracks.length;
332    var w = new Writer();
333    writeHeader(w, header, len);
334    for (i = 0; i < len; i++) {
335      writeTrack(w, tracks[i], opts);
336    }
337    return w.buffer;
338  }
339  function writeHeader(w, header, numTracks) {
340    var format = header.format == null ? 1 : header.format;
341    var timeDivision = 128;
342    if (header.timeDivision) {
343      timeDivision = header.timeDivision;
344    } else if (header.ticksPerFrame && header.framesPerSecond) {
345      timeDivision = -(header.framesPerSecond & 255) << 8 | header.ticksPerFrame & 255;
346    } else if (header.ticksPerBeat) {
347      timeDivision = header.ticksPerBeat & 32767;
348    }
349    var h = new Writer();
350    h.writeUInt16(format);
351    h.writeUInt16(numTracks);
352    h.writeUInt16(timeDivision);
353    w.writeChunk("MThd", h.buffer);
354  }
355  function writeTrack(w, track, opts) {
356    var t = new Writer();
357    var i, len = track.length;
358    var eventTypeByte = null;
359    for (i = 0; i < len; i++) {
360      if (opts.running === false || !opts.running && !track[i].running) eventTypeByte = null;
361      eventTypeByte = writeEvent(t, track[i], eventTypeByte, opts.useByte9ForNoteOff);
362    }
363    w.writeChunk("MTrk", t.buffer);
364  }
365  function writeEvent(w, event, lastEventTypeByte, useByte9ForNoteOff) {
366    var type = event.type;
367    var deltaTime = event.deltaTime;
368    var text = event.text || "";
369    var data = event.data || [];
370    var eventTypeByte = null;
371    w.writeVarInt(deltaTime);
372    switch (type) {
373      case "sequenceNumber":
374        w.writeUInt8(255);
375        w.writeUInt8(0);
376        w.writeVarInt(2);
377        w.writeUInt16(event.number);
378        break;
379      case "text":
380        w.writeUInt8(255);
381        w.writeUInt8(1);
382        w.writeVarInt(text.length);
383        w.writeString(text);
384        break;
385      case "copyrightNotice":
386        w.writeUInt8(255);
387        w.writeUInt8(2);
388        w.writeVarInt(text.length);
389        w.writeString(text);
390        break;
391      case "trackName":
392        w.writeUInt8(255);
393        w.writeUInt8(3);
394        w.writeVarInt(text.length);
395        w.writeString(text);
396        break;
397      case "instrumentName":
398        w.writeUInt8(255);
399        w.writeUInt8(4);
400        w.writeVarInt(text.length);
401        w.writeString(text);
402        break;
403      case "lyrics":
404        w.writeUInt8(255);
405        w.writeUInt8(5);
406        w.writeVarInt(text.length);
407        w.writeString(text);
408        break;
409      case "marker":
410        w.writeUInt8(255);
411        w.writeUInt8(6);
412        w.writeVarInt(text.length);
413        w.writeString(text);
414        break;
415      case "cuePoint":
416        w.writeUInt8(255);
417        w.writeUInt8(7);
418        w.writeVarInt(text.length);
419        w.writeString(text);
420        break;
421      case "channelPrefix":
422        w.writeUInt8(255);
423        w.writeUInt8(32);
424        w.writeVarInt(1);
425        w.writeUInt8(event.channel);
426        break;
427      case "portPrefix":
428        w.writeUInt8(255);
429        w.writeUInt8(33);
430        w.writeVarInt(1);
431        w.writeUInt8(event.port);
432        break;
433      case "endOfTrack":
434        w.writeUInt8(255);
435        w.writeUInt8(47);
436        w.writeVarInt(0);
437        break;
438      case "setTempo":
439        w.writeUInt8(255);
440        w.writeUInt8(81);
441        w.writeVarInt(3);
442        w.writeUInt24(event.microsecondsPerBeat);
443        break;
444      case "smpteOffset":
445        w.writeUInt8(255);
446        w.writeUInt8(84);
447        w.writeVarInt(5);
448        var FRAME_RATES = { 24: 0, 25: 32, 29: 64, 30: 96 };
449        var hourByte = event.hour & 31 | FRAME_RATES[event.frameRate];
450        w.writeUInt8(hourByte);
451        w.writeUInt8(event.min);
452        w.writeUInt8(event.sec);
453        w.writeUInt8(event.frame);
454        w.writeUInt8(event.subFrame);
455        break;
456      case "timeSignature":
457        w.writeUInt8(255);
458        w.writeUInt8(88);
459        w.writeVarInt(4);
460        w.writeUInt8(event.numerator);
461        var denominator = Math.floor(Math.log(event.denominator) / Math.LN2) & 255;
462        w.writeUInt8(denominator);
463        w.writeUInt8(event.metronome);
464        w.writeUInt8(event.thirtyseconds || 8);
465        break;
466      case "keySignature":
467        w.writeUInt8(255);
468        w.writeUInt8(89);
469        w.writeVarInt(2);
470        w.writeInt8(event.key);
471        w.writeUInt8(event.scale);
472        break;
473      case "sequencerSpecific":
474        w.writeUInt8(255);
475        w.writeUInt8(127);
476        w.writeVarInt(data.length);
477        w.writeBytes(data);
478        break;
479      case "unknownMeta":
480        if (event.metatypeByte != null) {
481          w.writeUInt8(255);
482          w.writeUInt8(event.metatypeByte);
483          w.writeVarInt(data.length);
484          w.writeBytes(data);
485        }
486        break;
487      case "sysEx":
488        w.writeUInt8(240);
489        w.writeVarInt(data.length);
490        w.writeBytes(data);
491        break;
492      case "endSysEx":
493        w.writeUInt8(247);
494        w.writeVarInt(data.length);
495        w.writeBytes(data);
496        break;
497      case "noteOff":
498        var noteByte = useByte9ForNoteOff !== false && event.byte9 || useByte9ForNoteOff && event.velocity == 0 ? 144 : 128;
499        eventTypeByte = noteByte | event.channel;
500        if (eventTypeByte !== lastEventTypeByte) w.writeUInt8(eventTypeByte);
501        w.writeUInt8(event.noteNumber);
502        w.writeUInt8(event.velocity);
503        break;
504      case "noteOn":
505        eventTypeByte = 144 | event.channel;
506        if (eventTypeByte !== lastEventTypeByte) w.writeUInt8(eventTypeByte);
507        w.writeUInt8(event.noteNumber);
508        w.writeUInt8(event.velocity);
509        break;
510      case "noteAftertouch":
511        eventTypeByte = 160 | event.channel;
512        if (eventTypeByte !== lastEventTypeByte) w.writeUInt8(eventTypeByte);
513        w.writeUInt8(event.noteNumber);
514        w.writeUInt8(event.amount);
515        break;
516      case "controller":
517        eventTypeByte = 176 | event.channel;
518        if (eventTypeByte !== lastEventTypeByte) w.writeUInt8(eventTypeByte);
519        w.writeUInt8(event.controllerType);
520        w.writeUInt8(event.value);
521        break;
522      case "programChange":
523        eventTypeByte = 192 | event.channel;
524        if (eventTypeByte !== lastEventTypeByte) w.writeUInt8(eventTypeByte);
525        w.writeUInt8(event.programNumber);
526        break;
527      case "channelAftertouch":
528        eventTypeByte = 208 | event.channel;
529        if (eventTypeByte !== lastEventTypeByte) w.writeUInt8(eventTypeByte);
530        w.writeUInt8(event.amount);
531        break;
532      case "pitchBend":
533        eventTypeByte = 224 | event.channel;
534        if (eventTypeByte !== lastEventTypeByte) w.writeUInt8(eventTypeByte);
535        var value14 = 8192 + event.value;
536        var lsb14 = value14 & 127;
537        var msb14 = value14 >> 7 & 127;
538        w.writeUInt8(lsb14);
539        w.writeUInt8(msb14);
540        break;
541      default:
542        throw "Unrecognized event type: " + type;
543    }
544    return eventTypeByte;
545  }
546  function Writer() {
547    this.buffer = [];
548  }
549  Writer.prototype.writeUInt8 = function(v) {
550    this.buffer.push(v & 255);
551  };
552  Writer.prototype.writeInt8 = Writer.prototype.writeUInt8;
553  Writer.prototype.writeUInt16 = function(v) {
554    var b0 = v >> 8 & 255, b1 = v & 255;
555    this.writeUInt8(b0);
556    this.writeUInt8(b1);
557  };
558  Writer.prototype.writeInt16 = Writer.prototype.writeUInt16;
559  Writer.prototype.writeUInt24 = function(v) {
560    var b0 = v >> 16 & 255, b1 = v >> 8 & 255, b2 = v & 255;
561    this.writeUInt8(b0);
562    this.writeUInt8(b1);
563    this.writeUInt8(b2);
564  };
565  Writer.prototype.writeInt24 = Writer.prototype.writeUInt24;
566  Writer.prototype.writeUInt32 = function(v) {
567    var b0 = v >> 24 & 255, b1 = v >> 16 & 255, b2 = v >> 8 & 255, b3 = v & 255;
568    this.writeUInt8(b0);
569    this.writeUInt8(b1);
570    this.writeUInt8(b2);
571    this.writeUInt8(b3);
572  };
573  Writer.prototype.writeInt32 = Writer.prototype.writeUInt32;
574  Writer.prototype.writeBytes = function(arr) {
575    this.buffer = this.buffer.concat(Array.prototype.slice.call(arr, 0));
576  };
577  Writer.prototype.writeString = function(str) {
578    var i, len = str.length, arr = [];
579    for (i = 0; i < len; i++) {
580      arr.push(str.codePointAt(i));
581    }
582    this.writeBytes(arr);
583  };
584  Writer.prototype.writeVarInt = function(v) {
585    if (v < 0) throw "Cannot write negative variable-length integer";
586    if (v <= 127) {
587      this.writeUInt8(v);
588    } else {
589      var i = v;
590      var bytes = [];
591      bytes.push(i & 127);
592      i >>= 7;
593      while (i) {
594        var b = i & 127 | 128;
595        bytes.push(b);
596        i >>= 7;
597      }
598      this.writeBytes(bytes.reverse());
599    }
600  };
601  Writer.prototype.writeChunk = function(id, data) {
602    this.writeString(id);
603    this.writeUInt32(data.length);
604    this.writeBytes(data);
605  };
606  var midiWriter = writeMidi;
607  midiFile.parseMidi = midiParser;
608  midiFile.writeMidi = midiWriter;
609  var Header = {};
610  var BinarySearch = {};
611  Object.defineProperty(BinarySearch, "__esModule", { value: true });
612  BinarySearch.insert = BinarySearch.search = void 0;
613  function search(array, value, prop) {
614    if (prop === void 0) {
615      prop = "ticks";
616    }
617    var beginning = 0;
618    var len = array.length;
619    var end = len;
620    if (len > 0 && array[len - 1][prop] <= value) {
621      return len - 1;
622    }
623    while (beginning < end) {
624      var midPoint = Math.floor(beginning + (end - beginning) / 2);
625      var event_1 = array[midPoint];
626      var nextEvent = array[midPoint + 1];
627      if (event_1[prop] === value) {
628        for (var i = midPoint; i < array.length; i++) {
629          var testEvent = array[i];
630          if (testEvent[prop] === value) {
631            midPoint = i;
632          }
633        }
634        return midPoint;
635      } else if (event_1[prop] < value && nextEvent[prop] > value) {
636        return midPoint;
637      } else if (event_1[prop] > value) {
638        end = midPoint;
639      } else if (event_1[prop] < value) {
640        beginning = midPoint + 1;
641      }
642    }
643    return -1;
644  }
645  BinarySearch.search = search;
646  function insert(array, event, prop) {
647    if (prop === void 0) {
648      prop = "ticks";
649    }
650    if (array.length) {
651      var index = search(array, event[prop], prop);
652      array.splice(index + 1, 0, event);
653    } else {
654      array.push(event);
655    }
656  }
657  BinarySearch.insert = insert;
658  (function(exports$1) {
659    Object.defineProperty(exports$1, "__esModule", { value: true });
660    exports$1.Header = exports$1.keySignatureKeys = void 0;
661    var BinarySearch_12 = BinarySearch;
662    var privatePPQMap = /* @__PURE__ */ new WeakMap();
663    exports$1.keySignatureKeys = [
664      "Cb",
665      "Gb",
666      "Db",
667      "Ab",
668      "Eb",
669      "Bb",
670      "F",
671      "C",
672      "G",
673      "D",
674      "A",
675      "E",
676      "B",
677      "F#",
678      "C#"
679    ];
680    var Header2 = (
681      /** @class */
682      function() {
683        function Header3(midiData) {
684          var _this = this;
685          this.tempos = [];
686          this.timeSignatures = [];
687          this.keySignatures = [];
688          this.meta = [];
689          this.name = "";
690          privatePPQMap.set(this, 480);
691          if (midiData) {
692            privatePPQMap.set(this, midiData.header.ticksPerBeat);
693            midiData.tracks.forEach(function(track) {
694              track.forEach(function(event) {
695                if (event.meta) {
696                  if (event.type === "timeSignature") {
697                    _this.timeSignatures.push({
698                      ticks: event.absoluteTime,
699                      timeSignature: [
700                        event.numerator,
701                        event.denominator
702                      ]
703                    });
704                  } else if (event.type === "setTempo") {
705                    _this.tempos.push({
706                      bpm: 6e7 / event.microsecondsPerBeat,
707                      ticks: event.absoluteTime
708                    });
709                  } else if (event.type === "keySignature") {
710                    _this.keySignatures.push({
711                      key: exports$1.keySignatureKeys[event.key + 7],
712                      scale: event.scale === 0 ? "major" : "minor",
713                      ticks: event.absoluteTime
714                    });
715                  }
716                }
717              });
718            });
719            var firstTrackCurrentTicks_1 = 0;
720            midiData.tracks[0].forEach(function(event) {
721              firstTrackCurrentTicks_1 += event.deltaTime;
722              if (event.meta) {
723                if (event.type === "trackName") {
724                  _this.name = event.text;
725                } else if (event.type === "text" || event.type === "cuePoint" || event.type === "marker" || event.type === "lyrics") {
726                  _this.meta.push({
727                    text: event.text,
728                    ticks: firstTrackCurrentTicks_1,
729                    type: event.type
730                  });
731                }
732              }
733            });
734            this.update();
735          }
736        }
737        Header3.prototype.update = function() {
738          var _this = this;
739          var currentTime = 0;
740          var lastEventBeats = 0;
741          this.tempos.sort(function(a, b) {
742            return a.ticks - b.ticks;
743          });
744          this.tempos.forEach(function(event, index) {
745            var lastBPM = index > 0 ? _this.tempos[index - 1].bpm : _this.tempos[0].bpm;
746            var beats = event.ticks / _this.ppq - lastEventBeats;
747            var elapsedSeconds = 60 / lastBPM * beats;
748            event.time = elapsedSeconds + currentTime;
749            currentTime = event.time;
750            lastEventBeats += beats;
751          });
752          this.timeSignatures.sort(function(a, b) {
753            return a.ticks - b.ticks;
754          });
755          this.timeSignatures.forEach(function(event, index) {
756            var lastEvent = index > 0 ? _this.timeSignatures[index - 1] : _this.timeSignatures[0];
757            var elapsedBeats = (event.ticks - lastEvent.ticks) / _this.ppq;
758            var elapsedMeasures = elapsedBeats / lastEvent.timeSignature[0] / (lastEvent.timeSignature[1] / 4);
759            lastEvent.measures = lastEvent.measures || 0;
760            event.measures = elapsedMeasures + lastEvent.measures;
761          });
762        };
763        Header3.prototype.ticksToSeconds = function(ticks) {
764          var index = (0, BinarySearch_12.search)(this.tempos, ticks);
765          if (index !== -1) {
766            var tempo = this.tempos[index];
767            var tempoTime = tempo.time;
768            var elapsedBeats = (ticks - tempo.ticks) / this.ppq;
769            return tempoTime + 60 / tempo.bpm * elapsedBeats;
770          } else {
771            var beats = ticks / this.ppq;
772            return 60 / 120 * beats;
773          }
774        };
775        Header3.prototype.ticksToMeasures = function(ticks) {
776          var index = (0, BinarySearch_12.search)(this.timeSignatures, ticks);
777          if (index !== -1) {
778            var timeSigEvent = this.timeSignatures[index];
779            var elapsedBeats = (ticks - timeSigEvent.ticks) / this.ppq;
780            return timeSigEvent.measures + elapsedBeats / (timeSigEvent.timeSignature[0] / timeSigEvent.timeSignature[1]) / 4;
781          } else {
782            return ticks / this.ppq / 4;
783          }
784        };
785        Object.defineProperty(Header3.prototype, "ppq", {
786          /**
787           * The number of ticks per quarter note.
788           */
789          get: function() {
790            return privatePPQMap.get(this);
791          },
792          enumerable: false,
793          configurable: true
794        });
795        Header3.prototype.secondsToTicks = function(seconds) {
796          var index = (0, BinarySearch_12.search)(this.tempos, seconds, "time");
797          if (index !== -1) {
798            var tempo = this.tempos[index];
799            var tempoTime = tempo.time;
800            var elapsedTime = seconds - tempoTime;
801            var elapsedBeats = elapsedTime / (60 / tempo.bpm);
802            return Math.round(tempo.ticks + elapsedBeats * this.ppq);
803          } else {
804            var beats = seconds / (60 / 120);
805            return Math.round(beats * this.ppq);
806          }
807        };
808        Header3.prototype.toJSON = function() {
809          return {
810            keySignatures: this.keySignatures,
811            meta: this.meta,
812            name: this.name,
813            ppq: this.ppq,
814            tempos: this.tempos.map(function(t) {
815              return {
816                bpm: t.bpm,
817                ticks: t.ticks
818              };
819            }),
820            timeSignatures: this.timeSignatures
821          };
822        };
823        Header3.prototype.fromJSON = function(json) {
824          this.name = json.name;
825          this.tempos = json.tempos.map(function(t) {
826            return Object.assign({}, t);
827          });
828          this.timeSignatures = json.timeSignatures.map(function(t) {
829            return Object.assign({}, t);
830          });
831          this.keySignatures = json.keySignatures.map(function(t) {
832            return Object.assign({}, t);
833          });
834          this.meta = json.meta.map(function(t) {
835            return Object.assign({}, t);
836          });
837          privatePPQMap.set(this, json.ppq);
838          this.update();
839        };
840        Header3.prototype.setTempo = function(bpm) {
841          this.tempos = [
842            {
843              bpm,
844              ticks: 0
845            }
846          ];
847          this.update();
848        };
849        return Header3;
850      }()
851    );
852    exports$1.Header = Header2;
853  })(Header);
854  var Track$1 = {};
855  var ControlChange = {};
856  (function(exports$1) {
857    Object.defineProperty(exports$1, "__esModule", { value: true });
858    exports$1.ControlChange = exports$1.controlChangeIds = exports$1.controlChangeNames = void 0;
859    exports$1.controlChangeNames = {
860      1: "modulationWheel",
861      2: "breath",
862      4: "footController",
863      5: "portamentoTime",
864      7: "volume",
865      8: "balance",
866      10: "pan",
867      64: "sustain",
868      65: "portamentoTime",
869      66: "sostenuto",
870      67: "softPedal",
871      68: "legatoFootswitch",
872      84: "portamentoControl"
873    };
874    exports$1.controlChangeIds = Object.keys(exports$1.controlChangeNames).reduce(function(obj, key) {
875      obj[exports$1.controlChangeNames[key]] = key;
876      return obj;
877    }, {});
878    var privateHeaderMap2 = /* @__PURE__ */ new WeakMap();
879    var privateCCNumberMap = /* @__PURE__ */ new WeakMap();
880    var ControlChange2 = (
881      /** @class */
882      function() {
883        function ControlChange3(event, header) {
884          privateHeaderMap2.set(this, header);
885          privateCCNumberMap.set(this, event.controllerType);
886          this.ticks = event.absoluteTime;
887          this.value = event.value;
888        }
889        Object.defineProperty(ControlChange3.prototype, "number", {
890          /**
891           * The controller number
892           */
893          get: function() {
894            return privateCCNumberMap.get(this);
895          },
896          enumerable: false,
897          configurable: true
898        });
899        Object.defineProperty(ControlChange3.prototype, "name", {
900          /**
901           * return the common name of the control number if it exists
902           */
903          get: function() {
904            if (exports$1.controlChangeNames[this.number]) {
905              return exports$1.controlChangeNames[this.number];
906            } else {
907              return null;
908            }
909          },
910          enumerable: false,
911          configurable: true
912        });
913        Object.defineProperty(ControlChange3.prototype, "time", {
914          /**
915           * The time of the event in seconds
916           */
917          get: function() {
918            var header = privateHeaderMap2.get(this);
919            return header.ticksToSeconds(this.ticks);
920          },
921          set: function(t) {
922            var header = privateHeaderMap2.get(this);
923            this.ticks = header.secondsToTicks(t);
924          },
925          enumerable: false,
926          configurable: true
927        });
928        ControlChange3.prototype.toJSON = function() {
929          return {
930            number: this.number,
931            ticks: this.ticks,
932            time: this.time,
933            value: this.value
934          };
935        };
936        return ControlChange3;
937      }()
938    );
939    exports$1.ControlChange = ControlChange2;
940  })(ControlChange);
941  var ControlChanges = {};
942  Object.defineProperty(ControlChanges, "__esModule", { value: true });
943  ControlChanges.createControlChanges = void 0;
944  var ControlChange_1$1 = ControlChange;
945  function createControlChanges() {
946    return new Proxy({}, {
947      // tslint:disable-next-line: typedef
948      get: function(target, handler) {
949        if (target[handler]) {
950          return target[handler];
951        } else if (ControlChange_1$1.controlChangeIds.hasOwnProperty(handler)) {
952          return target[ControlChange_1$1.controlChangeIds[handler]];
953        }
954      },
955      // tslint:disable-next-line: typedef
956      set: function(target, handler, value) {
957        if (ControlChange_1$1.controlChangeIds.hasOwnProperty(handler)) {
958          target[ControlChange_1$1.controlChangeIds[handler]] = value;
959        } else {
960          target[handler] = value;
961        }
962        return true;
963      }
964    });
965  }
966  ControlChanges.createControlChanges = createControlChanges;
967  var PitchBend$1 = {};
968  Object.defineProperty(PitchBend$1, "__esModule", { value: true });
969  PitchBend$1.PitchBend = void 0;
970  var privateHeaderMap$2 = /* @__PURE__ */ new WeakMap();
971  var PitchBend = (
972    /** @class */
973    function() {
974      function PitchBend2(event, header) {
975        privateHeaderMap$2.set(this, header);
976        this.ticks = event.absoluteTime;
977        this.value = event.value;
978      }
979      Object.defineProperty(PitchBend2.prototype, "time", {
980        /**
981         * The time of the event in seconds
982         */
983        get: function() {
984          var header = privateHeaderMap$2.get(this);
985          return header.ticksToSeconds(this.ticks);
986        },
987        set: function(t) {
988          var header = privateHeaderMap$2.get(this);
989          this.ticks = header.secondsToTicks(t);
990        },
991        enumerable: false,
992        configurable: true
993      });
994      PitchBend2.prototype.toJSON = function() {
995        return {
996          ticks: this.ticks,
997          time: this.time,
998          value: this.value
999        };
1000      };
1001      return PitchBend2;
1002    }()
1003  );
1004  PitchBend$1.PitchBend = PitchBend;
1005  var Instrument$1 = {};
1006  var InstrumentMaps = {};
1007  Object.defineProperty(InstrumentMaps, "__esModule", { value: true });
1008  InstrumentMaps.DrumKitByPatchID = InstrumentMaps.InstrumentFamilyByID = InstrumentMaps.instrumentByPatchID = void 0;
1009  InstrumentMaps.instrumentByPatchID = [
1010    "acoustic grand piano",
1011    "bright acoustic piano",
1012    "electric grand piano",
1013    "honky-tonk piano",
1014    "electric piano 1",
1015    "electric piano 2",
1016    "harpsichord",
1017    "clavi",
1018    "celesta",
1019    "glockenspiel",
1020    "music box",
1021    "vibraphone",
1022    "marimba",
1023    "xylophone",
1024    "tubular bells",
1025    "dulcimer",
1026    "drawbar organ",
1027    "percussive organ",
1028    "rock organ",
1029    "church organ",
1030    "reed organ",
1031    "accordion",
1032    "harmonica",
1033    "tango accordion",
1034    "acoustic guitar (nylon)",
1035    "acoustic guitar (steel)",
1036    "electric guitar (jazz)",
1037    "electric guitar (clean)",
1038    "electric guitar (muted)",
1039    "overdriven guitar",
1040    "distortion guitar",
1041    "guitar harmonics",
1042    "acoustic bass",
1043    "electric bass (finger)",
1044    "electric bass (pick)",
1045    "fretless bass",
1046    "slap bass 1",
1047    "slap bass 2",
1048    "synth bass 1",
1049    "synth bass 2",
1050    "violin",
1051    "viola",
1052    "cello",
1053    "contrabass",
1054    "tremolo strings",
1055    "pizzicato strings",
1056    "orchestral harp",
1057    "timpani",
1058    "string ensemble 1",
1059    "string ensemble 2",
1060    "synthstrings 1",
1061    "synthstrings 2",
1062    "choir aahs",
1063    "voice oohs",
1064    "synth voice",
1065    "orchestra hit",
1066    "trumpet",
1067    "trombone",
1068    "tuba",
1069    "muted trumpet",
1070    "french horn",
1071    "brass section",
1072    "synthbrass 1",
1073    "synthbrass 2",
1074    "soprano sax",
1075    "alto sax",
1076    "tenor sax",
1077    "baritone sax",
1078    "oboe",
1079    "english horn",
1080    "bassoon",
1081    "clarinet",
1082    "piccolo",
1083    "flute",
1084    "recorder",
1085    "pan flute",
1086    "blown bottle",
1087    "shakuhachi",
1088    "whistle",
1089    "ocarina",
1090    "lead 1 (square)",
1091    "lead 2 (sawtooth)",
1092    "lead 3 (calliope)",
1093    "lead 4 (chiff)",
1094    "lead 5 (charang)",
1095    "lead 6 (voice)",
1096    "lead 7 (fifths)",
1097    "lead 8 (bass + lead)",
1098    "pad 1 (new age)",
1099    "pad 2 (warm)",
1100    "pad 3 (polysynth)",
1101    "pad 4 (choir)",
1102    "pad 5 (bowed)",
1103    "pad 6 (metallic)",
1104    "pad 7 (halo)",
1105    "pad 8 (sweep)",
1106    "fx 1 (rain)",
1107    "fx 2 (soundtrack)",
1108    "fx 3 (crystal)",
1109    "fx 4 (atmosphere)",
1110    "fx 5 (brightness)",
1111    "fx 6 (goblins)",
1112    "fx 7 (echoes)",
1113    "fx 8 (sci-fi)",
1114    "sitar",
1115    "banjo",
1116    "shamisen",
1117    "koto",
1118    "kalimba",
1119    "bag pipe",
1120    "fiddle",
1121    "shanai",
1122    "tinkle bell",
1123    "agogo",
1124    "steel drums",
1125    "woodblock",
1126    "taiko drum",
1127    "melodic tom",
1128    "synth drum",
1129    "reverse cymbal",
1130    "guitar fret noise",
1131    "breath noise",
1132    "seashore",
1133    "bird tweet",
1134    "telephone ring",
1135    "helicopter",
1136    "applause",
1137    "gunshot"
1138  ];
1139  InstrumentMaps.InstrumentFamilyByID = [
1140    "piano",
1141    "chromatic percussion",
1142    "organ",
1143    "guitar",
1144    "bass",
1145    "strings",
1146    "ensemble",
1147    "brass",
1148    "reed",
1149    "pipe",
1150    "synth lead",
1151    "synth pad",
1152    "synth effects",
1153    "world",
1154    "percussive",
1155    "sound effects"
1156  ];
1157  InstrumentMaps.DrumKitByPatchID = {
1158    0: "standard kit",
1159    8: "room kit",
1160    16: "power kit",
1161    24: "electronic kit",
1162    25: "tr-808 kit",
1163    32: "jazz kit",
1164    40: "brush kit",
1165    48: "orchestra kit",
1166    56: "sound fx kit"
1167  };
1168  Object.defineProperty(Instrument$1, "__esModule", { value: true });
1169  Instrument$1.Instrument = void 0;
1170  var InstrumentMaps_1 = InstrumentMaps;
1171  var privateTrackMap = /* @__PURE__ */ new WeakMap();
1172  var Instrument = (
1173    /** @class */
1174    function() {
1175      function Instrument2(trackData, track) {
1176        this.number = 0;
1177        privateTrackMap.set(this, track);
1178        this.number = 0;
1179        if (trackData) {
1180          var programChange = trackData.find(function(e) {
1181            return e.type === "programChange";
1182          });
1183          if (programChange) {
1184            this.number = programChange.programNumber;
1185          }
1186        }
1187      }
1188      Object.defineProperty(Instrument2.prototype, "name", {
1189        /**
1190         * The common name of the instrument.
1191         */
1192        get: function() {
1193          if (this.percussion) {
1194            return InstrumentMaps_1.DrumKitByPatchID[this.number];
1195          } else {
1196            return InstrumentMaps_1.instrumentByPatchID[this.number];
1197          }
1198        },
1199        set: function(n) {
1200          var patchNumber = InstrumentMaps_1.instrumentByPatchID.indexOf(n);
1201          if (patchNumber !== -1) {
1202            this.number = patchNumber;
1203          }
1204        },
1205        enumerable: false,
1206        configurable: true
1207      });
1208      Object.defineProperty(Instrument2.prototype, "family", {
1209        /**
1210         * The instrument family, e.g. "piano".
1211         */
1212        get: function() {
1213          if (this.percussion) {
1214            return "drums";
1215          } else {
1216            return InstrumentMaps_1.InstrumentFamilyByID[Math.floor(this.number / 8)];
1217          }
1218        },
1219        enumerable: false,
1220        configurable: true
1221      });
1222      Object.defineProperty(Instrument2.prototype, "percussion", {
1223        /**
1224         * If the instrument is a percussion instrument.
1225         */
1226        get: function() {
1227          var track = privateTrackMap.get(this);
1228          return track.channel === 9;
1229        },
1230        enumerable: false,
1231        configurable: true
1232      });
1233      Instrument2.prototype.toJSON = function() {
1234        return {
1235          family: this.family,
1236          number: this.number,
1237          name: this.name
1238        };
1239      };
1240      Instrument2.prototype.fromJSON = function(json) {
1241        this.number = json.number;
1242      };
1243      return Instrument2;
1244    }()
1245  );
1246  Instrument$1.Instrument = Instrument;
1247  var Note$1 = {};
1248  Object.defineProperty(Note$1, "__esModule", { value: true });
1249  Note$1.Note = void 0;
1250  function midiToPitch(midi) {
1251    var octave = Math.floor(midi / 12) - 1;
1252    return midiToPitchClass(midi) + octave.toString();
1253  }
1254  function midiToPitchClass(midi) {
1255    var scaleIndexToNote = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
1256    var note = midi % 12;
1257    return scaleIndexToNote[note];
1258  }
1259  function pitchClassToMidi(pitch) {
1260    var scaleIndexToNote = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
1261    return scaleIndexToNote.indexOf(pitch);
1262  }
1263  var pitchToMidi = /* @__PURE__ */ function() {
1264    var regexp = /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i;
1265    var noteToScaleIndex = {
1266      // tslint:disable-next-line: object-literal-sort-keys
1267      cbb: -2,
1268      cb: -1,
1269      c: 0,
1270      "c#": 1,
1271      cx: 2,
1272      dbb: 0,
1273      db: 1,
1274      d: 2,
1275      "d#": 3,
1276      dx: 4,
1277      ebb: 2,
1278      eb: 3,
1279      e: 4,
1280      "e#": 5,
1281      ex: 6,
1282      fbb: 3,
1283      fb: 4,
1284      f: 5,
1285      "f#": 6,
1286      fx: 7,
1287      gbb: 5,
1288      gb: 6,
1289      g: 7,
1290      "g#": 8,
1291      gx: 9,
1292      abb: 7,
1293      ab: 8,
1294      a: 9,
1295      "a#": 10,
1296      ax: 11,
1297      bbb: 9,
1298      bb: 10,
1299      b: 11,
1300      "b#": 12,
1301      bx: 13
1302    };
1303    return function(note) {
1304      var split = regexp.exec(note);
1305      var pitch = split[1];
1306      var octave = split[2];
1307      var index = noteToScaleIndex[pitch.toLowerCase()];
1308      return index + (parseInt(octave, 10) + 1) * 12;
1309    };
1310  }();
1311  var privateHeaderMap$1 = /* @__PURE__ */ new WeakMap();
1312  var Note = (
1313    /** @class */
1314    function() {
1315      function Note2(noteOn, noteOff, header) {
1316        privateHeaderMap$1.set(this, header);
1317        this.midi = noteOn.midi;
1318        this.velocity = noteOn.velocity;
1319        this.noteOffVelocity = noteOff.velocity;
1320        this.ticks = noteOn.ticks;
1321        this.durationTicks = noteOff.ticks - noteOn.ticks;
1322      }
1323      Object.defineProperty(Note2.prototype, "name", {
1324        /**
1325         * The note name and octave in scientific pitch notation, e.g. "C4".
1326         */
1327        get: function() {
1328          return midiToPitch(this.midi);
1329        },
1330        set: function(n) {
1331          this.midi = pitchToMidi(n);
1332        },
1333        enumerable: false,
1334        configurable: true
1335      });
1336      Object.defineProperty(Note2.prototype, "octave", {
1337        /**
1338         * The notes octave number.
1339         */
1340        get: function() {
1341          return Math.floor(this.midi / 12) - 1;
1342        },
1343        set: function(o) {
1344          var diff = o - this.octave;
1345          this.midi += diff * 12;
1346        },
1347        enumerable: false,
1348        configurable: true
1349      });
1350      Object.defineProperty(Note2.prototype, "pitch", {
1351        /**
1352         * The pitch class name. e.g. "A".
1353         */
1354        get: function() {
1355          return midiToPitchClass(this.midi);
1356        },
1357        set: function(p) {
1358          this.midi = 12 * (this.octave + 1) + pitchClassToMidi(p);
1359        },
1360        enumerable: false,
1361        configurable: true
1362      });
1363      Object.defineProperty(Note2.prototype, "duration", {
1364        /**
1365         * The duration of the segment in seconds.
1366         */
1367        get: function() {
1368          var header = privateHeaderMap$1.get(this);
1369          return header.ticksToSeconds(this.ticks + this.durationTicks) - header.ticksToSeconds(this.ticks);
1370        },
1371        set: function(d) {
1372          var header = privateHeaderMap$1.get(this);
1373          var noteEndTicks = header.secondsToTicks(this.time + d);
1374          this.durationTicks = noteEndTicks - this.ticks;
1375        },
1376        enumerable: false,
1377        configurable: true
1378      });
1379      Object.defineProperty(Note2.prototype, "time", {
1380        /**
1381         * The time of the event in seconds.
1382         */
1383        get: function() {
1384          var header = privateHeaderMap$1.get(this);
1385          return header.ticksToSeconds(this.ticks);
1386        },
1387        set: function(t) {
1388          var header = privateHeaderMap$1.get(this);
1389          this.ticks = header.secondsToTicks(t);
1390        },
1391        enumerable: false,
1392        configurable: true
1393      });
1394      Object.defineProperty(Note2.prototype, "bars", {
1395        /**
1396         * The number of measures (and partial measures) to this beat.
1397         * Takes into account time signature changes.
1398         * @readonly
1399         */
1400        get: function() {
1401          var header = privateHeaderMap$1.get(this);
1402          return header.ticksToMeasures(this.ticks);
1403        },
1404        enumerable: false,
1405        configurable: true
1406      });
1407      Note2.prototype.toJSON = function() {
1408        return {
1409          duration: this.duration,
1410          durationTicks: this.durationTicks,
1411          midi: this.midi,
1412          name: this.name,
1413          ticks: this.ticks,
1414          time: this.time,
1415          velocity: this.velocity
1416        };
1417      };
1418      return Note2;
1419    }()
1420  );
1421  Note$1.Note = Note;
1422  Object.defineProperty(Track$1, "__esModule", { value: true });
1423  Track$1.Track = void 0;
1424  var BinarySearch_1 = BinarySearch;
1425  var ControlChange_1 = ControlChange;
1426  var ControlChanges_1 = ControlChanges;
1427  var PitchBend_1 = PitchBend$1;
1428  var Instrument_1 = Instrument$1;
1429  var Note_1 = Note$1;
1430  var privateHeaderMap = /* @__PURE__ */ new WeakMap();
1431  var Track = (
1432    /** @class */
1433    function() {
1434      function Track2(trackData, header) {
1435        var _this = this;
1436        this.name = "";
1437        this.notes = [];
1438        this.controlChanges = (0, ControlChanges_1.createControlChanges)();
1439        this.pitchBends = [];
1440        privateHeaderMap.set(this, header);
1441        if (trackData) {
1442          var nameEvent = trackData.find(function(e) {
1443            return e.type === "trackName";
1444          });
1445          this.name = nameEvent ? nameEvent.text : "";
1446        }
1447        this.instrument = new Instrument_1.Instrument(trackData, this);
1448        this.channel = 0;
1449        if (trackData) {
1450          var noteOns = trackData.filter(function(event) {
1451            return event.type === "noteOn";
1452          });
1453          var noteOffs = trackData.filter(function(event) {
1454            return event.type === "noteOff";
1455          });
1456          var _loop_1 = function() {
1457            var currentNote = noteOns.shift();
1458            this_1.channel = currentNote.channel;
1459            var offIndex = noteOffs.findIndex(function(note) {
1460              return note.noteNumber === currentNote.noteNumber && note.absoluteTime >= currentNote.absoluteTime;
1461            });
1462            if (offIndex !== -1) {
1463              var noteOff = noteOffs.splice(offIndex, 1)[0];
1464              this_1.addNote({
1465                durationTicks: noteOff.absoluteTime - currentNote.absoluteTime,
1466                midi: currentNote.noteNumber,
1467                noteOffVelocity: noteOff.velocity / 127,
1468                ticks: currentNote.absoluteTime,
1469                velocity: currentNote.velocity / 127
1470              });
1471            }
1472          };
1473          var this_1 = this;
1474          while (noteOns.length) {
1475            _loop_1();
1476          }
1477          var controlChanges = trackData.filter(function(event) {
1478            return event.type === "controller";
1479          });
1480          controlChanges.forEach(function(event) {
1481            _this.addCC({
1482              number: event.controllerType,
1483              ticks: event.absoluteTime,
1484              value: event.value / 127
1485            });
1486          });
1487          var pitchBends = trackData.filter(function(event) {
1488            return event.type === "pitchBend";
1489          });
1490          pitchBends.forEach(function(event) {
1491            _this.addPitchBend({
1492              ticks: event.absoluteTime,
1493              // Scale the value between -2^13 to 2^13 to -2 to 2.
1494              value: event.value / Math.pow(2, 13)
1495            });
1496          });
1497          var endOfTrackEvent = trackData.find(function(event) {
1498            return event.type === "endOfTrack";
1499          });
1500          this.endOfTrackTicks = endOfTrackEvent !== void 0 ? endOfTrackEvent.absoluteTime : void 0;
1501        }
1502      }
1503      Track2.prototype.addNote = function(props) {
1504        var header = privateHeaderMap.get(this);
1505        var note = new Note_1.Note({
1506          midi: 0,
1507          ticks: 0,
1508          velocity: 1
1509        }, {
1510          ticks: 0,
1511          velocity: 0
1512        }, header);
1513        Object.assign(note, props);
1514        (0, BinarySearch_1.insert)(this.notes, note, "ticks");
1515        return this;
1516      };
1517      Track2.prototype.addCC = function(props) {
1518        var header = privateHeaderMap.get(this);
1519        var cc = new ControlChange_1.ControlChange({
1520          controllerType: props.number
1521        }, header);
1522        delete props.number;
1523        Object.assign(cc, props);
1524        if (!Array.isArray(this.controlChanges[cc.number])) {
1525          this.controlChanges[cc.number] = [];
1526        }
1527        (0, BinarySearch_1.insert)(this.controlChanges[cc.number], cc, "ticks");
1528        return this;
1529      };
1530      Track2.prototype.addPitchBend = function(props) {
1531        var header = privateHeaderMap.get(this);
1532        var pb = new PitchBend_1.PitchBend({}, header);
1533        Object.assign(pb, props);
1534        (0, BinarySearch_1.insert)(this.pitchBends, pb, "ticks");
1535        return this;
1536      };
1537      Object.defineProperty(Track2.prototype, "duration", {
1538        /**
1539         * The end time of the last event in the track.
1540         */
1541        get: function() {
1542          if (!this.notes.length) {
1543            return 0;
1544          }
1545          var maxDuration = this.notes[this.notes.length - 1].time + this.notes[this.notes.length - 1].duration;
1546          for (var i = 0; i < this.notes.length - 1; i++) {
1547            var duration = this.notes[i].time + this.notes[i].duration;
1548            if (maxDuration < duration) {
1549              maxDuration = duration;
1550            }
1551          }
1552          return maxDuration;
1553        },
1554        enumerable: false,
1555        configurable: true
1556      });
1557      Object.defineProperty(Track2.prototype, "durationTicks", {
1558        /**
1559         * The end time of the last event in the track in ticks.
1560         */
1561        get: function() {
1562          if (!this.notes.length) {
1563            return 0;
1564          }
1565          var maxDuration = this.notes[this.notes.length - 1].ticks + this.notes[this.notes.length - 1].durationTicks;
1566          for (var i = 0; i < this.notes.length - 1; i++) {
1567            var duration = this.notes[i].ticks + this.notes[i].durationTicks;
1568            if (maxDuration < duration) {
1569              maxDuration = duration;
1570            }
1571          }
1572          return maxDuration;
1573        },
1574        enumerable: false,
1575        configurable: true
1576      });
1577      Track2.prototype.fromJSON = function(json) {
1578        var _this = this;
1579        this.name = json.name;
1580        this.channel = json.channel;
1581        this.instrument = new Instrument_1.Instrument(void 0, this);
1582        this.instrument.fromJSON(json.instrument);
1583        if (json.endOfTrackTicks !== void 0) {
1584          this.endOfTrackTicks = json.endOfTrackTicks;
1585        }
1586        for (var number in json.controlChanges) {
1587          if (json.controlChanges[number]) {
1588            json.controlChanges[number].forEach(function(cc) {
1589              _this.addCC({
1590                number: cc.number,
1591                ticks: cc.ticks,
1592                value: cc.value
1593              });
1594            });
1595          }
1596        }
1597        json.notes.forEach(function(n) {
1598          _this.addNote({
1599            durationTicks: n.durationTicks,
1600            midi: n.midi,
1601            ticks: n.ticks,
1602            velocity: n.velocity
1603          });
1604        });
1605      };
1606      Track2.prototype.toJSON = function() {
1607        var controlChanges = {};
1608        for (var i = 0; i < 127; i++) {
1609          if (this.controlChanges.hasOwnProperty(i)) {
1610            controlChanges[i] = this.controlChanges[i].map(function(c) {
1611              return c.toJSON();
1612            });
1613          }
1614        }
1615        var json = {
1616          channel: this.channel,
1617          controlChanges,
1618          pitchBends: this.pitchBends.map(function(pb) {
1619            return pb.toJSON();
1620          }),
1621          instrument: this.instrument.toJSON(),
1622          name: this.name,
1623          notes: this.notes.map(function(n) {
1624            return n.toJSON();
1625          })
1626        };
1627        if (this.endOfTrackTicks !== void 0) {
1628          json.endOfTrackTicks = this.endOfTrackTicks;
1629        }
1630        return json;
1631      };
1632      return Track2;
1633    }()
1634  );
1635  Track$1.Track = Track;
1636  var Encode = {};
1637  function flatten(array) {
1638    var result = [];
1639    $flatten(array, result);
1640    return result;
1641  }
1642  function $flatten(array, result) {
1643    for (var i = 0; i < array.length; i++) {
1644      var value = array[i];
1645      if (Array.isArray(value)) {
1646        $flatten(value, result);
1647      } else {
1648        result.push(value);
1649      }
1650    }
1651  }
1652  var dist_es2015 = /* @__PURE__ */ Object.freeze({
1653    __proto__: null,
1654    flatten
1655  });
1656  var require$$2 = /* @__PURE__ */ getAugmentedNamespace(dist_es2015);
1657  var __spreadArray = commonjsGlobal && commonjsGlobal.__spreadArray || function(to, from, pack) {
1658    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
1659      if (ar || !(i in from)) {
1660        if (!ar) ar = Array.prototype.slice.call(from, 0, i);
1661        ar[i] = from[i];
1662      }
1663    }
1664    return to.concat(ar || Array.prototype.slice.call(from));
1665  };
1666  Object.defineProperty(Encode, "__esModule", { value: true });
1667  Encode.encode = void 0;
1668  var midi_file_1 = midiFile;
1669  var Header_1 = Header;
1670  var array_flatten_1 = require$$2;
1671  function encodeNote(note, channel) {
1672    return [
1673      {
1674        absoluteTime: note.ticks,
1675        channel,
1676        deltaTime: 0,
1677        noteNumber: note.midi,
1678        type: "noteOn",
1679        velocity: Math.floor(note.velocity * 127)
1680      },
1681      {
1682        absoluteTime: note.ticks + note.durationTicks,
1683        channel,
1684        deltaTime: 0,
1685        noteNumber: note.midi,
1686        type: "noteOff",
1687        velocity: Math.floor(note.noteOffVelocity * 127)
1688      }
1689    ];
1690  }
1691  function encodeNotes(track) {
1692    return (0, array_flatten_1.flatten)(track.notes.map(function(note) {
1693      return encodeNote(note, track.channel);
1694    }));
1695  }
1696  function encodeControlChange(cc, channel) {
1697    return {
1698      absoluteTime: cc.ticks,
1699      channel,
1700      controllerType: cc.number,
1701      deltaTime: 0,
1702      type: "controller",
1703      value: Math.floor(cc.value * 127)
1704    };
1705  }
1706  function encodeControlChanges(track) {
1707    var controlChanges = [];
1708    for (var i = 0; i < 127; i++) {
1709      if (track.controlChanges.hasOwnProperty(i)) {
1710        track.controlChanges[i].forEach(function(cc) {
1711          controlChanges.push(encodeControlChange(cc, track.channel));
1712        });
1713      }
1714    }
1715    return controlChanges;
1716  }
1717  function encodePitchBend(pb, channel) {
1718    return {
1719      absoluteTime: pb.ticks,
1720      channel,
1721      deltaTime: 0,
1722      type: "pitchBend",
1723      value: pb.value
1724    };
1725  }
1726  function encodePitchBends(track) {
1727    var pitchBends = [];
1728    track.pitchBends.forEach(function(pb) {
1729      pitchBends.push(encodePitchBend(pb, track.channel));
1730    });
1731    return pitchBends;
1732  }
1733  function encodeInstrument(track) {
1734    return {
1735      absoluteTime: 0,
1736      channel: track.channel,
1737      deltaTime: 0,
1738      programNumber: track.instrument.number,
1739      type: "programChange"
1740    };
1741  }
1742  function encodeTrackName(name) {
1743    return {
1744      absoluteTime: 0,
1745      deltaTime: 0,
1746      meta: true,
1747      text: name,
1748      type: "trackName"
1749    };
1750  }
1751  function encodeTempo(tempo) {
1752    return {
1753      absoluteTime: tempo.ticks,
1754      deltaTime: 0,
1755      meta: true,
1756      microsecondsPerBeat: Math.floor(6e7 / tempo.bpm),
1757      type: "setTempo"
1758    };
1759  }
1760  function encodeTimeSignature(timeSig) {
1761    return {
1762      absoluteTime: timeSig.ticks,
1763      deltaTime: 0,
1764      denominator: timeSig.timeSignature[1],
1765      meta: true,
1766      metronome: 24,
1767      numerator: timeSig.timeSignature[0],
1768      thirtyseconds: 8,
1769      type: "timeSignature"
1770    };
1771  }
1772  function encodeKeySignature(keySig) {
1773    var keyIndex = Header_1.keySignatureKeys.indexOf(keySig.key);
1774    return {
1775      absoluteTime: keySig.ticks,
1776      deltaTime: 0,
1777      key: keyIndex + 7,
1778      meta: true,
1779      scale: keySig.scale === "major" ? 0 : 1,
1780      type: "keySignature"
1781    };
1782  }
1783  function encodeText(textEvent) {
1784    return {
1785      absoluteTime: textEvent.ticks,
1786      deltaTime: 0,
1787      meta: true,
1788      text: textEvent.text,
1789      type: textEvent.type
1790    };
1791  }
1792  function encode(midi) {
1793    var midiData = {
1794      header: {
1795        format: 1,
1796        numTracks: midi.tracks.length + 1,
1797        ticksPerBeat: midi.header.ppq
1798      },
1799      tracks: __spreadArray([
1800        __spreadArray(__spreadArray(__spreadArray(__spreadArray([
1801          // The name data.
1802          {
1803            absoluteTime: 0,
1804            deltaTime: 0,
1805            meta: true,
1806            text: midi.header.name,
1807            type: "trackName"
1808          }
1809        ], midi.header.keySignatures.map(function(keySig) {
1810          return encodeKeySignature(keySig);
1811        }), true), midi.header.meta.map(function(e) {
1812          return encodeText(e);
1813        }), true), midi.header.tempos.map(function(tempo) {
1814          return encodeTempo(tempo);
1815        }), true), midi.header.timeSignatures.map(function(timeSig) {
1816          return encodeTimeSignature(timeSig);
1817        }), true)
1818      ], midi.tracks.map(function(track) {
1819        return __spreadArray(__spreadArray(__spreadArray([
1820          // Add the name
1821          encodeTrackName(track.name),
1822          // the instrument
1823          encodeInstrument(track)
1824        ], encodeNotes(track), true), encodeControlChanges(track), true), encodePitchBends(track), true);
1825      }), true)
1826    };
1827    midiData.tracks = midiData.tracks.map(function(track) {
1828      track = track.sort(function(a, b) {
1829        return a.absoluteTime - b.absoluteTime;
1830      });
1831      var lastTime = 0;
1832      track.forEach(function(note) {
1833        note.deltaTime = note.absoluteTime - lastTime;
1834        lastTime = note.absoluteTime;
1835        delete note.absoluteTime;
1836      });
1837      track.push({
1838        deltaTime: 0,
1839        meta: true,
1840        type: "endOfTrack"
1841      });
1842      return track;
1843    });
1844    return new Uint8Array((0, midi_file_1.writeMidi)(midiData));
1845  }
1846  Encode.encode = encode;
1847  (function(exports$1) {
1848    var __awaiter = commonjsGlobal && commonjsGlobal.__awaiter || function(thisArg, _arguments, P, generator) {
1849      function adopt(value) {
1850        return value instanceof P ? value : new P(function(resolve) {
1851          resolve(value);
1852        });
1853      }
1854      return new (P || (P = Promise))(function(resolve, reject) {
1855        function fulfilled(value) {
1856          try {
1857            step(generator.next(value));
1858          } catch (e) {
1859            reject(e);
1860          }
1861        }
1862        function rejected(value) {
1863          try {
1864            step(generator["throw"](value));
1865          } catch (e) {
1866            reject(e);
1867          }
1868        }
1869        function step(result) {
1870          result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
1871        }
1872        step((generator = generator.apply(thisArg, _arguments || [])).next());
1873      });
1874    };
1875    var __generator = commonjsGlobal && commonjsGlobal.__generator || function(thisArg, body) {
1876      var _ = { label: 0, sent: function() {
1877        if (t[0] & 1) throw t[1];
1878        return t[1];
1879      }, trys: [], ops: [] }, f, y, t, g;
1880      return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
1881        return this;
1882      }), g;
1883      function verb(n) {
1884        return function(v) {
1885          return step([n, v]);
1886        };
1887      }
1888      function step(op) {
1889        if (f) throw new TypeError("Generator is already executing.");
1890        while (_) try {
vendor: 6,106 bytes, lines 1891-2073
1891          if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
1892          if (y = 0, t) op = [op[0] & 2, t.value];
1893          switch (op[0]) {
1894            case 0:
1895            case 1:
1896              t = op;
1897              break;
1898            case 4:
1899              _.label++;
1900              return { value: op[1], done: false };
1901            case 5:
1902              _.label++;
1903              y = op[1];
1904              op = [0];
1905              continue;
1906            case 7:
1907              op = _.ops.pop();
1908              _.trys.pop();
1909              continue;
1910            default:
1911              if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
1912                _ = 0;
1913                continue;
1914              }
1915              if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
1916                _.label = op[1];
1917                break;
1918              }
1919              if (op[0] === 6 && _.label < t[1]) {
1920                _.label = t[1];
1921                t = op;
1922                break;
1923              }
1924              if (t && _.label < t[2]) {
1925                _.label = t[2];
1926                _.ops.push(op);
1927                break;
1928              }
1929              if (t[2]) _.ops.pop();
1930              _.trys.pop();
1931              continue;
1932          }
1933          op = body.call(thisArg, _);
1934        } catch (e) {
1935          op = [6, e];
1936          y = 0;
1937        } finally {
1938          f = t = 0;
1939        }
1940        if (op[0] & 5) throw op[1];
1941        return { value: op[0] ? op[1] : void 0, done: true };
1942      }
1943    };
1944    Object.defineProperty(exports$1, "__esModule", { value: true });
1945    exports$1.Header = exports$1.Track = exports$1.Midi = void 0;
1946    var midi_file_12 = midiFile;
1947    var Header_12 = Header;
1948    var Track_1 = Track$1;
1949    var Encode_1 = Encode;
1950    var Midi2 = (
1951      /** @class */
1952      function() {
1953        function Midi3(midiArray) {
1954          var _this = this;
1955          var midiData = null;
1956          if (midiArray) {
1957            var midiArrayLike = midiArray instanceof ArrayBuffer ? new Uint8Array(midiArray) : midiArray;
1958            midiData = (0, midi_file_12.parseMidi)(midiArrayLike);
1959            midiData.tracks.forEach(function(track) {
1960              var currentTicks = 0;
1961              track.forEach(function(event) {
1962                currentTicks += event.deltaTime;
1963                event.absoluteTime = currentTicks;
1964              });
1965            });
1966            midiData.tracks = splitTracks(midiData.tracks);
1967          }
1968          this.header = new Header_12.Header(midiData);
1969          this.tracks = [];
1970          if (midiArray) {
1971            this.tracks = midiData.tracks.map(function(trackData) {
1972              return new Track_1.Track(trackData, _this.header);
1973            });
1974            if (midiData.header.format === 1 && this.tracks[0].duration === 0) {
1975              this.tracks.shift();
1976            }
1977          }
1978        }
1979        Midi3.fromUrl = function(url) {
1980          return __awaiter(this, void 0, void 0, function() {
1981            var response, arrayBuffer;
1982            return __generator(this, function(_a) {
1983              switch (_a.label) {
1984                case 0:
1985                  return [4, fetch(url)];
1986                case 1:
1987                  response = _a.sent();
1988                  if (!response.ok) return [3, 3];
1989                  return [4, response.arrayBuffer()];
1990                case 2:
1991                  arrayBuffer = _a.sent();
1992                  return [2, new Midi3(arrayBuffer)];
1993                case 3:
1994                  throw new Error("Could not load '".concat(url, "'"));
1995              }
1996            });
1997          });
1998        };
1999        Object.defineProperty(Midi3.prototype, "name", {
2000          /**
2001           * The name of the midi file, taken from the first track.
2002           */
2003          get: function() {
2004            return this.header.name;
2005          },
2006          set: function(n) {
2007            this.header.name = n;
2008          },
2009          enumerable: false,
2010          configurable: true
2011        });
2012        Object.defineProperty(Midi3.prototype, "duration", {
2013          /**
2014           * The total length of the file in seconds.
2015           */
2016          get: function() {
2017            var durations = this.tracks.map(function(t) {
2018              return t.duration;
2019            });
2020            return Math.max.apply(Math, durations);
2021          },
2022          enumerable: false,
2023          configurable: true
2024        });
2025        Object.defineProperty(Midi3.prototype, "durationTicks", {
2026          /**
2027           * The total length of the file in ticks.
2028           */
2029          get: function() {
2030            var durationTicks = this.tracks.map(function(t) {
2031              return t.durationTicks;
2032            });
2033            return Math.max.apply(Math, durationTicks);
2034          },
2035          enumerable: false,
2036          configurable: true
2037        });
2038        Midi3.prototype.addTrack = function() {
2039          var track = new Track_1.Track(void 0, this.header);
2040          this.tracks.push(track);
2041          return track;
2042        };
2043        Midi3.prototype.toArray = function() {
2044          return (0, Encode_1.encode)(this);
2045        };
2046        Midi3.prototype.toJSON = function() {
2047          return {
2048            header: this.header.toJSON(),
2049            tracks: this.tracks.map(function(track) {
2050              return track.toJSON();
2051            })
2052          };
2053        };
2054        Midi3.prototype.fromJSON = function(json) {
2055          var _this = this;
2056          this.header = new Header_12.Header();
2057          this.header.fromJSON(json.header);
2058          this.tracks = json.tracks.map(function(trackJSON) {
2059            var track = new Track_1.Track(void 0, _this.header);
2060            track.fromJSON(trackJSON);
2061            return track;
2062          });
2063        };
2064        Midi3.prototype.clone = function() {
2065          var midi = new Midi3();
2066          midi.fromJSON(this.toJSON());
2067          return midi;
2068        };
2069        return Midi3;
2070      }()
2071    );
2072    exports$1.Midi = Midi2;
2073    var Track_2 = Track$1;
2074    Object.defineProperty(exports$1, "Track", { enumerable: true, get: function() {
2075      return Track_2.Track;
2076    } });
2077    var Header_2 = Header;
2078    Object.defineProperty(exports$1, "Header", { enumerable: true, get: function() {
2079      return Header_2.Header;
2080    } });
2081    function splitTracks(tracks) {
2082      var newTracks = [];
2083      for (var i = 0; i < tracks.length; i++) {
2084        var defaultTrack = newTracks.length;
2085        var trackMap = /* @__PURE__ */ new Map();
2086        var currentProgram = Array(16).fill(0);
2087        for (var _i = 0, _a = tracks[i]; _i < _a.length; _i++) {
2088          var event_1 = _a[_i];
2089          var targetTrack = defaultTrack;
2090          var channel = event_1.channel;
2091          if (channel !== void 0) {
2092            if (event_1.type === "programChange") {
2093              currentProgram[channel] = event_1.programNumber;
2094            }
2095            var program = currentProgram[channel];
2096            var trackKey = "".concat(program, " ").concat(channel);
2097            if (trackMap.has(trackKey)) {
2098              targetTrack = trackMap.get(trackKey);
2099            } else {
2100              targetTrack = defaultTrack + trackMap.size;
2101              trackMap.set(trackKey, targetTrack);
2102            }
2103          }
2104          if (!newTracks[targetTrack]) {
2105            newTracks.push([]);
2106          }
2107          newTracks[targetTrack].push(event_1);
2108        }
2109      }
2110      return newTracks;
2111    }
2112  })(Midi);
2113  self.onmessage = async (e) => {
2114    try {
2115      const { trackId, midiBuffer } = e.data;
2116      const parsedMidi = new Midi.Midi(midiBuffer);
2117      const duration = parsedMidi.duration;
2118      const instruments = [];
2119      parsedMidi.tracks.forEach((track, i) => {
2120        instruments.push({
2121          trackId: i,
2122          name: track.name || track.instrument.name || `Track ${i + 1}`,
2123          family: track.instrument.family,
2124          program: track.instrument.number !== void 0 ? track.instrument.number : 0,
2125          midiChannel: track.notes.length === 0 ? -1 : track.channel !== void 0 ? track.channel : 0,
2126          notesCount: track.notes.length
2127        });
2128      });
2129      const pianoRollData = [];
2130      let musicalTrackIdx = 0;
2131      parsedMidi.tracks.forEach((track, i) => {
2132        if (track.notes.length > 0) {
2133          track.notes.forEach((n) => {
2134            pianoRollData.push({
2135              t: parseFloat(n.time.toFixed(3)),
2136              n: n.midi,
2137              d: parseFloat(n.duration.toFixed(3)),
2138              v: Math.round(n.velocity * 127),
2139              i: track.name || track.instrument.name || `Track ${i + 1}`,
2140              trackIdx: musicalTrackIdx,
2141              p: track.instrument.number !== void 0 ? track.instrument.number : 0,
2142              isDrum: track.instrument.family === "drums"
2143            });
2144          });
2145          musicalTrackIdx++;
2146        }
2147      });
2148      const timeSignatures = parsedMidi.header.timeSignatures;
2149      const tempos = parsedMidi.header.tempos;
2150      const measureMap = [];
2151      let currentTick = 0;
2152      let currentTime = 0;
2153      if (timeSignatures && timeSignatures.length > 0) {
2154        measureMap.push({ time: 0, timeSignature: timeSignatures[0].timeSignature });
2155      }
2156      let melodyTrackId = -1;
2157      let bassTrackId = -1;
2158      let highestAvgPitch = -1;
2159      let lowestAvgPitch = 999;
2160      parsedMidi.tracks.forEach((track, i) => {
2161        if (track.notes.length === 0 || track.instrument.family === "drums") return;
2162        let sumPitch = 0;
2163        track.notes.forEach((n) => sumPitch += n.midi);
2164        const avgPitch = sumPitch / track.notes.length;
2165        if (avgPitch > highestAvgPitch) {
2166          highestAvgPitch = avgPitch;
2167          melodyTrackId = i;
2168        }
2169        if (avgPitch < lowestAvgPitch) {
2170          lowestAvgPitch = avgPitch;
2171          bassTrackId = i;
2172        }
2173      });
2174      const melodyDetection = { melodyTrackId, bassTrackId };
2175      let intervals = [];
2176      let parsons = "";
2177      if (melodyTrackId !== -1) {
2178        const melodyNotes = parsedMidi.tracks[melodyTrackId].notes.sort((a, b) => a.time - b.time);
2179        if (melodyNotes.length > 1) {
2180          parsons = "*";
2181          for (let i = 1; i < Math.min(melodyNotes.length, 100); i++) {
2182            const prev = melodyNotes[i - 1].midi;
2183            const curr = melodyNotes[i].midi;
2184            const diff = curr - prev;
2185            intervals.push(diff);
2186            if (diff > 0) parsons += "U";
2187            else if (diff < 0) parsons += "D";
2188            else parsons += "R";
2189          }
2190        }
2191      }
2192      let totalNotes = 0;
2193      let maxNotesPerSec = 0;
2194      parsedMidi.tracks.forEach((t) => totalNotes += t.notes.length);
2195      const notesPerSec = duration > 0 ? totalNotes / duration : 0;
2196      let difficulty = "Beginner";
2197      if (notesPerSec > 15) difficulty = "Virtuoso";
2198      else if (notesPerSec > 8) difficulty = "Advanced";
2199      else if (notesPerSec > 4) difficulty = "Intermediate";
2200      const majorProfile = [6.35, 2.23, 3.48, 2.33, 4.38, 4.09, 2.52, 5.19, 2.39, 3.66, 2.29, 2.88];
2201      const minorProfile = [6.33, 2.68, 3.52, 5.38, 2.6, 3.53, 2.54, 4.75, 3.98, 2.69, 3.34, 3.17];
2202      const pitchClassDuration = new Array(12).fill(0);
2203      parsedMidi.tracks.forEach((track) => {
2204        if (track.instrument.family === "drums") return;
2205        track.notes.forEach((n) => {
2206          pitchClassDuration[n.midi % 12] += n.duration;
2207        });
2208      });
2209      let bestKey = "C Major";
2210      let maxCorr = -Infinity;
2211      const keys = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
2212      for (let i = 0; i < 12; i++) {
2213        let corrMaj = 0;
2214        let corrMin = 0;
2215        for (let j = 0; j < 12; j++) {
2216          corrMaj += pitchClassDuration[(i + j) % 12] * majorProfile[j];
2217          corrMin += pitchClassDuration[(i + j) % 12] * minorProfile[j];
2218        }
2219        if (corrMaj > maxCorr) {
2220          maxCorr = corrMaj;
2221          bestKey = keys[i] + " Major";
2222        }
2223        if (corrMin > maxCorr) {
2224          maxCorr = corrMin;
2225          bestKey = keys[i] + " Minor";
2226        }
2227      }
2228      let lyrics = [];
2229      if (parsedMidi.header.lyrics) {
2230        lyrics = parsedMidi.header.lyrics.map((l) => ({ time: l.time, text: l.text }));
2231      }
2232      self.postMessage({
2233        trackId,
2234        status: "success",
2235        data: {
2236          instruments,
2237          duration,
2238          pianoRollData,
2239          measureMap,
2240          intervals,
2241          parsons,
2242          melodyDetection,
2243          bassDetection: { bassTrackId },
2244          difficulty,
2245          rhythmFingerprint: null,
2246          // Placeholder for rhythm fingerprint
2247          keySignature: bestKey,
2248          lyrics
2249        }
2250      });
2251    } catch (error) {
2252      self.postMessage({
2253        status: "error",
2254        error: error.message
2255      });
2256    }
2257  };
2258})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.