UNPKG

musicvis-lib

Version:

Music analysis and visualization library

1,007 lines (1,003 loc) 433 kB
var musicvislib = (() => { var __create = Object.create; var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __commonJS = (cb, mod2) => function __require() { return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports; }; var __export = (target, all4) => { for (var name2 in all4) __defProp(target, name2, { get: all4[name2], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__getProtoOf(mod2)) : {}, __copyProps(isNodeMode || !mod2 || !mod2.__esModule ? __defProp(target, "default", { value: mod2, enumerable: true }) : target, mod2)); var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2); // node_modules/.pnpm/midi-parser-js@4.0.4/node_modules/midi-parser-js/src/main.js var require_main = __commonJS({ "node_modules/.pnpm/midi-parser-js@4.0.4/node_modules/midi-parser-js/src/main.js"(exports2, module2) { (function() { "use strict"; const _atob = function(string) { let b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; let b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/; string = string.replace(/^.*?base64,/, ""); string = String(string).replace(/[\t\n\f\r ]+/g, ""); if (!b64re.test(string)) throw new TypeError("Failed to execute _atob() : The string to be decoded is not correctly encoded."); string += "==".slice(2 - (string.length & 3)); let bitmap, result = ""; let r1, r2, i = 0; for (; i < string.length; ) { bitmap = b64.indexOf(string.charAt(i++)) << 18 | b64.indexOf(string.charAt(i++)) << 12 | (r1 = b64.indexOf(string.charAt(i++))) << 6 | (r2 = b64.indexOf(string.charAt(i++))); result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) : r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) : String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255); } return result; }; const MidiParser = { debug: false, parse: function(input, _callback) { if (input instanceof Uint8Array) return MidiParser.Uint8(input); else if (typeof input === "string") return MidiParser.Base64(input); else if (input instanceof HTMLElement && input.type === "file") return MidiParser.addListener(input, _callback); else throw new Error("MidiParser.parse() : Invalid input provided"); }, addListener: function(_fileElement, _callback) { if (!File || !FileReader) throw new Error("The File|FileReader APIs are not supported in this browser. Use instead MidiParser.Base64() or MidiParser.Uint8()"); if (_fileElement === void 0 || !(_fileElement instanceof HTMLElement) || _fileElement.tagName !== "INPUT" || _fileElement.type.toLowerCase() !== "file") { console.warn("MidiParser.addListener() : Provided element is not a valid FILE INPUT element"); return false; } _callback = _callback || function() { }; _fileElement.addEventListener("change", function(InputEvt) { if (!InputEvt.target.files.length) return false; console.log("MidiParser.addListener() : File detected in INPUT ELEMENT processing data.."); let reader = new FileReader(); reader.readAsArrayBuffer(InputEvt.target.files[0]); reader.onload = function(e) { _callback(MidiParser.Uint8(new Uint8Array(e.target.result))); }; }); }, Base64: function(b64String) { b64String = String(b64String); let raw = _atob(b64String); let rawLength = raw.length; let t_array = new Uint8Array(new ArrayBuffer(rawLength)); for (let i = 0; i < rawLength; i++) t_array[i] = raw.charCodeAt(i); return MidiParser.Uint8(t_array); }, Uint8: function(FileAsUint8Array) { let file = { data: null, pointer: 0, movePointer: function(_bytes) { this.pointer += _bytes; return this.pointer; }, readInt: function(_bytes) { _bytes = Math.min(_bytes, this.data.byteLength - this.pointer); if (_bytes < 1) return -1; let value = 0; if (_bytes > 1) { for (let i = 1; i <= _bytes - 1; i++) { value += this.data.getUint8(this.pointer) * Math.pow(256, _bytes - i); this.pointer++; } } value += this.data.getUint8(this.pointer); this.pointer++; return value; }, readStr: function(_bytes) { let text = ""; for (let char = 1; char <= _bytes; char++) text += String.fromCharCode(this.readInt(1)); return text; }, readIntVLV: function() { let value = 0; if (this.pointer >= this.data.byteLength) { return -1; } else if (this.data.getUint8(this.pointer) < 128) { value = this.readInt(1); } else { let FirstBytes = []; while (this.data.getUint8(this.pointer) >= 128) { FirstBytes.push(this.readInt(1) - 128); } let lastByte = this.readInt(1); for (let dt = 1; dt <= FirstBytes.length; dt++) { value += FirstBytes[FirstBytes.length - dt] * Math.pow(128, dt); } value += lastByte; } return value; } }; file.data = new DataView(FileAsUint8Array.buffer, FileAsUint8Array.byteOffset, FileAsUint8Array.byteLength); if (file.readInt(4) !== 1297377380) { console.warn("Header validation failed (not MIDI standard or file corrupt.)"); return false; } let headerSize = file.readInt(4); let MIDI = {}; MIDI.formatType = file.readInt(2); MIDI.tracks = file.readInt(2); MIDI.track = []; let timeDivisionByte1 = file.readInt(1); let timeDivisionByte2 = file.readInt(1); if (timeDivisionByte1 >= 128) { MIDI.timeDivision = []; MIDI.timeDivision[0] = timeDivisionByte1 - 128; MIDI.timeDivision[1] = timeDivisionByte2; } else MIDI.timeDivision = timeDivisionByte1 * 256 + timeDivisionByte2; for (let t = 1; t <= MIDI.tracks; t++) { MIDI.track[t - 1] = { event: [] }; let headerValidation = file.readInt(4); if (headerValidation === -1) break; if (headerValidation !== 1297379947) return false; file.readInt(4); let e = 0; let endOfTrack = false; let statusByte; let laststatusByte; while (!endOfTrack) { e++; MIDI.track[t - 1].event[e - 1] = {}; MIDI.track[t - 1].event[e - 1].deltaTime = file.readIntVLV(); statusByte = file.readInt(1); if (statusByte === -1) break; else if (statusByte >= 128) laststatusByte = statusByte; else { statusByte = laststatusByte; file.movePointer(-1); } if (statusByte === 255) { MIDI.track[t - 1].event[e - 1].type = 255; MIDI.track[t - 1].event[e - 1].metaType = file.readInt(1); let metaEventLength = file.readIntVLV(); switch (MIDI.track[t - 1].event[e - 1].metaType) { case 47: case -1: endOfTrack = true; break; case 1: case 2: case 3: case 4: case 5: case 7: case 6: MIDI.track[t - 1].event[e - 1].data = file.readStr(metaEventLength); break; case 33: case 89: case 81: MIDI.track[t - 1].event[e - 1].data = file.readInt(metaEventLength); break; case 84: MIDI.track[t - 1].event[e - 1].data = []; MIDI.track[t - 1].event[e - 1].data[0] = file.readInt(1); MIDI.track[t - 1].event[e - 1].data[1] = file.readInt(1); MIDI.track[t - 1].event[e - 1].data[2] = file.readInt(1); MIDI.track[t - 1].event[e - 1].data[3] = file.readInt(1); MIDI.track[t - 1].event[e - 1].data[4] = file.readInt(1); break; case 88: MIDI.track[t - 1].event[e - 1].data = []; MIDI.track[t - 1].event[e - 1].data[0] = file.readInt(1); MIDI.track[t - 1].event[e - 1].data[1] = file.readInt(1); MIDI.track[t - 1].event[e - 1].data[2] = file.readInt(1); MIDI.track[t - 1].event[e - 1].data[3] = file.readInt(1); break; default: if (this.customInterpreter !== null) { MIDI.track[t - 1].event[e - 1].data = this.customInterpreter(MIDI.track[t - 1].event[e - 1].metaType, file, metaEventLength); } if (this.customInterpreter === null || MIDI.track[t - 1].event[e - 1].data === false) { file.readInt(metaEventLength); MIDI.track[t - 1].event[e - 1].data = file.readInt(metaEventLength); if (this.debug) console.info("Unimplemented 0xFF meta event! data block readed as Integer"); } } } else { statusByte = statusByte.toString(16).split(""); if (!statusByte[1]) statusByte.unshift("0"); MIDI.track[t - 1].event[e - 1].type = parseInt(statusByte[0], 16); MIDI.track[t - 1].event[e - 1].channel = parseInt(statusByte[1], 16); switch (MIDI.track[t - 1].event[e - 1].type) { case 15: { if (this.customInterpreter !== null) { MIDI.track[t - 1].event[e - 1].data = this.customInterpreter(MIDI.track[t - 1].event[e - 1].type, file, false); } if (this.customInterpreter === null || MIDI.track[t - 1].event[e - 1].data === false) { let event_length = file.readIntVLV(); MIDI.track[t - 1].event[e - 1].data = file.readInt(event_length); if (this.debug) console.info("Unimplemented 0xF exclusive events! data block readed as Integer"); } break; } case 10: case 11: case 14: case 8: case 9: MIDI.track[t - 1].event[e - 1].data = []; MIDI.track[t - 1].event[e - 1].data[0] = file.readInt(1); MIDI.track[t - 1].event[e - 1].data[1] = file.readInt(1); break; case 12: case 13: MIDI.track[t - 1].event[e - 1].data = file.readInt(1); break; case -1: endOfTrack = true; break; default: if (this.customInterpreter !== null) { MIDI.track[t - 1].event[e - 1].data = this.customInterpreter(MIDI.track[t - 1].event[e - 1].metaType, file, false); } if (this.customInterpreter === null || MIDI.track[t - 1].event[e - 1].data === false) { console.log("Unknown EVENT detected... reading cancelled!"); return false; } } } } } return MIDI; }, customInterpreter: null }; if (typeof module2 !== "undefined") module2.exports = MidiParser; else { let _global = typeof window === "object" && window.self === window && window || typeof self === "object" && self.self === self && self || typeof global === "object" && global.global === global && global; _global.MidiParser = MidiParser; } })(); } }); // src/index.js var src_exports = {}; __export(src_exports, { Alignment: () => Alignment_exports, Canvas: () => Canvas_exports, Chords: () => Chords_exports, DiffAlignment: () => DiffAlignment_exports, Drums: () => Drums_exports, Guitar: () => Guitar_exports, GuitarNote: () => GuitarNote_default, HarmonicaNote: () => HarmonicaNote_default, Lamellophone: () => Lamellophone_exports, Matching: () => Matching_exports, Midi: () => Midi_exports, MidiInputManager: () => MidiInputManager_default, MusicPiece: () => MusicPiece_default, Note: () => Note_default, NoteArray: () => NoteArray_default, Piano: () => Piano_exports, PitchSequence: () => PitchSequence_default, PriorityMatching: () => PriorityMatching_exports, Recording: () => Recording_default, SimilarSections: () => SimilarSections_exports, Similarity: () => Similarity_exports, StringBased: () => stringBased_exports, Utils: () => utils_exports, getVersion: () => getVersion, recordAudio: () => recordAudio, recordMidi: () => recordMidi }); // package.json var name = "musicvis-lib"; var version = "0.57.1"; var description = "Music analysis and visualization library"; var author = "Frank Heyen"; var license = "ISC"; var homepage = "https://fheyen.github.io/musicvis-lib"; var repository = { url: "git+https://github.com/fheyen/musicvis-lib", type: "git" }; var bugs = { url: "https://github.com/fheyen/musicvis-lib/issues" }; var keywords = [ "visualization", "music visualization", "visual analytics", "JavaScript", "ECMAScript", "web-based", "MIDI", "MusicXML", "Web MIDI", "music", "string comparison" ]; var type = "module"; var exports = "./src/index.js"; var main = "dist/musicvislib.node.js"; var module = "dist/musicvislib.esm.js"; var unpkg = "dist/musicvislib.min.js"; var browser = "dist/musicvislib.min.js"; var scripts = { upd: "npm-check-updates -u", "upd:i": "npm-check-updates -u && npm i && npm audit fix", "upd:i:t": "npm-check-updates -u && npm i && npm test", build: "npm run build:bundle && npm run build:browser && npm run build:browser:min && npm run build:node", "build:bundle": "esbuild src/index.js --bundle --format=esm --sourcemap --outfile=dist/musicvislib.esm.js", "build:browser": "esbuild src/index.js --bundle --format=iife --global-name=musicvislib --sourcemap --target=chrome90,firefox90,edge90 --outfile=dist/musicvislib.js", "build:browser:min": "esbuild src/index.js --bundle --format=iife --global-name=musicvislib --sourcemap --minify --target=chrome90,firefox90,edge90 --outfile=dist/musicvislib.min.js", "build:node": "esbuild src/index.js --bundle --sourcemap --platform=node --target=node16.5 --outfile=dist/musicvislib.node.js", test: "jest --coverage", testch: "jest --coverage --changedFilesWithAncestor", testfail: "jest --changedFilesWithAncestor --onlyFailures", testclear: "jest --clearCache", doc: "jsdoc -c jsdoc.conf.json", "doc:md": "jsdoc2md src/**/*.js > api.md", lint: "standard --verbose", "lint:fix": "standard --fix --verbose", "git:all": "npm run git:add && npm run git:commit && npm run git:push && npm run git:pushtags", "git:add": "git add .", "git:commit": 'git commit -m "new version build"', "git:push": "git push", "git:pushtags": "git push origin --tags", predeploy: "npm run lint:fix && npm run doc:md && npm run build && jest --silent", predeploy_old: "npm run lint:fix && npm run doc:md && npm run doc && npm run build && jest --silent", deploy: "npm publish && npm run git:all", prepare: "husky install" }; var dependencies = { "@tonaljs/tonal": "^4.6.5", d3: "^6.7.0", "midi-parser-js": "^4.0.4" }; var devDependencies = { "@babel/core": "^7.19.3", "@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-optional-chaining": "^7.18.9", "@babel/preset-env": "^7.19.4", "@types/d3": "^7.4.0", "@types/jest": "^29.1.2", "clean-jsdoc-theme": "^4.1.8", esbuild: "^0.15.10", glob: "^8.0.3", husky: "^8.0.1", jest: "^29.1.2", "jest-canvas-mock": "^2.4.0", "jest-environment-jsdom": "^29.1.2", "jest-extended": "^3.1.0", jsdoc: "^3.6.11", "jsdoc-to-markdown": "^7.1.1", "npm-check-updates": "^16.3.11", standard: "^17.0.0" }; var jest = { testEnvironment: "jsdom", testPathIgnorePatterns: [ "<rootDir>/node_modules/", "<rootDir>/dist/" ], collectCoverageFrom: [ "src/**/*.js" ], setupFilesAfterEnv: [ "jest-extended/all" ] }; var standard = { ignore: [ "/dist/", "/docs/" ], globals: [ "MediaRecorder", "Blob", "DOMParser", "CanvasRenderingContext2D", "localStorage", "FileReader" ], env: [ "jest" ] }; var package_default = { name, version, description, author, license, homepage, repository, bugs, keywords, type, exports, main, module, unpkg, browser, scripts, dependencies, devDependencies, jest, standard }; // src/fileFormats/Midi.js var Midi_exports = {}; __export(Midi_exports, { MIDI_COMMANDS: () => MIDI_COMMANDS, MIDI_NOTES: () => MIDI_NOTES, MIDI_NOTE_RANGES: () => MIDI_NOTE_RANGES, NOTE_NAMES: () => NOTE_NAMES, NOTE_NAMES_FLAT: () => NOTE_NAMES_FLAT, SHARPS: () => SHARPS, flatToSharp: () => flatToSharp, getMidiDrumNoteByNr: () => getMidiDrumNoteByNr, getMidiInstrumentByNr: () => getMidiInstrumentByNr, getMidiInstrumentByNrL2: () => getMidiInstrumentByNrL2, getMidiNoteByLabel: () => getMidiNoteByLabel, getMidiNoteByNameAndOctave: () => getMidiNoteByNameAndOctave, getMidiNoteByNr: () => getMidiNoteByNr, getNoteNameFromNoteNr: () => getNoteNameFromNoteNr, isSharp: () => isSharp, sharpToFlat: () => sharpToFlat }); var MidiNoteByPitch = /* @__PURE__ */ new Map(); var MidiNoteByLabel = /* @__PURE__ */ new Map(); var MidiInstrumentByNumber = /* @__PURE__ */ new Map(); var MidiInstrumentByNumberLev2 = /* @__PURE__ */ new Map(); function getMidiNoteByNr(nr) { return MidiNoteByPitch.get(nr); } function getMidiNoteByLabel(label) { return MidiNoteByLabel.get(label); } function getMidiNoteByNameAndOctave(name2, octave) { return MidiNoteByLabel.get(`${name2}${octave}`); } function getMidiInstrumentByNr(nr) { return MidiInstrumentByNumber.get(nr); } function getMidiInstrumentByNrL2(nr, subNr) { const key = `${nr}-${subNr}`; return MidiInstrumentByNumberLev2.get(key); } function getMidiDrumNoteByNr(nr) { return GENERAL_MIDI_DRUM_NOTE_NUMBERS.get(nr); } function isSharp(nr) { const chroma = nr % 12; return chroma === 1 || chroma === 3 || chroma === 6 || chroma === 8 || chroma === 10; } function getNoteNameFromNoteNr(nr) { return NOTE_NAMES[nr % 12]; } var flatToSharp = /* @__PURE__ */ new Map([ ["Cb", "B"], ["Db", "C#"], ["Eb", "D#"], ["Fb", "E"], ["Gb", "F#"], ["Ab", "G#"], ["Bb", "A#"] ]); var sharpToFlat = /* @__PURE__ */ new Map([ ["C#", "Db"], ["D#", "Eb"], ["E#", "F"], ["F#", "Gb"], ["G#", "Ab"], ["A#", "Bb"], ["B#", "C"] ]); var NOTE_NAMES = [ "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" ]; var NOTE_NAMES_FLAT = [ "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B" ]; var MIDI_NOTES = [ { pitch: 0, name: "C", octave: -1, label: "C-1", frequency: 8.176 }, { pitch: 1, name: "C#", octave: -1, label: "C#-1", frequency: 8.662 }, { pitch: 2, name: "D", octave: -1, label: "D-1", frequency: 9.177 }, { pitch: 3, name: "D#", octave: -1, label: "D#-1", frequency: 9.723 }, { pitch: 4, name: "E", octave: -1, label: "E-1", frequency: 10.301 }, { pitch: 5, name: "F", octave: -1, label: "F-1", frequency: 10.913 }, { pitch: 6, name: "F#", octave: -1, label: "F#-1", frequency: 11.562 }, { pitch: 7, name: "G", octave: -1, label: "G-1", frequency: 12.25 }, { pitch: 8, name: "G#", octave: -1, label: "G#-1", frequency: 12.978 }, { pitch: 9, name: "A", octave: -1, label: "A-1", frequency: 13.75 }, { pitch: 10, name: "A#", octave: -1, label: "A#-1", frequency: 14.568 }, { pitch: 11, name: "B", octave: -1, label: "B-1", frequency: 15.434 }, { pitch: 12, name: "C", octave: 0, label: "C0", frequency: 16.352 }, { pitch: 13, name: "C#", octave: 0, label: "C#0", frequency: 17.324 }, { pitch: 14, name: "D", octave: 0, label: "D0", frequency: 18.354 }, { pitch: 15, name: "D#", octave: 0, label: "D#0", frequency: 19.445 }, { pitch: 16, name: "E", octave: 0, label: "E0", frequency: 20.602 }, { pitch: 17, name: "F", octave: 0, label: "F0", frequency: 21.827 }, { pitch: 18, name: "F#", octave: 0, label: "F#0", frequency: 23.125 }, { pitch: 19, name: "G", octave: 0, label: "G0", frequency: 24.5 }, { pitch: 20, name: "G#", octave: 0, label: "G#0", frequency: 25.957 }, { pitch: 21, name: "A", octave: 0, label: "A0", frequency: 27.5 }, { pitch: 22, name: "A#", octave: 0, label: "A#0", frequency: 29.135 }, { pitch: 23, name: "B", octave: 0, label: "B0", frequency: 30.868 }, { pitch: 24, name: "C", octave: 1, label: "C1", frequency: 32.703 }, { pitch: 25, name: "C#", octave: 1, label: "C#1", frequency: 34.648 }, { pitch: 26, name: "D", octave: 1, label: "D1", frequency: 36.708 }, { pitch: 27, name: "D#", octave: 1, label: "D#1", frequency: 38.891 }, { pitch: 28, name: "E", octave: 1, label: "E1", frequency: 41.203 }, { pitch: 29, name: "F", octave: 1, label: "F1", frequency: 43.654 }, { pitch: 30, name: "F#", octave: 1, label: "F#1", frequency: 46.249 }, { pitch: 31, name: "G", octave: 1, label: "G1", frequency: 48.999 }, { pitch: 32, name: "G#", octave: 1, label: "G#1", frequency: 51.913 }, { pitch: 33, name: "A", octave: 1, label: "A1", frequency: 55 }, { pitch: 34, name: "A#", octave: 1, label: "A#1", frequency: 58.27 }, { pitch: 35, name: "B", octave: 1, label: "B1", frequency: 61.735 }, { pitch: 36, name: "C", octave: 2, label: "C2", frequency: 65.406 }, { pitch: 37, name: "C#", octave: 2, label: "C#2", frequency: 69.296 }, { pitch: 38, name: "D", octave: 2, label: "D2", frequency: 73.416 }, { pitch: 39, name: "D#", octave: 2, label: "D#2", frequency: 77.782 }, { pitch: 40, name: "E", octave: 2, label: "E2", frequency: 82.407 }, { pitch: 41, name: "F", octave: 2, label: "F2", frequency: 87.307 }, { pitch: 42, name: "F#", octave: 2, label: "F#2", frequency: 92.499 }, { pitch: 43, name: "G", octave: 2, label: "G2", frequency: 97.999 }, { pitch: 44, name: "G#", octave: 2, label: "G#2", frequency: 103.826 }, { pitch: 45, name: "A", octave: 2, label: "A2", frequency: 110 }, { pitch: 46, name: "A#", octave: 2, label: "A#2", frequency: 116.541 }, { pitch: 47, name: "B", octave: 2, label: "B2", frequency: 123.471 }, { pitch: 48, name: "C", octave: 3, label: "C3", frequency: 130.813 }, { pitch: 49, name: "C#", octave: 3, label: "C#3", frequency: 138.591 }, { pitch: 50, name: "D", octave: 3, label: "D3", frequency: 146.832 }, { pitch: 51, name: "D#", octave: 3, label: "D#3", frequency: 155.563 }, { pitch: 52, name: "E", octave: 3, label: "E3", frequency: 164.814 }, { pitch: 53, name: "F", octave: 3, label: "F3", frequency: 174.614 }, { pitch: 54, name: "F#", octave: 3, label: "F#3", frequency: 184.997 }, { pitch: 55, name: "G", octave: 3, label: "G3", frequency: 195.998 }, { pitch: 56, name: "G#", octave: 3, label: "G#3", frequency: 207.652 }, { pitch: 57, name: "A", octave: 3, label: "A3", frequency: 220 }, { pitch: 58, name: "A#", octave: 3, label: "A#3", frequency: 233.082 }, { pitch: 59, name: "B", octave: 3, label: "B3", frequency: 246.942 }, { pitch: 60, name: "C", octave: 4, label: "C4", frequency: 261.626 }, { pitch: 61, name: "C#", octave: 4, label: "C#4", frequency: 277.183 }, { pitch: 62, name: "D", octave: 4, label: "D4", frequency: 293.665 }, { pitch: 63, name: "D#", octave: 4, label: "D#4", frequency: 311.127 }, { pitch: 64, name: "E", octave: 4, label: "E4", frequency: 329.628 }, { pitch: 65, name: "F", octave: 4, label: "F4", frequency: 349.228 }, { pitch: 66, name: "F#", octave: 4, label: "F#4", frequency: 369.994 }, { pitch: 67, name: "G", octave: 4, label: "G4", frequency: 391.995 }, { pitch: 68, name: "G#", octave: 4, label: "G#4", frequency: 415.305 }, { pitch: 69, name: "A", octave: 4, label: "A4", frequency: 440 }, { pitch: 70, name: "A#", octave: 4, label: "A#4", frequency: 466.164 }, { pitch: 71, name: "B", octave: 4, label: "B4", frequency: 493.883 }, { pitch: 72, name: "C", octave: 5, label: "C5", frequency: 523.251 }, { pitch: 73, name: "C#", octave: 5, label: "C#5", frequency: 554.365 }, { pitch: 74, name: "D", octave: 5, label: "D5", frequency: 587.33 }, { pitch: 75, name: "D#", octave: 5, label: "D#5", frequency: 622.254 }, { pitch: 76, name: "E", octave: 5, label: "E5", frequency: 659.255 }, { pitch: 77, name: "F", octave: 5, label: "F5", frequency: 698.456 }, { pitch: 78, name: "F#", octave: 5, label: "F#5", frequency: 739.989 }, { pitch: 79, name: "G", octave: 5, label: "G5", frequency: 783.991 }, { pitch: 80, name: "G#", octave: 5, label: "G#5", frequency: 830.609 }, { pitch: 81, name: "A", octave: 5, label: "A5", frequency: 880 }, { pitch: 82, name: "A#", octave: 5, label: "A#5", frequency: 932.328 }, { pitch: 83, name: "B", octave: 5, label: "B5", frequency: 987.767 }, { pitch: 84, name: "C", octave: 6, label: "C6", frequency: 1046.502 }, { pitch: 85, name: "C#", octave: 6, label: "C#6", frequency: 1108.731 }, { pitch: 86, name: "D", octave: 6, label: "D6", frequency: 1174.659 }, { pitch: 87, name: "D#", octave: 6, label: "D#6", frequency: 1244.508 }, { pitch: 88, name: "E", octave: 6, label: "E6", frequency: 1318.51 }, { pitch: 89, name: "F", octave: 6, label: "F6", frequency: 1396.913 }, { pitch: 90, name: "F#", octave: 6, label: "F#6", frequency: 1479.978 }, { pitch: 91, name: "G", octave: 6, label: "G6", frequency: 1567.982 }, { pitch: 92, name: "G#", octave: 6, label: "G#6", frequency: 1661.219 }, { pitch: 93, name: "A", octave: 6, label: "A6", frequency: 1760 }, { pitch: 94, name: "A#", octave: 6, label: "A#6", frequency: 1864.655 }, { pitch: 95, name: "B", octave: 6, label: "B6", frequency: 1975.533 }, { pitch: 96, name: "C", octave: 7, label: "C7", frequency: 2093.005 }, { pitch: 97, name: "C#", octave: 7, label: "C#7", frequency: 2217.461 }, { pitch: 98, name: "D", octave: 7, label: "D7", frequency: 2349.318 }, { pitch: 99, name: "D#", octave: 7, label: "D#7", frequency: 2489.016 }, { pitch: 100, name: "E", octave: 7, label: "E7", frequency: 2637.02 }, { pitch: 101, name: "F", octave: 7, label: "F7", frequency: 2793.826 }, { pitch: 102, name: "F#", octave: 7, label: "F#7", frequency: 2959.955 }, { pitch: 103, name: "G", octave: 7, label: "G7", frequency: 3135.963 }, { pitch: 104, name: "G#", octave: 7, label: "G#7", frequency: 3322.438 }, { pitch: 105, name: "A", octave: 7, label: "A7", frequency: 3520 }, { pitch: 106, name: "A#", octave: 7, label: "A#7", frequency: 3729.31 }, { pitch: 107, name: "B", octave: 7, label: "B7", frequency: 3951.066 }, { pitch: 108, name: "C", octave: 8, label: "C8", frequency: 4186.009 }, { pitch: 109, name: "C#", octave: 8, label: "C#8", frequency: 4434.922 }, { pitch: 110, name: "D", octave: 8, label: "D8", frequency: 4698.636 }, { pitch: 111, name: "D#", octave: 8, label: "D#8", frequency: 4978.032 }, { pitch: 112, name: "E", octave: 8, label: "E8", frequency: 5274.041 }, { pitch: 113, name: "F", octave: 8, label: "F8", frequency: 5587.652 }, { pitch: 114, name: "F#", octave: 8, label: "F#8", frequency: 5919.911 }, { pitch: 115, name: "G", octave: 8, label: "G8", frequency: 6271.927 }, { pitch: 116, name: "G#", octave: 8, label: "G#8", frequency: 6644.875 }, { pitch: 117, name: "A", octave: 8, label: "A8", frequency: 7040 }, { pitch: 118, name: "A#", octave: 8, label: "A#8", frequency: 7458.62 }, { pitch: 119, name: "B", octave: 8, label: "B8", frequency: 7902.133 }, { pitch: 120, name: "C", octave: 9, label: "C9", frequency: 8372.018 }, { pitch: 121, name: "C#", octave: 9, label: "C#9", frequency: 8869.844 }, { pitch: 122, name: "D", octave: 9, label: "D9", frequency: 9397.273 }, { pitch: 123, name: "D#", octave: 9, label: "D#9", frequency: 9956.063 }, { pitch: 124, name: "E", octave: 9, label: "E9", frequency: 10548.08 }, { pitch: 125, name: "F", octave: 9, label: "F9", frequency: 11175.3 }, { pitch: 126, name: "F#", octave: 9, label: "F#9", frequency: 11839.82 }, { pitch: 127, name: "G", octave: 9, label: "G9", frequency: 12543.85 } ]; var SHARPS = /* @__PURE__ */ new Set([ 1, 3, 6, 8, 10, 13, 15, 18, 20, 22, 25, 27, 30, 32, 34, 37, 39, 42, 44, 46, 49, 51, 54, 56, 58, 61, 63, 66, 68, 70, 73, 75, 78, 80, 82, 85, 87, 90, 92, 94, 97, 99, 102, 104, 106, 109, 111, 114, 116, 118, 121, 123, 126 ]); var MIDI_COMMANDS = /* @__PURE__ */ new Map([ [128, { name: "noteOff", description: "Note-off", params: ["key", "velocity"] }], [144, { name: "noteOn", description: "Note-on", params: ["key", "velocity"] }], [160, { name: "aftertouch", description: "Aftertouch", params: ["key", "touch"] }], [176, { name: "continuousController", description: "Continuous controller", params: ["controller #", "controller value"] }], [192, { name: "patchChange", description: "Patch change", params: ["instrument number", "instrument number"] }], [208, { name: "channelPressure", description: "Channel Pressure", params: ["pressure"] }], [224, { name: "pitchBend", description: "Pitch bend", params: ["lsb (7 bits)", "msb (7 bits)"] }], [240, { name: "sysExStart", description: "start of system exclusive message" }], [241, { name: "timeCodeQuarter", description: "MIDI Time Code Quarter Frame (Sys Common)" }], [242, { name: "posPointer", description: "Song Position Pointer (Sys Common)" }], [243, { name: "songSelect", description: "Song Select (Sys Common)" }], [244, { name: "unknown1", description: "???" }], [245, { name: "unknown2", description: "???" }], [246, { name: "tuneRequest", description: "Tune Request (Sys Common)" }], [247, { name: "syExEnd", description: "end of system exclusive message 0" }], [248, { name: "timingClock", description: "Timing Clock (Sys Realtime)" }], [250, { name: "start", description: "Start (Sys Realtime)" }], [251, { name: "continue", description: "Continue (Sys Realtime)" }], [252, { name: "stop", description: "Stop (Sys Realtime)" }], [253, { name: "unknwon3", description: "???" }], [254, { name: "activeSensing", description: "Active Sensing (Sys Realtime)" }], [255, { name: "systemReset", description: "System Reset (Sys Realtime)" }] ]); var MIDI_INSTRUMENTS = [ { number: 0, group: "Piano", label: "Acoustic Grand Piano" }, { number: 1, group: "Piano", label: "Bright Acoustic Piano" }, { number: 2, group: "Piano", label: "Electric Grand Piano" }, { number: 3, group: "Piano", label: "Honky-tonk Piano" }, { number: 4, group: "Piano", label: "Electric Piano 1" }, { number: 5, group: "Piano", label: "Electric Piano 2" }, { number: 6, group: "Piano", label: "Harpsichord" }, { number: 7, group: "Piano", label: "Clavinet" }, { number: 8, group: "Chromatic Percussion", label: "Celesta" }, { number: 9, group: "Chromatic Percussion", label: "Glockenspiel" }, { number: 10, group: "Chromatic Percussion", label: "Music Box" }, { number: 11, group: "Chromatic Percussion", label: "Vibraphone" }, { number: 12, group: "Chromatic Percussion", label: "Marimba" }, { number: 13, group: "Chromatic Percussion", label: "Xylophone" }, { number: 14, group: "Chromatic Percussion", label: "Tubular Bells" }, { number: 15, group: "Chromatic Percussion", label: "Dulcimer" }, { number: 16, group: "Organ", label: "Drawbar Organ" }, { number: 17, group: "Organ", label: "Percussive Organ" }, { number: 18, group: "Organ", label: "Rock Organ" }, { number: 19, group: "Organ", label: "Church Organ" }, { number: 20, group: "Organ", label: "Reed Organ" }, { number: 21, group: "Organ", label: "Accordion" }, { number: 22, group: "Organ", label: "Harmonica" }, { number: 23, group: "Organ", label: "Tango Accordion" }, { number: 24, group: "Guitar", label: "Acoustic Guitar(nylon)" }, { number: 25, group: "Guitar", label: "Acoustic Guitar(steel)" }, { number: 26, group: "Guitar", label: "Electric Guitar(jazz)" }, { number: 27, group: "Guitar", label: "Electric Guitar(clean)" }, { number: 28, group: "Guitar", label: "Electric Guitar(muted)" }, { number: 29, group: "Guitar", label: "Overdriven Guitar" }, { number: 30, group: "Guitar", label: "Distortion Guitar" }, { number: 31, group: "Guitar", label: "Guitar harmonics" }, { number: 32, group: "Bass", label: "Acoustic Bass" }, { number: 33, group: "Bass", label: "Electric Bass(finger)" }, { number: 34, group: "Bass", label: "Electric Bass(pick)" }, { number: 35, group: "Bass", label: "Fretless Bass" }, { number: 36, group: "Bass", label: "Slap Bass 1" }, { number: 37, group: "Bass", label: "Slap Bass 2" }, { number: 38, group: "Bass", label: "Synth Bass 1" }, { number: 39, group: "Bass", label: "Synth Bass 2" }, { number: 40, group: "Strings", label: "Violin" }, { number: 41, group: "Strings", label: "Viola" }, { number: 42, group: "Strings", label: "Cello" }, { number: 43, group: "Strings", label: "Contrabass" }, { number: 44, group: "Strings", label: "Tremolo Strings" }, { number: 45, group: "Strings", label: "Pizzicato Strings" }, { number: 46, group: "Strings", label: "Orchestral Harp" }, { number: 47, group: "Strings", label: "Timpani" }, { number: 48, group: "Strings (continued)", label: "String Ensemble 1" }, { number: 49, group: "Strings (continued)", label: "String Ensemble 2" }, { number: 50, group: "Strings (continued)", label: "Synth Strings 1" }, { number: 51, group: "Strings (continued)", label: "Synth Strings 2" }, { number: 52, group: "Strings (continued)", label: "Choir Aahs" }, { number: 53, group: "Strings (continued)", label: "Voice Oohs" }, { number: 54, group: "Strings (continued)", label: "Synth Voice" }, { number: 55, group: "Strings (continued)", label: "Orchestra Hit" }, { number: 56, group: "Brass", label: "Trumpet" }, { number: 57, group: "Brass", label: "Trombone" }, { number: 58, group: "Brass", label: "Tuba" }, { number: 59, group: "Brass", label: "Muted Trumpet" }, { number: 60, group: "Brass", label: "French Horn" }, { number: 61, group: "Brass", label: "Brass Section" }, { number: 62, group: "Brass", label: "Synth Brass 1" }, { number: 63, group: "Brass", label: "Synth Brass 2" }, { number: 64, group: "Reed", label: "Soprano Sax" }, { number: 65, group: "Reed", label: "Alto Sax" }, { number: 66, group: "Reed", label: "Tenor Sax" }, { number: 67, group: "Reed", label: "Baritone Sax" }, { number: 68, group: "Reed", label: "Oboe" }, { number: 69, group: "Reed", label: "English Horn" }, { number: 70, group: "Reed", label: "Bassoon" }, { number: 71, group: "Reed", label: "Clarinet" }, { number: 72, group: "Pipe", label: "Piccolo" }, { number: 73, group: "Pipe", label: "Flute" }, { number: 74, group: "Pipe", label: "Recorder" }, { number: 75, group: "Pipe", label: "Pan Flute" }, { number: 76, group: "Pipe", label: "Blown Bottle" }, { number: 77, group: "Pipe", label: "Shakuhachi" }, { number: 78, group: "Pipe", label: "Whistle" }, { number: 79, group: "Pipe", label: "Ocarina" }, { number: 80, group: "Synth Lead", label: "Lead 1(square)" }, { number: 81, group: "Synth Lead", label: "Lead 2(sawtooth)" }, { number: 82, group: "Synth Lead", label: "Lead 3(calliope)" }, { number: 83, group: "Synth Lead", label: "Lead 4(chiff)" }, { number: 84, group: "Synth Lead", label: "Lead 5(charang)" }, { number: 85, group: "Synth Lead", label: "Lead 6(voice)" }, { number: 86, group: "Synth Lead", label: "Lead 7(fifths)" }, { number: 87, group: "Synth Lead", label: "Lead 8(bass + lead)" }, { number: 88, group: "Synth Pad", label: "Pad 1(new age)" }, { number: 89, group: "Synth Pad", label: "Pad 2(warm)" }, { number: 90, group: "Synth Pad", label: "Pad 3(polysynth)" }, { number: 91, group: "Synth Pad", label: "Pad 4(choir)" }, { number: 92, group: "Synth Pad", label: "Pad 5(bowed)" }, { number: 93, group: "Synth Pad", label: "Pad 6(metallic)" }, { number: 94, group: "Synth Pad", label: "Pad 7(halo)" }, { number: 95, group: "Synth Pad", label: "Pad 8(sweep)" }, { number: 96, group: "Synth Effects", label: "FX 1(rain)" }, { number: 97, group: "Synth Effects", label: "FX 2(soundtrack)" }, { number: 98, group: "Synth Effects", label: "FX 3(crystal)" }, { number: 99, group: "Synth Effects", label: "FX 4(atmosphere)" }, { number: 100, group: "Synth Effects", label: "FX 5(brightness)" }, { number: 101, group: "Synth Effects", label: "FX 6(goblins)" }, { number: 102, group: "Synth Effects", label: "FX 7(echoes)" }, { number: 103, group: "Synth Effects", label: "FX 8(sci-fi)" }, { number: 104, group: "Ethnic", label: "Sitar" }, { number: 105, group: "Ethnic", label: "Banjo" }, { number: 106, group: "Ethnic", label: "Shamisen" }, { number: 107, group: "Ethnic", label: "Koto" }, { number: 108, group: "Ethnic", label: "Kalimba" }, { number: 109, group: "Ethnic", label: "Bag pipe" }, { number: 110, group: "Ethnic", label: "Fiddle" }, { number: 111, group: "Ethnic", label: "Shanai" }, { number: 112, group: "Percussive", label: "Tinkle Bell" }, { number: 113, group: "Percussive", label: "Agogo" }, { number: 114, group: "Percussive", label: "Steel Drums" }, { number: 115, group: "Percussive", label: "Woodblock" }, { number: 116, group: "Percussive", label: "Taiko Drum" }, { number: 117, group: "Percussive", label: "Melodic Tom" }, { number: 118, group: "Percussive", label: "Synth Drum" }, { number: 119, group: "Sound Effects", label: "Reverse Cymbal" }, { number: 120, group: "Sound Effects", label: "Guitar Fret Noise" }, { number: 121, group: "Sound Effects", label: "Breath Noise" }, { number: 122, group: "Sound Effects", label: "Seashore" }, { number: 123, group: "Sound Effects", label: "Bird Tweet" }, { number: 124, group: "Sound Effects", label: "Telephone Ring" }, { number: 125, group: "Sound Effects", label: "Helicopter" }, { number: 126, group: "Sound Effects", label: "Applause" }, { number: 127, group: "Sound Effects", label: "Gunshot" } ]; var MIDI_INSTRUMENTS_LEV2 = [ { number: 1, subnumber: 0, group: "Piano", label: "Acoustic Grand Piano" }, { number: 1, subnumber: 1, group: "Piano", label: "Wide Acoustic Grand" }, { number: 1, subnumber: 2, group: "Piano", label: "Dark Acoustic Grand" }, { number: 2, subnumber: 0, group: "Piano", label: "Bright Acoustic Piano" }, { number: 2, subnumber: 1, group: "Piano", label: "Wide Bright Acoustic" }, { number: 3, subnumber: 0, group: "Piano", label: "Electric Grand Piano" }, { number: 3, subnumber: 1, group: "Piano", label: "Wide Electric Grand" }, { number: 4, subnumber: 0, group: "Piano", label: "Honky-tonk Piano" }, { number: 4, subnumber: 1, group: "Piano", label: "Wide Honky-tonk" }, { number: 5, subnumber: 0, group: "Piano", label: "Rhodes Piano" }, { number: 5, subnumber: 1, group: "Piano", label: "Detuned Electric Piano 1" }, { number: 5, subnumber: 2, group: "Piano", label: "Electric Piano 1 Variation" }, { number: 5, subnumber: 3, group: "Piano", label: "60's Electric Piano" }, { number: 6, subnumber: 0, group: "Piano", label: "Chorused Electric Piano" }, { number: 6, subnumber: 1, group: "Piano", label: "Detuned Electric Piano 2" }, { number: 6, subnumber: 2, group: "Piano", label: "Electric Piano 2 Variation" }, { number: 6, subnumber: 3, group: "Piano", label: "Electric Piano Legend" }, { number: 6, subnumber: 4, group: "Piano", label: "Electric Piano Phase" }, { number: 7, subnumber: 0, group: "Piano", label: "Harpsichord" }, { number: 7, subnumber: 1, group: "Piano", label: "Coupled Harpsichord" }, { number: 7, subnumber: 2, group: "Piano", label: "Wide Harpsichord" }, { number: 7, subnumber: 3, group: "Piano", label: "Open Harpsichord" }, { number: 8, subnumber: 0, group: "Piano", label: "Clavinet" }, { number: 8, subnumber: 1, group: "Piano", label: "Pulse Clavinet" }, { number: 9, subnumber: 0, group: "Chromatic Percussion", label: "Celesta" }, { number: 10, subnumber: 0, group: "Chromatic Percussion", label: "Glockenspiel" }, { number: 11, subnumber: 0, group: "Chromatic Percussion", label: "Music Box" }, { number: 12, subnumber: 0, group: "Chromatic Percussion", label: "Vibraphone" }, { number: 12, subnumber: 1, group: "Chromatic Percussion", label: "Wet Vibraphone" }, { number: 13, subnumber: 0, group: "Chromatic Percussion", label: "Marimba" }, { number: 13, subnumber: 1, group: "Chromatic Percussion", label: "Wide Marimba" }, { number: 14, subnumber: 0, group: "Chromatic Percussion", label: "Xylophone" }, { number: 15, subnumber: 0, group: "Chromatic Percussion", label: "Tubular Bells" }, { number: 15, subnumber: 1, group: "Chromatic Percussion", label: "Church Bells" }, { number: 15, subnumber: 2, group: "Chromatic Percussion", label: "Carillon" }, { number: 16, subnumber: 0, group: "Chromatic Percussion", label: "Dulcimer / Santur" }, { number: 17, subnumber: 0, group: "Organ", label: "Hammond Organ" }, { number: 17, subnumber: 1, group: "Organ", label: "Detuned Organ 1" }, { number: 17, subnumber: 2, group: "Organ", label: "60's Organ 1" }, { number: 17, subnumber: 3, group: "Organ", label: "Organ 4" }, { number: 18, subnumber: 0, group: "Organ", label: "Percussive Organ" }, { number: 18, subnumber: 1, group: "Organ", label: "Detuned Organ 2" }, { number: 18, subnumber: 2, group: "Organ", label: "Organ 5" }, { number: 19, subnumber: 0, group: "Organ", label: "Rock Organ" }, { number: 20, subnumber: 0, group: "Organ", label: "Church Organ 1" }, { number: 20, subnumber: 1, group: "Organ", label: "Church Organ 2" }, { number: 20, subnumber: 2, group: "Organ", label: "Church Organ 3" }, { number: 21, subnumber: 0, group: "Organ", label: "Reed Organ" }, { number: 21, subnumber: 1, group: "Organ", label: "Puff Organ" }, { number: 22, subnumber: 0, group: "Organ", label: "French Accordion" }, { number: 22, subnumber: 1, group: "Organ", label: "Italian Accordion" }, { number: 23, subnumber: 0, group: "Organ", label: "Harmonica" }, { number: 24, subnumber: 0, group: "Organ", label: "Bandoneon" }, { number: 25, subnumber: 0, group: "Guitar", label: "Nylon-String Guitar" }, { number: 25, subnumber: 1, group: "Guitar", label: "Ukelele" }, { number: 25, subnumber: 2, group: "Guitar", label: "Open Nylon Guitar" }, { number: 25, subnumber: 3, group: "Guitar", label: "Nylon Guitar 2" }, { number: 26, subnumber: 0, group: "Guitar", label: "Steel-String Guitar" }, { number: 26, subnumber: 1, group: "Guitar", label: "12-String Guitar" }, { number: 26, subnumber: 2, group: "Guitar", label: "Mandolin" }, { number: 26, subnumber: 3, group: "Guitar", label: "Steel + Body" }, { number: 27, subnumber: 0, group: "Guitar", label: "Jazz Guitar" }, { number: 27, subnumber: 1, group: "Guitar", label: "Hawaiian Guitar" }, { number: 28, subnumber: 0, group: "Guitar", label: "Clean Electric Guitar" }, { number: 28, subnumber: 1, group: "Guitar", label: "Chorus Guitar" }, { number: 28, subnumber: 2, group: "Guitar", label: "Mid Tone Guitar" }, { number: 29, subnumber: 0, group: "Guitar", label: "Muted Electric Guitar" }, { number: 29, subnumber: 1, group: "Guitar", label: "Funk Guitar" }, { number: 29, subnumber: 2, group: "Guitar", label: "Funk Guitar 2" }, { number: 29, subnumber: 3, group: "Guitar", label: "Jazz Man" }, { number: 30, subnumber: 0, group: "Guitar", label: "Overdriven Guitar" }, { number: 30, subnumber: 1, group: "Guitar", label: "Guitar Pinch" }, { number: 31, subnumber: 0, group: "Guitar", label: "Distortion Guitar" }, { number: 31, subnumber: 1, group: "Guitar", label: "Feedback Guitar" }, { number: 31, subnumber: 2, group: "Guitar", label: "Distortion Rtm Guitar" }, { number: 32, subnumber: 0, group: "Guitar", label: "Guitar Harmonics" }, { number: 32, subnumber: 1, group: "Guitar", label: "Guitar Feedback" }, { number: 33, subnumber: 0, group: "Bass", label: "Acoustic Bass" }, { number: 34, subnumber: 0, group: "Bass", label: "Fingered Bass" }, { number: 34, subnumber: 1, group: "Bass", label: "Finger Slap" }, { number: 35, subnumber: 0, group: "Bass", label: "Picked Bass" }, { number: 36, subnumber: 0, group: "Bass", label: "Fretless Bass" }, { number: 37, subnumber: 0, group: "Bass", label: "Slap Bass 1" }, { number: 38, subnumber: 0, group: "Bass", label: "Slap Bass 2" }, { number: 39, subnumber: 0, group: "Bass", label: "Synth Bass 1" }, { number: 39, subnumber: 1, group: "Bass", label: "Synth Bass 101" }, { number: 39, subnumber: 2, group: "Bass", label: "Synth Bass 3" }, { number: 39, subnumber: 3, group: "Bass", label: "Clavi Bass" }, { number: 39, subnumber: 4, group: "Bass", label: "Hammer" }, { number: 40, subnumber: 0, group: "Bass", label: "Synth Bass 2" }, { number: 40, subnumber: 1, group: "Bass", label: "Synth Bass 4" }, { number: 40, subnumber: 2, group: "Bass", label: "Rubber Bass" }, { number: 40, subnumber: 3, group: "Bass", label: "Attack Pulse" }, { number: 41, subnumber: 0, group: "Strings", label: "Violin" }, { numb