midi-audio-player 1.1.2 → 2.0.0

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.
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../node_modules/midi-player-js/build/index.browser.js", "../src/webaudiofontplayer.js", "../src/presets/defaultpreset.json", "../src/midiaudioplayer.js", "../index.js"],
4
- "sourcesContent": ["function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\n\nfunction _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n Object.defineProperty(Constructor, \"prototype\", {\n writable: false\n });\n return Constructor;\n}\n\n/**\n * Constants used in player.\n */\nvar Constants = {\n VERSION: '2.0.17',\n NOTES: [],\n HEADER_CHUNK_LENGTH: 14,\n CIRCLE_OF_FOURTHS: ['C', 'F', 'Bb', 'Eb', 'Ab', 'Db', 'Gb', 'Cb', 'Fb', 'Bbb', 'Ebb', 'Abb'],\n CIRCLE_OF_FIFTHS: ['C', 'G', 'D', 'A', 'E', 'B', 'F#', 'C#', 'G#', 'D#', 'A#', 'E#']\n}; // Builds notes object for reference against binary values.\n\nvar allNotes = [['C'], ['C#', 'Db'], ['D'], ['D#', 'Eb'], ['E'], ['F'], ['F#', 'Gb'], ['G'], ['G#', 'Ab'], ['A'], ['A#', 'Bb'], ['B']];\nvar counter = 0; // All available octaves.\n\nvar _loop = function _loop(i) {\n allNotes.forEach(function (noteGroup) {\n noteGroup.forEach(function (note) {\n return Constants.NOTES[counter] = note + i;\n });\n counter++;\n });\n};\n\nfor (var i = -1; i <= 9; i++) {\n _loop(i);\n}\n\n/**\n * Contains misc static utility methods.\n */\nvar Utils = /*#__PURE__*/function () {\n function Utils() {\n _classCallCheck(this, Utils);\n }\n\n _createClass(Utils, null, [{\n key: \"byteToHex\",\n value:\n /**\n * Converts a single byte to a hex string.\n * @param {number} byte\n * @return {string}\n */\n function byteToHex(_byte) {\n // Ensure hex string always has two chars\n return ('0' + _byte.toString(16)).slice(-2);\n }\n /**\n * Converts an array of bytes to a hex string.\n * @param {array} byteArray\n * @return {string}\n */\n\n }, {\n key: \"bytesToHex\",\n value: function bytesToHex(byteArray) {\n var hex = [];\n byteArray.forEach(function (_byte2) {\n return hex.push(Utils.byteToHex(_byte2));\n });\n return hex.join('');\n }\n /**\n * Converts a hex string to a number.\n * @param {string} hexString\n * @return {number}\n */\n\n }, {\n key: \"hexToNumber\",\n value: function hexToNumber(hexString) {\n return parseInt(hexString, 16);\n }\n /**\n * Converts an array of bytes to a number.\n * @param {array} byteArray\n * @return {number}\n */\n\n }, {\n key: \"bytesToNumber\",\n value: function bytesToNumber(byteArray) {\n return Utils.hexToNumber(Utils.bytesToHex(byteArray));\n }\n /**\n * Converts an array of bytes to letters.\n * @param {array} byteArray\n * @return {string}\n */\n\n }, {\n key: \"bytesToLetters\",\n value: function bytesToLetters(byteArray) {\n var letters = [];\n byteArray.forEach(function (_byte3) {\n return letters.push(String.fromCharCode(_byte3));\n });\n return letters.join('');\n }\n /**\n * Converts a decimal to it's binary representation.\n * @param {number} dec\n * @return {string}\n */\n\n }, {\n key: \"decToBinary\",\n value: function decToBinary(dec) {\n return (dec >>> 0).toString(2);\n }\n /**\n * Determines the length in bytes of a variable length quaantity. The first byte in given range is assumed to be beginning of var length quantity.\n * @param {array} byteArray\n * @return {number}\n */\n\n }, {\n key: \"getVarIntLength\",\n value: function getVarIntLength(byteArray) {\n // Get byte count of delta VLV\n // http://www.ccarh.org/courses/253/handout/vlv/\n // If byte is greater or equal to 80h (128 decimal) then the next byte\n // is also part of the VLV,\n // else byte is the last byte in a VLV.\n var currentByte = byteArray[0];\n var byteCount = 1;\n\n while (currentByte >= 128) {\n currentByte = byteArray[byteCount];\n byteCount++;\n }\n\n return byteCount;\n }\n /**\n * Reads a variable length value.\n * @param {array} byteArray\n * @return {number}\n */\n\n }, {\n key: \"readVarInt\",\n value: function readVarInt(byteArray) {\n var result = 0;\n byteArray.forEach(function (number) {\n var b = number;\n\n if (b & 0x80) {\n result += b & 0x7f;\n result <<= 7;\n } else {\n /* b is the last byte */\n result += b;\n }\n });\n return result;\n }\n /**\n * Decodes base-64 encoded string\n * @param {string} string\n * @return {string}\n */\n\n }, {\n key: \"atob\",\n value: function (_atob) {\n function atob(_x) {\n return _atob.apply(this, arguments);\n }\n\n atob.toString = function () {\n return _atob.toString();\n };\n\n return atob;\n }(function (string) {\n if (typeof atob === 'function') return atob(string);\n return Buffer.from(string, 'base64').toString('binary');\n })\n }]);\n\n return Utils;\n}();\n\n/**\n * Class representing a track. Contains methods for parsing events and keeping track of pointer.\n */\n\nvar Track = /*#__PURE__*/function () {\n function Track(index, data) {\n _classCallCheck(this, Track);\n\n this.enabled = true;\n this.eventIndex = 0;\n this.pointer = 0;\n this.lastTick = 0;\n this.lastStatus = null;\n this.index = index;\n this.data = data;\n this.delta = 0;\n this.runningDelta = 0;\n this.events = []; // Ensure last 3 bytes of track are End of Track event\n\n var lastThreeBytes = this.data.subarray(this.data.length - 3, this.data.length);\n\n if (!(lastThreeBytes[0] === 0xff && lastThreeBytes[1] === 0x2f && lastThreeBytes[2] === 0x00)) {\n throw 'Invalid MIDI file; Last three bytes of track ' + this.index + 'must be FF 2F 00 to mark end of track';\n }\n }\n /**\n * Resets all stateful track informaion used during playback.\n * @return {Track}\n */\n\n\n _createClass(Track, [{\n key: \"reset\",\n value: function reset() {\n this.enabled = true;\n this.eventIndex = 0;\n this.pointer = 0;\n this.lastTick = 0;\n this.lastStatus = null;\n this.delta = 0;\n this.runningDelta = 0;\n return this;\n }\n /**\n * Sets this track to be enabled during playback.\n * @return {Track}\n */\n\n }, {\n key: \"enable\",\n value: function enable() {\n this.enabled = true;\n return this;\n }\n /**\n * Sets this track to be disabled during playback.\n * @return {Track}\n */\n\n }, {\n key: \"disable\",\n value: function disable() {\n this.enabled = false;\n return this;\n }\n /**\n * Sets the track event index to the nearest event to the given tick.\n * @param {number} tick\n * @return {Track}\n */\n\n }, {\n key: \"setEventIndexByTick\",\n value: function setEventIndexByTick(tick) {\n tick = tick || 0;\n\n for (var i = 0; i < this.events.length; i++) {\n if (this.events[i].tick >= tick) {\n this.eventIndex = i;\n return this;\n }\n }\n }\n /**\n * Gets byte located at pointer position.\n * @return {number}\n */\n\n }, {\n key: \"getCurrentByte\",\n value: function getCurrentByte() {\n return this.data[this.pointer];\n }\n /**\n * Gets count of delta bytes and current pointer position.\n * @return {number}\n */\n\n }, {\n key: \"getDeltaByteCount\",\n value: function getDeltaByteCount() {\n return Utils.getVarIntLength(this.data.subarray(this.pointer));\n }\n /**\n * Get delta value at current pointer position.\n * @return {number}\n */\n\n }, {\n key: \"getDelta\",\n value: function getDelta() {\n return Utils.readVarInt(this.data.subarray(this.pointer, this.pointer + this.getDeltaByteCount()));\n }\n /**\n * Handles event within a given track starting at specified index\n * @param {number} currentTick\n * @param {boolean} dryRun - If true events will be parsed and returned regardless of time.\n */\n\n }, {\n key: \"handleEvent\",\n value: function handleEvent(currentTick, dryRun) {\n dryRun = dryRun || false;\n\n if (dryRun) {\n var elapsedTicks = currentTick - this.lastTick;\n var delta = this.getDelta();\n var eventReady = elapsedTicks >= delta;\n\n if (this.pointer < this.data.length && (dryRun || eventReady)) {\n var event = this.parseEvent();\n if (this.enabled) return event; // Recursively call this function for each event ahead that has 0 delta time?\n }\n } else {\n // Let's actually play the MIDI from the generated JSON events created by the dry run.\n // Process all events that have passed to avoid falling behind on dense MIDI files.\n var events = [];\n\n while (this.events[this.eventIndex] && this.events[this.eventIndex].tick <= currentTick) {\n if (this.enabled) events.push(this.events[this.eventIndex]);\n this.eventIndex++;\n }\n\n if (events.length > 0) return events;\n }\n\n return null;\n }\n /**\n * Get string data from event.\n * @param {number} eventStartIndex\n * @return {string}\n */\n\n }, {\n key: \"getStringData\",\n value: function getStringData(eventStartIndex) {\n var varIntLength = Utils.getVarIntLength(this.data.subarray(eventStartIndex + 2));\n var varIntValue = Utils.readVarInt(this.data.subarray(eventStartIndex + 2, eventStartIndex + 2 + varIntLength));\n var letters = Utils.bytesToLetters(this.data.subarray(eventStartIndex + 2 + varIntLength, eventStartIndex + 2 + varIntLength + varIntValue));\n return letters;\n }\n /**\n * Parses event into JSON and advances pointer for the track\n * @return {object}\n */\n\n }, {\n key: \"parseEvent\",\n value: function parseEvent() {\n var eventStartIndex = this.pointer + this.getDeltaByteCount();\n var eventJson = {};\n var deltaByteCount = this.getDeltaByteCount();\n eventJson.track = this.index + 1;\n eventJson.delta = this.getDelta();\n this.lastTick = this.lastTick + eventJson.delta;\n this.runningDelta += eventJson.delta;\n eventJson.tick = this.runningDelta;\n eventJson.byteIndex = this.pointer; //eventJson.raw = event;\n\n if (this.data[eventStartIndex] == 0xff) {\n // Meta Event\n // If this is a meta event we should emit the data and immediately move to the next event\n // otherwise if we let it run through the next cycle a slight delay will accumulate if multiple tracks\n // are being played simultaneously\n switch (this.data[eventStartIndex + 1]) {\n case 0x00:\n // Sequence Number\n eventJson.name = 'Sequence Number';\n break;\n\n case 0x01:\n // Text Event\n eventJson.name = 'Text Event';\n eventJson.string = this.getStringData(eventStartIndex);\n break;\n\n case 0x02:\n // Copyright Notice\n eventJson.name = 'Copyright Notice';\n break;\n\n case 0x03:\n // Sequence/Track Name\n eventJson.name = 'Sequence/Track Name';\n eventJson.string = this.getStringData(eventStartIndex);\n break;\n\n case 0x04:\n // Instrument Name\n eventJson.name = 'Instrument Name';\n eventJson.string = this.getStringData(eventStartIndex);\n break;\n\n case 0x05:\n // Lyric\n eventJson.name = 'Lyric';\n eventJson.string = this.getStringData(eventStartIndex);\n break;\n\n case 0x06:\n // Marker\n eventJson.name = 'Marker';\n eventJson.string = this.getStringData(eventStartIndex);\n break;\n\n case 0x07:\n // Cue Point\n eventJson.name = 'Cue Point';\n eventJson.string = this.getStringData(eventStartIndex);\n break;\n\n case 0x09:\n // Device Name\n eventJson.name = 'Device Name';\n eventJson.string = this.getStringData(eventStartIndex);\n break;\n\n case 0x20:\n // MIDI Channel Prefix\n eventJson.name = 'MIDI Channel Prefix';\n break;\n\n case 0x21:\n // MIDI Port\n eventJson.name = 'MIDI Port';\n eventJson.data = Utils.bytesToNumber([this.data[eventStartIndex + 3]]);\n break;\n\n case 0x2F:\n // End of Track\n eventJson.name = 'End of Track';\n break;\n\n case 0x51:\n // Set Tempo\n eventJson.name = 'Set Tempo';\n eventJson.data = Math.round(60000000 / Utils.bytesToNumber(this.data.subarray(eventStartIndex + 3, eventStartIndex + 6)));\n this.tempo = eventJson.data;\n break;\n\n case 0x54:\n // SMTPE Offset\n eventJson.name = 'SMTPE Offset';\n break;\n\n case 0x58:\n // Time Signature\n // FF 58 04 nn dd cc bb\n eventJson.name = 'Time Signature';\n eventJson.data = this.data.subarray(eventStartIndex + 3, eventStartIndex + 7);\n eventJson.timeSignature = \"\" + eventJson.data[0] + \"/\" + Math.pow(2, eventJson.data[1]);\n break;\n\n case 0x59:\n // Key Signature\n // FF 59 02 sf mi\n eventJson.name = 'Key Signature';\n eventJson.data = this.data.subarray(eventStartIndex + 3, eventStartIndex + 5); // sf byte is signed (-7 to 7), but Uint8Array gives unsigned values\n\n var sf = eventJson.data[0] > 127 ? eventJson.data[0] - 256 : eventJson.data[0];\n\n if (sf >= 0) {\n eventJson.keySignature = Constants.CIRCLE_OF_FIFTHS[sf];\n } else {\n eventJson.keySignature = Constants.CIRCLE_OF_FOURTHS[Math.abs(sf)];\n }\n\n if (eventJson.data[1] == 0) {\n eventJson.keySignature += \" Major\";\n } else if (eventJson.data[1] == 1) {\n eventJson.keySignature += \" Minor\";\n }\n\n break;\n\n case 0x7F:\n // Sequencer-Specific Meta-event\n eventJson.name = 'Sequencer-Specific Meta-event';\n break;\n\n default:\n eventJson.name = 'Unknown: ' + this.data[eventStartIndex + 1].toString(16);\n break;\n }\n\n var varIntLength = Utils.getVarIntLength(this.data.subarray(eventStartIndex + 2));\n var length = Utils.readVarInt(this.data.subarray(eventStartIndex + 2, eventStartIndex + 2 + varIntLength)); //console.log(eventJson);\n\n this.pointer += deltaByteCount + 2 + varIntLength + length; //console.log(eventJson);\n } else if (this.data[eventStartIndex] === 0xf0) {\n // Sysex\n eventJson.name = 'Sysex';\n var varQuantityByteLength = Utils.getVarIntLength(this.data.subarray(eventStartIndex + 1));\n var varQuantityByteValue = Utils.readVarInt(this.data.subarray(eventStartIndex + 1, eventStartIndex + 1 + varQuantityByteLength));\n eventJson.data = this.data.subarray(eventStartIndex + 1 + varQuantityByteLength, eventStartIndex + 1 + varQuantityByteLength + varQuantityByteValue);\n this.pointer += deltaByteCount + 1 + varQuantityByteLength + varQuantityByteValue;\n } else if (this.data[eventStartIndex] === 0xf7) {\n // Sysex (escape)\n // http://www.somascape.org/midi/tech/mfile.html#sysex\n eventJson.name = 'Sysex (escape)';\n\n var _varQuantityByteLength = Utils.getVarIntLength(this.data.subarray(eventStartIndex + 1));\n\n var _varQuantityByteValue = Utils.readVarInt(this.data.subarray(eventStartIndex + 1, eventStartIndex + 1 + _varQuantityByteLength));\n\n eventJson.data = this.data.subarray(eventStartIndex + 1 + _varQuantityByteLength, eventStartIndex + 1 + _varQuantityByteLength + _varQuantityByteValue);\n this.pointer += deltaByteCount + 1 + _varQuantityByteLength + _varQuantityByteValue;\n } else {\n // Voice event\n if (this.data[eventStartIndex] < 0x80) {\n // Running status\n eventJson.running = true;\n eventJson.noteNumber = this.data[eventStartIndex];\n eventJson.noteName = Constants.NOTES[this.data[eventStartIndex]];\n eventJson.velocity = this.data[eventStartIndex + 1];\n\n if (this.lastStatus <= 0x8f) {\n eventJson.name = 'Note off';\n eventJson.channel = this.lastStatus - 0x80 + 1;\n this.pointer += deltaByteCount + 2;\n } else if (this.lastStatus <= 0x9f) {\n eventJson.name = 'Note on';\n eventJson.channel = this.lastStatus - 0x90 + 1;\n this.pointer += deltaByteCount + 2;\n } else if (this.lastStatus <= 0xaf) {\n // Polyphonic Key Pressure\n eventJson.name = 'Polyphonic Key Pressure';\n eventJson.channel = this.lastStatus - 0xa0 + 1;\n eventJson.note = Constants.NOTES[this.data[eventStartIndex]];\n eventJson.pressure = this.data[eventStartIndex + 1];\n this.pointer += deltaByteCount + 2;\n } else if (this.lastStatus <= 0xbf) {\n // Controller Change\n eventJson.name = 'Controller Change';\n eventJson.channel = this.lastStatus - 0xb0 + 1;\n eventJson.number = this.data[eventStartIndex];\n eventJson.value = this.data[eventStartIndex + 1];\n this.pointer += deltaByteCount + 2;\n } else if (this.lastStatus <= 0xcf) {\n // Program Change\n eventJson.name = 'Program Change';\n eventJson.channel = this.lastStatus - 0xc0 + 1;\n eventJson.value = this.data[eventStartIndex + 1];\n this.pointer += deltaByteCount + 1;\n } else if (this.lastStatus <= 0xdf) {\n // Channel Key Pressure\n eventJson.name = 'Channel Key Pressure';\n eventJson.channel = this.lastStatus - 0xd0 + 1;\n this.pointer += deltaByteCount + 1;\n } else if (this.lastStatus <= 0xef) {\n // Pitch Bend\n eventJson.name = 'Pitch Bend';\n eventJson.channel = this.lastStatus - 0xe0 + 1;\n eventJson.value = (this.data[eventStartIndex + 1] & 0x7f) << 7 | this.data[eventStartIndex] & 0x7f;\n this.pointer += deltaByteCount + 2;\n } else {\n throw \"Unknown event (running): \".concat(this.lastStatus);\n }\n } else {\n this.lastStatus = this.data[eventStartIndex];\n\n if (this.data[eventStartIndex] <= 0x8f) {\n // Note off\n eventJson.name = 'Note off';\n eventJson.channel = this.lastStatus - 0x80 + 1;\n eventJson.noteNumber = this.data[eventStartIndex + 1];\n eventJson.noteName = Constants.NOTES[this.data[eventStartIndex + 1]];\n eventJson.velocity = Math.round(this.data[eventStartIndex + 2] / 127 * 100);\n this.pointer += deltaByteCount + 3;\n } else if (this.data[eventStartIndex] <= 0x9f) {\n // Note on\n eventJson.name = 'Note on';\n eventJson.channel = this.lastStatus - 0x90 + 1;\n eventJson.noteNumber = this.data[eventStartIndex + 1];\n eventJson.noteName = Constants.NOTES[this.data[eventStartIndex + 1]];\n eventJson.velocity = Math.round(this.data[eventStartIndex + 2] / 127 * 100);\n this.pointer += deltaByteCount + 3;\n } else if (this.data[eventStartIndex] <= 0xaf) {\n // Polyphonic Key Pressure\n eventJson.name = 'Polyphonic Key Pressure';\n eventJson.channel = this.lastStatus - 0xa0 + 1;\n eventJson.note = Constants.NOTES[this.data[eventStartIndex + 1]];\n eventJson.pressure = this.data[eventStartIndex + 2];\n this.pointer += deltaByteCount + 3;\n } else if (this.data[eventStartIndex] <= 0xbf) {\n // Controller Change\n eventJson.name = 'Controller Change';\n eventJson.channel = this.lastStatus - 0xb0 + 1;\n eventJson.number = this.data[eventStartIndex + 1];\n eventJson.value = this.data[eventStartIndex + 2];\n this.pointer += deltaByteCount + 3;\n } else if (this.data[eventStartIndex] <= 0xcf) {\n // Program Change\n eventJson.name = 'Program Change';\n eventJson.channel = this.lastStatus - 0xc0 + 1;\n eventJson.value = this.data[eventStartIndex + 1];\n this.pointer += deltaByteCount + 2;\n } else if (this.data[eventStartIndex] <= 0xdf) {\n // Channel Key Pressure\n eventJson.name = 'Channel Key Pressure';\n eventJson.channel = this.lastStatus - 0xd0 + 1;\n this.pointer += deltaByteCount + 2;\n } else if (this.data[eventStartIndex] <= 0xef) {\n // Pitch Bend\n eventJson.name = 'Pitch Bend';\n eventJson.channel = this.lastStatus - 0xe0 + 1;\n eventJson.value = (this.data[eventStartIndex + 2] & 0x7f) << 7 | this.data[eventStartIndex + 1] & 0x7f;\n this.pointer += deltaByteCount + 3;\n } else {\n throw \"Unknown event: \".concat(this.data[eventStartIndex]); //eventJson.name = `Unknown. Pointer: ${this.pointer.toString()}, ${eventStartIndex.toString()}, ${this.data[eventStartIndex]}, ${this.data.length}`;\n }\n }\n }\n\n this.delta += eventJson.delta;\n this.events.push(eventJson);\n return eventJson;\n }\n /**\n * Returns true if pointer has reached the end of the track.\n * @param {boolean}\n */\n\n }, {\n key: \"endOfTrack\",\n value: function endOfTrack() {\n if (this.data[this.pointer + 1] == 0xff && this.data[this.pointer + 2] == 0x2f && this.data[this.pointer + 3] == 0x00) {\n return true;\n }\n\n return false;\n }\n }]);\n\n return Track;\n}();\n\nif (!Uint8Array.prototype.forEach) {\n Object.defineProperty(Uint8Array.prototype, 'forEach', {\n value: Array.prototype.forEach\n });\n}\n/**\n * Main player class. Contains methods to load files, start, stop.\n * @param {function} - Callback to fire for each MIDI event. Can also be added with on('midiEvent', fn)\n * @param {array} - Array buffer of MIDI file (optional).\n */\n\n\nvar Player = /*#__PURE__*/function () {\n function Player(eventHandler, buffer) {\n _classCallCheck(this, Player);\n\n this.sampleRate = 5; // milliseconds\n\n this.startTime = 0;\n this.buffer = buffer || null;\n this.midiChunksByteLength = null;\n this.division;\n this.format;\n this.setTimeoutId = false;\n this.scheduledTime = 0;\n this.tracks = [];\n this.instruments = [];\n this.defaultTempo = 120;\n this.tempo = null;\n this.startTick = 0;\n this.tick = 0;\n this.lastTick = null;\n this.inLoop = false;\n this.totalTicks = 0;\n this.events = [];\n this.totalEvents = 0;\n this.tempoMap = [];\n this.eventListeners = {};\n if (typeof eventHandler === 'function') this.on('midiEvent', eventHandler);\n }\n /**\n * Load a file into the player (Node.js only).\n * @param {string} path - Path of file.\n * @return {Player}\n */\n\n\n _createClass(Player, [{\n key: \"loadFile\",\n value: function loadFile(path) {\n {\n throw 'loadFile is only supported on Node.js';\n }\n }\n /**\n * Load an array buffer into the player.\n * @param {array} arrayBuffer - Array buffer of file to be loaded.\n * @return {Player}\n */\n\n }, {\n key: \"loadArrayBuffer\",\n value: function loadArrayBuffer(arrayBuffer) {\n this.buffer = new Uint8Array(arrayBuffer);\n return this.fileLoaded();\n }\n /**\n * Load a data URI into the player.\n * @param {string} dataUri - Data URI to be loaded.\n * @return {Player}\n */\n\n }, {\n key: \"loadDataUri\",\n value: function loadDataUri(dataUri) {\n // convert base64 to raw binary data held in a string.\n // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this\n var byteString = Utils.atob(dataUri.split(',')[1]); // write the bytes of the string to an ArrayBuffer\n\n var ia = new Uint8Array(byteString.length);\n\n for (var i = 0; i < byteString.length; i++) {\n ia[i] = byteString.charCodeAt(i);\n }\n\n this.buffer = ia;\n return this.fileLoaded();\n }\n /**\n * Get filesize of loaded file in number of bytes.\n * @return {number} - The filesize.\n */\n\n }, {\n key: \"getFilesize\",\n value: function getFilesize() {\n return this.buffer ? this.buffer.length : 0;\n }\n /**\n * Sets default tempo, parses file for necessary information, and does a dry run to calculate total length.\n * Populates this.events & this.totalTicks.\n * @return {Player}\n */\n\n }, {\n key: \"fileLoaded\",\n value: function fileLoaded() {\n if (!this.validate()) throw 'Invalid MIDI file; should start with MThd';\n this.defaultTempo = 120;\n return this.setTempo(this.defaultTempo).getDivision().getFormat().getTracks().dryRun();\n }\n /**\n * Validates file using simple means - first four bytes should == MThd.\n * @return {boolean}\n */\n\n }, {\n key: \"validate\",\n value: function validate() {\n //console.log((this.buffer.subarray(0, 15)));\n return Utils.bytesToLetters(this.buffer.subarray(0, 4)) === 'MThd';\n }\n /**\n * Gets MIDI file format for loaded file.\n * @return {Player}\n */\n\n }, {\n key: \"getFormat\",\n value: function getFormat() {\n /*\n MIDI files come in 3 variations:\n Format 0 which contain a single track\n Format 1 which contain one or more simultaneous tracks\n (ie all tracks are to be played simultaneously).\n Format 2 which contain one or more independant tracks\n (ie each track is to be played independantly of the others).\n return Utils.bytesToNumber(this.buffer.subarray(8, 10));\n */\n this.format = Utils.bytesToNumber(this.buffer.subarray(8, 10));\n return this;\n }\n /**\n * Parses out tracks, places them in this.tracks and initializes this.pointers\n * @return {Player}\n */\n\n }, {\n key: \"getTracks\",\n value: function getTracks() {\n this.tracks = [];\n var trackOffset = 0;\n\n while (trackOffset < this.buffer.length) {\n if (Utils.bytesToLetters(this.buffer.subarray(trackOffset, trackOffset + 4)) == 'MTrk') {\n var trackLength = Utils.bytesToNumber(this.buffer.subarray(trackOffset + 4, trackOffset + 8));\n this.tracks.push(new Track(this.tracks.length, this.buffer.subarray(trackOffset + 8, trackOffset + 8 + trackLength)));\n }\n\n trackOffset += Utils.bytesToNumber(this.buffer.subarray(trackOffset + 4, trackOffset + 8)) + 8;\n } // Get sum of all MIDI chunks here while we're at it\n\n\n var trackChunksByteLength = 0;\n this.tracks.forEach(function (track) {\n trackChunksByteLength += 8 + track.data.length;\n });\n this.midiChunksByteLength = Constants.HEADER_CHUNK_LENGTH + trackChunksByteLength;\n return this;\n }\n /**\n * Enables a track for playing.\n * @param {number} trackNumber - Track number\n * @return {Player}\n */\n\n }, {\n key: \"enableTrack\",\n value: function enableTrack(trackNumber) {\n this.tracks[trackNumber - 1].enable();\n return this;\n }\n /**\n * Disables a track for playing.\n * @param {number} - Track number\n * @return {Player}\n */\n\n }, {\n key: \"disableTrack\",\n value: function disableTrack(trackNumber) {\n this.tracks[trackNumber - 1].disable();\n return this;\n }\n /**\n * Gets quarter note division of loaded MIDI file.\n * @return {Player}\n */\n\n }, {\n key: \"getDivision\",\n value: function getDivision() {\n this.division = Utils.bytesToNumber(this.buffer.subarray(12, Constants.HEADER_CHUNK_LENGTH));\n return this;\n }\n /**\n * The main play loop.\n * @param {boolean} - Indicates whether or not this is being called simply for parsing purposes. Disregards timing if so.\n * @return {undefined}\n */\n\n }, {\n key: \"playLoop\",\n value: function playLoop(dryRun) {\n if (!this.inLoop) {\n this.inLoop = true;\n this.tick = this.getCurrentTick();\n this.tracks.forEach(function (track, index) {\n // Handle next event\n if (!dryRun && this.endOfFile()) {\n //console.log('end of file')\n this.stop();\n this.triggerPlayerEvent('endOfFile');\n } else {\n var result = track.handleEvent(this.tick, dryRun);\n\n if (dryRun && result) {\n if (result.hasOwnProperty('name') && result.name === 'Set Tempo') {\n // Grab tempo if available.\n this.setTempo(result.data);\n }\n\n if (result.hasOwnProperty('name') && result.name === 'Program Change') {\n if (!this.instruments.includes(result.value)) {\n this.instruments.push(result.value);\n }\n }\n } else if (result) {\n // result is an array of events during playback\n var events = Array.isArray(result) ? result : [result];\n events.forEach(function (event) {\n if (event.hasOwnProperty('name') && event.name === 'Set Tempo') {\n // Grab tempo if available.\n this.setTempo(event.data);\n }\n\n this.emitEvent(event);\n }, this);\n }\n }\n }, this);\n if (!dryRun && this.isPlaying()) this.triggerPlayerEvent('playing', {\n tick: this.tick\n });\n this.inLoop = false;\n }\n }\n /**\n * Setter for tempo.\n * @param {number} - Tempo in bpm (defaults to 120)\n */\n\n }, {\n key: \"setTempo\",\n value: function setTempo(tempo) {\n this.tempo = tempo;\n return this;\n }\n /**\n * Setter for startTime.\n * @param {number} - UTC timestamp\n * @return {Player}\n */\n\n }, {\n key: \"setStartTime\",\n value: function setStartTime(startTime) {\n this.startTime = startTime;\n return this;\n }\n /**\n * Start playing loaded MIDI file if not already playing.\n * @return {Player}\n */\n\n }, {\n key: \"play\",\n value: function play() {\n if (this.isPlaying()) throw 'Already playing...'; // Initialize\n\n if (!this.startTime) this.startTime = new Date().getTime(); // Start play loop using drift-correcting setTimeout\n\n this.scheduledTime = Date.now();\n this.schedulePlayLoop(this.sampleRate);\n return this;\n }\n /**\n * Schedules the next play loop iteration, correcting for timer drift.\n * @param {number} delay - Delay in milliseconds before next iteration.\n * @return {undefined}\n */\n\n }, {\n key: \"schedulePlayLoop\",\n value: function schedulePlayLoop(delay) {\n var _this = this;\n\n this.setTimeoutId = setTimeout(function () {\n _this.playLoop();\n\n if (_this.setTimeoutId !== false) {\n _this.scheduledTime += _this.sampleRate;\n\n var drift = Date.now() - _this.scheduledTime;\n\n _this.schedulePlayLoop(Math.max(0, _this.sampleRate - drift));\n }\n }, delay);\n }\n /**\n * Pauses playback if playing.\n * @return {Player}\n */\n\n }, {\n key: \"pause\",\n value: function pause() {\n clearTimeout(this.setTimeoutId);\n this.setTimeoutId = false;\n this.scheduledTime = 0;\n this.startTick = this.tick;\n this.startTime = 0;\n return this;\n }\n /**\n * Stops playback if playing.\n * @return {Player}\n */\n\n }, {\n key: \"stop\",\n value: function stop() {\n clearTimeout(this.setTimeoutId);\n this.setTimeoutId = false;\n this.scheduledTime = 0;\n this.startTick = 0;\n this.startTime = 0;\n this.resetTracks();\n return this;\n }\n /**\n * Skips player pointer to specified tick.\n * @param {number} - Tick to skip to.\n * @return {Player}\n */\n\n }, {\n key: \"skipToTick\",\n value: function skipToTick(tick) {\n this.stop();\n this.startTick = tick; // Set tempo to the value that applies at the target tick\n\n for (var i = this.tempoMap.length - 1; i >= 0; i--) {\n if (this.tempoMap[i].tick <= tick) {\n this.setTempo(this.tempoMap[i].tempo);\n break;\n }\n } // Emit intermediate state-changing events so the consumer's synth is in the correct state\n\n\n this.collectStateAtTick(tick).forEach(function (event) {\n this.emitEvent(event);\n }, this); // Need to set track event indexes to the nearest possible event to the specified tick.\n\n this.tracks.forEach(function (track) {\n track.setEventIndexByTick(tick);\n });\n return this;\n }\n /**\n * Collects the last state-changing MIDI events (Program Change, Controller Change, Pitch Bend)\n * before the specified tick across all tracks.\n * @param {number} tick - Target tick to collect state up to.\n * @return {array} - Array of state events representing the MIDI state at the target tick.\n */\n\n }, {\n key: \"collectStateAtTick\",\n value: function collectStateAtTick(tick) {\n var dominated = {};\n this.events.forEach(function (trackEvents) {\n trackEvents.forEach(function (event) {\n if (event.tick >= tick) return;\n var key;\n\n if (event.name === 'Program Change') {\n key = 'pc:' + event.channel;\n } else if (event.name === 'Controller Change') {\n key = 'cc:' + event.channel + ':' + event.number;\n } else if (event.name === 'Pitch Bend') {\n key = 'pb:' + event.channel;\n }\n\n if (key) {\n dominated[key] = event;\n }\n });\n });\n return Object.keys(dominated).map(function (key) {\n return dominated[key];\n });\n }\n /**\n * Skips player pointer to specified percentage.\n * @param {number} - Percent value in integer format.\n * @return {Player}\n */\n\n }, {\n key: \"skipToPercent\",\n value: function skipToPercent(percent) {\n if (percent < 0 || percent > 100) throw \"Percent must be number between 1 and 100.\";\n this.skipToTick(Math.round(percent / 100 * this.totalTicks));\n return this;\n }\n /**\n * Skips player pointer to specified seconds.\n * @param {number} - Seconds to skip to.\n * @return {Player}\n */\n\n }, {\n key: \"skipToSeconds\",\n value: function skipToSeconds(seconds) {\n var songTime = this.getSongTime();\n if (seconds < 0 || seconds > songTime) throw seconds + \" seconds not within song time of \" + songTime;\n this.skipToTick(this.secondsToTicks(seconds));\n return this;\n }\n /**\n * Checks if player is playing\n * @return {boolean}\n */\n\n }, {\n key: \"isPlaying\",\n value: function isPlaying() {\n return this.setTimeoutId !== false;\n }\n /**\n * Plays the loaded MIDI file without regard for timing and saves events in this.events. Essentially used as a parser.\n * @return {Player}\n */\n\n }, {\n key: \"dryRun\",\n value: function dryRun() {\n // Reset tracks first\n this.resetTracks();\n\n while (!this.endOfFile()) {\n this.playLoop(true); //console.log(this.bytesProcessed(), this.midiChunksByteLength);\n }\n\n this.events = this.getEvents();\n this.totalEvents = this.getTotalEvents();\n this.totalTicks = this.getTotalTicks();\n this.buildTempoMap();\n this.startTick = 0;\n this.startTime = 0; // Leave tracks in pristine condish\n\n this.resetTracks(); //console.log('Song time: ' + this.getSongTime() + ' seconds / ' + this.totalTicks + ' ticks.');\n\n this.triggerPlayerEvent('fileLoaded', this);\n return this;\n }\n /**\n * Resets play pointers for all tracks.\n * @return {Player}\n */\n\n }, {\n key: \"resetTracks\",\n value: function resetTracks() {\n this.tracks.forEach(function (track) {\n return track.reset();\n });\n return this;\n }\n /**\n * Gets an array of events grouped by track.\n * @return {array}\n */\n\n }, {\n key: \"getEvents\",\n value: function getEvents() {\n return this.tracks.map(function (track) {\n return track.events;\n });\n }\n /**\n * Gets total number of ticks in the loaded MIDI file.\n * @return {number}\n */\n\n }, {\n key: \"getTotalTicks\",\n value: function getTotalTicks() {\n return Math.max.apply(null, this.tracks.map(function (track) {\n return track.delta;\n }));\n }\n /**\n * Gets total number of events in the loaded MIDI file.\n * @return {number}\n */\n\n }, {\n key: \"getTotalEvents\",\n value: function getTotalEvents() {\n return this.tracks.reduce(function (a, b) {\n return {\n events: {\n length: a.events.length + b.events.length\n }\n };\n }, {\n events: {\n length: 0\n }\n }).events.length;\n }\n /**\n * Builds a tempo map from all Set Tempo events across all tracks.\n * @return {Player}\n */\n\n }, {\n key: \"buildTempoMap\",\n value: function buildTempoMap() {\n // Collect all Set Tempo events from all tracks\n var tempoEvents = [];\n this.events.forEach(function (trackEvents) {\n trackEvents.forEach(function (event) {\n if (event.name === 'Set Tempo') {\n tempoEvents.push({\n tick: event.tick,\n tempo: event.data\n });\n }\n });\n }); // Sort by tick\n\n tempoEvents.sort(function (a, b) {\n return a.tick - b.tick;\n }); // Build map starting with default tempo\n\n this.tempoMap = [{\n tick: 0,\n tempo: this.defaultTempo\n }];\n tempoEvents.forEach(function (event) {\n var last = this.tempoMap[this.tempoMap.length - 1];\n\n if (event.tick === last.tick) {\n // Same tick: update existing entry\n last.tempo = event.tempo;\n } else {\n this.tempoMap.push({\n tick: event.tick,\n tempo: event.tempo\n });\n }\n }, this);\n return this;\n }\n /**\n * Converts a tick range to seconds using the tempo map.\n * @param {number} startTick\n * @param {number} endTick\n * @return {number}\n */\n\n }, {\n key: \"ticksToSeconds\",\n value: function ticksToSeconds(startTick, endTick) {\n var seconds = 0;\n var currentTick = startTick;\n\n for (var i = 0; i < this.tempoMap.length; i++) {\n var entry = this.tempoMap[i];\n var nextTick = i + 1 < this.tempoMap.length ? this.tempoMap[i + 1].tick : endTick; // Skip entries entirely before our start\n\n if (nextTick <= startTick) continue; // Clamp segment to our range\n\n var segStart = Math.max(entry.tick, startTick);\n var segEnd = Math.min(nextTick, endTick);\n if (segStart >= endTick) break;\n var segmentTicks = segEnd - segStart;\n seconds += segmentTicks / this.division / entry.tempo * 60;\n currentTick = segEnd;\n } // Handle remaining ticks after last tempo change\n\n\n if (currentTick < endTick) {\n var lastEntry = this.tempoMap[this.tempoMap.length - 1];\n seconds += (endTick - currentTick) / this.division / lastEntry.tempo * 60;\n }\n\n return seconds;\n }\n /**\n * Converts seconds to a tick position using the tempo map.\n * @param {number} seconds\n * @return {number}\n */\n\n }, {\n key: \"secondsToTicks\",\n value: function secondsToTicks(seconds) {\n var remainingSeconds = seconds;\n var currentTick = 0;\n\n for (var i = 0; i < this.tempoMap.length; i++) {\n var entry = this.tempoMap[i];\n var nextTick = i + 1 < this.tempoMap.length ? this.tempoMap[i + 1].tick : Infinity;\n var segmentTicks = nextTick - entry.tick;\n var segmentSeconds = segmentTicks / this.division / entry.tempo * 60;\n\n if (remainingSeconds <= segmentSeconds) {\n // Target is within this segment\n currentTick = entry.tick + Math.round(remainingSeconds / 60 * entry.tempo * this.division);\n return currentTick;\n }\n\n remainingSeconds -= segmentSeconds;\n currentTick = nextTick;\n } // Should not reach here, but return totalTicks as fallback\n\n\n return this.totalTicks;\n }\n /**\n * Gets song duration in seconds.\n * @return {number}\n */\n\n }, {\n key: \"getSongTime\",\n value: function getSongTime() {\n return this.ticksToSeconds(0, this.totalTicks);\n }\n /**\n * Gets remaining number of seconds in playback.\n * @return {number}\n */\n\n }, {\n key: \"getSongTimeRemaining\",\n value: function getSongTimeRemaining() {\n return Math.round(this.ticksToSeconds(this.getCurrentTick(), this.totalTicks));\n }\n /**\n * Gets remaining percent of playback.\n * @return {number}\n */\n\n }, {\n key: \"getSongPercentRemaining\",\n value: function getSongPercentRemaining() {\n return Math.round(this.getSongTimeRemaining() / this.getSongTime() * 100);\n }\n /**\n * Number of bytes processed in the loaded MIDI file.\n * @return {number}\n */\n\n }, {\n key: \"bytesProcessed\",\n value: function bytesProcessed() {\n return Constants.HEADER_CHUNK_LENGTH + this.tracks.length * 8 + this.tracks.reduce(function (a, b) {\n return {\n pointer: a.pointer + b.pointer\n };\n }, {\n pointer: 0\n }).pointer;\n }\n /**\n * Number of events played up to this point.\n * @return {number}\n */\n\n }, {\n key: \"eventsPlayed\",\n value: function eventsPlayed() {\n return this.tracks.reduce(function (a, b) {\n return {\n eventIndex: a.eventIndex + b.eventIndex\n };\n }, {\n eventIndex: 0\n }).eventIndex;\n }\n /**\n * Determines if the player pointer has reached the end of the loaded MIDI file.\n * Used in two ways:\n * 1. If playing result is based on loaded JSON events.\n * 2. If parsing (dryRun) it's based on the actual buffer length vs bytes processed.\n * @return {boolean}\n */\n\n }, {\n key: \"endOfFile\",\n value: function endOfFile() {\n if (this.isPlaying()) {\n return this.totalTicks - this.tick <= 0;\n }\n\n return this.bytesProcessed() >= this.midiChunksByteLength; //this.buffer.length;\n }\n /**\n * Gets the current tick number in playback.\n * @return {number}\n */\n\n }, {\n key: \"getCurrentTick\",\n value: function getCurrentTick() {\n if (!this.startTime) return this.startTick;\n var elapsedSeconds = (new Date().getTime() - this.startTime) / 1000;\n var startSeconds = this.ticksToSeconds(0, this.startTick);\n return this.secondsToTicks(startSeconds + elapsedSeconds);\n }\n /**\n * Sends MIDI event out to listener.\n * @param {object}\n * @return {Player}\n */\n\n }, {\n key: \"emitEvent\",\n value: function emitEvent(event) {\n this.triggerPlayerEvent('midiEvent', event);\n return this;\n }\n /**\n * Subscribes events to listeners\n * @param {string} - Name of event to subscribe to.\n * @param {function} - Callback to fire when event is broadcast.\n * @return {Player}\n */\n\n }, {\n key: \"on\",\n value: function on(playerEvent, fn) {\n if (!this.eventListeners.hasOwnProperty(playerEvent)) this.eventListeners[playerEvent] = [];\n this.eventListeners[playerEvent].push(fn);\n return this;\n }\n /**\n * Broadcasts event to trigger subscribed callbacks.\n * @param {string} - Name of event.\n * @param {object} - Data to be passed to subscriber callback.\n * @return {Player}\n */\n\n }, {\n key: \"triggerPlayerEvent\",\n value: function triggerPlayerEvent(playerEvent, data) {\n if (this.eventListeners.hasOwnProperty(playerEvent)) this.eventListeners[playerEvent].forEach(function (fn) {\n return fn(data || {});\n });\n return this;\n }\n }]);\n\n return Player;\n}();\n\nvar index = {\n Player: Player,\n Utils: Utils,\n Constants: Constants\n};\n\nexport { index as default };\n", "export default class WebAudioFontPlayer {\r\n\r\n #audioCtx = null;\r\n #preset = null;\r\n\r\n #envelopes = [];\r\n #afterTime = 0.05;\r\n #nearZero = 0.000001;\r\n\r\n\r\n constructor(audioCtx, preset) {\r\n this.#audioCtx = audioCtx;\r\n this.#preset = preset;\r\n this.#preset.zones.map(zone => this.#adjustZone(zone));\r\n }\r\n\r\n\r\n queueWaveTable(when, pitch, duration, volume, slides) {\r\n if(this.#audioCtx.state === 'suspended') this.#audioCtx.resume().catch(() => { });\r\n\r\n const vol = this.#limitVolume(volume);\r\n const zone = this.#findZone(pitch);\r\n if (!zone?.buffer) return null;\r\n\r\n const baseDetune = zone.originalPitch - 100.0 * zone.coarseTune - zone.fineTune;\r\n const playbackRate = Math.pow(2, (100.0 * pitch - baseDetune) / 1200.0);\r\n const startWhen = Math.max(when, this.#audioCtx.currentTime);\r\n let waveDuration = duration + this.#afterTime;\r\n\r\n const loop = zone.loopStart >= 1 && zone.loopStart < zone.loopEnd;\r\n if (!loop) waveDuration = Math.min(waveDuration, zone.buffer.duration / playbackRate);\r\n\r\n const envelope = this.#findEnvelope();\r\n this.#setupEnvelope(envelope, zone, vol, startWhen, waveDuration, duration);\r\n\r\n const source = this.#audioCtx.createBufferSource();\r\n source.buffer = zone.buffer;\r\n source.playbackRate.setValueAtTime(playbackRate, 0);\r\n\r\n if (slides?.length > 0) {\r\n source.playbackRate.setValueAtTime(playbackRate, startWhen);\r\n slides.forEach(s => {\r\n const newRate = Math.pow(2, (100.0 * (pitch + s.delta) - baseDetune) / 1200.0);\r\n source.playbackRate.linearRampToValueAtTime(newRate, startWhen + s.when);\r\n });\r\n }\r\n\r\n source.loop = loop;\r\n if (loop) {\r\n const d = zone.delay ?? 0;\r\n source.loopStart = zone.loopStart / zone.sampleRate + d;\r\n source.loopEnd = zone.loopEnd / zone.sampleRate + d;\r\n }\r\n\r\n source.connect(envelope);\r\n source.start(startWhen, zone.delay ?? 0);\r\n source.stop(startWhen + waveDuration);\r\n\r\n envelope.audioBufferSourceNode = source;\r\n envelope.when = startWhen;\r\n envelope.duration = waveDuration;\r\n\r\n return envelope;\r\n }\r\n\r\n\r\n queueChord(prst, w, pchs, d, v, s) {\r\n const vol = this.#limitVolume(v);\r\n return pchs.map((p, i) => this.queueWaveTable(this.#audioCtx, this.#audioCtx.destination, prst, w, p, d, vol - Math.random() * 0.01, s?.[i])).filter(Boolean);\r\n }\r\n\r\n\r\n async cancelQueue() {\r\n this.#envelopes.forEach(e => {\r\n e.gain.cancelScheduledValues(0);\r\n e.gain.setValueAtTime(this.#nearZero, this.#audioCtx.currentTime);\r\n e.when = -1;\r\n try { e.audioBufferSourceNode?.disconnect(); } catch (e) { }\r\n });\r\n }\r\n\r\n\r\n #adjustZone(zone) {\r\n if (zone.buffer) return Promise.resolve(zone);\r\n zone.delay = 0;\r\n if (zone.sample) {\r\n const binaryString = atob(zone.sample);\r\n const len = binaryString.length;\r\n const bytes = new Uint8Array(len);\r\n for (let i = 0; i < len; i++) bytes[i] = binaryString.charCodeAt(i);\r\n const int16Samples = new Int16Array(bytes.buffer);\r\n const numSamples = int16Samples.length;\r\n zone.buffer = this.#audioCtx.createBuffer(1, numSamples, zone.sampleRate);\r\n const float32Array = zone.buffer.getChannelData(0);\r\n for (let i = 0; i < numSamples; i++) float32Array[i] = int16Samples[i] / 32768.0;\r\n this.#applyZoneParameters(zone);\r\n return zone;\r\n } else if (zone.file) {\r\n const decoded = atob(zone.file);\r\n const uint8Array = new Uint8Array(decoded.length);\r\n for (let i = 0; i < decoded.length; i++) uint8Array[i] = decoded.charCodeAt(i);\r\n this.#audioCtx.decodeAudioData(\r\n uint8Array.buffer,\r\n audioBuffer => {\r\n zone.buffer = audioBuffer;\r\n this.#applyZoneParameters(zone);\r\n return zone;\r\n },\r\n error => {\r\n console.error(\"Audio decoding error:\", error);\r\n return false;\r\n }\r\n );\r\n } else {\r\n this.#applyZoneParameters(zone);\r\n return zone;\r\n }\r\n };\r\n\r\n\r\n #applyZoneParameters(zone) {\r\n zone.loopStart = this.#numValue(zone.loopStart, 0);\r\n zone.loopEnd = this.#numValue(zone.loopEnd, 0);\r\n zone.coarseTune = this.#numValue(zone.coarseTune, 0);\r\n zone.fineTune = this.#numValue(zone.fineTune, 0);\r\n zone.originalPitch = this.#numValue(zone.originalPitch, 6000);\r\n zone.sampleRate = this.#numValue(zone.sampleRate, 44100);\r\n };\r\n\r\n\r\n #setupEnvelope(envelope, zone, volume, when, sampleDuration, noteDuration) {\r\n envelope.gain.setValueAtTime(this.#noZeroVolume(0), this.#audioCtx.currentTime);\r\n\r\n const duration = Math.min(noteDuration, sampleDuration - this.#afterTime);\r\n const ahdsr = (zone.ahdsr && zone.ahdsr.length > 0) ? zone.ahdsr : [\r\n { duration: 0, volume: 1 },\r\n { duration: duration, volume: 1 }\r\n ];\r\n\r\n envelope.gain.cancelScheduledValues(when);\r\n const initialVol = (ahdsr[0]?.volume ?? 1) * volume;\r\n envelope.gain.setValueAtTime(this.#noZeroVolume(initialVol), when);\r\n\r\n let lastTime = 0;\r\n let lastVolume = ahdsr[0]?.volume ?? 1;\r\n\r\n for (const stage of ahdsr) {\r\n const { duration: stageDuration, volume: stageVolume } = stage;\r\n if (stageDuration <= 0) continue;\r\n const remainingTime = duration - lastTime;\r\n if (stageDuration > remainingTime) {\r\n const ratio = remainingTime / stageDuration;\r\n const interpolatedVolume = lastVolume + ratio * (stageVolume - lastVolume);\r\n envelope.gain.linearRampToValueAtTime(\r\n this.#noZeroVolume(volume * interpolatedVolume),\r\n when + duration\r\n );\r\n break;\r\n }\r\n lastTime += stageDuration;\r\n lastVolume = stageVolume;\r\n envelope.gain.linearRampToValueAtTime(\r\n this.#noZeroVolume(volume * lastVolume),\r\n when + lastTime\r\n );\r\n }\r\n\r\n envelope.gain.linearRampToValueAtTime(this.#noZeroVolume(0), when + duration + this.#afterTime);\r\n }\r\n\r\n\r\n #findEnvelope() {\r\n let envelope = this.#envelopes.find(e => e.target === this.#audioCtx.destination && this.#audioCtx.currentTime > e.when + e.duration + 0.001);\r\n if (envelope) {\r\n if (envelope.audioBufferSourceNode) {\r\n try {\r\n envelope.audioBufferSourceNode.stop(0);\r\n envelope.audioBufferSourceNode.disconnect();\r\n } catch (e) { }\r\n envelope.audioBufferSourceNode = null;\r\n }\r\n } else {\r\n envelope = this.#audioCtx.createGain();\r\n envelope.gain.value = 0;\r\n envelope.target = this.#audioCtx.destination;\r\n envelope.connect(this.#audioCtx.destination);\r\n envelope.cancel = () => {\r\n if (envelope.when + envelope.duration > this.#audioCtx.currentTime) {\r\n envelope.gain.cancelScheduledValues(0);\r\n envelope.gain.setTargetAtTime(this.#nearZero, this.#audioCtx.currentTime, 0.1);\r\n envelope.when = this.#audioCtx.currentTime + 0.00001;\r\n envelope.duration = 0;\r\n }\r\n };\r\n this.#envelopes.push(envelope);\r\n }\r\n return envelope;\r\n }\r\n\r\n\r\n #findZone(pitch) {\r\n const zone = this.#preset.zones.findLast(z => pitch >= z.keyRangeLow && pitch <= z.keyRangeHigh + 1);\r\n if (zone) this.#adjustZone(zone);\r\n return zone;\r\n };\r\n\r\n \r\n #limitVolume(v) {\r\n const requestedVolume = v ? 1.0 * v : 0.5;\r\n return Math.min(requestedVolume, 0.8);\r\n };\r\n\r\n\r\n #noZeroVolume(n) {\r\n return n > this.#nearZero ? n : this.#nearZero;\r\n }\r\n\r\n\r\n #numValue(a, b) {\r\n return typeof a === \"number\" ? a : b;\r\n }\r\n\r\n}\r\n\r\n\r\nclass WebAudioFontChannel {\r\n\r\n #input = null;\r\n #output = null;\r\n #audioCtx = null;\r\n #limiter = null;\r\n\r\n constructor(audioCtx) {\r\n this.#audioCtx = audioCtx;\r\n this.#input = this.#audioCtx.createGain();\r\n\r\n let lastNode = this.#input;\r\n [32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384].forEach(freq => {\r\n lastNode = this.#bandEqualizer(lastNode, freq);\r\n this[`band${freq < 1000 ? freq : (freq / 1024) + 'k'}`] = lastNode;\r\n });\r\n\r\n this.#limiter = this.#audioCtx.createDynamicsCompressor();\r\n this.#limiter.threshold.setValueAtTime(-3.0, this.#audioCtx.currentTime);\r\n this.#limiter.ratio.setValueAtTime(40, this.#audioCtx.currentTime);\r\n this.#limiter.attack.setValueAtTime(0.000, this.#audioCtx.currentTime);\r\n this.#limiter.release.setValueAtTime(0.25, this.#audioCtx.currentTime);\r\n this.#output = this.#audioCtx.createGain();\r\n lastNode.connect(this.#limiter);\r\n this.#limiter.connect(this.#output);\r\n }\r\n\r\n\r\n #bandEqualizer(from, frequency) {\r\n const filter = this.#audioCtx.createBiquadFilter();\r\n filter.frequency.setTargetAtTime(frequency, 0, 0.0001);\r\n filter.type = \"peaking\";\r\n filter.gain.setTargetAtTime(0, 0, 0.0001);\r\n filter.Q.setTargetAtTime(1.0, 0, 0.0001);\r\n from.connect(filter);\r\n return filter;\r\n }\r\n\r\n}", "{\n \"zones\": [\n {\n \"midi\": 81,\n \"originalPitch\": 4200,\n \"keyRangeLow\": 0,\n \"keyRangeHigh\": 43,\n \"loopStart\": 256,\n \"loopEnd\": 768,\n \"coarseTune\": 0,\n \"fineTune\": 0,\n \"sampleRate\": 48000,\n \"ahdsr\": false,\n \"file\": \"SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU3LjcyLjEwMQAAAAAAAAAAAAAA//tUwAAAAAAAAAAAAAAAAAAAAAAAWGluZwAAAA8AAAACAAAGAACgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg//////////////////////////////////////////////////////////////////8AAAAATGF2YzU3Ljk2AAAAAAAAAAAAAAAAJALAAAAAAAAABgA5CeiPAAAAAAAAAAAAAAAAAAAA//vUxAAAB+gfQ1TwACTywCx/NYAJAABZOW7fg6F8L8A3AOwb5L2e7x5R5EoCADB8HwfPxACAYrB8H8oCDsHw/lAQdlwPqDHh/UCEp4fhiU8/ynv6BAGOZS1NzNUNm83W5HHJGz4Kk0TfzwzSZu8CgJ3TZ11pu3hi1hoxY8qMFcPAcBX40CM1RcwUo9EFQgiY2VPldy90c24GUwVQROZnA0ZXohQyMsyIBlAWEQK/zrsHfSBGmF4i+yiKKKNrP5FDrYJM+8XdeIRR1FaEwk0mLq5Upl0G35bBliJz8DxCcgSVtAYMpU27BVbW0tSXOzHsLU+88MTkCQ3PwO05aTrtqwF1G2YFHc7M1hamc5RYnJXbn6S9OU7L2apytcaEpk5bQVbXIszWrUzuzNatW5HKL05K+z9Jyip+vcyqG3yZTDELa1DcIazEIXV3jW1lV3jW1lV7h/M/7h/M/7h/9/+f/f/n/3/58qr2JTUtyqvYlNy3TXbFLct012xS3Kemu0lLWp6arSexu7G62Ja2Ja2Ja0QsKrWx13Wb36/a/7/ew5kMjLhQNcmAxqICUIjQsMqB4zeSzGokEALDBOxI2OrTTJJMLBUwcCQYAVMDdlQ0A6Zkis4q5jIAQzknMdGQMBLAltWVxZrJm4ma0hGaGCmrpKmfS87RrhMci3muq5p4+b4wKbPCqVlsBQHbcmCKhmxoZcGGmnZmJeZOEmiGS7nGjrWX5mn+j92HZJcMqKDIgYz0vMnJTHwUzYoMiIGdQNMuTIbj/U13dLc1aMqCjSTkzEvMpCTQjQy4qMkBjPTGR3X9pMI1N9q1aWtWpqtUyspMhBTOCwyYkMeAjNSsyUjMdATMCYyIgpZJZygGm+AqXGzWrWqtWzWrWjGgAy0lMhHwEXmVERjw4AigycfMdGwMVmSDhjQwCiSU1solVxiNamhqlpYZx3jllljvHLWWLlv/F3cfyKO+/8vfx/JY/7/y9/H8lj/v/Pv5Dk5D8bn4xGJyNxuf1llvHHWWW8cdZZbx//u0xLeAL2H/Z7nNkIFVkCR3sMAFx1llvHHWVbHGrllWAbmu1l2+wACIJmablgZJEkGiBRmRmRKSQMOakoAW1jywyxmXRDkBISlWnK1b7K0xdxcdLomjI+e1lat9latrlly7rLnrbVat8FFQgpgKeCmxTcgrgVVMQU1FMy45OS41VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV\",\n \"anchor\": 0.00533333\n },\n {\n \"midi\": 81,\n \"originalPitch\": 5400,\n \"keyRangeLow\": 44,\n \"keyRangeHigh\": 55,\n \"loopStart\": 128,\n \"loopEnd\": 384,\n \"coarseTune\": 0,\n \"fineTune\": 0,\n \"sampleRate\": 48000,\n \"ahdsr\": false,\n \"file\": \"SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU3LjcyLjEwMQAAAAAAAAAAAAAA//tUwAAAAAAAAAAAAAAAAAAAAAAAWGluZwAAAA8AAAACAAAEsADMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM//////////////////////////////////////////////////////////////////8AAAAATGF2YzU3Ljk2AAAAAAAAAAAAAAAAJATAAAAAAAAABLAMEvhQAAAAAAAAAAAAAAAAAAAA//vUxAAACSwNaVQwACRXSC6/NYAIAAa9txyS8qHAwMDPlz5QEIIROfLn1AhBBy3lz/BCt5c/wQz5c/RBCXPlw/EEEHLPlz9EEOt8QQQcs+XPykQVh8uH4gcIHLD6w+JgcGkGbGakSCqjColKJDEMCR4mYQ8kQZ1UAiwCAIbAc4b1maEch6LAEVzMhwxuYQGCgLBWbmQSPi+kAzkOM6i/Ei2XrGgFiMbisXednEOO7NP9KJdLKedbxd7vvezh3pl/YdmreFqxnZjEgf+NyN/I1TXaWzqnqWqTOzTyyihuX0cMUlNa3S81TYWrGd63q/RRuno4xSUUbt3YzSYU1fuH8z/uH8zp6OMUlFK6e/KKTG5zKZy+ax/+4fzP+4fzP70rp78opL1PXv0lSzVy+tjjVyyrY41e4fzf91/N/3X83/dfzf91/N/3X5/3D+b/uv5v+6/m/7r/3/6/9/+sst446yy3jVyyrY41csq2ONXLKtjjVyyrKiLXdbW5JI24SEB1CQjhFAAXAIxdxbUKO0ekXEuKphJ5DkSgYKJVFFxQVwUwFDcRcUFcFcCjsTYoK4K4FHYmxQXwrgUdibFBfCvCjsTcRXhXhT8TcRXhXhT8TcRXhXhT8TcRXhXhT8TcakxBTUUzLjk5LjWqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq//tkxMWDzQgxS7zzACgAADSAAAAEqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\",\n \"anchor\": 0.00266667\n },\n {\n \"midi\": 81,\n \"originalPitch\": 6600,\n \"keyRangeLow\": 56,\n \"keyRangeHigh\": 67,\n \"loopStart\": 64,\n \"loopEnd\": 192,\n \"coarseTune\": 0,\n \"fineTune\": 0,\n \"sampleRate\": 48000,\n \"ahdsr\": false,\n \"file\": \"SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU3LjcyLjEwMQAAAAAAAAAAAAAA//tUwAAAAAAAAAAAAAAAAAAAAAAAWGluZwAAAA8AAAACAAAE4ADs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs//////////////////////////////////////////////////////////////////8AAAAATGF2YzU3Ljk2AAAAAAAAAAAAAAAAJAXAAAAAAAAABODQyktQAAAAAAAAAAAAAAAAAAAA//vkxAAABywBgbQAACYVyC6/P9AwKAASUcckkt4YWD4fLn1AhBCJz5c+oEFghy5/ghy5+cghy7+GKZd/DHLn1HIYk5d/DHL+6H5d5TOdLnbLTLKrBqyq+vlkqeD4lCzTAngBgvMYACAAGg+NZZoFwogYAGAZCwCsDgBJsJhRJLyYvYUvg4BLFAA9AKpqYxQCumE3hMhEBIkBkBLuNR5oOGzUbs0Jk7jR1yTFgpzGY2TMgWV8qtT4fmaf4xDKgxlNgzTGRZScSFbPVQxarGZbWMLiNMUC1MshXMJx+MRSeaZHnuceOvbGrV2ls6MOQUMAAnMDAzMMgRMAQkMCQufiahT9zMJfim7ul5rIDBEFgJBgHgoHQuBANAwFA1WkUbqzssyns944flv09UjUcU9kjkkk9UjZfjOyzKep8Z2kxucyq9+ax9JFNJNJNZNFNFNVNJNJNbKRRvGQxjKejfJ2Udq/9bf1darY41U0U0U1U0k0k+k0U0U+U0k0k+k0e5/zD+5/zD+5/zX93/Nf3f81/d////////7/9f+//X/v/1/7/9Jop8ppJpJ9Jop6qwppJ7KxJGp6qwpHKrKxI2qqqwo3KrKxI2qqq9RuVWV8jaqqr1G5TEFNRTMuOTkuNVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVMQU1FMy45OS41VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//sUxNoDwAAB/hwAACAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV\",\n \"anchor\": 0.00133333\n },\n {\n \"midi\": 81,\n \"originalPitch\": 7800,\n \"keyRangeLow\": 68,\n \"keyRangeHigh\": 79,\n \"loopStart\": 32,\n \"loopEnd\": 96,\n \"coarseTune\": 0,\n \"fineTune\": 0,\n \"sampleRate\": 48000,\n \"ahdsr\": false,\n \"file\": \"SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU3LjcyLjEwMQAAAAAAAAAAAAAA//tUwAAAAAAAAAAAAAAAAAAAAAAAWGluZwAAAA8AAAACAAADwADm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm//////////////////////////////////////////////////////////////////8AAAAATGF2YzU3Ljk2AAAAAAAAAAAAAAAAJAZAAAAAAAAAA8CsVDBMAAAAAAAAAAAAAAAAAAAA//vExAAABmQBjaAAACGQBa9497AdtbAkWdckklxRyjhQ5BBYYqOFHRAXDHKHOGOUOcMco7nOJHawxynnOU5cMcHOXOcHOl3NXGMqsiEAqoMI8QsSUcIsgeiQgJISFCg5ABAyw+VQaiK8yY18FNiuxBUorwU0FdiC4ivimgrsQXEV4KaCuxBcTfBXAv4isTfiuBf6KxN+L4r8RUU3wXoL+JsU3wXoL+JsV3gvRSpMQU1FMy45OS41qqqqqqqqqqqqqqqqqqqqqqqq6goZoAABEOiCXDs8P3G8oicJAhZjVVVBlsStNFVVUT8StNVMQU1FMy45OS41VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//sUxOuDxEQnByYExigAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV\",\n \"anchor\": 0.00066667\n },\n {\n \"midi\": 81,\n \"originalPitch\": 9000,\n \"keyRangeLow\": 80,\n \"keyRangeHigh\": 91,\n \"loopStart\": 16,\n \"loopEnd\": 48,\n \"coarseTune\": 0,\n \"fineTune\": 0,\n \"sampleRate\": 48000,\n \"ahdsr\": false,\n \"file\": \"SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU3LjcyLjEwMQAAAAAAAAAAAAAA//tUwAAAAAAAAAAAAAAAAAAAAAAAWGluZwAAAA8AAAACAAADwADm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm//////////////////////////////////////////////////////////////////8AAAAATGF2YzU3Ljk2AAAAAAAAAAAAAAAAJAaAAAAAAAAAA8ChXkahAAAAAAAAAAAAAAAAAAAA//vExAAABkQDh+AAACGUhq9895iZZVlzMgFEYk0nBACCLQfD6gTB8/qBDBwMflC4f/gQMfqBMH/4OHP4Df+XBw5+UBN/6wJu1fapqZhlttyF2FyUYQ0W0QkFSJiRIro4TAYk8aQCAQCAKjiRIkSr+xQUFOBQUV/5BQU4KChv+CgoL4KCu/4QUN8KCn/8UFN8FFf/wgp/hQ3/8FBXYgoL/+FBX5BQ3/8FBfigopVMQU1FMy45OS41VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVMQU1FMy45OS41VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//sUxNoDwAAB/gAAACAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV\",\n \"anchor\": 0.00033333\n },\n {\n \"midi\": 81,\n \"originalPitch\": 10200,\n \"keyRangeLow\": 92,\n \"keyRangeHigh\": 103,\n \"loopStart\": 8,\n \"loopEnd\": 56,\n \"coarseTune\": 0,\n \"fineTune\": 0,\n \"sampleRate\": 48000,\n \"ahdsr\": false,\n \"file\": \"SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU3LjcyLjEwMQAAAAAAAAAAAAAA//tUwAAAAAAAAAAAAAAAAAAAAAAAWGluZwAAAA8AAAACAAADwADm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm//////////////////////////////////////////////////////////////////8AAAAATGF2YzU3Ljk2AAAAAAAAAAAAAAAAJAaAAAAAAAAAA8AljJJeAAAAAAAAAAAAAAAAAAAA//vExAAABmgDh+AAACG7Cq649JmAh3unfGYwJRhSgQBBEXB8PjogBDn8EwfP6gQdicP/g4GOXB/lHfgmH905/UclwcOf/8oA/2r/qekIFM1D+AxK8OEgo9IhpLSJFdJaehzC3CbBom0GChJpEiRn/tRxIkSJT6OJJB3BUFXSwNB3BUFQVgqCoaqBoGsqd4iBo8oGgaTWCoaxEDR6VBUFTpUFQV//BoGoiBoO//rxKCv//iIGv/+WTEFNRTMuOTkuNVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVMQU1FMy45OS41VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//sUxNoDwAAB/gAAACAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV\",\n \"anchor\": 0.00016667\n },\n {\n \"midi\": 81,\n \"originalPitch\": 11400,\n \"keyRangeLow\": 104,\n \"keyRangeHigh\": 115,\n \"loopStart\": 12,\n \"loopEnd\": 52,\n \"coarseTune\": 0,\n \"fineTune\": 0,\n \"sampleRate\": 48000,\n \"ahdsr\": false,\n \"file\": \"SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU3LjcyLjEwMQAAAAAAAAAAAAAA//tUwAAAAAAAAAAAAAAAAAAAAAAAWGluZwAAAA8AAAACAAADwADm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm//////////////////////////////////////////////////////////////////8AAAAATGF2YzU3Ljk2AAAAAAAAAAAAAAAAJAaAAAAAAAAAA8CNr1v4AAAAAAAAAAAAAAAAAAAA//vExAAAB1SVheCEbeI4SC349ApomIy4jYiPtA6x5AACs4xjvkAAPmMY/wAXzGMf4AL/X+IgG4PvwQOfIQQOZcH//wQlwfBA5/1h/iB2sP/17/1GMvIAEJ8BiUYMEW0NSAKQjJWj5HCbB/EGHqQ5m2plUuYL1WvVqeGZmb/VVVf9mZr/1VVX9hYGwKgFgbB9TCwNgbB8BG6lKUreYxjfKUrfQxvylK3oYxjeUKAgICJYoCAgICUvoYxvylL9DGN9SlL9P+UrfMYxjOoYCAgIUb6lL////////qUpSzASTEFNRTMuOTkuNaqqqqpMQU1FMy45OS41qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq//sUxNoDwAAB/gAAACAAADSAAAAEqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\",\n \"anchor\": 0.00008333\n },\n {\n \"midi\": 81,\n \"originalPitch\": 12600,\n \"keyRangeLow\": 116,\n \"keyRangeHigh\": 127,\n \"loopStart\": 6,\n \"loopEnd\": 42,\n \"coarseTune\": 0,\n \"fineTune\": 0,\n \"sampleRate\": 48000,\n \"ahdsr\": false,\n \"file\": \"SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU3LjcyLjEwMQAAAAAAAAAAAAAA//tUwAAAAAAAAAAAAAAAAAAAAAAAWGluZwAAAA8AAAACAAAEIADo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo//////////////////////////////////////////////////////////////////8AAAAATGF2YzU3Ljk2AAAAAAAAAAAAAAAAJAaQAAAAAAAABCDWHfeqAAAAAAAAAAAAAAAAAAAA//vUxAAACUUrfeCE1eMLSCx88a54l3jMh4t/trUApEAAAUAGYxja+WMYx/yAAH+MY/+AYx/4AAX8xjH/7/8AF//zHyAMdoIAgAAADAYWTt4IA/Kc5/////////y4Pg/v3FZropQkAAAEiDVBBhkjdBSk5JyDlHqDmWi+kJRsJiOZ69eva6x+zAQEBCm/9VVVb/9mVVL/9mZmP/6qqqn/8ZlVV/6zMzM3/VCgICanXX+5I2JRJHaana+SSNwIQEQAwAQAQEw6j5KBCASACACAKAmBGHcdr5RNR2jtJRsed/DkTU1NTra/3Oc5znf+1rWuc7/3Na1ra/9znOc7/9rWtc7/9zWta3/4c5znO/9rTU1NXOvbW4lDtDyHkPI7TqQIQAxMQU1FMy45OS41qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpMQU1FMy45OS41qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq//sUxNoDwAABpAAAACAAADSAAAAEqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\",\n \"anchor\": 0.00004167\n }\n ]\n}", "import MidiPlayer from 'midi-player-js';\r\nimport WebAudioFontPlayer from \"./webaudiofontplayer\";\r\nimport DefaultPreset from \"./presets/defaultpreset.json\";\r\n\r\n\r\n\r\nexport default class MidiAudioPlayer extends MidiPlayer.Player {\r\n\r\n\t#audioCtx = null;\r\n\t#audioPlayer = null;\r\n\t#activeNotes = null;\r\n\r\n\t#opts = {\r\n\t\tpreset: DefaultPreset,\r\n volume: 0.012,\r\n\t\tonEndFile: null\r\n\t};\r\n\r\n\r\n\tconstructor(opts = {}) {\r\n super(event => this.#handleMidiPipeline(event));\r\n\t\tthis.#opts = { ...this.#opts, ...opts };\r\n this.#activeNotes = new Map();\r\n\t\tthis.#audioCtx = new (window.AudioContext || window.webkitAudioContext)();\r\n\t\tthis.#audioPlayer = new WebAudioFontPlayer(this.#audioCtx, this.#opts.preset);\r\n this.on('endOfFile', async () => {\r\n\t\t\tawait new Promise(resolve => requestAnimationFrame(() => setTimeout(resolve, 1)));\r\n\t\t\tawait this.#endOfFile();\r\n });\r\n\t}\r\n\r\n async load(content) {\r\n\t\tif(this.isPlaying()) this.stop();\r\n\t\tthis.#clearActiveNotes();\r\n\t\tawait this.loadArrayBuffer(content);\r\n\t}\r\n \r\n\r\n\tasync play(content = null) {\r\n\t\tif(content) await this.load(content);\r\n await this.#audioCtx.resume();\r\n\t\tawait super.play();\r\n\t}\r\n \r\n\r\n\tasync pause() {\r\n await super.pause();\r\n await this.#clearActiveNotes();\r\n await this.#audioPlayer.cancelQueue();\r\n\t}\r\n\r\n\t\r\n async stop() {\r\n await super.stop();\r\n await this.#clearActiveNotes();\r\n await this.#audioPlayer.cancelQueue();\r\n\t}\r\n\r\n\r\n\tasync #endOfFile() {\r\n\t\tif(typeof this.#opts.onEndFile == 'function') await this.#opts.onEndFile();\r\n\t}\r\n\r\n\r\n async #handleMidiPipeline(event) {\r\n if (event.name !== 'Note on' && event.name !== 'Note off') return;\r\n if (!this.isPlaying()) return;\r\n if (event.noteNumber === undefined) return;\r\n\r\n const now = this.#audioCtx.currentTime;\r\n\r\n switch (event.name) {\r\n case 'Note on':\r\n if (event.velocity > 0 && event.velocity <= 127) {\r\n this.#stopNotePipe(event.noteNumber);\r\n const vol = (event.velocity / 127) * this.#opts.volume;\r\n const envelope = this.#audioPlayer.queueWaveTable(0, event.noteNumber, 2, vol);\r\n this.#activeNotes.set(event.noteNumber, envelope);\r\n } else {\r\n this.#stopNotePipe(event.noteNumber);\r\n }\r\n break;\r\n\r\n case 'Note off':\r\n this.#stopNotePipe(event.noteNumber);\r\n break;\r\n }\r\n }\r\n\r\n\r\n #stopNotePipe(noteNumber) {\r\n const envelope = this.#activeNotes.get(noteNumber);\r\n if (envelope) {\r\n envelope.cancel();\r\n this.#activeNotes.delete(noteNumber);\r\n }\r\n }\r\n\r\n\r\n #clearActiveNotes() {\r\n if (this.#activeNotes) {\r\n this.#activeNotes.forEach((envelope, note) => { if (envelope && envelope.cancel) envelope.cancel(); });\r\n this.#activeNotes.clear();\r\n }\r\n }\r\n\r\n}\r\n\r\n// export { MidiAudioPlayer };", "import MidiAudioPlayer from './src/midiaudioplayer.js';\r\n\r\nif (typeof window !== 'undefined') window.MidiAudioPlayer = MidiAudioPlayer;\r\n\r\n\r\nexport { MidiAudioPlayer };\r\nexport default MidiAudioPlayer;"],
5
- "mappings": "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",
6
- "names": ["_loop", "Utils", "atob", "Track", "index", "Player", "e"]
3
+ "sources": ["../node_modules/midi-player-js/build/index.browser.js", "../node_modules/webaudiofontplayer/src/webaudiofontplayer.js", "../node_modules/webaudiofontplayer/index.js", "../src/libraries/audiocompressor.js", "../src/libraries/indexeddbstorage.js", "../src/midiaudioplayer.js", "../index.js"],
4
+ "sourcesContent": ["function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\n\nfunction _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n Object.defineProperty(Constructor, \"prototype\", {\n writable: false\n });\n return Constructor;\n}\n\n/**\n * Constants used in player.\n */\nvar Constants = {\n VERSION: '2.0.17',\n NOTES: [],\n HEADER_CHUNK_LENGTH: 14,\n CIRCLE_OF_FOURTHS: ['C', 'F', 'Bb', 'Eb', 'Ab', 'Db', 'Gb', 'Cb', 'Fb', 'Bbb', 'Ebb', 'Abb'],\n CIRCLE_OF_FIFTHS: ['C', 'G', 'D', 'A', 'E', 'B', 'F#', 'C#', 'G#', 'D#', 'A#', 'E#']\n}; // Builds notes object for reference against binary values.\n\nvar allNotes = [['C'], ['C#', 'Db'], ['D'], ['D#', 'Eb'], ['E'], ['F'], ['F#', 'Gb'], ['G'], ['G#', 'Ab'], ['A'], ['A#', 'Bb'], ['B']];\nvar counter = 0; // All available octaves.\n\nvar _loop = function _loop(i) {\n allNotes.forEach(function (noteGroup) {\n noteGroup.forEach(function (note) {\n return Constants.NOTES[counter] = note + i;\n });\n counter++;\n });\n};\n\nfor (var i = -1; i <= 9; i++) {\n _loop(i);\n}\n\n/**\n * Contains misc static utility methods.\n */\nvar Utils = /*#__PURE__*/function () {\n function Utils() {\n _classCallCheck(this, Utils);\n }\n\n _createClass(Utils, null, [{\n key: \"byteToHex\",\n value:\n /**\n * Converts a single byte to a hex string.\n * @param {number} byte\n * @return {string}\n */\n function byteToHex(_byte) {\n // Ensure hex string always has two chars\n return ('0' + _byte.toString(16)).slice(-2);\n }\n /**\n * Converts an array of bytes to a hex string.\n * @param {array} byteArray\n * @return {string}\n */\n\n }, {\n key: \"bytesToHex\",\n value: function bytesToHex(byteArray) {\n var hex = [];\n byteArray.forEach(function (_byte2) {\n return hex.push(Utils.byteToHex(_byte2));\n });\n return hex.join('');\n }\n /**\n * Converts a hex string to a number.\n * @param {string} hexString\n * @return {number}\n */\n\n }, {\n key: \"hexToNumber\",\n value: function hexToNumber(hexString) {\n return parseInt(hexString, 16);\n }\n /**\n * Converts an array of bytes to a number.\n * @param {array} byteArray\n * @return {number}\n */\n\n }, {\n key: \"bytesToNumber\",\n value: function bytesToNumber(byteArray) {\n return Utils.hexToNumber(Utils.bytesToHex(byteArray));\n }\n /**\n * Converts an array of bytes to letters.\n * @param {array} byteArray\n * @return {string}\n */\n\n }, {\n key: \"bytesToLetters\",\n value: function bytesToLetters(byteArray) {\n var letters = [];\n byteArray.forEach(function (_byte3) {\n return letters.push(String.fromCharCode(_byte3));\n });\n return letters.join('');\n }\n /**\n * Converts a decimal to it's binary representation.\n * @param {number} dec\n * @return {string}\n */\n\n }, {\n key: \"decToBinary\",\n value: function decToBinary(dec) {\n return (dec >>> 0).toString(2);\n }\n /**\n * Determines the length in bytes of a variable length quaantity. The first byte in given range is assumed to be beginning of var length quantity.\n * @param {array} byteArray\n * @return {number}\n */\n\n }, {\n key: \"getVarIntLength\",\n value: function getVarIntLength(byteArray) {\n // Get byte count of delta VLV\n // http://www.ccarh.org/courses/253/handout/vlv/\n // If byte is greater or equal to 80h (128 decimal) then the next byte\n // is also part of the VLV,\n // else byte is the last byte in a VLV.\n var currentByte = byteArray[0];\n var byteCount = 1;\n\n while (currentByte >= 128) {\n currentByte = byteArray[byteCount];\n byteCount++;\n }\n\n return byteCount;\n }\n /**\n * Reads a variable length value.\n * @param {array} byteArray\n * @return {number}\n */\n\n }, {\n key: \"readVarInt\",\n value: function readVarInt(byteArray) {\n var result = 0;\n byteArray.forEach(function (number) {\n var b = number;\n\n if (b & 0x80) {\n result += b & 0x7f;\n result <<= 7;\n } else {\n /* b is the last byte */\n result += b;\n }\n });\n return result;\n }\n /**\n * Decodes base-64 encoded string\n * @param {string} string\n * @return {string}\n */\n\n }, {\n key: \"atob\",\n value: function (_atob) {\n function atob(_x) {\n return _atob.apply(this, arguments);\n }\n\n atob.toString = function () {\n return _atob.toString();\n };\n\n return atob;\n }(function (string) {\n if (typeof atob === 'function') return atob(string);\n return Buffer.from(string, 'base64').toString('binary');\n })\n }]);\n\n return Utils;\n}();\n\n/**\n * Class representing a track. Contains methods for parsing events and keeping track of pointer.\n */\n\nvar Track = /*#__PURE__*/function () {\n function Track(index, data) {\n _classCallCheck(this, Track);\n\n this.enabled = true;\n this.eventIndex = 0;\n this.pointer = 0;\n this.lastTick = 0;\n this.lastStatus = null;\n this.index = index;\n this.data = data;\n this.delta = 0;\n this.runningDelta = 0;\n this.events = []; // Ensure last 3 bytes of track are End of Track event\n\n var lastThreeBytes = this.data.subarray(this.data.length - 3, this.data.length);\n\n if (!(lastThreeBytes[0] === 0xff && lastThreeBytes[1] === 0x2f && lastThreeBytes[2] === 0x00)) {\n throw 'Invalid MIDI file; Last three bytes of track ' + this.index + 'must be FF 2F 00 to mark end of track';\n }\n }\n /**\n * Resets all stateful track informaion used during playback.\n * @return {Track}\n */\n\n\n _createClass(Track, [{\n key: \"reset\",\n value: function reset() {\n this.enabled = true;\n this.eventIndex = 0;\n this.pointer = 0;\n this.lastTick = 0;\n this.lastStatus = null;\n this.delta = 0;\n this.runningDelta = 0;\n return this;\n }\n /**\n * Sets this track to be enabled during playback.\n * @return {Track}\n */\n\n }, {\n key: \"enable\",\n value: function enable() {\n this.enabled = true;\n return this;\n }\n /**\n * Sets this track to be disabled during playback.\n * @return {Track}\n */\n\n }, {\n key: \"disable\",\n value: function disable() {\n this.enabled = false;\n return this;\n }\n /**\n * Sets the track event index to the nearest event to the given tick.\n * @param {number} tick\n * @return {Track}\n */\n\n }, {\n key: \"setEventIndexByTick\",\n value: function setEventIndexByTick(tick) {\n tick = tick || 0;\n\n for (var i = 0; i < this.events.length; i++) {\n if (this.events[i].tick >= tick) {\n this.eventIndex = i;\n return this;\n }\n }\n }\n /**\n * Gets byte located at pointer position.\n * @return {number}\n */\n\n }, {\n key: \"getCurrentByte\",\n value: function getCurrentByte() {\n return this.data[this.pointer];\n }\n /**\n * Gets count of delta bytes and current pointer position.\n * @return {number}\n */\n\n }, {\n key: \"getDeltaByteCount\",\n value: function getDeltaByteCount() {\n return Utils.getVarIntLength(this.data.subarray(this.pointer));\n }\n /**\n * Get delta value at current pointer position.\n * @return {number}\n */\n\n }, {\n key: \"getDelta\",\n value: function getDelta() {\n return Utils.readVarInt(this.data.subarray(this.pointer, this.pointer + this.getDeltaByteCount()));\n }\n /**\n * Handles event within a given track starting at specified index\n * @param {number} currentTick\n * @param {boolean} dryRun - If true events will be parsed and returned regardless of time.\n */\n\n }, {\n key: \"handleEvent\",\n value: function handleEvent(currentTick, dryRun) {\n dryRun = dryRun || false;\n\n if (dryRun) {\n var elapsedTicks = currentTick - this.lastTick;\n var delta = this.getDelta();\n var eventReady = elapsedTicks >= delta;\n\n if (this.pointer < this.data.length && (dryRun || eventReady)) {\n var event = this.parseEvent();\n if (this.enabled) return event; // Recursively call this function for each event ahead that has 0 delta time?\n }\n } else {\n // Let's actually play the MIDI from the generated JSON events created by the dry run.\n // Process all events that have passed to avoid falling behind on dense MIDI files.\n var events = [];\n\n while (this.events[this.eventIndex] && this.events[this.eventIndex].tick <= currentTick) {\n if (this.enabled) events.push(this.events[this.eventIndex]);\n this.eventIndex++;\n }\n\n if (events.length > 0) return events;\n }\n\n return null;\n }\n /**\n * Get string data from event.\n * @param {number} eventStartIndex\n * @return {string}\n */\n\n }, {\n key: \"getStringData\",\n value: function getStringData(eventStartIndex) {\n var varIntLength = Utils.getVarIntLength(this.data.subarray(eventStartIndex + 2));\n var varIntValue = Utils.readVarInt(this.data.subarray(eventStartIndex + 2, eventStartIndex + 2 + varIntLength));\n var letters = Utils.bytesToLetters(this.data.subarray(eventStartIndex + 2 + varIntLength, eventStartIndex + 2 + varIntLength + varIntValue));\n return letters;\n }\n /**\n * Parses event into JSON and advances pointer for the track\n * @return {object}\n */\n\n }, {\n key: \"parseEvent\",\n value: function parseEvent() {\n var eventStartIndex = this.pointer + this.getDeltaByteCount();\n var eventJson = {};\n var deltaByteCount = this.getDeltaByteCount();\n eventJson.track = this.index + 1;\n eventJson.delta = this.getDelta();\n this.lastTick = this.lastTick + eventJson.delta;\n this.runningDelta += eventJson.delta;\n eventJson.tick = this.runningDelta;\n eventJson.byteIndex = this.pointer; //eventJson.raw = event;\n\n if (this.data[eventStartIndex] == 0xff) {\n // Meta Event\n // If this is a meta event we should emit the data and immediately move to the next event\n // otherwise if we let it run through the next cycle a slight delay will accumulate if multiple tracks\n // are being played simultaneously\n switch (this.data[eventStartIndex + 1]) {\n case 0x00:\n // Sequence Number\n eventJson.name = 'Sequence Number';\n break;\n\n case 0x01:\n // Text Event\n eventJson.name = 'Text Event';\n eventJson.string = this.getStringData(eventStartIndex);\n break;\n\n case 0x02:\n // Copyright Notice\n eventJson.name = 'Copyright Notice';\n break;\n\n case 0x03:\n // Sequence/Track Name\n eventJson.name = 'Sequence/Track Name';\n eventJson.string = this.getStringData(eventStartIndex);\n break;\n\n case 0x04:\n // Instrument Name\n eventJson.name = 'Instrument Name';\n eventJson.string = this.getStringData(eventStartIndex);\n break;\n\n case 0x05:\n // Lyric\n eventJson.name = 'Lyric';\n eventJson.string = this.getStringData(eventStartIndex);\n break;\n\n case 0x06:\n // Marker\n eventJson.name = 'Marker';\n eventJson.string = this.getStringData(eventStartIndex);\n break;\n\n case 0x07:\n // Cue Point\n eventJson.name = 'Cue Point';\n eventJson.string = this.getStringData(eventStartIndex);\n break;\n\n case 0x09:\n // Device Name\n eventJson.name = 'Device Name';\n eventJson.string = this.getStringData(eventStartIndex);\n break;\n\n case 0x20:\n // MIDI Channel Prefix\n eventJson.name = 'MIDI Channel Prefix';\n break;\n\n case 0x21:\n // MIDI Port\n eventJson.name = 'MIDI Port';\n eventJson.data = Utils.bytesToNumber([this.data[eventStartIndex + 3]]);\n break;\n\n case 0x2F:\n // End of Track\n eventJson.name = 'End of Track';\n break;\n\n case 0x51:\n // Set Tempo\n eventJson.name = 'Set Tempo';\n eventJson.data = Math.round(60000000 / Utils.bytesToNumber(this.data.subarray(eventStartIndex + 3, eventStartIndex + 6)));\n this.tempo = eventJson.data;\n break;\n\n case 0x54:\n // SMTPE Offset\n eventJson.name = 'SMTPE Offset';\n break;\n\n case 0x58:\n // Time Signature\n // FF 58 04 nn dd cc bb\n eventJson.name = 'Time Signature';\n eventJson.data = this.data.subarray(eventStartIndex + 3, eventStartIndex + 7);\n eventJson.timeSignature = \"\" + eventJson.data[0] + \"/\" + Math.pow(2, eventJson.data[1]);\n break;\n\n case 0x59:\n // Key Signature\n // FF 59 02 sf mi\n eventJson.name = 'Key Signature';\n eventJson.data = this.data.subarray(eventStartIndex + 3, eventStartIndex + 5); // sf byte is signed (-7 to 7), but Uint8Array gives unsigned values\n\n var sf = eventJson.data[0] > 127 ? eventJson.data[0] - 256 : eventJson.data[0];\n\n if (sf >= 0) {\n eventJson.keySignature = Constants.CIRCLE_OF_FIFTHS[sf];\n } else {\n eventJson.keySignature = Constants.CIRCLE_OF_FOURTHS[Math.abs(sf)];\n }\n\n if (eventJson.data[1] == 0) {\n eventJson.keySignature += \" Major\";\n } else if (eventJson.data[1] == 1) {\n eventJson.keySignature += \" Minor\";\n }\n\n break;\n\n case 0x7F:\n // Sequencer-Specific Meta-event\n eventJson.name = 'Sequencer-Specific Meta-event';\n break;\n\n default:\n eventJson.name = 'Unknown: ' + this.data[eventStartIndex + 1].toString(16);\n break;\n }\n\n var varIntLength = Utils.getVarIntLength(this.data.subarray(eventStartIndex + 2));\n var length = Utils.readVarInt(this.data.subarray(eventStartIndex + 2, eventStartIndex + 2 + varIntLength)); //console.log(eventJson);\n\n this.pointer += deltaByteCount + 2 + varIntLength + length; //console.log(eventJson);\n } else if (this.data[eventStartIndex] === 0xf0) {\n // Sysex\n eventJson.name = 'Sysex';\n var varQuantityByteLength = Utils.getVarIntLength(this.data.subarray(eventStartIndex + 1));\n var varQuantityByteValue = Utils.readVarInt(this.data.subarray(eventStartIndex + 1, eventStartIndex + 1 + varQuantityByteLength));\n eventJson.data = this.data.subarray(eventStartIndex + 1 + varQuantityByteLength, eventStartIndex + 1 + varQuantityByteLength + varQuantityByteValue);\n this.pointer += deltaByteCount + 1 + varQuantityByteLength + varQuantityByteValue;\n } else if (this.data[eventStartIndex] === 0xf7) {\n // Sysex (escape)\n // http://www.somascape.org/midi/tech/mfile.html#sysex\n eventJson.name = 'Sysex (escape)';\n\n var _varQuantityByteLength = Utils.getVarIntLength(this.data.subarray(eventStartIndex + 1));\n\n var _varQuantityByteValue = Utils.readVarInt(this.data.subarray(eventStartIndex + 1, eventStartIndex + 1 + _varQuantityByteLength));\n\n eventJson.data = this.data.subarray(eventStartIndex + 1 + _varQuantityByteLength, eventStartIndex + 1 + _varQuantityByteLength + _varQuantityByteValue);\n this.pointer += deltaByteCount + 1 + _varQuantityByteLength + _varQuantityByteValue;\n } else {\n // Voice event\n if (this.data[eventStartIndex] < 0x80) {\n // Running status\n eventJson.running = true;\n eventJson.noteNumber = this.data[eventStartIndex];\n eventJson.noteName = Constants.NOTES[this.data[eventStartIndex]];\n eventJson.velocity = this.data[eventStartIndex + 1];\n\n if (this.lastStatus <= 0x8f) {\n eventJson.name = 'Note off';\n eventJson.channel = this.lastStatus - 0x80 + 1;\n this.pointer += deltaByteCount + 2;\n } else if (this.lastStatus <= 0x9f) {\n eventJson.name = 'Note on';\n eventJson.channel = this.lastStatus - 0x90 + 1;\n this.pointer += deltaByteCount + 2;\n } else if (this.lastStatus <= 0xaf) {\n // Polyphonic Key Pressure\n eventJson.name = 'Polyphonic Key Pressure';\n eventJson.channel = this.lastStatus - 0xa0 + 1;\n eventJson.note = Constants.NOTES[this.data[eventStartIndex]];\n eventJson.pressure = this.data[eventStartIndex + 1];\n this.pointer += deltaByteCount + 2;\n } else if (this.lastStatus <= 0xbf) {\n // Controller Change\n eventJson.name = 'Controller Change';\n eventJson.channel = this.lastStatus - 0xb0 + 1;\n eventJson.number = this.data[eventStartIndex];\n eventJson.value = this.data[eventStartIndex + 1];\n this.pointer += deltaByteCount + 2;\n } else if (this.lastStatus <= 0xcf) {\n // Program Change\n eventJson.name = 'Program Change';\n eventJson.channel = this.lastStatus - 0xc0 + 1;\n eventJson.value = this.data[eventStartIndex + 1];\n this.pointer += deltaByteCount + 1;\n } else if (this.lastStatus <= 0xdf) {\n // Channel Key Pressure\n eventJson.name = 'Channel Key Pressure';\n eventJson.channel = this.lastStatus - 0xd0 + 1;\n this.pointer += deltaByteCount + 1;\n } else if (this.lastStatus <= 0xef) {\n // Pitch Bend\n eventJson.name = 'Pitch Bend';\n eventJson.channel = this.lastStatus - 0xe0 + 1;\n eventJson.value = (this.data[eventStartIndex + 1] & 0x7f) << 7 | this.data[eventStartIndex] & 0x7f;\n this.pointer += deltaByteCount + 2;\n } else {\n throw \"Unknown event (running): \".concat(this.lastStatus);\n }\n } else {\n this.lastStatus = this.data[eventStartIndex];\n\n if (this.data[eventStartIndex] <= 0x8f) {\n // Note off\n eventJson.name = 'Note off';\n eventJson.channel = this.lastStatus - 0x80 + 1;\n eventJson.noteNumber = this.data[eventStartIndex + 1];\n eventJson.noteName = Constants.NOTES[this.data[eventStartIndex + 1]];\n eventJson.velocity = Math.round(this.data[eventStartIndex + 2] / 127 * 100);\n this.pointer += deltaByteCount + 3;\n } else if (this.data[eventStartIndex] <= 0x9f) {\n // Note on\n eventJson.name = 'Note on';\n eventJson.channel = this.lastStatus - 0x90 + 1;\n eventJson.noteNumber = this.data[eventStartIndex + 1];\n eventJson.noteName = Constants.NOTES[this.data[eventStartIndex + 1]];\n eventJson.velocity = Math.round(this.data[eventStartIndex + 2] / 127 * 100);\n this.pointer += deltaByteCount + 3;\n } else if (this.data[eventStartIndex] <= 0xaf) {\n // Polyphonic Key Pressure\n eventJson.name = 'Polyphonic Key Pressure';\n eventJson.channel = this.lastStatus - 0xa0 + 1;\n eventJson.note = Constants.NOTES[this.data[eventStartIndex + 1]];\n eventJson.pressure = this.data[eventStartIndex + 2];\n this.pointer += deltaByteCount + 3;\n } else if (this.data[eventStartIndex] <= 0xbf) {\n // Controller Change\n eventJson.name = 'Controller Change';\n eventJson.channel = this.lastStatus - 0xb0 + 1;\n eventJson.number = this.data[eventStartIndex + 1];\n eventJson.value = this.data[eventStartIndex + 2];\n this.pointer += deltaByteCount + 3;\n } else if (this.data[eventStartIndex] <= 0xcf) {\n // Program Change\n eventJson.name = 'Program Change';\n eventJson.channel = this.lastStatus - 0xc0 + 1;\n eventJson.value = this.data[eventStartIndex + 1];\n this.pointer += deltaByteCount + 2;\n } else if (this.data[eventStartIndex] <= 0xdf) {\n // Channel Key Pressure\n eventJson.name = 'Channel Key Pressure';\n eventJson.channel = this.lastStatus - 0xd0 + 1;\n this.pointer += deltaByteCount + 2;\n } else if (this.data[eventStartIndex] <= 0xef) {\n // Pitch Bend\n eventJson.name = 'Pitch Bend';\n eventJson.channel = this.lastStatus - 0xe0 + 1;\n eventJson.value = (this.data[eventStartIndex + 2] & 0x7f) << 7 | this.data[eventStartIndex + 1] & 0x7f;\n this.pointer += deltaByteCount + 3;\n } else {\n throw \"Unknown event: \".concat(this.data[eventStartIndex]); //eventJson.name = `Unknown. Pointer: ${this.pointer.toString()}, ${eventStartIndex.toString()}, ${this.data[eventStartIndex]}, ${this.data.length}`;\n }\n }\n }\n\n this.delta += eventJson.delta;\n this.events.push(eventJson);\n return eventJson;\n }\n /**\n * Returns true if pointer has reached the end of the track.\n * @param {boolean}\n */\n\n }, {\n key: \"endOfTrack\",\n value: function endOfTrack() {\n if (this.data[this.pointer + 1] == 0xff && this.data[this.pointer + 2] == 0x2f && this.data[this.pointer + 3] == 0x00) {\n return true;\n }\n\n return false;\n }\n }]);\n\n return Track;\n}();\n\nif (!Uint8Array.prototype.forEach) {\n Object.defineProperty(Uint8Array.prototype, 'forEach', {\n value: Array.prototype.forEach\n });\n}\n/**\n * Main player class. Contains methods to load files, start, stop.\n * @param {function} - Callback to fire for each MIDI event. Can also be added with on('midiEvent', fn)\n * @param {array} - Array buffer of MIDI file (optional).\n */\n\n\nvar Player = /*#__PURE__*/function () {\n function Player(eventHandler, buffer) {\n _classCallCheck(this, Player);\n\n this.sampleRate = 5; // milliseconds\n\n this.startTime = 0;\n this.buffer = buffer || null;\n this.midiChunksByteLength = null;\n this.division;\n this.format;\n this.setTimeoutId = false;\n this.scheduledTime = 0;\n this.tracks = [];\n this.instruments = [];\n this.defaultTempo = 120;\n this.tempo = null;\n this.startTick = 0;\n this.tick = 0;\n this.lastTick = null;\n this.inLoop = false;\n this.totalTicks = 0;\n this.events = [];\n this.totalEvents = 0;\n this.tempoMap = [];\n this.eventListeners = {};\n if (typeof eventHandler === 'function') this.on('midiEvent', eventHandler);\n }\n /**\n * Load a file into the player (Node.js only).\n * @param {string} path - Path of file.\n * @return {Player}\n */\n\n\n _createClass(Player, [{\n key: \"loadFile\",\n value: function loadFile(path) {\n {\n throw 'loadFile is only supported on Node.js';\n }\n }\n /**\n * Load an array buffer into the player.\n * @param {array} arrayBuffer - Array buffer of file to be loaded.\n * @return {Player}\n */\n\n }, {\n key: \"loadArrayBuffer\",\n value: function loadArrayBuffer(arrayBuffer) {\n this.buffer = new Uint8Array(arrayBuffer);\n return this.fileLoaded();\n }\n /**\n * Load a data URI into the player.\n * @param {string} dataUri - Data URI to be loaded.\n * @return {Player}\n */\n\n }, {\n key: \"loadDataUri\",\n value: function loadDataUri(dataUri) {\n // convert base64 to raw binary data held in a string.\n // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this\n var byteString = Utils.atob(dataUri.split(',')[1]); // write the bytes of the string to an ArrayBuffer\n\n var ia = new Uint8Array(byteString.length);\n\n for (var i = 0; i < byteString.length; i++) {\n ia[i] = byteString.charCodeAt(i);\n }\n\n this.buffer = ia;\n return this.fileLoaded();\n }\n /**\n * Get filesize of loaded file in number of bytes.\n * @return {number} - The filesize.\n */\n\n }, {\n key: \"getFilesize\",\n value: function getFilesize() {\n return this.buffer ? this.buffer.length : 0;\n }\n /**\n * Sets default tempo, parses file for necessary information, and does a dry run to calculate total length.\n * Populates this.events & this.totalTicks.\n * @return {Player}\n */\n\n }, {\n key: \"fileLoaded\",\n value: function fileLoaded() {\n if (!this.validate()) throw 'Invalid MIDI file; should start with MThd';\n this.defaultTempo = 120;\n return this.setTempo(this.defaultTempo).getDivision().getFormat().getTracks().dryRun();\n }\n /**\n * Validates file using simple means - first four bytes should == MThd.\n * @return {boolean}\n */\n\n }, {\n key: \"validate\",\n value: function validate() {\n //console.log((this.buffer.subarray(0, 15)));\n return Utils.bytesToLetters(this.buffer.subarray(0, 4)) === 'MThd';\n }\n /**\n * Gets MIDI file format for loaded file.\n * @return {Player}\n */\n\n }, {\n key: \"getFormat\",\n value: function getFormat() {\n /*\n MIDI files come in 3 variations:\n Format 0 which contain a single track\n Format 1 which contain one or more simultaneous tracks\n (ie all tracks are to be played simultaneously).\n Format 2 which contain one or more independant tracks\n (ie each track is to be played independantly of the others).\n return Utils.bytesToNumber(this.buffer.subarray(8, 10));\n */\n this.format = Utils.bytesToNumber(this.buffer.subarray(8, 10));\n return this;\n }\n /**\n * Parses out tracks, places them in this.tracks and initializes this.pointers\n * @return {Player}\n */\n\n }, {\n key: \"getTracks\",\n value: function getTracks() {\n this.tracks = [];\n var trackOffset = 0;\n\n while (trackOffset < this.buffer.length) {\n if (Utils.bytesToLetters(this.buffer.subarray(trackOffset, trackOffset + 4)) == 'MTrk') {\n var trackLength = Utils.bytesToNumber(this.buffer.subarray(trackOffset + 4, trackOffset + 8));\n this.tracks.push(new Track(this.tracks.length, this.buffer.subarray(trackOffset + 8, trackOffset + 8 + trackLength)));\n }\n\n trackOffset += Utils.bytesToNumber(this.buffer.subarray(trackOffset + 4, trackOffset + 8)) + 8;\n } // Get sum of all MIDI chunks here while we're at it\n\n\n var trackChunksByteLength = 0;\n this.tracks.forEach(function (track) {\n trackChunksByteLength += 8 + track.data.length;\n });\n this.midiChunksByteLength = Constants.HEADER_CHUNK_LENGTH + trackChunksByteLength;\n return this;\n }\n /**\n * Enables a track for playing.\n * @param {number} trackNumber - Track number\n * @return {Player}\n */\n\n }, {\n key: \"enableTrack\",\n value: function enableTrack(trackNumber) {\n this.tracks[trackNumber - 1].enable();\n return this;\n }\n /**\n * Disables a track for playing.\n * @param {number} - Track number\n * @return {Player}\n */\n\n }, {\n key: \"disableTrack\",\n value: function disableTrack(trackNumber) {\n this.tracks[trackNumber - 1].disable();\n return this;\n }\n /**\n * Gets quarter note division of loaded MIDI file.\n * @return {Player}\n */\n\n }, {\n key: \"getDivision\",\n value: function getDivision() {\n this.division = Utils.bytesToNumber(this.buffer.subarray(12, Constants.HEADER_CHUNK_LENGTH));\n return this;\n }\n /**\n * The main play loop.\n * @param {boolean} - Indicates whether or not this is being called simply for parsing purposes. Disregards timing if so.\n * @return {undefined}\n */\n\n }, {\n key: \"playLoop\",\n value: function playLoop(dryRun) {\n if (!this.inLoop) {\n this.inLoop = true;\n this.tick = this.getCurrentTick();\n this.tracks.forEach(function (track, index) {\n // Handle next event\n if (!dryRun && this.endOfFile()) {\n //console.log('end of file')\n this.stop();\n this.triggerPlayerEvent('endOfFile');\n } else {\n var result = track.handleEvent(this.tick, dryRun);\n\n if (dryRun && result) {\n if (result.hasOwnProperty('name') && result.name === 'Set Tempo') {\n // Grab tempo if available.\n this.setTempo(result.data);\n }\n\n if (result.hasOwnProperty('name') && result.name === 'Program Change') {\n if (!this.instruments.includes(result.value)) {\n this.instruments.push(result.value);\n }\n }\n } else if (result) {\n // result is an array of events during playback\n var events = Array.isArray(result) ? result : [result];\n events.forEach(function (event) {\n if (event.hasOwnProperty('name') && event.name === 'Set Tempo') {\n // Grab tempo if available.\n this.setTempo(event.data);\n }\n\n this.emitEvent(event);\n }, this);\n }\n }\n }, this);\n if (!dryRun && this.isPlaying()) this.triggerPlayerEvent('playing', {\n tick: this.tick\n });\n this.inLoop = false;\n }\n }\n /**\n * Setter for tempo.\n * @param {number} - Tempo in bpm (defaults to 120)\n */\n\n }, {\n key: \"setTempo\",\n value: function setTempo(tempo) {\n this.tempo = tempo;\n return this;\n }\n /**\n * Setter for startTime.\n * @param {number} - UTC timestamp\n * @return {Player}\n */\n\n }, {\n key: \"setStartTime\",\n value: function setStartTime(startTime) {\n this.startTime = startTime;\n return this;\n }\n /**\n * Start playing loaded MIDI file if not already playing.\n * @return {Player}\n */\n\n }, {\n key: \"play\",\n value: function play() {\n if (this.isPlaying()) throw 'Already playing...'; // Initialize\n\n if (!this.startTime) this.startTime = new Date().getTime(); // Start play loop using drift-correcting setTimeout\n\n this.scheduledTime = Date.now();\n this.schedulePlayLoop(this.sampleRate);\n return this;\n }\n /**\n * Schedules the next play loop iteration, correcting for timer drift.\n * @param {number} delay - Delay in milliseconds before next iteration.\n * @return {undefined}\n */\n\n }, {\n key: \"schedulePlayLoop\",\n value: function schedulePlayLoop(delay) {\n var _this = this;\n\n this.setTimeoutId = setTimeout(function () {\n _this.playLoop();\n\n if (_this.setTimeoutId !== false) {\n _this.scheduledTime += _this.sampleRate;\n\n var drift = Date.now() - _this.scheduledTime;\n\n _this.schedulePlayLoop(Math.max(0, _this.sampleRate - drift));\n }\n }, delay);\n }\n /**\n * Pauses playback if playing.\n * @return {Player}\n */\n\n }, {\n key: \"pause\",\n value: function pause() {\n clearTimeout(this.setTimeoutId);\n this.setTimeoutId = false;\n this.scheduledTime = 0;\n this.startTick = this.tick;\n this.startTime = 0;\n return this;\n }\n /**\n * Stops playback if playing.\n * @return {Player}\n */\n\n }, {\n key: \"stop\",\n value: function stop() {\n clearTimeout(this.setTimeoutId);\n this.setTimeoutId = false;\n this.scheduledTime = 0;\n this.startTick = 0;\n this.startTime = 0;\n this.resetTracks();\n return this;\n }\n /**\n * Skips player pointer to specified tick.\n * @param {number} - Tick to skip to.\n * @return {Player}\n */\n\n }, {\n key: \"skipToTick\",\n value: function skipToTick(tick) {\n this.stop();\n this.startTick = tick; // Set tempo to the value that applies at the target tick\n\n for (var i = this.tempoMap.length - 1; i >= 0; i--) {\n if (this.tempoMap[i].tick <= tick) {\n this.setTempo(this.tempoMap[i].tempo);\n break;\n }\n } // Emit intermediate state-changing events so the consumer's synth is in the correct state\n\n\n this.collectStateAtTick(tick).forEach(function (event) {\n this.emitEvent(event);\n }, this); // Need to set track event indexes to the nearest possible event to the specified tick.\n\n this.tracks.forEach(function (track) {\n track.setEventIndexByTick(tick);\n });\n return this;\n }\n /**\n * Collects the last state-changing MIDI events (Program Change, Controller Change, Pitch Bend)\n * before the specified tick across all tracks.\n * @param {number} tick - Target tick to collect state up to.\n * @return {array} - Array of state events representing the MIDI state at the target tick.\n */\n\n }, {\n key: \"collectStateAtTick\",\n value: function collectStateAtTick(tick) {\n var dominated = {};\n this.events.forEach(function (trackEvents) {\n trackEvents.forEach(function (event) {\n if (event.tick >= tick) return;\n var key;\n\n if (event.name === 'Program Change') {\n key = 'pc:' + event.channel;\n } else if (event.name === 'Controller Change') {\n key = 'cc:' + event.channel + ':' + event.number;\n } else if (event.name === 'Pitch Bend') {\n key = 'pb:' + event.channel;\n }\n\n if (key) {\n dominated[key] = event;\n }\n });\n });\n return Object.keys(dominated).map(function (key) {\n return dominated[key];\n });\n }\n /**\n * Skips player pointer to specified percentage.\n * @param {number} - Percent value in integer format.\n * @return {Player}\n */\n\n }, {\n key: \"skipToPercent\",\n value: function skipToPercent(percent) {\n if (percent < 0 || percent > 100) throw \"Percent must be number between 1 and 100.\";\n this.skipToTick(Math.round(percent / 100 * this.totalTicks));\n return this;\n }\n /**\n * Skips player pointer to specified seconds.\n * @param {number} - Seconds to skip to.\n * @return {Player}\n */\n\n }, {\n key: \"skipToSeconds\",\n value: function skipToSeconds(seconds) {\n var songTime = this.getSongTime();\n if (seconds < 0 || seconds > songTime) throw seconds + \" seconds not within song time of \" + songTime;\n this.skipToTick(this.secondsToTicks(seconds));\n return this;\n }\n /**\n * Checks if player is playing\n * @return {boolean}\n */\n\n }, {\n key: \"isPlaying\",\n value: function isPlaying() {\n return this.setTimeoutId !== false;\n }\n /**\n * Plays the loaded MIDI file without regard for timing and saves events in this.events. Essentially used as a parser.\n * @return {Player}\n */\n\n }, {\n key: \"dryRun\",\n value: function dryRun() {\n // Reset tracks first\n this.resetTracks();\n\n while (!this.endOfFile()) {\n this.playLoop(true); //console.log(this.bytesProcessed(), this.midiChunksByteLength);\n }\n\n this.events = this.getEvents();\n this.totalEvents = this.getTotalEvents();\n this.totalTicks = this.getTotalTicks();\n this.buildTempoMap();\n this.startTick = 0;\n this.startTime = 0; // Leave tracks in pristine condish\n\n this.resetTracks(); //console.log('Song time: ' + this.getSongTime() + ' seconds / ' + this.totalTicks + ' ticks.');\n\n this.triggerPlayerEvent('fileLoaded', this);\n return this;\n }\n /**\n * Resets play pointers for all tracks.\n * @return {Player}\n */\n\n }, {\n key: \"resetTracks\",\n value: function resetTracks() {\n this.tracks.forEach(function (track) {\n return track.reset();\n });\n return this;\n }\n /**\n * Gets an array of events grouped by track.\n * @return {array}\n */\n\n }, {\n key: \"getEvents\",\n value: function getEvents() {\n return this.tracks.map(function (track) {\n return track.events;\n });\n }\n /**\n * Gets total number of ticks in the loaded MIDI file.\n * @return {number}\n */\n\n }, {\n key: \"getTotalTicks\",\n value: function getTotalTicks() {\n return Math.max.apply(null, this.tracks.map(function (track) {\n return track.delta;\n }));\n }\n /**\n * Gets total number of events in the loaded MIDI file.\n * @return {number}\n */\n\n }, {\n key: \"getTotalEvents\",\n value: function getTotalEvents() {\n return this.tracks.reduce(function (a, b) {\n return {\n events: {\n length: a.events.length + b.events.length\n }\n };\n }, {\n events: {\n length: 0\n }\n }).events.length;\n }\n /**\n * Builds a tempo map from all Set Tempo events across all tracks.\n * @return {Player}\n */\n\n }, {\n key: \"buildTempoMap\",\n value: function buildTempoMap() {\n // Collect all Set Tempo events from all tracks\n var tempoEvents = [];\n this.events.forEach(function (trackEvents) {\n trackEvents.forEach(function (event) {\n if (event.name === 'Set Tempo') {\n tempoEvents.push({\n tick: event.tick,\n tempo: event.data\n });\n }\n });\n }); // Sort by tick\n\n tempoEvents.sort(function (a, b) {\n return a.tick - b.tick;\n }); // Build map starting with default tempo\n\n this.tempoMap = [{\n tick: 0,\n tempo: this.defaultTempo\n }];\n tempoEvents.forEach(function (event) {\n var last = this.tempoMap[this.tempoMap.length - 1];\n\n if (event.tick === last.tick) {\n // Same tick: update existing entry\n last.tempo = event.tempo;\n } else {\n this.tempoMap.push({\n tick: event.tick,\n tempo: event.tempo\n });\n }\n }, this);\n return this;\n }\n /**\n * Converts a tick range to seconds using the tempo map.\n * @param {number} startTick\n * @param {number} endTick\n * @return {number}\n */\n\n }, {\n key: \"ticksToSeconds\",\n value: function ticksToSeconds(startTick, endTick) {\n var seconds = 0;\n var currentTick = startTick;\n\n for (var i = 0; i < this.tempoMap.length; i++) {\n var entry = this.tempoMap[i];\n var nextTick = i + 1 < this.tempoMap.length ? this.tempoMap[i + 1].tick : endTick; // Skip entries entirely before our start\n\n if (nextTick <= startTick) continue; // Clamp segment to our range\n\n var segStart = Math.max(entry.tick, startTick);\n var segEnd = Math.min(nextTick, endTick);\n if (segStart >= endTick) break;\n var segmentTicks = segEnd - segStart;\n seconds += segmentTicks / this.division / entry.tempo * 60;\n currentTick = segEnd;\n } // Handle remaining ticks after last tempo change\n\n\n if (currentTick < endTick) {\n var lastEntry = this.tempoMap[this.tempoMap.length - 1];\n seconds += (endTick - currentTick) / this.division / lastEntry.tempo * 60;\n }\n\n return seconds;\n }\n /**\n * Converts seconds to a tick position using the tempo map.\n * @param {number} seconds\n * @return {number}\n */\n\n }, {\n key: \"secondsToTicks\",\n value: function secondsToTicks(seconds) {\n var remainingSeconds = seconds;\n var currentTick = 0;\n\n for (var i = 0; i < this.tempoMap.length; i++) {\n var entry = this.tempoMap[i];\n var nextTick = i + 1 < this.tempoMap.length ? this.tempoMap[i + 1].tick : Infinity;\n var segmentTicks = nextTick - entry.tick;\n var segmentSeconds = segmentTicks / this.division / entry.tempo * 60;\n\n if (remainingSeconds <= segmentSeconds) {\n // Target is within this segment\n currentTick = entry.tick + Math.round(remainingSeconds / 60 * entry.tempo * this.division);\n return currentTick;\n }\n\n remainingSeconds -= segmentSeconds;\n currentTick = nextTick;\n } // Should not reach here, but return totalTicks as fallback\n\n\n return this.totalTicks;\n }\n /**\n * Gets song duration in seconds.\n * @return {number}\n */\n\n }, {\n key: \"getSongTime\",\n value: function getSongTime() {\n return this.ticksToSeconds(0, this.totalTicks);\n }\n /**\n * Gets remaining number of seconds in playback.\n * @return {number}\n */\n\n }, {\n key: \"getSongTimeRemaining\",\n value: function getSongTimeRemaining() {\n return Math.round(this.ticksToSeconds(this.getCurrentTick(), this.totalTicks));\n }\n /**\n * Gets remaining percent of playback.\n * @return {number}\n */\n\n }, {\n key: \"getSongPercentRemaining\",\n value: function getSongPercentRemaining() {\n return Math.round(this.getSongTimeRemaining() / this.getSongTime() * 100);\n }\n /**\n * Number of bytes processed in the loaded MIDI file.\n * @return {number}\n */\n\n }, {\n key: \"bytesProcessed\",\n value: function bytesProcessed() {\n return Constants.HEADER_CHUNK_LENGTH + this.tracks.length * 8 + this.tracks.reduce(function (a, b) {\n return {\n pointer: a.pointer + b.pointer\n };\n }, {\n pointer: 0\n }).pointer;\n }\n /**\n * Number of events played up to this point.\n * @return {number}\n */\n\n }, {\n key: \"eventsPlayed\",\n value: function eventsPlayed() {\n return this.tracks.reduce(function (a, b) {\n return {\n eventIndex: a.eventIndex + b.eventIndex\n };\n }, {\n eventIndex: 0\n }).eventIndex;\n }\n /**\n * Determines if the player pointer has reached the end of the loaded MIDI file.\n * Used in two ways:\n * 1. If playing result is based on loaded JSON events.\n * 2. If parsing (dryRun) it's based on the actual buffer length vs bytes processed.\n * @return {boolean}\n */\n\n }, {\n key: \"endOfFile\",\n value: function endOfFile() {\n if (this.isPlaying()) {\n return this.totalTicks - this.tick <= 0;\n }\n\n return this.bytesProcessed() >= this.midiChunksByteLength; //this.buffer.length;\n }\n /**\n * Gets the current tick number in playback.\n * @return {number}\n */\n\n }, {\n key: \"getCurrentTick\",\n value: function getCurrentTick() {\n if (!this.startTime) return this.startTick;\n var elapsedSeconds = (new Date().getTime() - this.startTime) / 1000;\n var startSeconds = this.ticksToSeconds(0, this.startTick);\n return this.secondsToTicks(startSeconds + elapsedSeconds);\n }\n /**\n * Sends MIDI event out to listener.\n * @param {object}\n * @return {Player}\n */\n\n }, {\n key: \"emitEvent\",\n value: function emitEvent(event) {\n this.triggerPlayerEvent('midiEvent', event);\n return this;\n }\n /**\n * Subscribes events to listeners\n * @param {string} - Name of event to subscribe to.\n * @param {function} - Callback to fire when event is broadcast.\n * @return {Player}\n */\n\n }, {\n key: \"on\",\n value: function on(playerEvent, fn) {\n if (!this.eventListeners.hasOwnProperty(playerEvent)) this.eventListeners[playerEvent] = [];\n this.eventListeners[playerEvent].push(fn);\n return this;\n }\n /**\n * Broadcasts event to trigger subscribed callbacks.\n * @param {string} - Name of event.\n * @param {object} - Data to be passed to subscriber callback.\n * @return {Player}\n */\n\n }, {\n key: \"triggerPlayerEvent\",\n value: function triggerPlayerEvent(playerEvent, data) {\n if (this.eventListeners.hasOwnProperty(playerEvent)) this.eventListeners[playerEvent].forEach(function (fn) {\n return fn(data || {});\n });\n return this;\n }\n }]);\n\n return Player;\n}();\n\nvar index = {\n Player: Player,\n Utils: Utils,\n Constants: Constants\n};\n\nexport { index as default };\n", "export default class WebAudioFontPlayer {\r\n\r\n #audioCtx = null;\r\n #compressor = null;\r\n #preset = null;\r\n\r\n #envelopes = [];\r\n #afterTime = 0.05;\r\n #nearZero = 0.000001;\r\n\r\n #bendRange = 2;\r\n\r\n #mainGain = null;\r\n #volumeValue = 0.7;\r\n #expressionValue = 1.0;\r\n #expressionGain = null;\r\n #sustain = false;\r\n #pitchBendValue = 8192;\r\n #notesWaitingForSustain = new Set();\r\n\r\n\r\n constructor(preset, audioCtx, compressor = null) {\r\n this.#audioCtx = audioCtx;\r\n this.#compressor = compressor;\r\n this.#preset = preset;\r\n this.#mainGain = this.#audioCtx.createGain();\r\n this.#mainGain.gain.setValueAtTime(this.#volumeValue, this.#audioCtx.currentTime);\r\n this.#expressionGain = this.#audioCtx.createGain();\r\n this.#expressionGain.gain.setValueAtTime(this.#expressionValue, this.#audioCtx.currentTime);\r\n this.#mainGain.connect(this.#expressionGain);\r\n this.#expressionGain.connect(this.#compressor ? this.#compressor.input : this.#audioCtx.destination);\r\n this.#preset.zones.map(zone => this.#adjustZone(zone));\r\n }\r\n\r\n get preset() { return this.#preset; }\r\n set preset(preset) {\r\n this.#preset = preset;\r\n this.#preset.zones.map(zone => this.#adjustZone(zone));\r\n }\r\n\r\n\r\n close() {\r\n const now = this.#audioCtx.currentTime;\r\n this.#envelopes.forEach(envelope => {\r\n try {\r\n envelope.gain.cancelScheduledValues(0);\r\n if (envelope.audioBufferSourceNode) {\r\n envelope.audioBufferSourceNode.stop(now);\r\n envelope.audioBufferSourceNode.disconnect();\r\n envelope.audioBufferSourceNode = null;\r\n }\r\n } catch (e) {}\r\n try { envelope.disconnect(); } catch (e) { }\r\n });\r\n this.#envelopes = [];\r\n this.#notesWaitingForSustain.clear();\r\n try { this.#mainGain.disconnect(); } catch (e) { }\r\n try { this.#expressionGain.disconnect(); } catch (e) { }\r\n this.#mainGain = null;\r\n this.#expressionGain = null;\r\n this.#preset = null;\r\n this.#compressor = null;\r\n this.#audioCtx = null;\r\n }\r\n\r\n\r\n queueWaveTable(when, pitch, duration, volume, slides) {\r\n if (this.#audioCtx.state === 'suspended') this.#audioCtx.resume().catch(() => { });\r\n const vol = this.#limitVolume(volume);\r\n const zone = this.#findZone(Math.round(pitch));\r\n if (!zone?.buffer) return null;\r\n\r\n const baseDetuneCents = zone.originalPitch - 100.0 * zone.coarseTune - zone.fineTune;\r\n const originalPitchCents = pitch * 100;\r\n const currentBendCents = ((this.#pitchBendValue - 8192) / 8192) * this.#bendRange * 100;\r\n const totalCents = (originalPitchCents - baseDetuneCents) + currentBendCents;\r\n const playbackRate = Math.pow(2, totalCents / 1200.0);\r\n const startWhen = Math.max(when, this.#audioCtx.currentTime);\r\n let waveDuration = duration + this.#afterTime;\r\n\r\n const loop = zone.loopStart >= 1 && zone.loopStart < zone.loopEnd;\r\n if (!loop) waveDuration = Math.min(waveDuration, zone.buffer.duration / playbackRate);\r\n\r\n const envelope = this.#findEnvelope();\r\n this.#setupEnvelope(envelope, zone, vol, startWhen, waveDuration, duration);\r\n\r\n const source = this.#audioCtx.createBufferSource();\r\n source.buffer = zone.buffer;\r\n source.playbackRate.setValueAtTime(playbackRate, 0);\r\n\r\n if (slides?.length > 0) {\r\n source.playbackRate.setValueAtTime(playbackRate, startWhen);\r\n slides.forEach(s => {\r\n const slidePitchCents = (pitch + s.delta) * 100;\r\n const totalSlideCents = (slidePitchCents - baseDetuneCents) + currentBendCents;\r\n const newRate = Math.pow(2, totalSlideCents / 1200.0);\r\n source.playbackRate.linearRampToValueAtTime(newRate, startWhen + s.when);\r\n });\r\n }\r\n\r\n source.loop = loop;\r\n if (loop) {\r\n const d = zone.delay ?? 0;\r\n source.loopStart = zone.loopStart / zone.sampleRate + d;\r\n source.loopEnd = zone.loopEnd / zone.sampleRate + d;\r\n }\r\n\r\n source.connect(envelope);\r\n source.start(startWhen, zone.delay ?? 0);\r\n source.stop(startWhen + waveDuration);\r\n\r\n envelope.audioBufferSourceNode = source;\r\n envelope.when = startWhen;\r\n envelope.duration = waveDuration;\r\n envelope.pitch = pitch;\r\n envelope.baseDetune = baseDetuneCents;\r\n\r\n return envelope;\r\n }\r\n\r\n\r\n async cancelQueue() {\r\n this.#envelopes.forEach(e => {\r\n e.gain.cancelScheduledValues(0);\r\n e.gain.setValueAtTime(this.#nearZero, this.#audioCtx.currentTime);\r\n e.when = -1;\r\n try { e.audioBufferSourceNode?.disconnect(); } catch (e) { }\r\n });\r\n }\r\n\r\n\r\n isSustainActive() {\r\n return this.#sustain;\r\n }\r\n\r\n\r\n registerSustainNote(cancelFn) {\r\n this.#notesWaitingForSustain.add(cancelFn);\r\n }\r\n\r\n\r\n setPitchBend(value) {\r\n this.#pitchBendValue = value;\r\n const normalized = value - 8192;\r\n const semitones = normalized >= 0\r\n ? (normalized / 8191) * this.#bendRange\r\n : (normalized / 8192) * this.#bendRange;\r\n const now = this.#audioCtx.currentTime;\r\n this.#envelopes.forEach(e => {\r\n if (e.audioBufferSourceNode && e.when + e.duration > now) {\r\n const originalPitchCents = e.pitch * 100;\r\n const baseDetuneCents = e.baseDetune;\r\n const bendCents = semitones * 100;\r\n const totalCents = (originalPitchCents - baseDetuneCents) + bendCents;\r\n const newRate = Math.pow(2, totalCents / 1200.0);\r\n e.audioBufferSourceNode.playbackRate.cancelScheduledValues(now);\r\n e.audioBufferSourceNode.playbackRate.setTargetAtTime(newRate, now, 0.015);\r\n }\r\n });\r\n }\r\n\r\n\r\n setController(number, value) {\r\n const now = this.#audioCtx.currentTime;\r\n const normalizedValue = Math.max(0, Math.min(127, value)) / 127;\r\n switch (number) {\r\n case 7:\r\n this.#volumeValue = normalizedValue;\r\n this.#mainGain.gain.setTargetAtTime(this.#volumeValue, now, 0.05);\r\n break;\r\n case 11:\r\n this.#expressionValue = normalizedValue;\r\n this.#expressionGain.gain.setTargetAtTime(this.#expressionValue, now, 0.03);\r\n break;\r\n case 64:\r\n this.#sustain = value >= 64;\r\n if (!this.#sustain) {\r\n this.#notesWaitingForSustain.forEach(cancelFn => cancelFn());\r\n this.#notesWaitingForSustain.clear();\r\n }\r\n break;\r\n }\r\n }\r\n\r\n\r\n #adjustZone(zone) {\r\n if (zone.buffer) return Promise.resolve(zone);\r\n zone.delay = 0;\r\n\r\n if (zone.file) {\r\n const decoded = atob(zone.file);\r\n const uint8Array = new Uint8Array(decoded.length);\r\n for (let i = 0; i < decoded.length; i++) uint8Array[i] = decoded.charCodeAt(i);\r\n this.#audioCtx.decodeAudioData(\r\n uint8Array.buffer,\r\n audioBuffer => {\r\n zone.buffer = audioBuffer;\r\n this.#applyZoneParameters(zone);\r\n return zone;\r\n },\r\n error => {\r\n console.error(\"Audio decoding error:\", error);\r\n console.warn(this.#preset);\r\n return false;\r\n }\r\n );\r\n } else {\r\n this.#applyZoneParameters(zone);\r\n return zone;\r\n }\r\n };\r\n\r\n\r\n #applyZoneParameters(zone) {\r\n zone.loopStart = this.#numValue(zone.loopStart, 0);\r\n zone.loopEnd = this.#numValue(zone.loopEnd, 0);\r\n zone.coarseTune = this.#numValue(zone.coarseTune, 0);\r\n zone.fineTune = this.#numValue(zone.fineTune, 0);\r\n zone.originalPitch = this.#numValue(zone.originalPitch, 6000);\r\n };\r\n\r\n\r\n #setupEnvelope(envelope, zone, volume, when, sampleDuration, noteDuration) {\r\n envelope.gain.setValueAtTime(this.#nearZero, this.#audioCtx.currentTime);\r\n const duration = Math.min(noteDuration, sampleDuration - this.#afterTime);\r\n const ahdsr = (zone.ahdsr && zone.ahdsr.length > 0) ? zone.ahdsr : [\r\n { duration: 0, volume: 1 },\r\n { duration: duration, volume: 1 }\r\n ];\r\n\r\n envelope.gain.cancelScheduledValues(when);\r\n const initialVol = (ahdsr[0]?.volume ?? 1) * volume;\r\n envelope.gain.linearRampToValueAtTime(this.#noZeroVolume(initialVol), when + 0.002);\r\n\r\n let lastTime = 0;\r\n let lastVolume = ahdsr[0]?.volume ?? 1;\r\n\r\n for (const stage of ahdsr) {\r\n const { duration: stageDuration, volume: stageVolume } = stage;\r\n if (stageDuration <= 0) continue;\r\n const remainingTime = duration - lastTime;\r\n if (stageDuration > remainingTime) {\r\n const ratio = remainingTime / stageDuration;\r\n const interpolatedVolume = lastVolume + ratio * (stageVolume - lastVolume);\r\n envelope.gain.exponentialRampToValueAtTime(\r\n this.#noZeroVolume(volume * interpolatedVolume),\r\n when + duration\r\n );\r\n break;\r\n }\r\n lastTime += stageDuration;\r\n lastVolume = stageVolume;\r\n envelope.gain.exponentialRampToValueAtTime(\r\n this.#noZeroVolume(volume * lastVolume),\r\n when + lastTime\r\n );\r\n }\r\n envelope.gain.exponentialRampToValueAtTime(this.#nearZero, when + duration + this.#afterTime);\r\n }\r\n\r\n\r\n #findEnvelope(destinationNode) {\r\n const target = destinationNode || this.#mainGain;\r\n const now = this.#audioCtx.currentTime;\r\n let envelope = this.#envelopes.find(e => e.target === target && now > e.when + e.duration + 0.05);\r\n if (!envelope && this.#envelopes.length >= 64) {\r\n const activeEnvelopes = this.#envelopes.filter(e => e.target === target);\r\n if (activeEnvelopes.length > 0) {\r\n activeEnvelopes.sort((a, b) => a.when - b.when);\r\n envelope = activeEnvelopes[0];\r\n }\r\n }\r\n if (envelope) {\r\n if (envelope.audioBufferSourceNode) {\r\n try {\r\n envelope.audioBufferSourceNode.stop(0);\r\n envelope.audioBufferSourceNode.disconnect();\r\n } catch (e) { }\r\n envelope.audioBufferSourceNode = null;\r\n }\r\n envelope.gain.cancelScheduledValues(0);\r\n envelope.gain.setValueAtTime(this.#nearZero, now);\r\n } else {\r\n envelope = this.#audioCtx.createGain();\r\n envelope.gain.value = 0;\r\n envelope.target = target;\r\n envelope.connect(target);\r\n this.#envelopes.push(envelope);\r\n }\r\n envelope.cancel = (force = false) => {\r\n const currentTime = this.#audioCtx.currentTime;\r\n if (force && envelope.audioBufferSourceNode) {\r\n try {\r\n envelope.audioBufferSourceNode.stop(0);\r\n envelope.audioBufferSourceNode.disconnect();\r\n } catch (e) { }\r\n envelope.audioBufferSourceNode = null;\r\n }\r\n if (envelope.when + envelope.duration > currentTime) {\r\n envelope.gain.cancelScheduledValues(0);\r\n envelope.gain.setTargetAtTime(this.#nearZero, currentTime, force ? 0.005 : 0.02);\r\n envelope.when = currentTime + 0.00001;\r\n envelope.duration = 0;\r\n }\r\n };\r\n return envelope;\r\n }\r\n\r\n\r\n #findZone(pitch) {\r\n const zone = this.#preset.zones.findLast(z => pitch >= z.keyRangeLow && pitch <= z.keyRangeHigh + 1);\r\n if (zone) this.#adjustZone(zone);\r\n return zone;\r\n };\r\n\r\n\r\n #limitVolume(v) {\r\n const requestedVolume = v ? 1.0 * v : 0.5;\r\n return Math.min(requestedVolume, 0.8);\r\n };\r\n\r\n\r\n #noZeroVolume(n) {\r\n return n > this.#nearZero ? n : this.#nearZero;\r\n }\r\n\r\n\r\n #numValue(a, b) {\r\n return typeof a === \"number\" ? a : b;\r\n }\r\n\r\n}\r\n", "import WebAudioFontPlayer from \"./src/webaudiofontplayer.js\";\r\n\r\nif (typeof window !== 'undefined') window.WebAudioFontPlayer = WebAudioFontPlayer;\r\n\r\nexport { WebAudioFontPlayer };\r\nexport default WebAudioFontPlayer;", "export default class AudioCompressor {\r\n #input = null;\r\n #output = null;\r\n #audioCtx = null;\r\n #limiter = null;\r\n #analyser = null;\r\n #reverbNode = null;\r\n #reverbWet = null;\r\n #currentReverbLevel = 0;\r\n #eqBands = new Map();\r\n \r\n static #EQ_FREQUENCIES = [32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384];\r\n static #EQ_Q = new Map([\r\n [32, 0.7],\r\n [64, 0.8],\r\n [128, 0.9],\r\n [256, 1.0],\r\n [512, 1.1],\r\n [1024, 1.2],\r\n [2048, 1.4],\r\n [4096, 1.6],\r\n [8192, 1.8],\r\n [16384, 2.0],\r\n ]);\r\n \r\n\r\n constructor(audioCtx, volume, reverb) {\r\n this.#audioCtx = audioCtx;\r\n this.#input = this.#audioCtx.createGain();\r\n let lastNode = this.#input;\r\n const frequencies = [32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384];\r\n frequencies.forEach(freq => {\r\n lastNode = this.#bandEqualizer(lastNode, freq);\r\n const label = freq < 1000 ? freq : (freq / 1024) + 'k';\r\n this[`band${label}`] = lastNode;\r\n });\r\n\r\n this.#currentReverbLevel = reverb;\r\n this.#reverbNode = this.#audioCtx.createConvolver();\r\n this.#reverbWet = this.#audioCtx.createGain();\r\n this.#reverbWet.gain.setValueAtTime(reverb, this.#audioCtx.currentTime);\r\n this.#generateImpulseResponse(1.5, 2.0);\r\n\r\n this.#limiter = this.#audioCtx.createDynamicsCompressor();\r\n this.#limiter.threshold.setValueAtTime(-10.0, this.#audioCtx.currentTime);\r\n this.#limiter.ratio.setValueAtTime(20, this.#audioCtx.currentTime);\r\n this.#limiter.attack.setValueAtTime(0.001, this.#audioCtx.currentTime);\r\n this.#limiter.release.setValueAtTime(0.1, this.#audioCtx.currentTime);\r\n this.#limiter.knee.setValueAtTime(0, this.#audioCtx.currentTime);\r\n\r\n this.#analyser = this.#audioCtx.createAnalyser();\r\n this.#analyser.fftSize = 256;\r\n this.#analyser.smoothingTimeConstant = 0.6;\r\n\r\n this.#output = this.#audioCtx.createGain();\r\n this.#output.gain.setValueAtTime(volume, this.#audioCtx.currentTime);\r\n\r\n lastNode.connect(this.#output);\r\n this.#output.connect(this.#limiter);\r\n this.#output.connect(this.#reverbNode);\r\n this.#reverbNode.connect(this.#reverbWet);\r\n this.#limiter.connect(this.#analyser);\r\n this.#reverbWet.connect(this.#analyser);\r\n this.#analyser.connect(this.#audioCtx.destination);\r\n }\r\n\r\n get eqFrequencies() { return AudioCompressor.#EQ_FREQUENCIES }\r\n get analyser() { return this.#analyser || null; }\r\n get input() { return this.#input; }\r\n get reverb() { return this.#currentReverbLevel; }\r\n set reverb(value) {\r\n this.#currentReverbLevel = Math.max(0, Math.min(1, value));\r\n this.#reverbWet.gain.setTargetAtTime(this.#currentReverbLevel, this.#audioCtx.currentTime, 0.1);\r\n }\r\n get masterVolume() { return this.#output.gain.value; }\r\n set masterVolume(value) {\r\n const linearValue = Math.max(0, Math.min(1, value));\r\n const logVolume = Math.pow(linearValue, 2);\r\n this.#output.gain.setTargetAtTime(logVolume, this.#audioCtx.currentTime, 0.01);\r\n }\r\n\r\n\r\n killReverbTail() {\r\n const now = this.#audioCtx.currentTime;\r\n this.#reverbWet.gain.cancelScheduledValues(now);\r\n this.#reverbWet.gain.setValueAtTime(0, now);\r\n }\r\n\r\n\r\n restoreReverb() {\r\n this.reverb = this.#currentReverbLevel;\r\n }\r\n\r\n\r\n setEQ(gains, smoothTime = 0.04) {\r\n const now = this.#audioCtx.currentTime;\r\n const MAX_DB = 12;\r\n for (const [key, val] of Object.entries(gains)) {\r\n const freq = Number(key);\r\n const band = this.#eqBands.get(freq);\r\n if (!band) continue;\r\n const dbValue = Math.max(-MAX_DB, Math.min(MAX_DB, val));\r\n band.filter.gain.setTargetAtTime(dbValue, now, smoothTime);\r\n band.gain = dbValue;\r\n }\r\n }\r\n\r\n\r\n getEQ() {\r\n const result = {};\r\n for (const [freq, band] of this.#eqBands) result[freq] = band.gain;\r\n return result;\r\n }\r\n\r\n \r\n resetEQ(smoothTime = 0.04) {\r\n const flat = {};\r\n for (const freq of AudioCompressor.#EQ_FREQUENCIES) flat[freq] = 0;\r\n this.setEQ(flat, smoothTime);\r\n }\r\n\r\n\r\n setEQPreset(name) {\r\n const presets = {\r\n flat: { 32:0, 64:0, 128:0, 256:0, 512:0, 1024:0, 2048:0, 4096:0, 8192:0, 16384:0 },\r\n bass: { 32:7, 64:6, 128:4, 256:2, 512:0, 1024:-1, 2048:-1, 4096:0, 8192:0, 16384:0 },\r\n treble: { 32:0, 64:0, 128:0, 256:0, 512:0, 1024:1, 2048:3, 4096:5, 8192:7, 16384:8 },\r\n vocal: { 32:-3, 64:-2, 128:0, 256:2, 512:4, 1024:5, 2048:4, 4096:2, 8192:1, 16384:0 },\r\n loudness: { 32:6, 64:4, 128:1, 256:0, 512:-1, 1024:-1, 2048:0, 4096:2, 8192:4, 16384:5 },\r\n classical: { 32:4, 64:3, 128:2, 256:0, 512:0, 1024:0, 2048:0, 4096:2, 8192:3, 16384:4 },\r\n jazz: { 32:4, 64:3, 128:1, 256:0, 512:-1, 1024:-1, 2048:0, 4096:1, 8192:3, 16384:4 },\r\n electronic: { 32:6, 64:5, 128:2, 256:-1, 512:-2, 1024:-1, 2048:2, 4096:4, 8192:5, 16384:6 },\r\n };\r\n const preset = presets[name];\r\n if (!preset) throw new Error(`Preset EQ unkown: \"${name}\". Avaiables: ${Object.keys(presets).join(', ')}`);\r\n this.setEQ(preset);\r\n }\r\n\r\n\r\n #bandEqualizer(from, frequency) {\r\n const filter = this.#audioCtx.createBiquadFilter();\r\n filter.type = \"peaking\";\r\n filter.frequency.setValueAtTime(frequency, this.#audioCtx.currentTime);\r\n filter.gain.setValueAtTime(0, this.#audioCtx.currentTime);\r\n const q = AudioCompressor.#EQ_Q.get(frequency) ?? 1.0;\r\n filter.Q.setValueAtTime(q, this.#audioCtx.currentTime);\r\n this.#eqBands.set(frequency, { filter, gain: 0 });\r\n from.connect(filter);\r\n return filter;\r\n }\r\n\r\n\r\n #generateImpulseResponse(duration, decay) {\r\n const sampleRate = this.#audioCtx.sampleRate;\r\n const length = sampleRate * duration;\r\n const impulse = this.#audioCtx.createBuffer(2, length, sampleRate);\r\n const preDelayTime = 0.015;\r\n const preDelaySamples = Math.floor(preDelayTime * sampleRate);\r\n for (let channel = 0; channel < impulse.numberOfChannels; channel++) {\r\n const data = impulse.getChannelData(channel);\r\n let lastValue = 0;\r\n const channelOffset = channel === 1 ? Math.floor(0.002 * sampleRate) : 0;\r\n for (let i = 0; i < length; i++) {\r\n if (i < preDelaySamples) {\r\n data[i] = 0;\r\n continue;\r\n }\r\n const t = (i - preDelaySamples) / sampleRate;\r\n const envelope = Math.exp(-t * (decay / duration));\r\n const dampingFactor = Math.max(0.01, 0.2 * Math.exp(-t * 2.5));\r\n const whiteNoise = (Math.random() * 2 - 1);\r\n lastValue = (whiteNoise * dampingFactor) + (lastValue * (1 - dampingFactor));\r\n let sampleValue = lastValue * envelope;\r\n if (t < 0.04) {\r\n if ((i % 123 === 0) || (i % 234 === 0)) {\r\n sampleValue += (Math.random() * 2 - 1) * 0.2 * (0.04 - t) / 0.04;\r\n }\r\n }\r\n if (i + channelOffset < length) data[i + channelOffset] = sampleValue;\r\n else data[i] = sampleValue;\r\n }\r\n }\r\n this.#reverbNode.buffer = impulse;\r\n }\r\n\r\n}", "const DB_NAME = \"MidiAudioPlayer\";\r\nconst STORE_NAME = \"KeyValues\";\r\nconst DEFAULT_VERSION = 1;\r\n\r\nlet dbInstance = null;\r\nlet currentVersion = DEFAULT_VERSION;\r\n\r\nasync function getDB(version = currentVersion) {\r\n if (dbInstance && version !== currentVersion) {\r\n dbInstance.close();\r\n dbInstance = null;\r\n currentVersion = version;\r\n }\r\n if (dbInstance) return dbInstance;\r\n return new Promise((resolve, reject) => {\r\n const request = indexedDB.open(DB_NAME, version);\r\n request.onupgradeneeded = (e) => {\r\n const db = e.target.result;\r\n if (!db.objectStoreNames.contains(STORE_NAME)) {\r\n db.createObjectStore(STORE_NAME);\r\n }\r\n };\r\n request.onsuccess = (e) => {\r\n dbInstance = e.target.result;\r\n resolve(dbInstance);\r\n };\r\n request.onerror = (e) => reject(e.target.error);\r\n });\r\n}\r\n\r\nconst indexedDbStorage = {\r\n async setVersion(version) {\r\n await getDB(version);\r\n },\r\n\r\n async setItem(key, value, compress = false) {\r\n const db = await getDB();\r\n let finalData = value;\r\n let isCompressed = false;\r\n\r\n if (compress) {\r\n const stringData = JSON.stringify(value);\r\n const stream = new Blob([stringData]).stream();\r\n const compressedStream = stream.pipeThrough(new CompressionStream(\"gzip\"));\r\n const response = new Response(compressedStream);\r\n finalData = await response.arrayBuffer();\r\n isCompressed = true;\r\n }\r\n\r\n const record = { data: finalData, isCompressed };\r\n\r\n return new Promise((resolve, reject) => {\r\n const transaction = db.transaction(STORE_NAME, \"readwrite\");\r\n const store = transaction.objectStore(STORE_NAME);\r\n const request = store.put(record, key);\r\n request.onsuccess = () => resolve();\r\n request.onerror = () => reject(request.error);\r\n });\r\n },\r\n\r\n async getItem(key) {\r\n const db = await getDB();\r\n const record = await new Promise((resolve, reject) => {\r\n const transaction = db.transaction(STORE_NAME, \"readonly\");\r\n const store = transaction.objectStore(STORE_NAME);\r\n const request = store.get(key);\r\n request.onsuccess = () => resolve(request.result);\r\n request.onerror = () => reject(request.error);\r\n });\r\n\r\n if (!record) return null;\r\n\r\n if (record.isCompressed) {\r\n const stream = new Blob([record.data]).stream();\r\n const decompressedStream = stream.pipeThrough(new DecompressionStream(\"gzip\"));\r\n const response = new Response(decompressedStream);\r\n const text = await response.text();\r\n return JSON.parse(text);\r\n }\r\n\r\n return record.data;\r\n },\r\n\r\n async removeItem(key) {\r\n const db = await getDB();\r\n return new Promise((resolve, reject) => {\r\n const transaction = db.transaction(STORE_NAME, \"readwrite\");\r\n const store = transaction.objectStore(STORE_NAME);\r\n const request = store.delete(key);\r\n request.onsuccess = () => resolve();\r\n request.onerror = () => reject(request.error);\r\n });\r\n },\r\n\r\n async clear() {\r\n const db = await getDB();\r\n return new Promise((resolve, reject) => {\r\n const transaction = db.transaction(STORE_NAME, \"readwrite\");\r\n const store = transaction.objectStore(STORE_NAME);\r\n const request = store.clear();\r\n request.onsuccess = () => resolve();\r\n request.onerror = () => reject(request.error);\r\n });\r\n }\r\n};\r\n\r\nexport default indexedDbStorage;", "import MidiPlayer from 'midi-player-js';\r\nimport WebAudioFontPlayer from 'webaudiofontplayer';\r\nimport AudioCompressor from './libraries/audiocompressor';\r\nimport indexedDbStorage from './libraries/indexeddbstorage';\r\n\r\nconst clamp = (num, min, max) => Math.min(Math.max(num, min), max);\r\n\r\n\r\nexport default class MidiAudioPlayer extends MidiPlayer.Player {\r\n\r\n static ENDPOINT = 'https://webaudiofonts.com/presets/';\r\n static DEFAULT_PRESET = -1;\r\n static REFERENCE_GAIN = 0.15;\r\n static KARAOKE_CHANNEL = 0;\r\n\r\n #catalog = null;\r\n\t#audioCtx = null;\r\n\t#compressor = null;\r\n #vocalChannel = null;\r\n #activeNotes = {};\r\n #channelStates = {};\r\n #instruments = {};\r\n #players = {};\r\n #channels = {};\r\n #channelVolumes = {};\r\n #presetMap = {};\r\n #bufferHash = null;\r\n #presetTimer = null;\r\n #presetMapThread = null;\r\n #lyrics = null;\r\n #haveLyrics = false;\r\n #title = '';\r\n\r\n\t#opts = {\r\n endpoint: MidiAudioPlayer.ENDPOINT,\r\n volume: 0.6,\r\n reverb: 0.3,\r\n onEndFile: null,\r\n localCache: true,\r\n presetRandom: false,\r\n karaoke: false,\r\n karaokeDelay: 0,\r\n muteExpression: false,\r\n maxCharPerLine: 48,\r\n eqPreset: 'flat',\r\n preferred: [],\r\n presets: [],\r\n\t};\r\n\r\n\r\n\tconstructor(opts = {}) {\r\n super();\r\n this.#opts = { ...this.#opts, ...opts };\r\n this.#presetMapThread = this.#mapPresets();\r\n\t\tthis.#audioCtx = new (window.AudioContext || window.webkitAudioContext)();\r\n this.#compressor = new AudioCompressor(this.#audioCtx, this.#opts.volume, this.#opts.reverb);\r\n this.#compressor.setEQPreset(this.#opts.eqPreset);\r\n if(this.#opts.karaoke) this.#sendKaraokeFrame('intro');\r\n\t}\r\n\r\n get catalog() { return this.getCatalog(); }\r\n get channels() { return this.#players; }\r\n get channelStates() { return this.#channelStates; }\r\n get volume() { return this.#opts.volume; }\r\n set volume(vol) { this.#opts.volume = clamp(vol, 0, 1); this.#compressor.masterVolume = this.#opts.volume; }\r\n get volumes() { return this.#channelVolumes; }\r\n get reverb() { return this.#compressor.reverb; }\r\n set reverb(rev) { this.#compressor.reverb = rev; }\r\n get muteExpression() { return this.#opts.muteExpression; }\r\n set muteExpression(val) { this.#opts.muteExpression = Boolean(val); }\r\n get eqFrequencies() { return this.#compressor.eqFrequencies; }\r\n get eq() { return this.#compressor.getEQ(); }\r\n getEQ() { return this.#compressor.getEQ(); }\r\n setEQ(gains) { this.#compressor.setEQ(gains); }\r\n setEQPreset(name) { this.#compressor.setEQPreset(name); }\r\n setChannelVolume(channel, volume) { this.#channelVolumes[channel] = volume; this.#setupChange(); }\r\n\r\n\r\n async #mapPresets() {\r\n await Promise.all(this.#opts.presets.map(async p => {\r\n const preset = await this.findPreset(p);\r\n if(preset) this.#presetMap[preset.program] = preset;\r\n }));\r\n }\r\n\r\n\r\n async findPreset(id) {\r\n let preset = null;\r\n const categories = await this.getCategories();\r\n categories.some(c => {\r\n c.instruments.some(i => {\r\n preset = i.presets.find(p => p.id == id);\r\n if(preset) {\r\n preset.category = c.name;\r\n preset.instrument = i.name;\r\n preset.program = i.program;\r\n return true;\r\n }\r\n });\r\n if(preset) return true;\r\n });\r\n return preset;\r\n }\r\n\r\n\r\n async close() {\r\n Object.keys(this.#players).forEach(id => this.#players[id].close());\r\n await this.#audioCtx.close();\r\n }\r\n\r\n\r\n async getCatalog() {\r\n if(this.#catalog) return this.#catalog;\r\n const cachedata = this.#opts.localCache ? await sessionStorage.getItem('waf_catalog') : null;\r\n if (cachedata) this.#catalog = JSON.parse(cachedata);\r\n else {\r\n this.#log(`Downloading catalog...`);\r\n const response = await fetch(`${this.#opts.endpoint}catalog.json`);\r\n if (!response.ok) throw new Error(`Impossible to download catalog: ${response.status}`);\r\n this.#catalog = await response.json();\r\n if(this.#opts.localCache) await sessionStorage.setItem('waf_catalog', JSON.stringify(this.#catalog));\r\n }\r\n const catalogDate = new Date(this.#catalog.updatedAt).getTime();\r\n const catalogVersion = await indexedDbStorage.getItem(`waf_catalog_version`) || 1;\r\n if(catalogVersion < catalogDate) {\r\n await indexedDbStorage.clear();\r\n indexedDbStorage.setItem(`waf_catalog_version`, catalogDate)\r\n }\r\n return this.#catalog;\r\n }\r\n\r\n\r\n async getCategories() {\r\n return (await this.getCatalog()).categories;\r\n }\r\n\r\n\r\n async getProgramInstruments(program) {\r\n const categories = await this.getCategories();\r\n let instruments = [];\r\n await Promise.all(categories.map(async category => category.instruments.filter(elm => elm.program == program).forEach(elm => {\r\n elm.presets.forEach(p => {\r\n p.instrument = category.name + ' / ' + elm.name;\r\n instruments.push(p);\r\n });\r\n })));\r\n return instruments;\r\n }\r\n\r\n\r\n async getPreset(id) {\r\n try {\r\n if(typeof id === 'object') return id;\r\n const cacheid = `waf_preset_${id}`;\r\n const cachedata = this.#opts.localCache ? await indexedDbStorage.getItem(cacheid) : null;\r\n if (cachedata) return JSON.parse(cachedata);\r\n this.#log(`Downloading preset ${id}...`);\r\n const response = await fetch(`${MidiAudioPlayer.ENDPOINT}${id}.json`);\r\n const preset = await response.json();\r\n if(preset.zones === undefined) {\r\n console.error(`Invalid preset: ${$id}`);\r\n throw new Error(`Invalid preset: ${$id}`);\r\n }\r\n if(this.#opts.localCache) await indexedDbStorage.setItem(cacheid, JSON.stringify(preset), true);\r\n return preset;\r\n } catch(e) {\r\n console.error(`Invalid preset: ${id}`);\r\n throw new Error(`Invalid preset: ${id}`);\r\n }\r\n }\r\n\r\n\r\n async loadPreset(presetId, channel) {\r\n const presetInfo = await this.findPreset(presetId);\r\n if(!presetInfo) throw new Error(`Invalid preset: ${presetId}`);\r\n this.#presetMap[presetInfo.program] = presetInfo;\r\n const preset = await this.getPreset(presetId);\r\n this.#players[channel].preset = preset;\r\n this.#setupChange();\r\n }\r\n\r\n\r\n async load(content, setup) {\r\n if(typeof content === 'string') {\r\n this.#log('Downloading song...');\r\n const response = await fetch(content);\r\n content = await response.arrayBuffer();\r\n }\r\n if(typeof setup === 'string') {\r\n this.#log('Downloading setup...');\r\n const response = await fetch(setup);\r\n setup = await response.json();\r\n }\r\n this.#bufferHash = await this.hashBuffer(content);\r\n await this.#presetMapThread;\r\n\t\tif(this.isPlaying()) this.stop();\r\n\t\tthis.#clearActiveNotes();\r\n await Promise.all(Object.values(this.#players).map(async player => player.close()));\r\n this.#players = {};\r\n this.#instruments = {};\r\n this.#activeNotes = {};\r\n this.#title = \"\";\r\n\t\tthis.#log('Loading buffer...');\r\n try {\r\n await this.loadArrayBuffer(content);\r\n } catch(e) {\r\n await this.loadArrayBuffer(await this.#repairMidi(content));\r\n }\r\n\r\n this.#log('Loading instruments...');\r\n this.#channels = await this.#getInstruments();\r\n this.#channelStates = Object.keys(this.#channels).reduce((acc, key) => ({ ...acc, [key]: false }), {});\r\n this.#channelVolumes = Object.keys(this.#channels).reduce((acc, key) => ({ ...acc, [key]: 1.0 }), {});\r\n if(setup?.volumes !== undefined) {\r\n await Promise.all(Object.keys(setup.volumes).map(async channel => {\r\n if(this.#channelVolumes[channel] === undefined) return;\r\n this.#channelVolumes[channel] = setup.volumes[channel];\r\n }));\r\n }\r\n\r\n const setupPrograms = new Set();\r\n const setupPresets = {};\r\n if(setup?.presets !== undefined) {\r\n await Promise.all(Object.keys(setup.presets).map(async channel => {\r\n const presetInfo = await this.findPreset(setup.presets[channel]);\r\n if(!presetInfo) return;\r\n setupPresets[channel] = await this.getPreset(presetInfo.id);\r\n setupPrograms.add(presetInfo.program);\r\n }));\r\n }\r\n\r\n const uniqueInstruments = await this.#getUniqueInstruments();\r\n if(!Object.values(this.#channels).length) this.#log(\"Error: no instrument found\");\r\n const presets = Promise.all([...uniqueInstruments].map(async program => {\r\n if(setupPrograms.has(program)) return;\r\n let preset = null;\r\n if(this.#presetMap[program] !== undefined) preset = await this.getPreset(this.#presetMap[program].id);\r\n else if(this.#opts.presetRandom) preset = await this.#getRandomPreset(program);\r\n else preset = await this.#getAutoPreset(program);\r\n this.#instruments[program] = preset;\r\n }));\r\n\r\n if(this.#opts.karaoke) {\r\n this.#log('Generating karaoke frames...');\r\n this.#lyrics = null;\r\n await this.#generateKaraokeFrames();\r\n if(this.#title) this.#sendKaraokeFrame('title', this.#title);\r\n }\r\n\r\n this.#log(`Trim midi events...`);\r\n this.#trimMidiEvents();\r\n queueMicrotask(() => this.triggerPlayerEvent('computed'));\r\n\r\n await presets;\r\n await Promise.all(Object.keys(this.#channels).map(async channel => {\r\n if(this.#players[channel]) this.#players[channel].close();\r\n if(setupPresets[channel] !== undefined) this.#players[channel] = await this.#createPlayer(setupPresets[channel]);\r\n else this.#players[channel] = await this.#createPlayer(this.#instruments[this.#channels[channel]]);\r\n }));\r\n\r\n this.#log(\"Initializing instrument states...\");\r\n await this.#initInstrumentStates();\r\n await this.triggerPlayerEvent('presetsLoaded', this.#instruments);\r\n await this.#setupChange();\r\n this.#log(\"Player ready\");\r\n \r\n\t}\r\n\r\n\r\n async getSongSetup() {\r\n\t\tlet setup = { hash: this.#bufferHash, presets: {}, volumes: {} };\r\n Object.keys(this.#players).map(async channel => setup.presets[channel] = this.#players[channel].preset.id);\r\n\t\tsetup.volumes = this.#channelVolumes;\r\n return setup;\r\n }\r\n\r\n\r\n async getTrainingPresets() {\r\n return await Promise.all(Object.values(this.#presetMap).map(async preset => preset.id));\r\n }\r\n\r\n\r\n\tasync play(content = null) {\r\n if (this.#audioCtx.state === 'suspended') {\r\n try { await this.#audioCtx.resume(); }\r\n catch (e) { return false; }\r\n }\r\n if(content) await this.load(content);\r\n await Promise.all(Object.keys(this.#players).map(async k => await this.#players[k]?.cancelQueue()));\r\n this.#compressor.restoreReverb();\r\n if(!this.isPlaying()) {\r\n if (!this.startTime) this.startTime = new Date().getTime();\r\n this.scheduledTime = Date.now();\r\n this.schedulePlayLoop(this.sampleRate);\r\n }\r\n return true;\r\n\t}\r\n\r\n\r\n\tasync pause() {\r\n await super.pause();\r\n this.#compressor.killReverbTail();\r\n await this.#clearActiveNotes();\r\n await Promise.all(Object.keys(this.#players).map(async k => await this.#players[k]?.cancelQueue()));\r\n\t}\r\n\r\n\r\n async stop(skipKill = false) {\r\n await super.stop();\r\n this.setTimeoutId = false;\r\n if(!skipKill) {\r\n this.#compressor.killReverbTail();\r\n await Promise.all(Object.keys(this.#players).map(async k => await this.#players[k]?.cancelQueue()));\r\n }\r\n await this.#clearActiveNotes();\r\n if(this.#opts.karaoke) this.#sendKaraokeFrame('intro');\r\n return this;\r\n\t}\r\n\r\n\r\n getRealTimeVolume() {\r\n const analyser = this.#compressor.analyser;\r\n const dataArray = new Uint8Array(analyser.frequencyBinCount);\r\n analyser.getByteFrequencyData(dataArray);\r\n let values = 0;\r\n for (let i = 0; i < dataArray.length; i++) values += dataArray[i];\r\n return values / (dataArray.length * 100);\r\n }\r\n\r\n\r\n getSongTimeRemaining() {\r\n return this.ticksToSeconds(this.getCurrentTick(), this.totalTicks);\r\n }\r\n\r\n\r\n async skipToSeconds(seconds) {\r\n const songTime = this.getSongTime();\r\n if (seconds < 0 || seconds > songTime) throw seconds + \" seconds not within song time of \" + songTime;\r\n await this.skipToTick(this.secondsToTicks(seconds));\r\n return this;\r\n }\r\n\r\n\r\n async generateWaveformSVG(samples = 1000) {\r\n if (!this.totalTicks || !this.events) return '';\r\n const waveform = new Array(samples).fill(0);\r\n const tickInterval = this.totalTicks / samples;\r\n const allEvents = this.events\r\n .flatMap((track, trackIdx) =>\r\n track.map(event => ({\r\n ...event,\r\n computedChannel: event.channel !== undefined ? event.channel : trackIdx\r\n }))\r\n )\r\n .filter(event =>\r\n event.name === 'Controller Change' ||\r\n event.name === 'Program Change' ||\r\n (event.name === 'Note on' && event.velocity > 0)\r\n )\r\n .sort((a, b) => a.tick - b.tick);\r\n const channelsVolume = new Map();\r\n const channelsExpression = new Map();\r\n allEvents.forEach(event => {\r\n const idx = Math.floor(event.tick / tickInterval);\r\n if (idx >= samples) return;\r\n const chan = event.computedChannel;\r\n if (!channelsVolume.has(chan)) channelsVolume.set(chan, 100);\r\n if (!channelsExpression.has(chan)) channelsExpression.set(chan, 127);\r\n if (event.name === 'Controller Change') {\r\n if (event.number === 7) channelsVolume.set(chan, event.value);\r\n else if (event.number === 11) channelsExpression.set(chan, event.value);\r\n }\r\n else if (event.name === 'Note on') {\r\n const volFactor = channelsVolume.get(chan) / 127;\r\n const expFactor = channelsExpression.get(chan) / 127;\r\n const modulatedVelocity = event.velocity * volFactor * expFactor;\r\n waveform[idx] += modulatedVelocity;\r\n }\r\n });\r\n const maxAmp = waveform.reduce((max, val) => {\r\n if (isNaN(val)) return max;\r\n return val > max ? val : max;\r\n }, 0);\r\n const normalized = maxAmp > 0 ? waveform.map(v => isNaN(v) ? 0 : v / maxAmp) : waveform.fill(0);\r\n const width = samples;\r\n const height = width / 5;\r\n const points = normalized.map((val, i) => {\r\n const x = i;\r\n const y = Math.max(0, Math.min(height, height - (val * height)));\r\n return `${x},${y.toFixed(2)}`;\r\n });\r\n const d = `M 0,${height} L ${points.join(' L ')} L ${width},${height}`;\r\n return `<svg class=\"midiaudioplayer-waveform\" viewBox=\"0 0 ${width} ${height}\" preserveAspectRatio=\"none\"><path d=\"${d}\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /></svg>`;\r\n }\r\n\r\n // ----------------------------------------------------------------------------------------------------------------------\r\n // ----------------------------------------------------------------------------------------------------------------------\r\n // ----------------------------------------------------------------------------------------------------------------------\r\n\r\n\r\n async hashBuffer(arrayBuffer, algorithm = 'SHA-256') {\r\n const hashBuffer = await crypto.subtle.digest(algorithm, arrayBuffer);\r\n const hashArray = Array.from(new Uint8Array(hashBuffer));\r\n return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\r\n }\r\n\r\n\r\n async #setupChange() {\r\n if(this.#presetTimer) clearTimeout(this.#presetTimer);\r\n this.#presetTimer = setTimeout(async () => {\r\n const setup = await this.getSongSetup();\r\n queueMicrotask(() => this.triggerPlayerEvent('setupChange', setup));\r\n }, 1000);\r\n }\r\n\r\n\r\n async triggerPlayerEvent(playerEvent, data) {\r\n if(playerEvent == 'fileLoaded') return;\r\n else if(playerEvent == 'computed') {\r\n this.#vocalChannel = await this.#detectKaraokeVocalChannel();\r\n super.triggerPlayerEvent(playerEvent, {\r\n title: this.#title,\r\n karaoke: this.#haveLyrics,\r\n vocalChannel: this.#vocalChannel,\r\n tempo: this.tempo,\r\n division: this.division,\r\n duration: this.getSongTime(),\r\n sampleRate: this.sampleRate,\r\n totalTicks: this.totalTicks,\r\n totalEvents: this.totalEvents,\r\n channels: await this.#channels,\r\n });\r\n } else if(playerEvent == 'endOfFile' && this.#opts.karaoke) {\r\n queueMicrotask(() => super.triggerPlayerEvent(playerEvent, data));\r\n } else super.triggerPlayerEvent(playerEvent, data);\r\n }\r\n\r\n\r\n async playLoop(dryRun) {\r\n if (this.inLoop) return;\r\n if (!dryRun && this.endOfFile() && this.tick > 0) {\r\n await this.stop(true);\r\n this.tick = 0;\r\n this.triggerPlayerEvent('endOfFile');\r\n return;\r\n }\r\n this.inLoop = true;\r\n this.tick = this.getCurrentTick();\r\n const tracksLen = this.tracks.length;\r\n for (let i = 0; i < tracksLen; i++) {\r\n const result = this.tracks[i].handleEvent(this.tick, dryRun);\r\n if (!result) continue;\r\n const isArray = result.constructor === Array;\r\n const eventsLen = isArray ? result.length : 1;\r\n for (let j = 0; j < eventsLen; j++) {\r\n const event = isArray ? result[j] : result;\r\n const { name, data, value } = event;\r\n if (name === 'Set Tempo') this.setTempo(data);\r\n if (dryRun) {\r\n if (name === 'Program Change' && !this.instruments.includes(value)) this.instruments.push(value);\r\n } else {\r\n this.emitEvent(event);\r\n }\r\n }\r\n }\r\n if (!dryRun && this.isPlaying()) this.triggerPlayerEvent('playing', { tick: this.tick });\r\n this.inLoop = false;\r\n }\r\n\r\n\r\n schedulePlayLoop(delay) {\r\n this.setTimeoutId = setTimeout(() => {\r\n if (this.setTimeoutId === false) return;\r\n this.playLoop();\r\n const currentAudioTime = this.#audioCtx.currentTime;\r\n if (!this._lastAudioTime) this._lastAudioTime = currentAudioTime;\r\n const elapsed = currentAudioTime - this._lastAudioTime;\r\n this._lastAudioTime = currentAudioTime;\r\n const sampleRateSec = this.sampleRate / 1000;\r\n const drift = elapsed - sampleRateSec;\r\n const nextDelay = Math.max(0, this.sampleRate - (drift * 1000));\r\n this.schedulePlayLoop(nextDelay);\r\n }, delay);\r\n }\r\n\r\n\r\n emitEvent(event) {\r\n this.#handleMidiPipeline(event);\r\n }\r\n\r\n\r\n ticksToSeconds(startTick, endTick) {\r\n if (endTick === undefined) {\r\n endTick = startTick;\r\n startTick = 0;\r\n }\r\n if (startTick >= endTick) return 0;\r\n let seconds = 0;\r\n const len = this.tempoMap.length;\r\n const timeFactor = 60 / this.division;\r\n let low = 0;\r\n let high = len - 1;\r\n let startIndex = 0;\r\n while (low <= high) {\r\n const mid = (low + high) >> 1;\r\n if (this.tempoMap[mid].tick <= startTick) {\r\n startIndex = mid;\r\n low = mid + 1;\r\n } else {\r\n high = mid - 1;\r\n }\r\n }\r\n let currentTick = startTick;\r\n for (let i = startIndex; i < len; i++) {\r\n const entry = this.tempoMap[i];\r\n const nextTick = (i + 1 < len) ? this.tempoMap[i + 1].tick : endTick;\r\n if (nextTick <= startTick) continue;\r\n const segStart = Math.max(entry.tick, startTick);\r\n const segEnd = Math.min(nextTick, endTick);\r\n if (segStart >= endTick) break;\r\n seconds += ((segEnd - segStart) / entry.tempo) * timeFactor;\r\n currentTick = segEnd;\r\n }\r\n if (currentTick < endTick) {\r\n const lastEntry = this.tempoMap[len - 1];\r\n seconds += ((endTick - currentTick) / lastEntry.tempo) * timeFactor;\r\n }\r\n return seconds;\r\n }\r\n\r\n\r\n secondsToTicks(seconds) {\r\n let remainingSeconds = seconds;\r\n const len = this.tempoMap.length;\r\n const factor = 60 / this.division;\r\n for (let i = 0; i < len; i++) {\r\n const entry = this.tempoMap[i];\r\n const nextTick = (i + 1 < len) ? this.tempoMap[i + 1].tick : Infinity;\r\n const segmentTicks = nextTick - entry.tick;\r\n const segmentSeconds = (segmentTicks / entry.tempo) * factor;\r\n if (remainingSeconds <= segmentSeconds) {\r\n return entry.tick + Math.round((remainingSeconds * entry.tempo) / factor);\r\n }\r\n remainingSeconds -= segmentSeconds;\r\n }\r\n return this.totalTicks;\r\n }\r\n\r\n\r\n getTickBeforeSeconds(targetTick, seconds) {\r\n if (targetTick <= 0) return 0;\r\n const targetTime = this.ticksToSeconds(0, targetTick);\r\n const desiredTime = Math.max(0, targetTime - seconds);\r\n return this.secondsToTicks(desiredTime);\r\n }\r\n\r\n\r\n async skipToTick(tick) {\r\n const safeTick = Math.max(0, Math.min(tick, this.totalTicks || 0));\r\n const wasPlaying = this.isPlaying();\r\n this.#clearActiveNotes();\r\n Object.keys(this.channels).forEach(k => this.channels[k]?.cancelQueue?.());\r\n if (wasPlaying) super.pause();\r\n this.startTick = safeTick;\r\n this.tick = safeTick;\r\n if (this.tempoMap && this.tempoMap.length > 0) {\r\n for (let i = this.tempoMap.length - 1; i >= 0; i--) {\r\n if (this.tempoMap[i].tick <= safeTick) {\r\n this.setTempo(this.tempoMap[i].tempo);\r\n break;\r\n }\r\n }\r\n }\r\n try {\r\n const controllerChange = [];\r\n const programChange = [];\r\n const pitchBend = [];\r\n const karaokeEvent = [];\r\n\r\n this.#collectStateAtTick(safeTick).forEach(event => {\r\n const channel = event.channel;\r\n if ((channel === undefined || !this.channels[channel]) && event.name !== 'Karaoke Event') return;\r\n switch(event.name) {\r\n case 'Controller Change': controllerChange[event.channel] = event; break;\r\n case 'Program Change': programChange[event.channel] = event; break;\r\n case 'Pitch Bend': pitchBend[event.channel] = event; break;\r\n case 'Karaoke Event': karaokeEvent[event.channel] = event; break;\r\n }\r\n });\r\n controllerChange.forEach(evt => this.emitEvent(evt));\r\n programChange.forEach(evt => this.emitEvent(evt));\r\n pitchBend.forEach(evt => this.emitEvent(evt));\r\n karaokeEvent.forEach(evt => this.triggerPlayerEvent('karaoke', { type: evt.type, tick: evt.tick, html: evt.text}));\r\n } catch (e) {\r\n console.warn(\"Chase MIDI Error:\", e);\r\n this.#log(\"Chase MIDI Error:\", e);\r\n }\r\n if (this.tracks && this.tracks.length > 0) {\r\n this.tracks.forEach((track, index) => {\r\n const trackEvents = this.events[index];\r\n if (trackEvents && trackEvents.length > 0) {\r\n let low = 0;\r\n let high = trackEvents.length - 1;\r\n let pointer = trackEvents.length;\r\n while (low <= high) {\r\n const mid = (low + high) >> 1;\r\n if (trackEvents[mid].tick >= safeTick) {\r\n pointer = mid;\r\n high = mid - 1;\r\n } else {\r\n low = mid + 1;\r\n }\r\n }\r\n track.eventIndex = pointer;\r\n } else if (typeof track.setEventIndexByTick === 'function') {\r\n track.setEventIndexByTick(safeTick);\r\n }\r\n });\r\n }\r\n if (wasPlaying) this.play();\r\n else this.triggerPlayerEvent('playing', { tick: safeTick });\r\n return this;\r\n }\r\n\r\n\r\n #collectStateAtTick(tick) {\r\n const dominated = {};\r\n if (!this.events) return [];\r\n for (let t = 0; t < this.events.length; t++) {\r\n const trackEvents = this.events[t];\r\n if (!trackEvents || trackEvents.length === 0) continue;\r\n let low = 0;\r\n let high = trackEvents.length - 1;\r\n let endIdx = trackEvents.length;\r\n while (low <= high) {\r\n const mid = (low + high) >> 1;\r\n if (trackEvents[mid].tick >= tick) {\r\n endIdx = mid;\r\n high = mid - 1;\r\n } else {\r\n low = mid + 1;\r\n }\r\n }\r\n for (let i = 0; i < endIdx; i++) {\r\n const event = trackEvents[i];\r\n let key;\r\n if (event.name === 'Program Change') {\r\n key = 'pc:' + event.channel;\r\n }else if (event.name === 'Controller Change') {\r\n key = 'cc:' + event.channel + ':' + event.number;\r\n } else if (event.name === 'Pitch Bend') {\r\n key = 'pb:' + event.channel;\r\n } else if (event.name === 'Karaoke Event') {\r\n key = 'ke:' + event.channel;\r\n }\r\n if (key) {\r\n dominated[key] = event;\r\n }\r\n }\r\n }\r\n return Object.keys(dominated).map(key => dominated[key]);\r\n }\r\n\r\n\r\n async #initInstrumentStates() {\r\n if (this.events) {\r\n this.#collectStateAtTick(1).forEach(event => {\r\n const channel = event.channel;\r\n if (!this.#players[channel]) return;\r\n switch (event.name) {\r\n case 'Controller Change':\r\n this.#players[channel].setController(event.number, event.value);\r\n break;\r\n case 'Pitch Bend':\r\n this.#players[channel].setPitchBend?.(event.value);\r\n break;\r\n case 'Program Change':\r\n if (\r\n // (this.#opts.presetAuto || this.#opts.presetRandom) &&\r\n event.value >= 0 && event.value <= 127 &&\r\n this.#instruments[event.value + 1] !== undefined &&\r\n event.channel != 10) {\r\n if (this.#players[channel].preset?.program !== (event.value + 1)) {\r\n this.#players[channel].preset = this.#instruments[event.value + 1];\r\n }\r\n }\r\n break;\r\n }\r\n });\r\n }\r\n }\r\n\r\n\r\n async #getInstruments() {\r\n const instrumentMap = {};\r\n const channelUsed = new Set();\r\n this.events.forEach(track => {\r\n track.forEach(event => {\r\n if (event.name === 'Program Change' && event.value >= 0 && event.value <= 127) {\r\n if(instrumentMap[event.channel]) return;\r\n else if(event.channel == 10) instrumentMap[event.channel] = -1;\r\n else instrumentMap[event.channel] = event.value + 1;\r\n } else if (event.name === 'Note on' && event.channel == 10) {\r\n instrumentMap[event.channel] = -1;\r\n channelUsed.add(10);\r\n } else if(event.name === 'Note on') {\r\n channelUsed.add(event.channel);\r\n }\r\n });\r\n });\r\n Object.keys(instrumentMap).forEach(channel => {\r\n if(!channelUsed.has(Number(channel))) delete instrumentMap[channel];\r\n });\r\n return instrumentMap;\r\n }\r\n\r\n\r\n async #getUniqueInstruments() {\r\n const instrumentMap = new Set();\r\n this.events.forEach(track => {\r\n track.forEach(event => {\r\n if (event.name === 'Program Change' && event.value >= 0 && event.value <= 127) {\r\n instrumentMap.add(event.channel == 10 ? -1 : (event.value + 1));\r\n } else if (event.name === 'Note on' && event.channel == 10) instrumentMap.add(-1);\r\n });\r\n });\r\n return instrumentMap;\r\n }\r\n\r\n\r\n async #getRandomPreset(program) {\r\n const instruments = await this.getProgramInstruments(program);\r\n if(!instruments.length) return null;\r\n let preset = null;\r\n this.#opts.preferred.some(bank => {\r\n const regex = new RegExp(`_${bank}$`, 'i');\r\n const group = instruments.filter(i => regex.test(i.id));\r\n if(group.length) {\r\n preset = group[Math.floor(Math.random() * group.length)];\r\n return true;\r\n }\r\n });\r\n if(!preset) preset = instruments[Math.floor(Math.random() * instruments.length)];\r\n this.#presetMap[program] = preset;\r\n return await this.getPreset(preset.id);\r\n }\r\n\r\n\r\n async #getAutoPreset(program) {\r\n const instruments = await this.getProgramInstruments(program);\r\n if(!instruments.length) return null;\r\n let preset = null;\r\n this.#opts.preferred.some(bank => {\r\n const regex = new RegExp(`_${bank}$`, 'i');\r\n preset = instruments.find(i => regex.test(i.id));\r\n if(preset) return true;\r\n });\r\n if(!preset) preset = instruments[0];\r\n this.#presetMap[program] = preset;\r\n return await this.getPreset(preset.id);\r\n }\r\n\r\n\r\n async #createPlayer(preset) {\r\n return new WebAudioFontPlayer(preset, this.#audioCtx, this.#compressor);\r\n }\r\n\r\n\r\n async #handleMidiPipeline(event) {\r\n if(!this.isPlaying()) return;\r\n switch (event.name) {\r\n case 'Note on':\r\n if (event.tick < (this.tick - 100)) return;\r\n if (event.noteNumber === undefined) return;\r\n if (event.channel == this.#vocalChannel && this.#opts.muteExpression) return;\r\n if (event.velocity > 0 && event.velocity <= 127) {\r\n this.#stopNote(event.channel, event.noteNumber);\r\n if(this.#channelVolumes[event.channel] == 0) return;\r\n const noteVelocityRatio = event.velocity / 127;\r\n const finalVol = MidiAudioPlayer.REFERENCE_GAIN * Math.pow(noteVelocityRatio, 2) * this.#channelVolumes[event.channel];\r\n const envelope = this.#players[event.channel]?.queueWaveTable(0, event.noteNumber, 2, finalVol);\r\n if (envelope) this.#addNote(event.channel, event.noteNumber, envelope)\r\n } else {\r\n this.#stopNote(event.channel, event.noteNumber);\r\n }\r\n break;\r\n case 'Note off':\r\n if (event.noteNumber === undefined) return;\r\n this.#stopNote(event.channel, event.noteNumber);\r\n break;\r\n case 'Controller Change':\r\n this.#players[event.channel]?.setController(event.number, event.value);\r\n break;\r\n case 'Pitch Bend':\r\n this.#players[event.channel]?.setPitchBend?.(event.value);\r\n break;\r\n case 'Program Change':\r\n return;\r\n if(!this.#players[event.channel]) return;\r\n if(event.channel == 10 || event.value > 127 || event.value < 0) break;\r\n if(this.#players[event.channel] !== undefined && this.#players[event.channel].preset.program != (event.value + 1))\r\n this.#players[event.channel].preset = this.#instruments[event.value + 1];\r\n break;\r\n case 'Karaoke Event':\r\n if (event.tick < (this.tick - this.secondsToTicks(10))) return;\r\n this.triggerPlayerEvent('karaoke', { type: event.type, tick: event.tick, html: event.text});\r\n break;\r\n }\r\n }\r\n\r\n\r\n #addNote(channel, note, envelope) {\r\n if (!this.#activeNotes[channel]) this.#activeNotes[channel] = new Map();\r\n this.#activeNotes[channel].set(note, envelope);\r\n this.#updateChannelStates();\r\n const realDurationMs = (envelope.duration || 0) * 1000;\r\n envelope.cleanupTimer = setTimeout(() => {\r\n if (this.#activeNotes[channel]?.get(note) === envelope) {\r\n this.#activeNotes[channel].delete(note);\r\n this.#updateChannelStates();\r\n }\r\n }, realDurationMs + 50);\r\n }\r\n\r\n\r\n #stopNote(channel, noteNumber) {\r\n const player = this.#players[channel];\r\n const envelope = this.#activeNotes[channel]?.get(noteNumber);\r\n if (envelope) {\r\n if (envelope.cleanupTimer) clearTimeout(envelope.cleanupTimer);\r\n const removeNoteFromRegistry = () => {\r\n this.#activeNotes[channel]?.delete(noteNumber);\r\n this.#updateChannelStates();\r\n };\r\n if (player && player.isSustainActive()) {\r\n player.registerSustainNote(() => envelope.cancel(false));\r\n } else {\r\n envelope.cancel(false);\r\n }\r\n removeNoteFromRegistry();\r\n }\r\n }\r\n\r\n\r\n #clearActiveNotes() {\r\n Object.keys(this.#activeNotes).forEach(channel => {\r\n this.#activeNotes[channel].forEach((envelope, note) => {\r\n if (envelope) {\r\n if (envelope.cleanupTimer) clearTimeout(envelope.cleanupTimer);\r\n if (envelope.cancel) envelope.cancel(true);\r\n }\r\n this.#activeNotes[channel]?.delete(note);\r\n });\r\n });\r\n this.#updateChannelStates();\r\n }\r\n\r\n\r\n async #updateChannelStates() {\r\n let hasChanged = false;\r\n const nextStates = {};\r\n Object.keys(this.#players).forEach(channel => {\r\n const isActive = Boolean(this.#activeNotes[channel]?.size && this.#activeNotes[channel].size > 0);\r\n nextStates[channel] = isActive;\r\n if (this.#channelStates[channel] !== isActive) hasChanged = true;\r\n });\r\n if (hasChanged) {\r\n this.#channelStates = nextStates;\r\n this.triggerPlayerEvent('channelState', this.#channelStates);\r\n }\r\n }\r\n\r\n\r\n async #repairMidi(buffer) {\r\n const src = new Uint8Array(buffer);\r\n const view = new DataView(buffer);\r\n const magic = String.fromCharCode(...src.slice(0, 4));\r\n if (magic !== 'MThd') throw new Error('Invalid MIDI file (MThd missing)');\r\n const headerLen = view.getUint32(4);\r\n const format = view.getUint16(8);\r\n const ntrks = view.getUint16(10);\r\n const division = view.getUint16(12);\r\n const EOT = [0xFF, 0x2F, 0x00];\r\n const chunks = [];\r\n let pos = 8 + headerLen;\r\n while (pos < src.length) {\r\n if (pos + 8 > src.length) {\r\n break;\r\n }\r\n const tag = String.fromCharCode(...src.slice(pos, pos + 4));\r\n const declaredLen = view.getUint32(pos + 4);\r\n const dataStart = pos + 8;\r\n const dataEnd = dataStart + declaredLen;\r\n if (tag !== 'MTrk') {\r\n const end = Math.min(dataEnd, src.length);\r\n chunks.push({ tag, data: src.slice(pos, end), repaired: false });\r\n pos = dataEnd;\r\n continue;\r\n }\r\n const trackNum = chunks.filter(c => c.tag === 'MTrk').length + 1;\r\n const available = Math.min(declaredLen, src.length - dataStart);\r\n const trackData = src.slice(dataStart, dataStart + available);\r\n const last3 = trackData.slice(-3);\r\n const hasEOT = last3[0] === 0xFF && last3[1] === 0x2F && last3[2] === 0x00;\r\n if (hasEOT && available === declaredLen) {\r\n chunks.push({ tag, data: trackData, repaired: false });\r\n } else {\r\n let repairedData;\r\n if (available < declaredLen) {\r\n const missing = declaredLen - available;\r\n const last2 = trackData.slice(-2);\r\n if (last2[0] === 0xFF && last2[1] === 0x2F) {\r\n repairedData = new Uint8Array(trackData.length + 1);\r\n repairedData.set(trackData);\r\n repairedData[trackData.length] = 0x00;\r\n } else {\r\n repairedData = new Uint8Array(trackData.length + 3);\r\n repairedData.set(trackData);\r\n repairedData.set(EOT, trackData.length);\r\n }\r\n } else {\r\n repairedData = new Uint8Array(trackData.length + 3);\r\n repairedData.set(trackData);\r\n repairedData.set(EOT, trackData.length);\r\n }\r\n chunks.push({ tag, data: repairedData, repaired: true });\r\n }\r\n pos = dataEnd;\r\n }\r\n const fixedNtrks = chunks.filter(c => c.tag === 'MTrk').length;\r\n const totalSize = 14 + chunks.reduce((acc, c) => acc + 8 + c.data.length, 0);\r\n const out = new Uint8Array(totalSize);\r\n const outView = new DataView(out.buffer);\r\n out.set([0x4D, 0x54, 0x68, 0x64], 0);\r\n outView.setUint32(4, 6);\r\n outView.setUint16(8, format);\r\n outView.setUint16(10, fixedNtrks);\r\n outView.setUint16(12, division);\r\n let outPos = 14;\r\n for (const chunk of chunks) {\r\n const tagBytes = chunk.tag.split('').map(c => c.charCodeAt(0));\r\n out.set(tagBytes, outPos);\r\n outView.setUint32(outPos + 4, chunk.data.length);\r\n out.set(chunk.data, outPos + 8);\r\n outPos += 8 + chunk.data.length;\r\n }\r\n const repairedCount = chunks.filter(c => c.repaired).length;\r\n return out.buffer;\r\n }\r\n\r\n\r\n #trimMidiEvents() {\r\n if (!this.events || this.events.length === 0) return;\r\n let firstNoteTick = Infinity;\r\n let lastNoteTick = 0;\r\n this.events.forEach(track => {\r\n track.forEach(event => {\r\n if (event.name === 'Note on' || event.name === 'Note off') {\r\n if (event.tick < firstNoteTick) firstNoteTick = event.tick;\r\n if (event.tick > lastNoteTick) lastNoteTick = event.tick;\r\n }\r\n });\r\n });\r\n if (firstNoteTick === Infinity) return;\r\n const allSetupEventsBeforeFirstNote = [];\r\n this.events.forEach((track, trackIdx) => {\r\n track.forEach(event => {\r\n const isSetupEvent = event.name === 'Program Change' ||\r\n event.name === 'Controller Change' ||\r\n event.name === 'Pitch Bend' ||\r\n event.name === 'Set Tempo';\r\n if (event.tick < firstNoteTick && isSetupEvent) {\r\n allSetupEventsBeforeFirstNote.push({ event, trackIdx });\r\n }\r\n });\r\n });\r\n const uniqueSetupByTrack = Object.fromEntries(this.events.map((_, idx) => [idx, []]));\r\n const globalUniqueKeys = new Set();\r\n for (let i = allSetupEventsBeforeFirstNote.length - 1; i >= 0; i--) {\r\n const { event, trackIdx } = allSetupEventsBeforeFirstNote[i];\r\n const channel = event.channel !== undefined ? event.channel : `track-${trackIdx}`;\r\n let key = null;\r\n if (event.name === 'Program Change') {\r\n key = `pc:${channel}`;\r\n } else if (event.name === 'Controller Change') {\r\n key = `cc:${channel}:${event.number}`;\r\n } else if (event.name === 'Pitch Bend') {\r\n key = `pb:${channel}`;\r\n } else if (event.name === 'Set Tempo') {\r\n key = 'tempo';\r\n }\r\n if (key) {\r\n if (!globalUniqueKeys.has(key)) {\r\n globalUniqueKeys.add(key);\r\n const clonedEvent = { ...event, tick: 0 };\r\n uniqueSetupByTrack[trackIdx].push(clonedEvent);\r\n }\r\n }\r\n }\r\n const trimmedEvents = this.events.map((track, trackIdx) => {\r\n const newTrack = [];\r\n track.forEach(event => {\r\n const isSetupEvent = event.name === 'Program Change' ||\r\n event.name === 'Controller Change' ||\r\n event.name === 'Pitch Bend' ||\r\n event.name === 'Set Tempo';\r\n const isTextOrKaraoke = event.name === 'Text Event' ||\r\n event.name === 'Lyric Event' ||\r\n event.name === 'Track Name' ||\r\n event.name === 'Karaoke Event';\r\n\r\n if (event.tick < firstNoteTick) {\r\n if (!isSetupEvent && (isTextOrKaraoke || trackIdx === 0)) {\r\n event.tick = 0;\r\n newTrack.push(event);\r\n }\r\n } else {\r\n event.tick = event.tick - firstNoteTick;\r\n const maxAllowedTick = lastNoteTick - firstNoteTick;\r\n if (event.tick > maxAllowedTick) {\r\n event.tick = maxAllowedTick;\r\n }\r\n newTrack.push(event);\r\n }\r\n });\r\n const filteredTrackSetup = uniqueSetupByTrack[trackIdx] || [];\r\n return [...filteredTrackSetup, ...newTrack].sort((a, b) => a.tick - b.tick);\r\n });\r\n this.events = trimmedEvents;\r\n this.totalTicks = lastNoteTick - firstNoteTick;\r\n if (typeof this.computeTempoMap === 'function') this.computeTempoMap();\r\n }\r\n\r\n\r\n async #extractLyrics() {\r\n if (this.#lyrics) return this.#lyrics;\r\n const structure = { language: \"\", title: \"\", paragraphs: [] };\r\n let bestTrack = null;\r\n let maxTextEventsCount = 0;\r\n this.events.forEach(track => {\r\n const textEventsInTrack = track.filter(e =>\r\n e.name === 'Text Event' ||\r\n e.name === 'Lyric Event' ||\r\n e.name === 'Cue Point' ||\r\n e.name === 'Marker' ||\r\n e.name === 'Track Name'\r\n );\r\n const realLyricsCount = textEventsInTrack.filter(e => {\r\n const textStr = e.string || e.text || \"\";\r\n return textStr && !textStr.startsWith('@');\r\n }).length;\r\n if (realLyricsCount > maxTextEventsCount) {\r\n maxTextEventsCount = realLyricsCount;\r\n bestTrack = textEventsInTrack;\r\n }\r\n });\r\n\r\n if (!bestTrack || bestTrack.length === 0) return structure;\r\n const allTextEvents = bestTrack.sort((a, b) => a.tick - b.tick);\r\n let paragraphs = [];\r\n let currentParaLines = [];\r\n let currentLineBlocks = [];\r\n let lastBlockTick = 0;\r\n allTextEvents.forEach(event => {\r\n let text = this.#decodeKaraokeString(event.string || \"\");\r\n if (!text) return;\r\n if (/^Track-/i.test(text.trim()) ||\r\n /^Piste/i.test(text.trim()) ||\r\n text.trim() === \"\" ||\r\n (event.tick === 0 && text.length > 20)) {\r\n return;\r\n }\r\n if (text.startsWith('@L')) {\r\n structure.language = text.substring(2).trim();\r\n return;\r\n }\r\n if (text.startsWith('@T')) {\r\n structure.title += (structure.title ? ' / ' : '') + text.substring(2).trim();\r\n return;\r\n }\r\n if (text.startsWith('@') ||\r\n text.startsWith('(') ||\r\n text.startsWith('PART') ||\r\n /^\\d+\\s+\\d+/.test(text.trim())) {\r\n return;\r\n }\r\n if (/^(Verse|Chorus|Bridge|Break|Intro|End\\.)/i.test(text.trim())) {\r\n const isExplicitCut = text.startsWith('\\\\') || text.startsWith('/');\r\n const isNaturalTransition = currentLineBlocks.length === 0 || (event.tick - lastBlockTick > 500);\r\n if (isExplicitCut || isNaturalTransition) {\r\n if (currentLineBlocks.length > 0) {\r\n currentParaLines.push({ tick: currentLineBlocks[0].tick, blocks: currentLineBlocks });\r\n currentLineBlocks = [];\r\n }\r\n if (currentParaLines.length > 0) {\r\n while (currentParaLines.length > 4) {\r\n const linesToPush = currentParaLines.splice(0, 4);\r\n paragraphs.push({ tick: linesToPush[0].tick, lines: linesToPush });\r\n }\r\n if (currentParaLines.length > 0) {\r\n paragraphs.push({ tick: currentParaLines[0].tick, lines: currentParaLines });\r\n currentParaLines = [];\r\n }\r\n }\r\n }\r\n return;\r\n }\r\n let forceNewLine = false;\r\n if (currentLineBlocks.length > 0) {\r\n const prevBlock = currentLineBlocks[currentLineBlocks.length - 1];\r\n const prevText = prevBlock.text;\r\n const currentTrimmed = text.trimLeft();\r\n if (currentTrimmed.length > 0) {\r\n const isCapitalized = /^[A-Z]/.test(currentTrimmed) || /^'[A-Z]/.test(currentTrimmed);\r\n const prevIsCapitalized = /^[A-Z]/.test( prevText.trim()) || /^'[A-Z]/.test( prevText.trim());\r\n if (isCapitalized && !prevText.endsWith(' ') && prevText.trim() != 'o' && !prevIsCapitalized) {\r\n if (event.tick > lastBlockTick) {\r\n forceNewLine = true;\r\n }\r\n }\r\n if (text.startsWith('\"') && prevText.endsWith('\"')) {\r\n forceNewLine = true;\r\n }\r\n if (text.startsWith('\"') && (prevText.endsWith(')') || prevText.endsWith(')\"'))) {\r\n forceNewLine = true;\r\n }\r\n if (currentTrimmed.startsWith('\"') && prevText.trimRight().endsWith(')')) {\r\n forceNewLine = true;\r\n }\r\n }\r\n }\r\n const isNewParagraphMarker = text.startsWith('\\\\');\r\n const isNewLineMarker = text.startsWith('/') || forceNewLine;\r\n if (isNewParagraphMarker || isNewLineMarker) {\r\n if (text.startsWith('\\\\') || text.startsWith('/')) {\r\n text = text.substring(1);\r\n }\r\n }\r\n text = text.replace(/[\\r\\n]/g, \"\");\r\n let isTimeGapTrigger = false;\r\n if (lastBlockTick > 0 && event.tick > lastBlockTick) {\r\n const secondsSilence = this.ticksToSeconds(lastBlockTick, event.tick);\r\n if (secondsSilence > 2.5) {\r\n isTimeGapTrigger = true;\r\n }\r\n }\r\n const currentLineChars = currentLineBlocks.reduce((sum, b) => sum + b.text.length, 0);\r\n const isWordLimitTrigger = currentLineChars + text.length > this.#opts.maxCharPerLine;\r\n\r\n if (isNewLineMarker || isNewParagraphMarker || isTimeGapTrigger || isWordLimitTrigger) {\r\n if (currentLineBlocks.length > 0) {\r\n currentParaLines.push({ tick: currentLineBlocks[0].tick, blocks: currentLineBlocks });\r\n currentLineBlocks = [];\r\n }\r\n if (currentParaLines.length > 0) {\r\n if (isNewParagraphMarker || isTimeGapTrigger) {\r\n while (currentParaLines.length > 4) {\r\n const linesToPush = currentParaLines.splice(0, 4);\r\n paragraphs.push({ tick: linesToPush[0].tick, lines: linesToPush });\r\n }\r\n if (currentParaLines.length > 0) {\r\n paragraphs.push({ tick: currentParaLines[0].tick, lines: currentParaLines });\r\n currentParaLines = [];\r\n }\r\n }\r\n else if (currentParaLines.length >= 6) {\r\n const linesToPush = currentParaLines.splice(0, 4);\r\n paragraphs.push({ tick: linesToPush[0].tick, lines: linesToPush });\r\n }\r\n }\r\n }\r\n if (text.length > 0) {\r\n currentLineBlocks.push({ text: text, tick: event.tick });\r\n lastBlockTick = event.tick;\r\n }\r\n });\r\n if (currentLineBlocks.length > 0) {\r\n currentParaLines.push({\r\n tick: currentLineBlocks[0].tick,\r\n blocks: currentLineBlocks\r\n });\r\n }\r\n while (currentParaLines.length > 4) {\r\n const linesToPush = currentParaLines.splice(0, 4);\r\n paragraphs.push({ tick: linesToPush[0].tick, lines: linesToPush });\r\n }\r\n if (currentParaLines.length > 0) {\r\n paragraphs.push({ tick: currentParaLines[0].tick, lines: currentParaLines });\r\n }\r\n paragraphs = paragraphs.filter(p => {\r\n return !(p.lines.length == 1 && p.lines[0].blocks.length == 1 && (['intro', 'outro', 'sfx', 'solo', 'chorus', 'verse', 'bridge', 'break', 'end'].includes(p.lines[0].blocks[0].text.toLowerCase().trim())));\r\n });\r\n if(paragraphs.length <= 2) paragraphs = [];\r\n structure.paragraphs = paragraphs;\r\n this.#lyrics = structure;\r\n return structure;\r\n }\r\n\r\n\r\n async #generateKaraokeFrames() {\r\n const lyrics = await this.#extractLyrics();\r\n if (!lyrics.paragraphs.length) {\r\n this.#haveLyrics = false;\r\n this.events[MidiAudioPlayer.KARAOKE_CHANNEL].push({\r\n text: `<span class=\"karaoke-intro\"></span>`,\r\n name: 'Karaoke Event',\r\n type: 'intro',\r\n tick: 0,\r\n channel: MidiAudioPlayer.KARAOKE_CHANNEL,\r\n });\r\n this.events[MidiAudioPlayer.KARAOKE_CHANNEL] = this.events[MidiAudioPlayer.KARAOKE_CHANNEL].sort((a, b) => a.tick - b.tick);\r\n return;\r\n }\r\n this.#haveLyrics = true;\r\n this.#title = lyrics.title;\r\n let lastFrameEnd = 0;\r\n const delayTicks = this.secondsToTicks(this.#opts.karaokeDelay);\r\n const threeSecondsInTicks = this.secondsToTicks(3);\r\n const fiveSecondsInTicks = this.secondsToTicks(5);\r\n const sevenSecondsInTicks = this.secondsToTicks(7);\r\n const tenSecondsInTicks = this.secondsToTicks(10);\r\n const allBlocksInSong = [];\r\n lyrics.paragraphs.forEach((p, pIdx) => {\r\n p.lines.forEach((l, lIdx) => {\r\n l.blocks.forEach(b => {\r\n allBlocksInSong.push({\r\n block: b,\r\n lineIdx: lIdx,\r\n paraIdx: pIdx,\r\n paragraph: p,\r\n fastLinesText: p.lines.map(li => li.blocks.map(bl => bl.text).join(''))\r\n });\r\n });\r\n });\r\n });\r\n const paragraphDisplayTicks = [];\r\n lyrics.paragraphs.forEach((p, pIdx) => {\r\n let paragraphDisplayTick = this.getTickBeforeSeconds(p.tick, 5);\r\n if (paragraphDisplayTick < lastFrameEnd)\r\n paragraphDisplayTick = lastFrameEnd + ((p.tick - lastFrameEnd) / 2);\r\n if (pIdx === 0 && paragraphDisplayTick < 20)\r\n paragraphDisplayTick = 20;\r\n paragraphDisplayTicks[pIdx] = paragraphDisplayTick;\r\n const fastLinesText = p.lines.map(li => li.blocks.map(b => b.text).join(''));\r\n const initialHTML = fastLinesText\r\n .map(lineText => `<span class=\"karaoke-coming\">${lineText}</span>`)\r\n .join('<br/>');\r\n this.events[MidiAudioPlayer.KARAOKE_CHANNEL].push({\r\n text: initialHTML,\r\n name: 'Karaoke Event',\r\n type: 'lyric',\r\n tick: paragraphDisplayTick,\r\n channel: MidiAudioPlayer.KARAOKE_CHANNEL,\r\n });\r\n if (p.lines.length > 0) {\r\n const lastLine = p.lines[p.lines.length - 1];\r\n if (lastLine.blocks.length > 0)\r\n lastFrameEnd = lastLine.blocks[lastLine.blocks.length - 1].tick;\r\n }\r\n });\r\n const firstParaDisplayTick = paragraphDisplayTicks[0] || 0;\r\n if (firstParaDisplayTick > 25) {\r\n this.events[MidiAudioPlayer.KARAOKE_CHANNEL].push({\r\n text: `<span class=\"karaoke-clear\"></span>`,\r\n name: 'Karaoke Event',\r\n type: 'clear',\r\n tick: 5,\r\n channel: MidiAudioPlayer.KARAOKE_CHANNEL,\r\n });\r\n }\r\n allBlocksInSong.forEach((current, index) => {\r\n const currentBlock = current.block;\r\n const currentLineIdx = current.lineIdx;\r\n const currentParaIdx = current.paraIdx;\r\n const p = current.paragraph;\r\n const fastLinesText = current.fastLinesText;\r\n const generateHTML = (forceAllPlayedOnActiveLine = false) => {\r\n return p.lines.map((li, liIdx) => {\r\n if (liIdx < currentLineIdx)\r\n return `<span class=\"karaoke-played\">${fastLinesText[liIdx]}</span>`;\r\n if (liIdx > currentLineIdx)\r\n return `<span class=\"karaoke-coming\">${fastLinesText[liIdx]}</span>`;\r\n let lineHTML = '';\r\n li.blocks.forEach(block => {\r\n let className = 'coming';\r\n if (forceAllPlayedOnActiveLine || block.tick < currentBlock.tick)\r\n className = 'played';\r\n else if (block.tick === currentBlock.tick)\r\n className = 'playing';\r\n lineHTML += `<span class=\"karaoke-${className}\">${block.text}</span>`;\r\n });\r\n return lineHTML;\r\n }).join('<br>');\r\n };\r\n this.events[MidiAudioPlayer.KARAOKE_CHANNEL].push({\r\n text: generateHTML(false),\r\n name: 'Karaoke Event',\r\n type: 'lyric',\r\n tick: currentBlock.tick - delayTicks,\r\n channel: MidiAudioPlayer.KARAOKE_CHANNEL,\r\n });\r\n const next = allBlocksInSong[index + 1];\r\n if (next) {\r\n const tickDifference = next.block.tick - currentBlock.tick;\r\n if (tickDifference > threeSecondsInTicks) {\r\n let targetCleanupTick = currentBlock.tick + threeSecondsInTicks;\r\n let targetClearTick = currentBlock.tick + sevenSecondsInTicks;\r\n let shouldAddClear = tickDifference > tenSecondsInTicks && currentParaIdx > 0;\r\n if (next.paraIdx !== currentParaIdx) {\r\n const nextParaDisplayTick = paragraphDisplayTicks[next.paraIdx];\r\n if (targetCleanupTick >= nextParaDisplayTick)\r\n targetCleanupTick = nextParaDisplayTick - 1;\r\n if (shouldAddClear)\r\n if (targetClearTick >= nextParaDisplayTick || (nextParaDisplayTick - targetClearTick) < threeSecondsInTicks)\r\n shouldAddClear = false;\r\n }\r\n if (targetCleanupTick > currentBlock.tick) {\r\n this.events[MidiAudioPlayer.KARAOKE_CHANNEL].push({\r\n text: generateHTML(true),\r\n name: 'Karaoke Event',\r\n type: 'lyric',\r\n tick: targetCleanupTick - delayTicks,\r\n channel: MidiAudioPlayer.KARAOKE_CHANNEL,\r\n });\r\n }\r\n if (shouldAddClear && targetClearTick > targetCleanupTick) {\r\n this.events[MidiAudioPlayer.KARAOKE_CHANNEL].push({\r\n text: `<span class=\"karaoke-clear\"></span>`,\r\n name: 'Karaoke Event',\r\n type: 'clear',\r\n tick: targetClearTick - delayTicks,\r\n channel: MidiAudioPlayer.KARAOKE_CHANNEL,\r\n });\r\n }\r\n }\r\n }\r\n lastFrameEnd = currentBlock.tick;\r\n });\r\n if ((this.totalTicks - lastFrameEnd) > this.secondsToTicks(5)) {\r\n this.events[MidiAudioPlayer.KARAOKE_CHANNEL].push({\r\n text: `<span class=\"karaoke-clear\"></span>`,\r\n name: 'Karaoke Event',\r\n type: 'clear',\r\n tick: lastFrameEnd + this.secondsToTicks(5),\r\n channel: MidiAudioPlayer.KARAOKE_CHANNEL,\r\n });\r\n } else {\r\n this.events[MidiAudioPlayer.KARAOKE_CHANNEL].push({\r\n text: `<span class=\"karaoke-clear\"></span>`,\r\n name: 'Karaoke Event',\r\n type: 'clear',\r\n tick: this.totalTicks - 1,\r\n channel: MidiAudioPlayer.KARAOKE_CHANNEL,\r\n });\r\n }\r\n this.events[MidiAudioPlayer.KARAOKE_CHANNEL] = this.events[MidiAudioPlayer.KARAOKE_CHANNEL].sort((a, b) => a.tick - b.tick);\r\n }\r\n\r\n\r\n async #detectKaraokeVocalChannel() {\r\n const lyrics = await this.#extractLyrics();\r\n if (!lyrics?.paragraphs?.length) return null;\r\n const textTicks = lyrics.paragraphs\r\n .flatMap(p => p.lines.flatMap(l => l.blocks.map(b => b.tick)));\r\n if (textTicks.length === 0) return null;\r\n const tickTolerance = this.division ? (this.division / 2) : 48;\r\n const VOCAL_MIN = 48;\r\n const VOCAL_MAX = 84;\r\n const channelsToScan = Object.keys(this.#channels)\r\n .map(Number)\r\n .filter(chan => chan !== 10);\r\n let bestChannel = null;\r\n let bestScore = -Infinity;\r\n for (const channel of channelsToScan) {\r\n const notes = this.events.flatMap(track =>\r\n track.filter(e =>\r\n e.name === 'Note on' &&\r\n e.velocity > 0 &&\r\n e.channel === channel\r\n )\r\n );\r\n if (notes.length === 0) continue;\r\n const aligned = textTicks.filter(t =>\r\n notes.some(n => Math.abs(n.tick - t) <= tickTolerance)\r\n ).length;\r\n const alignmentScore = aligned / textTicks.length;\r\n const notesInRange = notes.filter(n => n.noteNumber >= VOCAL_MIN && n.noteNumber <= VOCAL_MAX);\r\n const rangeScore = notesInRange.length / notes.length;\r\n if (rangeScore < 0.30) continue;\r\n const sorted = [...notes].sort((a, b) => a.tick - b.tick);\r\n const minGap = (this.division / 8) || 6;\r\n const poly = sorted.filter((n, i) => i > 0 && Math.abs(n.tick - sorted[i - 1].tick) < minGap).length;\r\n const monophonyScore = 1 - poly / Math.max(notes.length - 1, 1);\r\n const densityRatio = notes.length / Math.max(textTicks.length, 1);\r\n const densityScore = densityRatio < 0.3 ? densityRatio / 0.3\r\n : densityRatio > 5 ? Math.max(0, 1 - (densityRatio - 5) / 10)\r\n : 1.0;\r\n const score = (alignmentScore * 0.45)\r\n + (rangeScore * 0.35)\r\n + (monophonyScore * 0.15)\r\n + (densityScore * 0.05);\r\n if (score > bestScore) {\r\n bestScore = score;\r\n bestChannel = channel;\r\n }\r\n }\r\n return bestScore >= 0.40 ? bestChannel : null;\r\n }\r\n\r\n\r\n #decodeKaraokeString(str) {\r\n if (!str) return '';\r\n const bytes = new Uint8Array(str.length);\r\n for (let i = 0; i < str.length; i++) bytes[i] = str.charCodeAt(i) & 0xff;\r\n const decoder = new TextDecoder('windows-1252');\r\n let decoded = decoder.decode(bytes);\r\n decoded = decoded.replace(/\u00FF/g, '');\r\n decoded = decoded.replace(/\u2019/g, \"'\");\r\n decoded = decoded.replace(/`/g, \"'\");\r\n return decoded;\r\n }\r\n\r\n\r\n #sendKaraokeFrame(type = 'clear', text = '') {\r\n const html = `<span class=\"karaoke-${type}\">${text.replace(/\\s\\/\\s/g, '<br>')}</span>`;\r\n if(this.#opts.karaoke) {\r\n if(type == 'title') queueMicrotask(() => this.triggerPlayerEvent('karaoke', { type: type, title: text, html: html}));\r\n else queueMicrotask(() => this.triggerPlayerEvent('karaoke', { type: type, html: html}));\r\n }\r\n }\r\n\r\n\r\n #log(str, err = false) {\r\n queueMicrotask(() => this.triggerPlayerEvent('logs', str));\r\n }\r\n\r\n}", "import MidiAudioPlayer from './src/midiaudioplayer.js';\r\n\r\nif (typeof window !== 'undefined') window.MidiAudioPlayer = MidiAudioPlayer;\r\n\r\nexport { MidiAudioPlayer };\r\nexport default MidiAudioPlayer;"],
5
+ "mappings": "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",
6
+ "names": ["_loop", "Utils", "atob", "Track", "index", "Player", "e", "index", "index_default"]
7
7
  }