musicvis-lib
Version:
Music analysis and visualization library
1,009 lines (1,006 loc) • 408 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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));
// 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;
}
})();
}
});
// 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" },
{ number: 41, subnumber: 1, group: "Strings", label: "Slow Violin" },
{ number: 42, subnumber: 0, group: "Strings", label: "Viola" },
{ number: 43, subnumber: 0, group: "Strings", label: "Cello" },
{ number: 44, subnumber: 0, group: "Strings", label: "Contrabass" },
{ number: 45, subnumber: 0, group: "Strings", label: "Tremolo Strings" },
{ number: 46, subnumber: 0, group: "Strings", label: "Pizzicato Strings" },
{ number: 47, subnumber: 0, group: "Strings", label: "Harp" },
{ number: 47, subnumber: 1, group: "Strings", label: "Yang Qin" },
{ number: 48, subnumber: 0, group: "Strings", label: "Timpani" },
{ number: 49, subnumber: 0, group: "Orchestral Ensemble", label: "String Ensemble" },
{ number: 49, subnumber: 1, group: "Orchestral Ensemble", label: "Orchestra Strings" },
{ number: 49, subnumber: 2, group: "Orchestral Ensemble", label: "60's Strings" },
{ number: 50, subnumber: 0, group: "Orchestral Ensemble", label: "Slow String Ensemble" },
{ number: 51, subnumber: 0, group: "Orchestral Ensemble", label: "Synth Strings 1" },
{ number: 51, subnumber: 1, group: "Orchestral Ensemble", label: "Synth Strings 3" },
{ number: 52, subnumber: 0, group: "Orchestral Ensemble", label: "Synth Strings 2" },
{ number: 53, subnumber: 0, group: "Orchestral Ensemble", label: "Choir Aahs" },
{ number: 53, subnumber: 1, group: "Orchestral Ensemble", label: "Choir Aahs 2" },
{ number: 54, subnumber: 0, group: "Orchestral Ensemble", label: "Voice Oohs" },
{ number: 54, subnumber: 1, group: "Orchestral Ensemble", label: "Humming" },
{ number: 55, subnumber: 0, group: "Orchestral Ensemble", label: "Synth Voice" },
{ number: 55, subnumber: 1, group: "Orchestral Ensemble", label: "Analog Voice" },
{ number: 56, subnumber: 0, group: "Orchestral Ensemble", label: "Orchestra Hit" },
{ number: 56, subnumber: 1, group: "Orchestral Ensemble", label: "Bass Hit" },
{ number: 56, subnumber: 2, group: "Orchestral Ensemble", label: "6th Hit" },
{ number: 56, subnumber: 3, group: "Orchestral Ensemble", label: "Euro Hit" },
{ number: 57, subnumber: 0, group: "Brass", label: "Trumpet" },
{ number: 57, subnumber: 1, group: "Brass", label: "Dark Trumpet" },
{ number: 58, subnumber: 0, group: "Brass", label: "Trombone" },
{ number: 58, subnumber: 1, group: "Brass", label: "Trombone 2" },
{ number: 58, subnumber: 2, group: "Brass", label: "Bright Trombone" },
{ number: 59, subnumber: 0, group: "Brass", label: "Tuba" },
{ number: 60, subnumber: 0, group: "Brass", label: "Muted Trumpet" },
{ number: 60, subnumber: 1, group: "Brass", label: "Muted Trumpet 2" },
{ number: 61, subnumber: 0, group: "Brass", label: "French Horn" },
{ number: 61, subnumber: 1, group: "Brass", label: "French Horn 2" },
{ number: 62, subnumber: 0, group: "Brass", label: "Brass Section" },
{ number: 62, subnumber: 1, group: "Brass", label: "Brass Section" },
{ number: 63, subnumber: 0, group: "Brass", label: "Synth Brass 1" },
{ number: 63, subnumber: 1, group: "Brass", label: "Synth Brass 3" },
{ number: 63, subnumber: 2, group: "Brass", label: "Analog Brass 1" },
{ number: 63, subnumber: 3, group: "Brass", label: "Jump Brass" },
{ number: 64, subnumber: 0, group: "Brass", label: "Synth Brass 2" },
{ number: 64, subnumber: 1, group: "Brass", label: "Synth Brass 4" },
{ number: 64, subnumber: 2, group: "Brass", label: "Analog Brass 2" },
{ number: 65, subnumber: 0, group: "Reed", label: "Soprano Sax" },
{ number: 66, subnumber: 0, group: "Reed", label: "Alto Sax" },
{ number: 67, subnumber: 0, group: "Reed", label: "Tenor Sax" },
{ number: 68, subnumber: 0, group: "Reed", label: "Baritone Sax" },
{ number: 69, subnumber: 0, group: "Reed", label: "Oboe" },
{ number: 70, subnumber: 0, group: "Reed", label: "English Horn" },
{ number: 71, subnumber: 0, group: "Reed", label: "Bassoon" },
{ number: 72, subnumber: 0, group: "Reed", label: "Cla