From b353db67d4d63963ee1e28b76f7a92d601ce1edc Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 19 Jun 2022 15:31:19 +0200 Subject: [PATCH 1/5] began soundfonts package --- package-lock.json | 224 ++++++++++++++++++- packages/soundfonts/index.mjs | 29 +++ packages/soundfonts/package-lock.json | 301 ++++++++++++++++++++++++++ packages/soundfonts/package.json | 31 +++ repl/src/App.jsx | 2 +- 5 files changed, 580 insertions(+), 7 deletions(-) create mode 100644 packages/soundfonts/index.mjs create mode 100644 packages/soundfonts/package-lock.json create mode 100644 packages/soundfonts/package.json diff --git a/package-lock.json b/package-lock.json index a4c5eaf8..579657c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2243,6 +2243,10 @@ "resolved": "packages/serial", "link": true }, + "node_modules/@strudel.cycles/soundfonts": { + "resolved": "packages/soundfonts", + "link": true + }, "node_modules/@strudel.cycles/tonal": { "resolved": "packages/tonal", "link": true @@ -6616,6 +6620,11 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==" + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -6926,6 +6935,11 @@ "node": ">=10" } }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -7019,9 +7033,9 @@ } }, "node_modules/marked": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.14.tgz", - "integrity": "sha512-HL5sSPE/LP6U9qKgngIIPTthuxC0jrfxpYMZ3LdGDD3vTnLs59m2Z7r6+LNDR3ToqEQdkKd6YaaEfJhodJmijQ==", + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.17.tgz", + "integrity": "sha512-Wfk0ATOK5iPxM4ptrORkFemqroz0ZDxp5MWfYA7H/F+wO17NRWV5Ypxi6p3g2Xmw2bKeiYOl6oVnLHKxBA0VhA==", "bin": { "marked": "bin/marked.js" }, @@ -9712,6 +9726,16 @@ "resolved": "https://registry.npmjs.org/shift-spec/-/shift-spec-2018.0.0.tgz", "integrity": "sha512-/aiPOkj7dbe+CV2VZhIMTHQToZmgniofpRG7Yr7x2/0sO6CSVC++py1Wzf+s+rWSTDHKcLvziVAxjRRV4i4EoQ==" }, + "node_modules/shiki": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz", + "integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==", + "dependencies": { + "jsonc-parser": "^3.0.0", + "vscode-oniguruma": "^1.6.1", + "vscode-textmate": "5.2.0" + } + }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -10548,6 +10572,77 @@ "is-typedarray": "^1.0.0" } }, + "node_modules/typedoc": { + "version": "0.22.17", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.17.tgz", + "integrity": "sha512-h6+uXHVVCPDaANzjwzdsj9aePBjZiBTpiMpBBeyh1zcN2odVsDCNajz8zyKnixF93HJeGpl34j/70yoEE5BfNg==", + "dependencies": { + "glob": "^8.0.3", + "lunr": "^2.3.9", + "marked": "^4.0.16", + "minimatch": "^5.1.0", + "shiki": "^0.10.1" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 12.10.0" + }, + "peerDependencies": { + "typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x || 4.6.x || 4.7.x" + } + }, + "node_modules/typedoc/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/typedoc/node_modules/glob": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typedoc/node_modules/minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/typescript": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", @@ -10796,6 +10891,16 @@ } } }, + "node_modules/vscode-oniguruma": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz", + "integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==" + }, + "node_modules/vscode-textmate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", + "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==" + }, "node_modules/w3c-keyname": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz", @@ -10819,6 +10924,14 @@ "defaults": "^1.0.3" } }, + "node_modules/webaudiofont": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webaudiofont/-/webaudiofont-3.0.1.tgz", + "integrity": "sha512-PwqbR4OdvzbW8/TLTitSU/rw4mxMKyAGTKV42mePCgMoUGLJoQj8HDLWVqtNOpUZ0ghPNhNE6cRFEv6HFFEBQA==", + "dependencies": { + "typedoc": "^0.22.14" + } + }, "node_modules/WebDirt": { "version": "1.0.0", "resolved": "git+ssh://git@github.com/dktr0/WebDirt.git#425dc8fd023440d9c61ffdb8642e44e2710faea0", @@ -11414,6 +11527,13 @@ "version": "0.1.0", "license": "AGPL-3.0-or-later" }, + "packages/soundfonts": { + "version": "0.1.0", + "license": "AGPL-3.0-or-later", + "dependencies": { + "webaudiofont": "^3.0.1" + } + }, "packages/tonal": { "name": "@strudel.cycles/tonal", "version": "0.1.1", @@ -13384,6 +13504,12 @@ "@strudel.cycles/serial": { "version": "file:packages/serial" }, + "@strudel.cycles/soundfonts": { + "version": "file:packages/soundfonts", + "requires": { + "webaudiofont": "^3.0.1" + } + }, "@strudel.cycles/tonal": { "version": "file:packages/tonal", "requires": { @@ -16732,6 +16858,11 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" }, + "jsonc-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==" + }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -16987,6 +17118,11 @@ "yallist": "^4.0.0" } }, + "lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -17058,9 +17194,9 @@ "requires": {} }, "marked": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.14.tgz", - "integrity": "sha512-HL5sSPE/LP6U9qKgngIIPTthuxC0jrfxpYMZ3LdGDD3vTnLs59m2Z7r6+LNDR3ToqEQdkKd6YaaEfJhodJmijQ==" + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.17.tgz", + "integrity": "sha512-Wfk0ATOK5iPxM4ptrORkFemqroz0ZDxp5MWfYA7H/F+wO17NRWV5Ypxi6p3g2Xmw2bKeiYOl6oVnLHKxBA0VhA==" }, "mdurl": { "version": "1.0.1", @@ -19163,6 +19299,16 @@ } } }, + "shiki": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz", + "integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==", + "requires": { + "jsonc-parser": "^3.0.0", + "vscode-oniguruma": "^1.6.1", + "vscode-textmate": "5.2.0" + } + }, "side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -19821,6 +19967,54 @@ "is-typedarray": "^1.0.0" } }, + "typedoc": { + "version": "0.22.17", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.17.tgz", + "integrity": "sha512-h6+uXHVVCPDaANzjwzdsj9aePBjZiBTpiMpBBeyh1zcN2odVsDCNajz8zyKnixF93HJeGpl34j/70yoEE5BfNg==", + "requires": { + "glob": "^8.0.3", + "lunr": "^2.3.9", + "marked": "^4.0.16", + "minimatch": "^5.1.0", + "shiki": "^0.10.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "glob": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + } + }, + "minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "typescript": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "peer": true + }, "typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", @@ -20009,6 +20203,16 @@ "rollup": "^2.59.0" } }, + "vscode-oniguruma": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz", + "integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==" + }, + "vscode-textmate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", + "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==" + }, "w3c-keyname": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz", @@ -20029,6 +20233,14 @@ "defaults": "^1.0.3" } }, + "webaudiofont": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webaudiofont/-/webaudiofont-3.0.1.tgz", + "integrity": "sha512-PwqbR4OdvzbW8/TLTitSU/rw4mxMKyAGTKV42mePCgMoUGLJoQj8HDLWVqtNOpUZ0ghPNhNE6cRFEv6HFFEBQA==", + "requires": { + "typedoc": "^0.22.14" + } + }, "WebDirt": { "version": "git+ssh://git@github.com/dktr0/WebDirt.git#425dc8fd023440d9c61ffdb8642e44e2710faea0", "from": "WebDirt@github:dktr0/WebDirt" diff --git a/packages/soundfonts/index.mjs b/packages/soundfonts/index.mjs new file mode 100644 index 00000000..4bc56730 --- /dev/null +++ b/packages/soundfonts/index.mjs @@ -0,0 +1,29 @@ +import { Pattern } from '@strudel.cycles/core'; +import { getAudioContext } from '@strudel.cycles/webaudio'; +// import * as WebAudioFontPlayer from 'webaudiofont'; +import * as WebAudioFont from 'webaudiofont'; +console.log('WebAudioFont:!', WebAudioFont); +// https://surikov.github.io/webaudiofont/npm/dist/WebAudioFontPlayer.js +// https://surikov.github.io/webaudiofontdata/sound/0000_JCLive_sf2_file.js + +// https://github.com/surikov/webaudiofont#dynamic-loading +/* function changeInstrument(path, name) { + player.loader.startLoad(audioContext, path, name); + player.loader.waitLoad(function () { + instr = window[name]; + }); +} */ + +Pattern.prototype.soundfont = function (soundfont) { + const ac = getAudioContext(); + return this.onTrigger((t, hap, ct) => { + // const url = `https://surikov.github.io/webaudiofontdata/sound/${soundfont}_sf2_file.js`; + // changeInstrument('https://surikov.github.io/webaudiofontdata/sound/0290_Aspirin_sf2_file.js','_tone_0290_Aspirin_sf2_file'); + console.log('url', url); + // const player = WebAudioFontPlayer(); + // console.log('soundfont', url, player); + /* var selectedPreset = _tone_0000_JCLive_sf2_file; + player.loader.decodeAfterLoading(ac, '_tone_0000_JCLive_sf2_file'); + player.queueWaveTable(ac, ac.destination, selectedPreset, 0, 55, 3.5); */ + }); +}; diff --git a/packages/soundfonts/package-lock.json b/packages/soundfonts/package-lock.json new file mode 100644 index 00000000..1624656e --- /dev/null +++ b/packages/soundfonts/package-lock.json @@ -0,0 +1,301 @@ +{ + "name": "@strudel.cycles/soundfonts", + "version": "0.1.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "@strudel.cycles/soundfonts", + "version": "0.1.0", + "license": "AGPL-3.0-or-later", + "dependencies": { + "webaudiofont": "^3.0.1" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/glob": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/jsonc-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==" + }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" + }, + "node_modules/marked": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.17.tgz", + "integrity": "sha512-Wfk0ATOK5iPxM4ptrORkFemqroz0ZDxp5MWfYA7H/F+wO17NRWV5Ypxi6p3g2Xmw2bKeiYOl6oVnLHKxBA0VhA==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/shiki": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz", + "integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==", + "dependencies": { + "jsonc-parser": "^3.0.0", + "vscode-oniguruma": "^1.6.1", + "vscode-textmate": "5.2.0" + } + }, + "node_modules/typedoc": { + "version": "0.22.17", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.17.tgz", + "integrity": "sha512-h6+uXHVVCPDaANzjwzdsj9aePBjZiBTpiMpBBeyh1zcN2odVsDCNajz8zyKnixF93HJeGpl34j/70yoEE5BfNg==", + "dependencies": { + "glob": "^8.0.3", + "lunr": "^2.3.9", + "marked": "^4.0.16", + "minimatch": "^5.1.0", + "shiki": "^0.10.1" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 12.10.0" + }, + "peerDependencies": { + "typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x || 4.6.x || 4.7.x" + } + }, + "node_modules/typescript": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/vscode-oniguruma": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz", + "integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==" + }, + "node_modules/vscode-textmate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", + "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==" + }, + "node_modules/webaudiofont": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webaudiofont/-/webaudiofont-3.0.1.tgz", + "integrity": "sha512-PwqbR4OdvzbW8/TLTitSU/rw4mxMKyAGTKV42mePCgMoUGLJoQj8HDLWVqtNOpUZ0ghPNhNE6cRFEv6HFFEBQA==", + "dependencies": { + "typedoc": "^0.22.14" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + } + }, + "dependencies": { + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "glob": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "jsonc-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==" + }, + "lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" + }, + "marked": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.17.tgz", + "integrity": "sha512-Wfk0ATOK5iPxM4ptrORkFemqroz0ZDxp5MWfYA7H/F+wO17NRWV5Ypxi6p3g2Xmw2bKeiYOl6oVnLHKxBA0VhA==" + }, + "minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "shiki": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz", + "integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==", + "requires": { + "jsonc-parser": "^3.0.0", + "vscode-oniguruma": "^1.6.1", + "vscode-textmate": "5.2.0" + } + }, + "typedoc": { + "version": "0.22.17", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.17.tgz", + "integrity": "sha512-h6+uXHVVCPDaANzjwzdsj9aePBjZiBTpiMpBBeyh1zcN2odVsDCNajz8zyKnixF93HJeGpl34j/70yoEE5BfNg==", + "requires": { + "glob": "^8.0.3", + "lunr": "^2.3.9", + "marked": "^4.0.16", + "minimatch": "^5.1.0", + "shiki": "^0.10.1" + } + }, + "typescript": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "peer": true + }, + "vscode-oniguruma": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz", + "integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==" + }, + "vscode-textmate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", + "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==" + }, + "webaudiofont": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webaudiofont/-/webaudiofont-3.0.1.tgz", + "integrity": "sha512-PwqbR4OdvzbW8/TLTitSU/rw4mxMKyAGTKV42mePCgMoUGLJoQj8HDLWVqtNOpUZ0ghPNhNE6cRFEv6HFFEBQA==", + "requires": { + "typedoc": "^0.22.14" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + } + } +} diff --git a/packages/soundfonts/package.json b/packages/soundfonts/package.json new file mode 100644 index 00000000..accb43e5 --- /dev/null +++ b/packages/soundfonts/package.json @@ -0,0 +1,31 @@ +{ + "name": "@strudel.cycles/soundfonts", + "version": "0.1.0", + "description": "Soundsfont support for strudel", + "main": "index.mjs", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/tidalcycles/strudel.git" + }, + "keywords": [ + "tidalcycles", + "strudel", + "pattern", + "livecoding", + "algorave" + ], + "author": "Felix Roos ", + "license": "AGPL-3.0-or-later", + "bugs": { + "url": "https://github.com/tidalcycles/strudel/issues" + }, + "homepage": "https://github.com/tidalcycles/strudel#readme", + "dependencies": { + "webaudiofont": "^3.0.1", + "@strudel.cycles/core": "*", + "@strudel.cycles/webaudio": "*" + } +} diff --git a/repl/src/App.jsx b/repl/src/App.jsx index 8a818af4..4b900591 100644 --- a/repl/src/App.jsx +++ b/repl/src/App.jsx @@ -15,7 +15,6 @@ import * as tunes from './tunes.mjs'; import * as WebDirt from 'WebDirt'; import { loadWebDirt } from '@strudel.cycles/webdirt'; import { resetLoadedSamples, getAudioContext } from '@strudel.cycles/webaudio'; - evalScope( Tone, controls, @@ -30,6 +29,7 @@ evalScope( import('@strudel.cycles/osc'), import('@strudel.cycles/webdirt'), import('@strudel.cycles/serial'), + import('@strudel.cycles/soundfonts'), ); loadWebDirt({ From 82d6103907f370c881cd2c2cfba1b289523a9951 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 20 Jun 2022 20:02:55 +0200 Subject: [PATCH 2/5] began soundfont implementation --- package-lock.json | 340 +++--- packages/core/controls.mjs | 1 + packages/soundfonts/convert.js | 13 + packages/soundfonts/fontloader.mjs | 108 ++ packages/soundfonts/index.mjs | 33 +- packages/soundfonts/list.mjs | 1767 ++++++++++++++++++++++++++++ packages/soundfonts/package.json | 5 +- packages/webaudio/webaudio.mjs | 140 ++- 8 files changed, 2144 insertions(+), 263 deletions(-) create mode 100644 packages/soundfonts/convert.js create mode 100644 packages/soundfonts/fontloader.mjs create mode 100644 packages/soundfonts/list.mjs diff --git a/package-lock.json b/package-lock.json index 579657c2..1b469861 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3951,6 +3951,15 @@ "node": ">=0.10" } }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", + "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, "node_modules/dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -4959,6 +4968,29 @@ "reusify": "^1.0.4" } }, + "node_modules/fetch-blob": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.5.tgz", + "integrity": "sha512-N64ZpKqoLejlrwkIAnb9iLSA3Vx/kjgzpcDhygcqJ2KKjky8nCgUQ+dzXtbrLaWZGZNmNfQTsiQ0weZ1svglHg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -5138,6 +5170,18 @@ "node": ">= 0.12" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/fraction.js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", @@ -6620,11 +6664,6 @@ "node": ">=6" } }, - "node_modules/jsonc-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", - "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==" - }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -6935,11 +6974,6 @@ "node": ">=10" } }, - "node_modules/lunr": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", - "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" - }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -7596,6 +7630,25 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, "node_modules/node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -9726,16 +9779,6 @@ "resolved": "https://registry.npmjs.org/shift-spec/-/shift-spec-2018.0.0.tgz", "integrity": "sha512-/aiPOkj7dbe+CV2VZhIMTHQToZmgniofpRG7Yr7x2/0sO6CSVC++py1Wzf+s+rWSTDHKcLvziVAxjRRV4i4EoQ==" }, - "node_modules/shiki": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz", - "integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==", - "dependencies": { - "jsonc-parser": "^3.0.0", - "vscode-oniguruma": "^1.6.1", - "vscode-textmate": "5.2.0" - } - }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -10572,77 +10615,6 @@ "is-typedarray": "^1.0.0" } }, - "node_modules/typedoc": { - "version": "0.22.17", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.17.tgz", - "integrity": "sha512-h6+uXHVVCPDaANzjwzdsj9aePBjZiBTpiMpBBeyh1zcN2odVsDCNajz8zyKnixF93HJeGpl34j/70yoEE5BfNg==", - "dependencies": { - "glob": "^8.0.3", - "lunr": "^2.3.9", - "marked": "^4.0.16", - "minimatch": "^5.1.0", - "shiki": "^0.10.1" - }, - "bin": { - "typedoc": "bin/typedoc" - }, - "engines": { - "node": ">= 12.10.0" - }, - "peerDependencies": { - "typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x || 4.6.x || 4.7.x" - } - }, - "node_modules/typedoc/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/typedoc/node_modules/glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/typedoc/node_modules/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, "node_modules/typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", @@ -10891,16 +10863,6 @@ } } }, - "node_modules/vscode-oniguruma": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz", - "integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==" - }, - "node_modules/vscode-textmate": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", - "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==" - }, "node_modules/w3c-keyname": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz", @@ -10924,12 +10886,13 @@ "defaults": "^1.0.3" } }, - "node_modules/webaudiofont": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webaudiofont/-/webaudiofont-3.0.1.tgz", - "integrity": "sha512-PwqbR4OdvzbW8/TLTitSU/rw4mxMKyAGTKV42mePCgMoUGLJoQj8HDLWVqtNOpUZ0ghPNhNE6cRFEv6HFFEBQA==", - "dependencies": { - "typedoc": "^0.22.14" + "node_modules/web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "dev": true, + "engines": { + "node": ">= 8" } }, "node_modules/WebDirt": { @@ -11528,10 +11491,33 @@ "license": "AGPL-3.0-or-later" }, "packages/soundfonts": { + "name": "@strudel.cycles/soundfonts", "version": "0.1.0", "license": "AGPL-3.0-or-later", "dependencies": { - "webaudiofont": "^3.0.1" + "@strudel.cycles/core": "*", + "@strudel.cycles/webaudio": "*" + }, + "devDependencies": { + "node-fetch": "^3.2.6" + } + }, + "packages/soundfonts/node_modules/node-fetch": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.6.tgz", + "integrity": "sha512-LAy/HZnLADOVkVPubaxHDft29booGglPFDr2Hw0J1AercRh01UiVFm++KMDnJeH9sHgNB4hsXPii7Sgym/sTbw==", + "dev": true, + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" } }, "packages/tonal": { @@ -13507,7 +13493,22 @@ "@strudel.cycles/soundfonts": { "version": "file:packages/soundfonts", "requires": { - "webaudiofont": "^3.0.1" + "@strudel.cycles/core": "*", + "@strudel.cycles/webaudio": "*", + "node-fetch": "^3.2.6" + }, + "dependencies": { + "node-fetch": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.6.tgz", + "integrity": "sha512-LAy/HZnLADOVkVPubaxHDft29booGglPFDr2Hw0J1AercRh01UiVFm++KMDnJeH9sHgNB4hsXPii7Sgym/sTbw==", + "dev": true, + "requires": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + } + } } }, "@strudel.cycles/tonal": { @@ -14934,6 +14935,12 @@ "assert-plus": "^1.0.0" } }, + "data-uri-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", + "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", + "dev": true + }, "dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -15607,6 +15614,16 @@ "reusify": "^1.0.4" } }, + "fetch-blob": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.5.tgz", + "integrity": "sha512-N64ZpKqoLejlrwkIAnb9iLSA3Vx/kjgzpcDhygcqJ2KKjky8nCgUQ+dzXtbrLaWZGZNmNfQTsiQ0weZ1svglHg==", + "dev": true, + "requires": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + } + }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -15735,6 +15752,15 @@ "mime-types": "^2.1.12" } }, + "formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "requires": { + "fetch-blob": "^3.1.2" + } + }, "fraction.js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", @@ -16858,11 +16884,6 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" }, - "jsonc-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", - "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==" - }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -17118,11 +17139,6 @@ "yallist": "^4.0.0" } }, - "lunr": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", - "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" - }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -17621,6 +17637,12 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true + }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -19299,16 +19321,6 @@ } } }, - "shiki": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz", - "integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==", - "requires": { - "jsonc-parser": "^3.0.0", - "vscode-oniguruma": "^1.6.1", - "vscode-textmate": "5.2.0" - } - }, "side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -19967,54 +19979,6 @@ "is-typedarray": "^1.0.0" } }, - "typedoc": { - "version": "0.22.17", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.17.tgz", - "integrity": "sha512-h6+uXHVVCPDaANzjwzdsj9aePBjZiBTpiMpBBeyh1zcN2odVsDCNajz8zyKnixF93HJeGpl34j/70yoEE5BfNg==", - "requires": { - "glob": "^8.0.3", - "lunr": "^2.3.9", - "marked": "^4.0.16", - "minimatch": "^5.1.0", - "shiki": "^0.10.1" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "requires": { - "balanced-match": "^1.0.0" - } - }, - "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - } - }, - "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "peer": true - }, "typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", @@ -20203,16 +20167,6 @@ "rollup": "^2.59.0" } }, - "vscode-oniguruma": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz", - "integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==" - }, - "vscode-textmate": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", - "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==" - }, "w3c-keyname": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz", @@ -20233,13 +20187,11 @@ "defaults": "^1.0.3" } }, - "webaudiofont": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webaudiofont/-/webaudiofont-3.0.1.tgz", - "integrity": "sha512-PwqbR4OdvzbW8/TLTitSU/rw4mxMKyAGTKV42mePCgMoUGLJoQj8HDLWVqtNOpUZ0ghPNhNE6cRFEv6HFFEBQA==", - "requires": { - "typedoc": "^0.22.14" - } + "web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "dev": true }, "WebDirt": { "version": "git+ssh://git@github.com/dktr0/WebDirt.git#425dc8fd023440d9c61ffdb8642e44e2710faea0", diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index c6f96263..a04cd706 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -27,6 +27,7 @@ const generic_params = [ * */ ['s', 's', 'sound'], + ['sf', 'sf', 'soundfont'], /** * The note or sample number to choose for a synth or sampleset * Note names currently not working yet, but will hopefully soon. Just stick to numbers for now diff --git a/packages/soundfonts/convert.js b/packages/soundfonts/convert.js new file mode 100644 index 00000000..91ecfc6c --- /dev/null +++ b/packages/soundfonts/convert.js @@ -0,0 +1,13 @@ +// this script converts a soundfont into a json file, it has not been not used yet +import fetch from 'node-fetch'; + +const name = '0000_JCLive'; + +const js = await fetch(`https://surikov.github.io/webaudiofontdata/sound/${name}_sf2_file.js`).then((res) => + res.text(), +); +// console.log(js); + +let [_, data] = js.split('_sf2_file='); +data = eval(data); +console.log(JSON.stringify(data)); diff --git a/packages/soundfonts/fontloader.mjs b/packages/soundfonts/fontloader.mjs new file mode 100644 index 00000000..09841780 --- /dev/null +++ b/packages/soundfonts/fontloader.mjs @@ -0,0 +1,108 @@ +let loadCache = {}; +async function loadFont(name) { + if (loadCache[name]) { + return loadCache[name]; + } + const load = async () => { + // TODO: make soundfont source configurable + const url = `https://surikov.github.io/webaudiofontdata/sound/${name}.js`; + console.log('load font', name, url); + const preset = await fetch(url).then((res) => res.text()); + let [_, data] = preset.split('={'); + return eval('{' + data); + }; + loadCache[name] = load(); + return loadCache[name]; +} + +let bufferCache = {}; +export async function getFontBufferSource(name, pitch, ac) { + const key = `${name}:::${pitch}`; + if (bufferCache[key]) { + return (await bufferCache[key])(); + } + // console.log('load buffer', key); + const load = async () => { + const preset = await loadFont(name); + if (!preset) { + throw new Error(`Could not load soundfont ${name}`); + } + const zone = findZone(preset, pitch); + if (!zone) { + throw new Error('no soundfont zone found for preset ', name, 'pitch', pitch); + } + const buffer = await getBuffer(zone, ac); + if (!buffer) { + throw new Error(`no soundfont buffer found for preset ${name}, pitch: ${pitch}`); + } + return () => { + const src = ac.createBufferSource(); + src.buffer = buffer; + const baseDetune = zone.originalPitch - 100.0 * zone.coarseTune - zone.fineTune; + const playbackRate = 1.0 * Math.pow(2, (100.0 * pitch - baseDetune) / 1200.0); + // src detune? + src.playbackRate.value = playbackRate; + const loop = zone.loopStart > 1 && zone.loopStart < zone.loopEnd; + if (!loop) { + /* const waveDuration = duration + this.afterTime; + if (waveDuration > zone.buffer.duration / playbackRate) { + waveDuration = zone.buffer.duration / playbackRate; + // TODO: do sth with waveduration + } */ + } else { + src.loop = true; + /* src.loopStart = zone.loopStart / zone.sampleRate + (zone.delay ? zone.delay : 0); + src.loopEnd = zone.loopEnd / zone.sampleRate + (zone.delay ? zone.delay : 0); */ + } + + return src; + }; + }; + bufferCache[key] = load(); // dont await here to cache promise immediately! + return (await bufferCache[key])(); +} + +function findZone(preset, pitch) { + return preset.find((zone) => { + return zone.keyRangeLow <= pitch && zone.keyRangeHigh + 1 >= pitch; + }); +} + +// promisified version of https://github.com/felixroos/webaudiofont/blob/c6f97249b60dcfafc20fca5bb381294a6b2f8f51/npm/dist/WebAudioFontPlayer.js#L740 +async function getBuffer(zone, audioContext) { + if (zone.sample) { + console.warn('zone.sample untested!'); + const decoded = atob(zone.sample); + zone.buffer = audioContext.createBuffer(1, decoded.length / 2, zone.sampleRate); + const float32Array = zone.buffer.getChannelData(0); + let b1, b2, n; + for (var i = 0; i < decoded.length / 2; i++) { + b1 = decoded.charCodeAt(i * 2); + b2 = decoded.charCodeAt(i * 2 + 1); + if (b1 < 0) { + b1 = 256 + b1; + } + if (b2 < 0) { + b2 = 256 + b2; + } + n = b2 * 256 + b1; + if (n >= 65536 / 2) { + n = n - 65536; + } + float32Array[i] = n / 65536.0; + } + } else { + if (zone.file) { + const datalen = zone.file.length; + const arraybuffer = new ArrayBuffer(datalen); + const view = new Uint8Array(arraybuffer); + const decoded = atob(zone.file); + let b; + for (let i = 0; i < decoded.length; i++) { + b = decoded.charCodeAt(i); + view[i] = b; + } + return new Promise((resolve) => audioContext.decodeAudioData(arraybuffer, resolve)); + } + } +} diff --git a/packages/soundfonts/index.mjs b/packages/soundfonts/index.mjs index 4bc56730..f5156cf1 100644 --- a/packages/soundfonts/index.mjs +++ b/packages/soundfonts/index.mjs @@ -1,29 +1,6 @@ -import { Pattern } from '@strudel.cycles/core'; -import { getAudioContext } from '@strudel.cycles/webaudio'; -// import * as WebAudioFontPlayer from 'webaudiofont'; -import * as WebAudioFont from 'webaudiofont'; -console.log('WebAudioFont:!', WebAudioFont); -// https://surikov.github.io/webaudiofont/npm/dist/WebAudioFontPlayer.js -// https://surikov.github.io/webaudiofontdata/sound/0000_JCLive_sf2_file.js +import { getFontBufferSource } from './fontloader.mjs'; +import * as soundfontList from './list.mjs'; -// https://github.com/surikov/webaudiofont#dynamic-loading -/* function changeInstrument(path, name) { - player.loader.startLoad(audioContext, path, name); - player.loader.waitLoad(function () { - instr = window[name]; - }); -} */ - -Pattern.prototype.soundfont = function (soundfont) { - const ac = getAudioContext(); - return this.onTrigger((t, hap, ct) => { - // const url = `https://surikov.github.io/webaudiofontdata/sound/${soundfont}_sf2_file.js`; - // changeInstrument('https://surikov.github.io/webaudiofontdata/sound/0290_Aspirin_sf2_file.js','_tone_0290_Aspirin_sf2_file'); - console.log('url', url); - // const player = WebAudioFontPlayer(); - // console.log('soundfont', url, player); - /* var selectedPreset = _tone_0000_JCLive_sf2_file; - player.loader.decodeAfterLoading(ac, '_tone_0000_JCLive_sf2_file'); - player.queueWaveTable(ac, ac.destination, selectedPreset, 0, 55, 3.5); */ - }); -}; +globalThis.getFontBufferSource = getFontBufferSource; +globalThis.soundfontList = soundfontList; +globalThis.soundfontList = soundfontList; diff --git a/packages/soundfonts/list.mjs b/packages/soundfonts/list.mjs new file mode 100644 index 00000000..69396a1d --- /dev/null +++ b/packages/soundfonts/list.mjs @@ -0,0 +1,1767 @@ +export const instruments = [ + '0000_JCLive_sf2_file', + '0000_Aspirin_sf2_file', + '0000_Chaos_sf2_file', + '0000_FluidR3_GM_sf2_file', + '0000_GeneralUserGS_sf2_file', + '0000_SBLive_sf2', + '0000_SoundBlasterOld_sf2', + '0001_FluidR3_GM_sf2_file', + '0001_GeneralUserGS_sf2_file', + '0002_GeneralUserGS_sf2_file', + '0003_GeneralUserGS_sf2_file', + '0010_Aspirin_sf2_file', + '0010_Chaos_sf2_file', + '0010_FluidR3_GM_sf2_file', + '0010_GeneralUserGS_sf2_file', + '0010_JCLive_sf2_file', + '0010_SBLive_sf2', + '0010_SoundBlasterOld_sf2', + '0011_Aspirin_sf2_file', + '0011_FluidR3_GM_sf2_file', + '0011_GeneralUserGS_sf2_file', + '0012_GeneralUserGS_sf2_file', + '0020_Aspirin_sf2_file', + '0020_Chaos_sf2_file', + '0020_FluidR3_GM_sf2_file', + '0020_GeneralUserGS_sf2_file', + '0020_JCLive_sf2_file', + '0020_SBLive_sf2', + '0020_SoundBlasterOld_sf2', + '0021_Aspirin_sf2_file', + '0021_GeneralUserGS_sf2_file', + '0022_Aspirin_sf2_file', + '0030_Aspirin_sf2_file', + '0030_Chaos_sf2_file', + '0030_FluidR3_GM_sf2_file', + '0030_GeneralUserGS_sf2_file', + '0030_JCLive_sf2_file', + '0030_SBLive_sf2', + '0030_SoundBlasterOld_sf2', + '0031_Aspirin_sf2_file', + '0031_FluidR3_GM_sf2_file', + '0031_GeneralUserGS_sf2_file', + '0031_SoundBlasterOld_sf2', // pianos until here + '0040_Aspirin_sf2_file', + '0040_Chaos_sf2_file', + '0040_FluidR3_GM_sf2_file', // rhodes + '0040_GeneralUserGS_sf2_file', // staccato rhodes + '0040_JCLive_sf2_file', // warbly rhodes + '0040_SBLive_sf2', // ? + '0040_SoundBlasterOld_sf2', // ? + '0041_FluidR3_GM_sf2_file', // rhodes + '0041_GeneralUserGS_sf2_file', // staccato rhodes + '0041_SoundBlasterOld_sf2', // ? + '0042_GeneralUserGS_sf2_file', // staccato wurly + '0043_GeneralUserGS_sf2_file', // high bell + '0044_GeneralUserGS_sf2_file', // reed organ + '0045_GeneralUserGS_sf2_file', // ? + '0046_GeneralUserGS_sf2_file', // ? + '0050_Aspirin_sf2_file', // glass organ + '0050_Chaos_sf2_file', // short glass organ + '0050_FluidR3_GM_sf2_file',// long glass organ ! + '0050_GeneralUserGS_sf2_file', // short glass organ + '0050_JCLive_sf2_file', // glass organ + '0050_SBLive_sf2', // ? + '0050_SoundBlasterOld_sf2', // ? + '0051_FluidR3_GM_sf2_file', // long lass organ + '0051_GeneralUserGS_sf2_file', + '0052_GeneralUserGS_sf2_file', // ? + '0053_GeneralUserGS_sf2_file', + '0054_GeneralUserGS_sf2_file', // piano + '0060_Aspirin_sf2_file', // harpsichord + '0060_Chaos_sf2_file', + '0060_FluidR3_GM_sf2_file', // harpsichord ! + '0060_GeneralUserGS_sf2_file', + '0060_JCLive_sf2_file', + '0060_SBLive_sf2', + '0060_SoundBlasterOld_sf2', + '0061_Aspirin_sf2_file', + '0061_GeneralUserGS_sf2_file', + '0061_SoundBlasterOld_sf2', + '0062_GeneralUserGS_sf2_file', + '0070_Aspirin_sf2_file', + '0070_Chaos_sf2_file', + '0070_FluidR3_GM_sf2_file', + '0070_GeneralUserGS_sf2_file', + '0070_JCLive_sf2_file', + '0070_SBLive_sf2', + '0070_SoundBlasterOld_sf2', + '0071_GeneralUserGS_sf2_file', + '0080_Aspirin_sf2_file', + '0080_Chaos_sf2_file', + '0080_FluidR3_GM_sf2_file', + '0080_GeneralUserGS_sf2_file', + '0080_JCLive_sf2_file', + '0080_SBLive_sf2', + '0080_SoundBlasterOld_sf2', + '0081_FluidR3_GM_sf2_file', + '0081_GeneralUserGS_sf2_file', + '0081_SoundBlasterOld_sf2', + '0090_Aspirin_sf2_file', + '0090_Chaos_sf2_file', + '0090_FluidR3_GM_sf2_file', + '0090_GeneralUserGS_sf2_file', + '0090_JCLive_sf2_file', + '0090_SBLive_sf2', + '0090_SoundBlasterOld_sf2', + '0091_SoundBlasterOld_sf2', + '0100_Aspirin_sf2_file', + '0100_Chaos_sf2_file', + '0100_FluidR3_GM_sf2_file', + '0100_GeneralUserGS_sf2_file', + '0100_JCLive_sf2_file', + '0100_SBLive_sf2', + '0100_SoundBlasterOld_sf2', + '0101_GeneralUserGS_sf2_file', + '0101_SoundBlasterOld_sf2', + '0110_Aspirin_sf2_file', + '0110_Chaos_sf2_file', + '0110_FluidR3_GM_sf2_file', + '0110_GeneralUserGS_sf2_file', + '0110_JCLive_sf2_file', + '0110_SBLive_sf2', + '0110_SoundBlasterOld_sf2', + '0111_FluidR3_GM_sf2_file', + '0120_Aspirin_sf2_file', + '0120_Chaos_sf2_file', + '0120_FluidR3_GM_sf2_file', + '0120_GeneralUserGS_sf2_file', + '0120_JCLive_sf2_file', + '0120_SBLive_sf2', + '0120_SoundBlasterOld_sf2', + '0121_FluidR3_GM_sf2_file', + '0121_GeneralUserGS_sf2_file', + '0130_Aspirin_sf2_file', + '0130_Chaos_sf2_file', + '0130_FluidR3_GM_sf2_file', + '0130_GeneralUserGS_sf2_file', + '0130_JCLive_sf2_file', + '0130_SBLive_sf2', + '0130_SoundBlasterOld_sf2', + '0131_FluidR3_GM_sf2_file', + '0140_Aspirin_sf2_file', + '0140_Chaos_sf2_file', + '0140_FluidR3_GM_sf2_file', + '0140_GeneralUserGS_sf2_file', + '0140_JCLive_sf2_file', + '0140_SBLive_sf2', + '0140_SoundBlasterOld_sf2', + '0141_FluidR3_GM_sf2_file', + '0141_GeneralUserGS_sf2_file', + '0142_GeneralUserGS_sf2_file', + '0143_GeneralUserGS_sf2_file', + '0150_Aspirin_sf2_file', + '0150_Chaos_sf2_file', + '0150_FluidR3_GM_sf2_file', + '0150_GeneralUserGS_sf2_file', + '0150_JCLive_sf2_file', + '0150_SBLive_sf2', + '0150_SoundBlasterOld_sf2', + '0151_FluidR3_GM_sf2_file', + '0160_Aspirin_sf2_file', + '0160_Chaos_sf2_file', + '0160_FluidR3_GM_sf2_file', + '0160_GeneralUserGS_sf2_file', + '0160_JCLive_sf2_file', + '0160_SBLive_sf2', + '0160_SoundBlasterOld_sf2', + '0161_Aspirin_sf2_file', + '0161_FluidR3_GM_sf2_file', + '0161_SoundBlasterOld_sf2', + '0170_Aspirin_sf2_file', + '0170_Chaos_sf2_file', + '0170_FluidR3_GM_sf2_file', + '0170_GeneralUserGS_sf2_file', + '0170_JCLive_sf2_file', + '0170_SBLive_sf2', + '0170_SoundBlasterOld_sf2', + '0171_FluidR3_GM_sf2_file', + '0171_GeneralUserGS_sf2_file', + '0172_FluidR3_GM_sf2_file', + '0180_Aspirin_sf2_file', + '0180_Chaos_sf2_file', + '0180_FluidR3_GM_sf2_file', + '0180_GeneralUserGS_sf2_file', + '0180_JCLive_sf2_file', + '0180_SBLive_sf2', + '0180_SoundBlasterOld_sf2', + '0181_Aspirin_sf2_file', + '0181_GeneralUserGS_sf2_file', + '0181_SoundBlasterOld_sf2', + '0190_Aspirin_sf2_file', + '0190_Chaos_sf2_file', + '0190_FluidR3_GM_sf2_file', + '0190_GeneralUserGS_sf2_file', + '0190_JCLive_sf2_file', + '0190_SBLive_sf2', + '0190_SoundBlasterOld_sf2', + '0191_Aspirin_sf2_file', + '0191_GeneralUserGS_sf2_file', + '0191_SoundBlasterOld_sf2', + '0200_Aspirin_sf2_file', + '0200_Chaos_sf2_file', + '0200_FluidR3_GM_sf2_file', + '0200_GeneralUserGS_sf2_file', + '0200_JCLive_sf2_file', + '0200_SBLive_sf2', + '0200_SoundBlasterOld_sf2', + '0201_Aspirin_sf2_file', + '0201_FluidR3_GM_sf2_file', + '0201_GeneralUserGS_sf2_file', + '0201_SoundBlasterOld_sf2', + '0210_Aspirin_sf2_file', + '0210_Chaos_sf2_file', + '0210_FluidR3_GM_sf2_file', + '0210_GeneralUserGS_sf2_file', + '0210_JCLive_sf2_file', + '0210_SBLive_sf2', + '0210_SoundBlasterOld_sf2', + '0211_Aspirin_sf2_file', + '0211_FluidR3_GM_sf2_file', + '0211_GeneralUserGS_sf2_file', + '0211_SoundBlasterOld_sf2', + '0212_GeneralUserGS_sf2_file', + '0220_Aspirin_sf2_file', + '0220_Chaos_sf2_file', + '0220_FluidR3_GM_sf2_file', + '0220_GeneralUserGS_sf2_file', + '0220_JCLive_sf2_file', + '0220_SBLive_sf2', + '0220_SoundBlasterOld_sf2', + '0221_FluidR3_GM_sf2_file', + '0230_Aspirin_sf2_file', + '0230_Chaos_sf2_file', + '0230_FluidR3_GM_sf2_file', + '0230_GeneralUserGS_sf2_file', + '0230_JCLive_sf2_file', + '0230_SBLive_sf2', + '0230_SoundBlasterOld_sf2', + '0231_FluidR3_GM_sf2_file', + '0231_GeneralUserGS_sf2_file', + '0231_JCLive_sf2_file', + '0231_SoundBlasterOld_sf2', + '0232_FluidR3_GM_sf2_file', + '0233_FluidR3_GM_sf2_file', + '0240_Aspirin_sf2_file', + '0240_Chaos_sf2_file', + '0240_FluidR3_GM_sf2_file', + '0240_GeneralUserGS_sf2_file', + '0240_JCLive_sf2_file', + '0240_LK_Godin_Nylon_SF2_file', + '0240_SBLive_sf2', + '0240_SoundBlasterOld_sf2', + '0241_GeneralUserGS_sf2_file', + '0241_JCLive_sf2_file', + '0242_JCLive_sf2_file', + '0243_JCLive_sf2_file', + '0253_Acoustic_Guitar_sf2_file', + '0250_Aspirin_sf2_file', + '0250_Chaos_sf2_file', + '0250_FluidR3_GM_sf2_file', + '0250_GeneralUserGS_sf2_file', + '0250_JCLive_sf2_file', + '0250_LK_AcousticSteel_SF2_file', + '0250_SBLive_sf2', + '0250_SoundBlasterOld_sf2', + '0251_Acoustic_Guitar_sf2_file', + '0251_GeneralUserGS_sf2_file', + '0252_Acoustic_Guitar_sf2_file', + '0252_GeneralUserGS_sf2_file', + '0253_Acoustic_Guitar_sf2_file', + '0253_GeneralUserGS_sf2_file', + '0254_Acoustic_Guitar_sf2_file', + '0254_GeneralUserGS_sf2_file', + '0255_GeneralUserGS_sf2_file', + '0260_Aspirin_sf2_file', + '0260_Chaos_sf2_file', + '0260_FluidR3_GM_sf2_file', + '0260_GeneralUserGS_sf2_file', + '0260_JCLive_sf2_file', + '0260_SBLive_sf2', + '0260_SoundBlasterOld_sf2', + '0260_Stratocaster_sf2_file', + '0261_GeneralUserGS_sf2_file', + '0261_SoundBlasterOld_sf2', + '0261_Stratocaster_sf2_file', + '0262_Stratocaster_sf2_file', + '0270_Aspirin_sf2_file', + '0270_Chaos_sf2_file', + '0270_FluidR3_GM_sf2_file', + '0270_GeneralUserGS_sf2_file', + '0270_Gibson_Les_Paul_sf2_file', + '0270_JCLive_sf2_file', + '0270_SBAWE32_sf2_file', + '0270_SBLive_sf2', + '0270_SoundBlasterOld_sf2', + '0270_Stratocaster_sf2_file', + '0271_GeneralUserGS_sf2_file', + '0271_Stratocaster_sf2_file', + '0272_Stratocaster_sf2_file', + '0280_Aspirin_sf2_file', + '0280_Chaos_sf2_file', + '0280_FluidR3_GM_sf2_file', + '0280_GeneralUserGS_sf2_file', + '0280_JCLive_sf2_file', + '0280_LesPaul_sf2', + '0280_LesPaul_sf2_file', + '0280_SBAWE32_sf2_file', + '0280_SBLive_sf2', + '0280_SoundBlasterOld_sf2', + '0281_Aspirin_sf2_file', + '0281_FluidR3_GM_sf2_file', + '0281_GeneralUserGS_sf2_file', + '0282_FluidR3_GM_sf2_file', + '0282_GeneralUserGS_sf2_file', + '0283_GeneralUserGS_sf2_file', + '0290_Aspirin_sf2_file', + '0290_Chaos_sf2_file', + '0290_FluidR3_GM_sf2_file', + '0290_GeneralUserGS_sf2_file', + '0290_JCLive_sf2_file', + '0290_LesPaul_sf2', + '0290_LesPaul_sf2_file', + '0290_SBAWE32_sf2_file', + '0290_SBLive_sf2', + '0290_SoundBlasterOld_sf2', + '0291_Aspirin_sf2_file', + '0291_LesPaul_sf2', + '0291_LesPaul_sf2_file', + '0291_SBAWE32_sf2_file', + '0291_SoundBlasterOld_sf2', + '0292_Aspirin_sf2_file', + '0292_LesPaul_sf2', + '0292_LesPaul_sf2_file', + '0300_Aspirin_sf2_file', + '0300_Chaos_sf2_file', + '0300_FluidR3_GM_sf2_file', + '0300_GeneralUserGS_sf2_file', + '0300_JCLive_sf2_file', + '0300_LesPaul_sf2', + '0300_LesPaul_sf2_file', + '0300_SBAWE32_sf2_file', + '0300_SBLive_sf2', + '0300_SoundBlasterOld_sf2', + '0301_Aspirin_sf2_file', + '0301_FluidR3_GM_sf2_file', + '0301_GeneralUserGS_sf2_file', + '0301_JCLive_sf2_file', + '0301_LesPaul_sf2', + '0301_LesPaul_sf2_file', + '0302_Aspirin_sf2_file', + '0302_GeneralUserGS_sf2_file', + '0302_JCLive_sf2_file', + '0303_Aspirin_sf2_file', + '0304_Aspirin_sf2_file', + '0310_Aspirin_sf2_file', + '0310_Chaos_sf2_file', + '0310_FluidR3_GM_sf2_file', + '0310_GeneralUserGS_sf2_file', + '0310_JCLive_sf2_file', + '0310_LesPaul_sf2', + '0310_LesPaul_sf2_file', + '0310_SBAWE32_sf2_file', + '0310_SBLive_sf2', + '0310_SoundBlasterOld_sf2', + '0311_FluidR3_GM_sf2_file', + '0311_GeneralUserGS_sf2_file', + '0320_Aspirin_sf2_file', + '0320_Chaos_sf2_file', + '0320_FluidR3_GM_sf2_file', + '0320_GeneralUserGS_sf2_file', + '0320_JCLive_sf2_file', + '0320_SBLive_sf2', + '0320_SoundBlasterOld_sf2', + '0321_GeneralUserGS_sf2_file', + '0322_GeneralUserGS_sf2_file', + '0330_Aspirin_sf2_file', + '0330_Chaos_sf2_file', + '0330_FluidR3_GM_sf2_file', + '0330_GeneralUserGS_sf2_file', + '0330_JCLive_sf2_file', + '0330_SBLive_sf2', + '0330_SoundBlasterOld_sf2', + '0331_GeneralUserGS_sf2_file', + '0332_GeneralUserGS_sf2_file', + '0340_Aspirin_sf2_file', + '0340_Chaos_sf2_file', + '0340_FluidR3_GM_sf2_file', + '0340_GeneralUserGS_sf2_file', + '0340_JCLive_sf2_file', + '0340_SBLive_sf2', + '0340_SoundBlasterOld_sf2', + '0341_Aspirin_sf2_file', + '0341_GeneralUserGS_sf2_file', + '0350_Aspirin_sf2_file', + '0350_Chaos_sf2_file', + '0350_FluidR3_GM_sf2_file', + '0350_GeneralUserGS_sf2_file', + '0350_JCLive_sf2_file', + '0350_SBLive_sf2', + '0350_SoundBlasterOld_sf2', + '0351_GeneralUserGS_sf2_file', + '0360_Aspirin_sf2_file', + '0360_Chaos_sf2_file', + '0360_FluidR3_GM_sf2_file', + '0360_GeneralUserGS_sf2_file', + '0360_JCLive_sf2_file', + '0360_SBLive_sf2', + '0360_SoundBlasterOld_sf2', + '0361_GeneralUserGS_sf2_file', + '0370_Aspirin_sf2_file', + '0370_Chaos_sf2_file', + '0370_FluidR3_GM_sf2_file', + '0370_GeneralUserGS_sf2_file', + '0370_JCLive_sf2_file', + '0370_SBLive_sf2', + '0370_SoundBlasterOld_sf2', + '0371_GeneralUserGS_sf2_file', + '0372_GeneralUserGS_sf2_file', + '0385_GeneralUserGS_sf2_file', + '0380_Aspirin_sf2_file', + '0380_Chaos_sf2_file', + '0380_FluidR3_GM_sf2_file', + '0380_GeneralUserGS_sf2_file', + '0380_JCLive_sf2_file', + '0380_SBLive_sf2', + '0380_SoundBlasterOld_sf2', + '0381_FluidR3_GM_sf2_file', + '0381_GeneralUserGS_sf2_file', + '0382_FluidR3_GM_sf2_file', + '0382_GeneralUserGS_sf2_file', + '0383_GeneralUserGS_sf2_file', + '0384_GeneralUserGS_sf2_file', + '0386_GeneralUserGS_sf2_file', + '0387_GeneralUserGS_sf2_file', + '0390_Aspirin_sf2_file', + '0390_Chaos_sf2_file', + '0390_FluidR3_GM_sf2_file', + '0390_GeneralUserGS_sf2_file', + '0390_JCLive_sf2_file', + '0390_SBLive_sf2', + '0390_SoundBlasterOld_sf2', + '0391_FluidR3_GM_sf2_file', + '0391_GeneralUserGS_sf2_file', + '0391_SoundBlasterOld_sf2', + '0392_FluidR3_GM_sf2_file', + '0392_GeneralUserGS_sf2_file', + '0393_GeneralUserGS_sf2_file', + '0400_Aspirin_sf2_file', + '0400_Chaos_sf2_file', + '0400_FluidR3_GM_sf2_file', + '0400_GeneralUserGS_sf2_file', + '0400_JCLive_sf2_file', + '0400_SBLive_sf2', + '0400_SoundBlasterOld_sf2', + '0401_Aspirin_sf2_file', + '0401_FluidR3_GM_sf2_file', + '0401_GeneralUserGS_sf2_file', + '0402_GeneralUserGS_sf2_file', + '0410_Aspirin_sf2_file', + '0410_Chaos_sf2_file', + '0410_FluidR3_GM_sf2_file', + '0410_GeneralUserGS_sf2_file', + '0410_JCLive_sf2_file', + '0410_SBLive_sf2', + '0410_SoundBlasterOld_sf2', + '0411_FluidR3_GM_sf2_file', + '0420_Aspirin_sf2_file', + '0420_Chaos_sf2_file', + '0420_FluidR3_GM_sf2_file', + '0420_GeneralUserGS_sf2_file', + '0420_JCLive_sf2_file', + '0420_SBLive_sf2', + '0420_SoundBlasterOld_sf2', + '0421_FluidR3_GM_sf2_file', + '0421_GeneralUserGS_sf2_file', + '0430_Aspirin_sf2_file', + '0430_Chaos_sf2_file', + '0430_FluidR3_GM_sf2_file', + '0430_GeneralUserGS_sf2_file', + '0430_JCLive_sf2_file', + '0430_SBLive_sf2', + '0430_SoundBlasterOld_sf2', + '0431_FluidR3_GM_sf2_file', + '0440_Aspirin_sf2_file', + '0440_Chaos_sf2_file', + '0440_FluidR3_GM_sf2_file', + '0440_GeneralUserGS_sf2_file', + '0440_JCLive_sf2_file', + '0440_SBLive_sf2', + '0440_SoundBlasterOld_sf2', + '0441_GeneralUserGS_sf2_file', + '0442_GeneralUserGS_sf2_file', + '0450_Aspirin_sf2_file', + '0450_Chaos_sf2_file', + '0450_FluidR3_GM_sf2_file', + '0450_GeneralUserGS_sf2_file', + '0450_JCLive_sf2_file', + '0450_SBLive_sf2', + '0450_SoundBlasterOld_sf2', + '0451_FluidR3_GM_sf2_file', + '0460_Aspirin_sf2_file', + '0460_Chaos_sf2_file', + '0460_FluidR3_GM_sf2_file', + '0460_GeneralUserGS_sf2_file', + '0460_JCLive_sf2_file', + '0460_SBLive_sf2', + '0460_SoundBlasterOld_sf2', + '0461_FluidR3_GM_sf2_file', + '0470_Aspirin_sf2_file', + '0470_Chaos_sf2_file', + '0470_FluidR3_GM_sf2_file', + '0470_GeneralUserGS_sf2_file', + '0470_JCLive_sf2_file', + '0470_SBLive_sf2', + '0470_SoundBlasterOld_sf2', + '0471_FluidR3_GM_sf2_file', + '0471_GeneralUserGS_sf2_file', + '0480_Aspirin_sf2_file', + '0480_Chaos_sf2_file', + '0480_FluidR3_GM_sf2_file', + '0480_GeneralUserGS_sf2_file', + '0480_JCLive_sf2_file', + '0480_SBLive_sf2', + '0480_SoundBlasterOld_sf2', + '04810_GeneralUserGS_sf2_file', + '04811_GeneralUserGS_sf2_file', + '04812_GeneralUserGS_sf2_file', + '04813_GeneralUserGS_sf2_file', + '04814_GeneralUserGS_sf2_file', + '04815_GeneralUserGS_sf2_file', + '04816_GeneralUserGS_sf2_file', + '04817_GeneralUserGS_sf2_file', + '0481_Aspirin_sf2_file', + '0481_FluidR3_GM_sf2_file', + '0481_GeneralUserGS_sf2_file', + '0482_Aspirin_sf2_file', + '0482_GeneralUserGS_sf2_file', + '0483_GeneralUserGS_sf2_file', + '0484_GeneralUserGS_sf2_file', + '0485_GeneralUserGS_sf2_file', + '0486_GeneralUserGS_sf2_file', + '0487_GeneralUserGS_sf2_file', + '0488_GeneralUserGS_sf2_file', + '0489_GeneralUserGS_sf2_file', + '0490_Aspirin_sf2_file', + '0490_Chaos_sf2_file', + '0490_FluidR3_GM_sf2_file', + '0490_GeneralUserGS_sf2_file', + '0490_JCLive_sf2_file', + '0490_SBLive_sf2', + '0490_SoundBlasterOld_sf2', + '0491_GeneralUserGS_sf2_file', + '0492_GeneralUserGS_sf2_file', + '0500_Aspirin_sf2_file', + '0500_Chaos_sf2_file', + '0500_FluidR3_GM_sf2_file', + '0500_GeneralUserGS_sf2_file', + '0500_JCLive_sf2_file', + '0500_SBLive_sf2', + '0500_SoundBlasterOld_sf2', + '0501_FluidR3_GM_sf2_file', + '0501_GeneralUserGS_sf2_file', + '0502_FluidR3_GM_sf2_file', + '0502_GeneralUserGS_sf2_file', + '0503_FluidR3_GM_sf2_file', + '0504_FluidR3_GM_sf2_file', + '0505_FluidR3_GM_sf2_file', + '0510_Aspirin_sf2_file', + '0510_Chaos_sf2_file', + '0510_FluidR3_GM_sf2_file', + '0510_GeneralUserGS_sf2_file', + '0510_JCLive_sf2_file', + '0510_SBLive_sf2', + '0510_SoundBlasterOld_sf2', + '0511_GeneralUserGS_sf2_file', + '0511_SoundBlasterOld_sf2', + '0520_Aspirin_sf2_file', + '0520_Chaos_sf2_file', + '0520_FluidR3_GM_sf2_file', + '0520_GeneralUserGS_sf2_file', + '0520_JCLive_sf2_file', + '0520_SBLive_sf2', + '0520_Soul_Ahhs_sf2_file', + '0520_SoundBlasterOld_sf2', + '0521_FluidR3_GM_sf2_file', + '0521_Soul_Ahhs_sf2_file', + '0521_SoundBlasterOld_sf2', + '0522_Soul_Ahhs_sf2_file', + '0530_Aspirin_sf2_file', + '0530_Chaos_sf2_file', + '0530_FluidR3_GM_sf2_file', + '0530_GeneralUserGS_sf2_file', + '0530_JCLive_sf2_file', + '0530_SBLive_sf2', + '0530_Soul_Ahhs_sf2_file', + '0530_SoundBlasterOld_sf2', + '0531_FluidR3_GM_sf2_file', + '0531_GeneralUserGS_sf2_file', + '0531_JCLive_sf2_file', + '0531_SoundBlasterOld_sf2', + '0540_Aspirin_sf2_file', + '0540_Chaos_sf2_file', + '0540_FluidR3_GM_sf2_file', + '0540_GeneralUserGS_sf2_file', + '0540_JCLive_sf2_file', + '0540_SBLive_sf2', + '0540_SoundBlasterOld_sf2', + '0541_FluidR3_GM_sf2_file', + '0550_Aspirin_sf2_file', + '0550_Chaos_sf2_file', + '0550_FluidR3_GM_sf2_file', + '0550_GeneralUserGS_sf2_file', + '0550_JCLive_sf2_file', + '0550_SBLive_sf2', + '0550_SoundBlasterOld_sf2', + '0551_Aspirin_sf2_file', + '0551_FluidR3_GM_sf2_file', + '0560_Aspirin_sf2_file', + '0560_Chaos_sf2_file', + '0560_FluidR3_GM_sf2_file', + '0560_GeneralUserGS_sf2_file', + '0560_JCLive_sf2_file', + '0560_SBLive_sf2', + '0560_SoundBlasterOld_sf2', + '0570_Aspirin_sf2_file', + '0570_Chaos_sf2_file', + '0570_FluidR3_GM_sf2_file', + '0570_GeneralUserGS_sf2_file', + '0570_JCLive_sf2_file', + '0570_SBLive_sf2', + '0570_SoundBlasterOld_sf2', + '0571_GeneralUserGS_sf2_file', + '0580_Aspirin_sf2_file', + '0580_Chaos_sf2_file', + '0580_FluidR3_GM_sf2_file', + '0580_GeneralUserGS_sf2_file', + '0580_JCLive_sf2_file', + '0580_SBLive_sf2', + '0580_SoundBlasterOld_sf2', + '0581_GeneralUserGS_sf2_file', + '0590_Aspirin_sf2_file', + '0590_Chaos_sf2_file', + '0590_FluidR3_GM_sf2_file', + '0590_GeneralUserGS_sf2_file', + '0590_JCLive_sf2_file', + '0590_SBLive_sf2', + '0590_SoundBlasterOld_sf2', + '0591_GeneralUserGS_sf2_file', + '0600_Aspirin_sf2_file', + '0600_Chaos_sf2_file', + '0600_FluidR3_GM_sf2_file', + '0600_GeneralUserGS_sf2_file', + '0600_JCLive_sf2_file', + '0600_SBLive_sf2', + '0600_SoundBlasterOld_sf2', + '0601_FluidR3_GM_sf2_file', + '0601_GeneralUserGS_sf2_file', + '0602_GeneralUserGS_sf2_file', + '0603_GeneralUserGS_sf2_file', + '0610_Aspirin_sf2_file', + '0610_Chaos_sf2_file', + '0610_FluidR3_GM_sf2_file', + '0610_GeneralUserGS_sf2_file', + '0610_JCLive_sf2_file', + '0610_SBLive_sf2', + '0610_SoundBlasterOld_sf2', + '0611_GeneralUserGS_sf2_file', + '0612_GeneralUserGS_sf2_file', + '0613_GeneralUserGS_sf2_file', + '0614_GeneralUserGS_sf2_file', + '0615_GeneralUserGS_sf2_file', + '0620_Aspirin_sf2_file', + '0620_Chaos_sf2_file', + '0620_FluidR3_GM_sf2_file', + '0620_GeneralUserGS_sf2_file', + '0620_JCLive_sf2_file', + '0620_SBLive_sf2', + '0620_SoundBlasterOld_sf2', + '0621_Aspirin_sf2_file', + '0621_FluidR3_GM_sf2_file', + '0621_GeneralUserGS_sf2_file', + '0622_FluidR3_GM_sf2_file', + '0622_GeneralUserGS_sf2_file', + '0630_Aspirin_sf2_file', + '0630_Chaos_sf2_file', + '0630_FluidR3_GM_sf2_file', + '0630_GeneralUserGS_sf2_file', + '0630_JCLive_sf2_file', + '0630_SBLive_sf2', + '0630_SoundBlasterOld_sf2', + '0631_Aspirin_sf2_file', + '0631_FluidR3_GM_sf2_file', + '0631_GeneralUserGS_sf2_file', + '0632_FluidR3_GM_sf2_file', + '0633_FluidR3_GM_sf2_file', + '0640_Aspirin_sf2_file', + '0640_Chaos_sf2_file', + '0640_FluidR3_GM_sf2_file', + '0640_GeneralUserGS_sf2_file', + '0640_JCLive_sf2_file', + '0640_SBLive_sf2', + '0640_SoundBlasterOld_sf2', + '0641_FluidR3_GM_sf2_file', + '0650_Aspirin_sf2_file', + '0650_Chaos_sf2_file', + '0650_FluidR3_GM_sf2_file', + '0650_GeneralUserGS_sf2_file', + '0650_JCLive_sf2_file', + '0650_SBLive_sf2', + '0650_SoundBlasterOld_sf2', + '0651_Aspirin_sf2_file', + '0651_FluidR3_GM_sf2_file', + '0660_Aspirin_sf2_file', + '0660_Chaos_sf2_file', + '0660_FluidR3_GM_sf2_file', + '0660_GeneralUserGS_sf2_file', + '0660_JCLive_sf2_file', + '0660_SBLive_sf2', + '0660_SoundBlasterOld_sf2', + '0661_FluidR3_GM_sf2_file', + '0661_GeneralUserGS_sf2_file', + '0670_Aspirin_sf2_file', + '0670_Chaos_sf2_file', + '0670_FluidR3_GM_sf2_file', + '0670_GeneralUserGS_sf2_file', + '0670_JCLive_sf2_file', + '0670_SBLive_sf2', + '0670_SoundBlasterOld_sf2', + '0671_FluidR3_GM_sf2_file', + '0680_Aspirin_sf2_file', + '0680_Chaos_sf2_file', + '0680_FluidR3_GM_sf2_file', + '0680_GeneralUserGS_sf2_file', + '0680_JCLive_sf2_file', + '0680_SBLive_sf2', + '0680_SoundBlasterOld_sf2', + '0681_FluidR3_GM_sf2_file', + '0690_Aspirin_sf2_file', + '0690_Chaos_sf2_file', + '0690_FluidR3_GM_sf2_file', + '0690_GeneralUserGS_sf2_file', + '0690_JCLive_sf2_file', + '0690_SBLive_sf2', + '0690_SoundBlasterOld_sf2', + '0691_FluidR3_GM_sf2_file', + '0700_Aspirin_sf2_file', + '0700_Chaos_sf2_file', + '0700_FluidR3_GM_sf2_file', + '0700_GeneralUserGS_sf2_file', + '0700_JCLive_sf2_file', + '0700_SBLive_sf2', + '0700_SoundBlasterOld_sf2', + '0701_FluidR3_GM_sf2_file', + '0701_GeneralUserGS_sf2_file', + '0710_Aspirin_sf2_file', + '0710_Chaos_sf2_file', + '0710_FluidR3_GM_sf2_file', + '0710_GeneralUserGS_sf2_file', + '0710_JCLive_sf2_file', + '0710_SBLive_sf2', + '0710_SoundBlasterOld_sf2', + '0711_FluidR3_GM_sf2_file', + '0720_Aspirin_sf2_file', + '0720_Chaos_sf2_file', + '0720_FluidR3_GM_sf2_file', + '0720_GeneralUserGS_sf2_file', + '0720_JCLive_sf2_file', + '0720_SBLive_sf2', + '0720_SoundBlasterOld_sf2', + '0721_FluidR3_GM_sf2_file', + '0721_SoundBlasterOld_sf2', + '0730_Aspirin_sf2_file', + '0730_Chaos_sf2_file', + '0730_FluidR3_GM_sf2_file', + '0730_GeneralUserGS_sf2_file', + '0730_JCLive_sf2_file', + '0730_SBLive_sf2', + '0730_SoundBlasterOld_sf2', + '0731_Aspirin_sf2_file', + '0731_FluidR3_GM_sf2_file', + '0731_SoundBlasterOld_sf2', + '0740_Aspirin_sf2_file', + '0740_Chaos_sf2_file', + '0740_FluidR3_GM_sf2_file', + '0740_GeneralUserGS_sf2_file', + '0740_JCLive_sf2_file', + '0740_SBLive_sf2', + '0740_SoundBlasterOld_sf2', + '0741_GeneralUserGS_sf2_file', + '0750_Aspirin_sf2_file', + '0750_Chaos_sf2_file', + '0750_FluidR3_GM_sf2_file', + '0750_GeneralUserGS_sf2_file', + '0750_JCLive_sf2_file', + '0750_SBLive_sf2', + '0750_SoundBlasterOld_sf2', + '0751_Aspirin_sf2_file', + '0751_FluidR3_GM_sf2_file', + '0751_GeneralUserGS_sf2_file', + '0751_SoundBlasterOld_sf2', + '0760_Aspirin_sf2_file', + '0760_Chaos_sf2_file', + '0760_FluidR3_GM_sf2_file', + '0760_GeneralUserGS_sf2_file', + '0760_JCLive_sf2_file', + '0760_SBLive_sf2', + '0760_SoundBlasterOld_sf2', + '0761_FluidR3_GM_sf2_file', + '0761_GeneralUserGS_sf2_file', + '0761_SoundBlasterOld_sf2', + '0762_GeneralUserGS_sf2_file', + '0770_Aspirin_sf2_file', + '0770_Chaos_sf2_file', + '0770_FluidR3_GM_sf2_file', + '0770_GeneralUserGS_sf2_file', + '0770_JCLive_sf2_file', + '0770_SBLive_sf2', + '0770_SoundBlasterOld_sf2', + '0771_FluidR3_GM_sf2_file', + '0771_GeneralUserGS_sf2_file', + '0772_GeneralUserGS_sf2_file', + '0780_Aspirin_sf2_file', + '0780_Chaos_sf2_file', + '0780_FluidR3_GM_sf2_file', + '0780_GeneralUserGS_sf2_file', + '0780_JCLive_sf2_file', + '0780_SBLive_sf2', + '0780_SoundBlasterOld_sf2', + '0781_GeneralUserGS_sf2_file', + '0790_Aspirin_sf2_file', + '0790_Chaos_sf2_file', + '0790_FluidR3_GM_sf2_file', + '0790_GeneralUserGS_sf2_file', + '0790_JCLive_sf2_file', + '0790_SBLive_sf2', + '0790_SoundBlasterOld_sf2', + '0791_GeneralUserGS_sf2_file', + '0800_Aspirin_sf2_file', + '0800_Chaos_sf2_file', + '0800_FluidR3_GM_sf2_file', + '0800_GeneralUserGS_sf2_file', + '0800_JCLive_sf2_file', + '0800_SBLive_sf2', + '0800_SoundBlasterOld_sf2', + '0801_FluidR3_GM_sf2_file', + '0801_GeneralUserGS_sf2_file', + '0810_Aspirin_sf2_file', + '0810_Chaos_sf2_file', + '0810_FluidR3_GM_sf2_file', + '0810_GeneralUserGS_sf2_file', + '0810_JCLive_sf2_file', + '0810_SBLive_sf2', + '0810_SoundBlasterOld_sf2', + '0811_Aspirin_sf2_file', + '0811_GeneralUserGS_sf2_file', + '0811_SoundBlasterOld_sf2', + '0820_Aspirin_sf2_file', + '0820_Chaos_sf2_file', + '0820_FluidR3_GM_sf2_file', + '0820_GeneralUserGS_sf2_file', + '0820_JCLive_sf2_file', + '0820_SBLive_sf2', + '0820_SoundBlasterOld_sf2', + '0821_FluidR3_GM_sf2_file', + '0821_GeneralUserGS_sf2_file', + '0821_SoundBlasterOld_sf2', + '0822_GeneralUserGS_sf2_file', + '0823_GeneralUserGS_sf2_file', + '0830_Aspirin_sf2_file', + '0830_Chaos_sf2_file', + '0830_FluidR3_GM_sf2_file', + '0830_GeneralUserGS_sf2_file', + '0830_JCLive_sf2_file', + '0830_SBLive_sf2', + '0830_SoundBlasterOld_sf2', + '0831_FluidR3_GM_sf2_file', + '0831_GeneralUserGS_sf2_file', + '0831_SoundBlasterOld_sf2', + '0840_Aspirin_sf2_file', + '0840_Chaos_sf2_file', + '0840_FluidR3_GM_sf2_file', + '0840_GeneralUserGS_sf2_file', + '0840_JCLive_sf2_file', + '0840_SBLive_sf2', + '0840_SoundBlasterOld_sf2', + '0841_Aspirin_sf2_file', + '0841_Chaos_sf2_file', + '0841_FluidR3_GM_sf2_file', + '0841_GeneralUserGS_sf2_file', + '0841_JCLive_sf2_file', + '0841_SoundBlasterOld_sf2', + '0842_FluidR3_GM_sf2_file', + '0850_Aspirin_sf2_file', + '0850_Chaos_sf2_file', + '0850_FluidR3_GM_sf2_file', + '0850_GeneralUserGS_sf2_file', + '0850_JCLive_sf2_file', + '0850_SBLive_sf2', + '0850_SoundBlasterOld_sf2', + '0851_FluidR3_GM_sf2_file', + '0851_GeneralUserGS_sf2_file', + '0851_JCLive_sf2_file', + '0851_SoundBlasterOld_sf2', + '0860_Aspirin_sf2_file', + '0860_Chaos_sf2_file', + '0860_FluidR3_GM_sf2_file', + '0860_GeneralUserGS_sf2_file', + '0860_JCLive_sf2_file', + '0860_SBLive_sf2', + '0860_SoundBlasterOld_sf2', + '0861_Aspirin_sf2_file', + '0861_FluidR3_GM_sf2_file', + '0861_SoundBlasterOld_sf2', + '0870_Aspirin_sf2_file', + '0870_Chaos_sf2_file', + '0870_FluidR3_GM_sf2_file', + '0870_GeneralUserGS_sf2_file', + '0870_JCLive_sf2_file', + '0870_SBLive_sf2', + '0870_SoundBlasterOld_sf2', + '0871_GeneralUserGS_sf2_file', + '0872_GeneralUserGS_sf2_file', + '0873_GeneralUserGS_sf2_file', + '0880_Aspirin_sf2_file', + '0880_Chaos_sf2_file', + '0880_FluidR3_GM_sf2_file', + '0880_GeneralUserGS_sf2_file', + '0880_JCLive_sf2_file', + '0880_SBLive_sf2', + '0880_SoundBlasterOld_sf2', + '0881_Aspirin_sf2_file', + '0881_FluidR3_GM_sf2_file', + '0881_GeneralUserGS_sf2_file', + '0881_SoundBlasterOld_sf2', + '0882_Aspirin_sf2_file', + '0882_FluidR3_GM_sf2_file', + '0882_GeneralUserGS_sf2_file', + '0883_GeneralUserGS_sf2_file', + '0884_GeneralUserGS_sf2_file', + '0885_GeneralUserGS_sf2_file', + '0886_GeneralUserGS_sf2_file', + '0887_GeneralUserGS_sf2_file', + '0888_GeneralUserGS_sf2_file', + '0889_GeneralUserGS_sf2_file', + '0890_Aspirin_sf2_file', + '0890_Chaos_sf2_file', + '0890_FluidR3_GM_sf2_file', + '0890_GeneralUserGS_sf2_file', + '0890_JCLive_sf2_file', + '0890_SBLive_sf2', + '0890_SoundBlasterOld_sf2', + '0891_Aspirin_sf2_file', + '0891_FluidR3_GM_sf2_file', + '0891_GeneralUserGS_sf2_file', + '0900_Aspirin_sf2_file', + '0900_Chaos_sf2_file', + '0900_FluidR3_GM_sf2_file', + '0900_GeneralUserGS_sf2_file', + '0900_JCLive_sf2_file', + '0900_SBLive_sf2', + '0900_SoundBlasterOld_sf2', + '0901_Aspirin_sf2_file', + '0901_FluidR3_GM_sf2_file', + '0901_GeneralUserGS_sf2_file', + '0901_SoundBlasterOld_sf2', + '0910_Aspirin_sf2_file', + '0910_Chaos_sf2_file', + '0910_FluidR3_GM_sf2_file', + '0910_GeneralUserGS_sf2_file', + '0910_JCLive_sf2_file', + '0910_SBLive_sf2', + '0910_SoundBlasterOld_sf2', + '0911_Aspirin_sf2_file', + '0911_GeneralUserGS_sf2_file', + '0911_JCLive_sf2_file', + '0911_SoundBlasterOld_sf2', + '0920_Aspirin_sf2_file', + '0920_Chaos_sf2_file', + '0920_FluidR3_GM_sf2_file', + '0920_GeneralUserGS_sf2_file', + '0920_JCLive_sf2_file', + '0920_SBLive_sf2', + '0920_SoundBlasterOld_sf2', + '0921_Aspirin_sf2_file', + '0921_GeneralUserGS_sf2_file', + '0921_SoundBlasterOld_sf2', + '0930_Aspirin_sf2_file', + '0930_Chaos_sf2_file', + '0930_FluidR3_GM_sf2_file', + '0930_GeneralUserGS_sf2_file', + '0930_JCLive_sf2_file', + '0930_SBLive_sf2', + '0930_SoundBlasterOld_sf2', + '0931_Aspirin_sf2_file', + '0931_FluidR3_GM_sf2_file', + '0931_GeneralUserGS_sf2_file', + '0931_SoundBlasterOld_sf2', + '0940_Aspirin_sf2_file', + '0940_Chaos_sf2_file', + '0940_FluidR3_GM_sf2_file', + '0940_GeneralUserGS_sf2_file', + '0940_JCLive_sf2_file', + '0940_SBLive_sf2', + '0940_SoundBlasterOld_sf2', + '0941_Aspirin_sf2_file', + '0941_FluidR3_GM_sf2_file', + '0941_GeneralUserGS_sf2_file', + '0941_JCLive_sf2_file', + '0950_Aspirin_sf2_file', + '0950_Chaos_sf2_file', + '0950_FluidR3_GM_sf2_file', + '0950_GeneralUserGS_sf2_file', + '0950_JCLive_sf2_file', + '0950_SBLive_sf2', + '0950_SoundBlasterOld_sf2', + '0951_FluidR3_GM_sf2_file', + '0951_GeneralUserGS_sf2_file', + '0960_Aspirin_sf2_file', + '0960_Chaos_sf2_file', + '0960_FluidR3_GM_sf2_file', + '0960_GeneralUserGS_sf2_file', + '0960_JCLive_sf2_file', + '0960_SBLive_sf2', + '0960_SoundBlasterOld_sf2', + '0961_Aspirin_sf2_file', + '0961_FluidR3_GM_sf2_file', + '0961_GeneralUserGS_sf2_file', + '0961_SoundBlasterOld_sf2', + '0962_GeneralUserGS_sf2_file', + '0970_Aspirin_sf2_file', + '0970_Chaos_sf2_file', + '0970_FluidR3_GM_sf2_file', + '0970_GeneralUserGS_sf2_file', + '0970_JCLive_sf2_file', + '0970_SBLive_sf2', + '0970_SoundBlasterOld_sf2', + '0971_FluidR3_GM_sf2_file', + '0971_GeneralUserGS_sf2_file', + '0971_SoundBlasterOld_sf2', + '0980_Aspirin_sf2_file', + '0980_Chaos_sf2_file', + '0980_FluidR3_GM_sf2_file', + '0980_GeneralUserGS_sf2_file', + '0980_JCLive_sf2_file', + '0980_SBLive_sf2', + '0980_SoundBlasterOld_sf2', + '0981_Aspirin_sf2_file', + '0981_FluidR3_GM_sf2_file', + '0981_GeneralUserGS_sf2_file', + '0981_SoundBlasterOld_sf2', + '0982_GeneralUserGS_sf2_file', + '0983_GeneralUserGS_sf2_file', + '0984_GeneralUserGS_sf2_file', + '0990_Aspirin_sf2_file', + '0990_Chaos_sf2_file', + '0990_FluidR3_GM_sf2_file', + '0990_GeneralUserGS_sf2_file', + '0990_JCLive_sf2_file', + '0990_SBLive_sf2', + '0990_SoundBlasterOld_sf2', + '0991_Aspirin_sf2_file', + '0991_FluidR3_GM_sf2_file', + '0991_GeneralUserGS_sf2_file', + '0991_JCLive_sf2_file', + '0991_SoundBlasterOld_sf2', + '0992_FluidR3_GM_sf2_file', + '0992_JCLive_sf2_file', + '0993_JCLive_sf2_file', + '0994_JCLive_sf2_file', + '1000_Aspirin_sf2_file', + '1000_Chaos_sf2_file', + '1000_FluidR3_GM_sf2_file', + '1000_GeneralUserGS_sf2_file', + '1000_JCLive_sf2_file', + '1000_SBLive_sf2', + '1000_SoundBlasterOld_sf2', + '1001_Aspirin_sf2_file', + '1001_FluidR3_GM_sf2_file', + '1001_GeneralUserGS_sf2_file', + '1001_JCLive_sf2_file', + '1001_SoundBlasterOld_sf2', + '1002_Aspirin_sf2_file', + '1002_FluidR3_GM_sf2_file', + '1002_GeneralUserGS_sf2_file', + '1010_Aspirin_sf2_file', + '1010_Chaos_sf2_file', + '1010_FluidR3_GM_sf2_file', + '1010_GeneralUserGS_sf2_file', + '1010_JCLive_sf2_file', + '1010_SBLive_sf2', + '1010_SoundBlasterOld_sf2', + '1011_Aspirin_sf2_file', + '1011_FluidR3_GM_sf2_file', + '1011_JCLive_sf2_file', + '1012_Aspirin_sf2_file', + '1020_Aspirin_sf2_file', + '1020_Chaos_sf2_file', + '1020_FluidR3_GM_sf2_file', + '1020_GeneralUserGS_sf2_file', + '1020_JCLive_sf2_file', + '1020_SBLive_sf2', + '1020_SoundBlasterOld_sf2', + '1021_Aspirin_sf2_file', + '1021_FluidR3_GM_sf2_file', + '1021_GeneralUserGS_sf2_file', + '1021_JCLive_sf2_file', + '1021_SoundBlasterOld_sf2', + '1022_GeneralUserGS_sf2_file', + '1030_Aspirin_sf2_file', + '1030_Chaos_sf2_file', + '1030_FluidR3_GM_sf2_file', + '1030_GeneralUserGS_sf2_file', + '1030_JCLive_sf2_file', + '1030_SBLive_sf2', + '1030_SoundBlasterOld_sf2', + '1031_Aspirin_sf2_file', + '1031_FluidR3_GM_sf2_file', + '1031_GeneralUserGS_sf2_file', + '1031_SoundBlasterOld_sf2', + '1032_FluidR3_GM_sf2_file', + '1040_Aspirin_sf2_file', + '1040_Chaos_sf2_file', + '1040_FluidR3_GM_sf2_file', + '1040_GeneralUserGS_sf2_file', + '1040_JCLive_sf2_file', + '1040_SBLive_sf2', + '1040_SoundBlasterOld_sf2', + '1041_FluidR3_GM_sf2_file', + '1041_GeneralUserGS_sf2_file', + '1050_Aspirin_sf2_file', + '1050_Chaos_sf2_file', + '1050_FluidR3_GM_sf2_file', + '1050_GeneralUserGS_sf2_file', + '1050_JCLive_sf2_file', + '1050_SBLive_sf2', + '1050_SoundBlasterOld_sf2', + '1051_GeneralUserGS_sf2_file', + '1060_Aspirin_sf2_file', + '1060_Chaos_sf2_file', + '1060_FluidR3_GM_sf2_file', + '1060_GeneralUserGS_sf2_file', + '1060_JCLive_sf2_file', + '1060_SBLive_sf2', + '1060_SoundBlasterOld_sf2', + '1061_FluidR3_GM_sf2_file', + '1061_GeneralUserGS_sf2_file', + '1061_SoundBlasterOld_sf2', + '1070_Aspirin_sf2_file', + '1070_Chaos_sf2_file', + '1070_FluidR3_GM_sf2_file', + '1070_GeneralUserGS_sf2_file', + '1070_JCLive_sf2_file', + '1070_SBLive_sf2', + '1070_SoundBlasterOld_sf2', + '1071_FluidR3_GM_sf2_file', + '1071_GeneralUserGS_sf2_file', + '1072_GeneralUserGS_sf2_file', + '1073_GeneralUserGS_sf2_file', + '1080_Aspirin_sf2_file', + '1080_Chaos_sf2_file', + '1080_FluidR3_GM_sf2_file', + '1080_GeneralUserGS_sf2_file', + '1080_JCLive_sf2_file', + '1080_SBLive_sf2', + '1080_SoundBlasterOld_sf2', + '1081_SoundBlasterOld_sf2', + '1090_Aspirin_sf2_file', + '1090_Chaos_sf2_file', + '1090_FluidR3_GM_sf2_file', + '1090_GeneralUserGS_sf2_file', + '1090_JCLive_sf2_file', + '1090_SBLive_sf2', + '1090_SoundBlasterOld_sf2', + '1091_SoundBlasterOld_sf2', + '1100_Aspirin_sf2_file', + '1100_Chaos_sf2_file', + '1100_FluidR3_GM_sf2_file', + '1100_GeneralUserGS_sf2_file', + '1100_JCLive_sf2_file', + '1100_SBLive_sf2', + '1100_SoundBlasterOld_sf2', + '1101_Aspirin_sf2_file', + '1101_FluidR3_GM_sf2_file', + '1101_GeneralUserGS_sf2_file', + '1102_GeneralUserGS_sf2_file', + '1110_Aspirin_sf2_file', + '1110_Chaos_sf2_file', + '1110_FluidR3_GM_sf2_file', + '1110_GeneralUserGS_sf2_file', + '1110_JCLive_sf2_file', + '1110_SBLive_sf2', + '1110_SoundBlasterOld_sf2', + '1120_Aspirin_sf2_file', + '1120_Chaos_sf2_file', + '1120_FluidR3_GM_sf2_file', + '1120_GeneralUserGS_sf2_file', + '1120_JCLive_sf2_file', + '1120_SBLive_sf2', + '1120_SoundBlasterOld_sf2', + '1121_SoundBlasterOld_sf2', + '1130_Aspirin_sf2_file', + '1130_Chaos_sf2_file', + '1130_FluidR3_GM_sf2_file', + '1130_GeneralUserGS_sf2_file', + '1130_JCLive_sf2_file', + '1130_SBLive_sf2', + '1130_SoundBlasterOld_sf2', + '1131_FluidR3_GM_sf2_file', + '1131_SoundBlasterOld_sf2', + '1140_Aspirin_sf2_file', + '1140_Chaos_sf2_file', + '1140_FluidR3_GM_sf2_file', + '1140_GeneralUserGS_sf2_file', + '1140_JCLive_sf2_file', + '1140_SBLive_sf2', + '1140_SoundBlasterOld_sf2', + '1141_FluidR3_GM_sf2_file', + '1150_Aspirin_sf2_file', + '1150_Chaos_sf2_file', + '1150_FluidR3_GM_sf2_file', + '1150_GeneralUserGS_sf2_file', + '1150_JCLive_sf2_file', + '1150_SBLive_sf2', + '1150_SoundBlasterOld_sf2', + '1151_FluidR3_GM_sf2_file', + '1151_GeneralUserGS_sf2_file', + '1152_FluidR3_GM_sf2_file', + '1152_GeneralUserGS_sf2_file', + '1160_Aspirin_sf2_file', + '1160_Chaos_sf2_file', + '1160_FluidR3_GM_sf2_file', + '1160_GeneralUserGS_sf2_file', + '1160_JCLive_sf2_file', + '1160_SBLive_sf2', + '1160_SoundBlasterOld_sf2', + '1161_FluidR3_GM_sf2_file', + '1161_GeneralUserGS_sf2_file', + '1161_SoundBlasterOld_sf2', + '1162_FluidR3_GM_sf2_file', + '1162_GeneralUserGS_sf2_file', + '1163_FluidR3_GM_sf2_file', + '1170_Aspirin_sf2_file', + '1170_Chaos_sf2_file', + '1170_FluidR3_GM_sf2_file', + '1170_GeneralUserGS_sf2_file', + '1170_JCLive_sf2_file', + '1170_SBLive_sf2', + '1170_SoundBlasterOld_sf2', + '1171_FluidR3_GM_sf2_file', + '1171_GeneralUserGS_sf2_file', + '1172_FluidR3_GM_sf2_file', + '1173_FluidR3_GM_sf2_file', + '1180_Aspirin_sf2_file', + '1180_Chaos_sf2_file', + '1180_FluidR3_GM_sf2_file', + '1180_GeneralUserGS_sf2_file', + '1180_JCLive_sf2_file', + '1180_SBLive_sf2', + '1180_SoundBlasterOld_sf2', + '1181_FluidR3_GM_sf2_file', + '1181_GeneralUserGS_sf2_file', + '1181_SoundBlasterOld_sf2', + '1190_Aspirin_sf2_file', + '1190_Chaos_sf2_file', + '1190_FluidR3_GM_sf2_file', + '1190_GeneralUserGS_sf2_file', + '1190_JCLive_sf2_file', + '1190_SBLive_sf2', + '1190_SoundBlasterOld_sf2', + '1191_GeneralUserGS_sf2_file', + '1192_GeneralUserGS_sf2_file', + '1193_GeneralUserGS_sf2_file', + '1194_GeneralUserGS_sf2_file', + '1200_Aspirin_sf2_file', + '1200_Chaos_sf2_file', + '1200_FluidR3_GM_sf2_file', + '1200_GeneralUserGS_sf2_file', + '1200_JCLive_sf2_file', + '1200_SBLive_sf2', + '1200_SoundBlasterOld_sf2', + '1201_Aspirin_sf2_file', + '1201_GeneralUserGS_sf2_file', + '1202_GeneralUserGS_sf2_file', + '1210_Aspirin_sf2_file', + '1210_Chaos_sf2_file', + '1210_FluidR3_GM_sf2_file', + '1210_GeneralUserGS_sf2_file', + '1210_JCLive_sf2_file', + '1210_SBLive_sf2', + '1210_SoundBlasterOld_sf2', + '1211_Aspirin_sf2_file', + '1211_GeneralUserGS_sf2_file', + '1212_GeneralUserGS_sf2_file', + '1220_Aspirin_sf2_file', + '1220_Chaos_sf2_file', + '1220_FluidR3_GM_sf2_file', + '1220_GeneralUserGS_sf2_file', + '1220_JCLive_sf2_file', + '1220_SBLive_sf2', + '1220_SoundBlasterOld_sf2', + '1221_Aspirin_sf2_file', + '1221_GeneralUserGS_sf2_file', + '1221_JCLive_sf2_file', + '1222_Aspirin_sf2_file', + '1222_GeneralUserGS_sf2_file', + '1223_Aspirin_sf2_file', + '1223_GeneralUserGS_sf2_file', + '1224_Aspirin_sf2_file', + '1224_GeneralUserGS_sf2_file', + '1225_GeneralUserGS_sf2_file', + '1226_GeneralUserGS_sf2_file', + '1230_Aspirin_sf2_file', + '1230_Chaos_sf2_file', + '1230_FluidR3_GM_sf2_file', + '1230_GeneralUserGS_sf2_file', + '1230_JCLive_sf2_file', + '1230_SBLive_sf2', + '1230_SoundBlasterOld_sf2', + '1231_Aspirin_sf2_file', + '1231_GeneralUserGS_sf2_file', + '1232_Aspirin_sf2_file', + '1232_GeneralUserGS_sf2_file', + '1233_GeneralUserGS_sf2_file', + '1234_GeneralUserGS_sf2_file', + '1240_Aspirin_sf2_file', + '1240_Chaos_sf2_file', + '1240_FluidR3_GM_sf2_file', + '1240_GeneralUserGS_sf2_file', + '1240_JCLive_sf2_file', + '1240_SBLive_sf2', + '1240_SoundBlasterOld_sf2', + '1241_Aspirin_sf2_file', + '1241_GeneralUserGS_sf2_file', + '1242_Aspirin_sf2_file', + '1242_GeneralUserGS_sf2_file', + '1243_Aspirin_sf2_file', + '1243_GeneralUserGS_sf2_file', + '1244_Aspirin_sf2_file', + '1244_GeneralUserGS_sf2_file', + '1250_Aspirin_sf2_file', + '1250_Chaos_sf2_file', + '1250_FluidR3_GM_sf2_file', + '1250_GeneralUserGS_sf2_file', + '1250_JCLive_sf2_file', + '1250_SBLive_sf2', + '1250_SoundBlasterOld_sf2', + '1251_Aspirin_sf2_file', + '1251_FluidR3_GM_sf2_file', + '1251_GeneralUserGS_sf2_file', + '1252_Aspirin_sf2_file', + '1252_FluidR3_GM_sf2_file', + '1252_GeneralUserGS_sf2_file', + '1253_Aspirin_sf2_file', + '1253_GeneralUserGS_sf2_file', + '1254_Aspirin_sf2_file', + '1254_GeneralUserGS_sf2_file', + '1255_Aspirin_sf2_file', + '1255_GeneralUserGS_sf2_file', + '1256_Aspirin_sf2_file', + '1256_GeneralUserGS_sf2_file', + '1257_Aspirin_sf2_file', + '1257_GeneralUserGS_sf2_file', + '1258_Aspirin_sf2_file', + '1258_GeneralUserGS_sf2_file', + '1259_GeneralUserGS_sf2_file', + '1260_Aspirin_sf2_file', + '1260_Chaos_sf2_file', + '1260_FluidR3_GM_sf2_file', + '1260_GeneralUserGS_sf2_file', + '1260_JCLive_sf2_file', + '1260_SBLive_sf2', + '1260_SoundBlasterOld_sf2', + '1261_Aspirin_sf2_file', + '1261_GeneralUserGS_sf2_file', + '1262_Aspirin_sf2_file', + '1262_GeneralUserGS_sf2_file', + '1263_Aspirin_sf2_file', + '1263_GeneralUserGS_sf2_file', + '1264_Aspirin_sf2_file', + '1264_GeneralUserGS_sf2_file', + '1265_Aspirin_sf2_file', + '1265_GeneralUserGS_sf2_file', + '1270_Aspirin_sf2_file', + '1270_Chaos_sf2_file', + '1270_FluidR3_GM_sf2_file', + '1270_GeneralUserGS_sf2_file', + '1270_JCLive_sf2_file', + '1270_SBLive_sf2', + '1270_SoundBlasterOld_sf2', + '1271_Aspirin_sf2_file', + '1271_GeneralUserGS_sf2_file', + '1272_Aspirin_sf2_file', + '1272_GeneralUserGS_sf2_file', + '1273_GeneralUserGS_sf2_file', + '1274_GeneralUserGS_sf2_file', +]; + +export const drums = [ + //'35_0_SBLive_sf2' + '35_0_Chaos_sf2_file', + '35_12_JCLive_sf2_file', + '35_16_JCLive_sf2_file', + '35_18_JCLive_sf2_file', + '35_4_Chaos_sf2_file', + '36_0_SBLive_sf2', + '36_12_JCLive_sf2_file', + '36_16_JCLive_sf2_file', + '36_18_JCLive_sf2_file', + '36_4_Chaos_sf2_file', + '37_0_SBLive_sf2', + '37_12_JCLive_sf2_file', + '37_16_JCLive_sf2_file', + '37_18_JCLive_sf2_file', + '37_4_Chaos_sf2_file', + '38_0_SBLive_sf2', + '38_12_JCLive_sf2_file', + '38_16_JCLive_sf2_file', + '38_18_JCLive_sf2_file', + '38_4_Chaos_sf2_file', + '39_0_SBLive_sf2', + '39_12_JCLive_sf2_file', + '39_16_JCLive_sf2_file', + '39_18_JCLive_sf2_file', + '39_4_Chaos_sf2_file', + '40_0_SBLive_sf2', + '40_12_JCLive_sf2_file', + '40_16_JCLive_sf2_file', + '40_18_JCLive_sf2_file', + '40_4_Chaos_sf2_file', + '41_0_SBLive_sf2', + '41_12_JCLive_sf2_file', + '41_16_JCLive_sf2_file', + '41_18_JCLive_sf2_file', + '41_4_Chaos_sf2_file', + '42_0_SBLive_sf2', + '42_12_JCLive_sf2_file', + '42_16_JCLive_sf2_file', + '42_18_JCLive_sf2_file', + '42_4_Chaos_sf2_file', + '43_0_SBLive_sf2', + '43_12_JCLive_sf2_file', + '43_16_JCLive_sf2_file', + '43_18_JCLive_sf2_file', + '43_4_Chaos_sf2_file', + '44_0_SBLive_sf2', + '44_12_JCLive_sf2_file', + '44_16_JCLive_sf2_file', + '44_18_JCLive_sf2_file', + '44_4_Chaos_sf2_file', + '45_0_SBLive_sf2', + '45_12_JCLive_sf2_file', + '45_16_JCLive_sf2_file', + '45_18_JCLive_sf2_file', + '45_4_Chaos_sf2_file', + '46_0_SBLive_sf2', + '46_12_JCLive_sf2_file', + '46_16_JCLive_sf2_file', + '46_18_JCLive_sf2_file', + '46_4_Chaos_sf2_file', + '47_0_SBLive_sf2', + '47_12_JCLive_sf2_file', + '47_16_JCLive_sf2_file', + '47_18_JCLive_sf2_file', + '47_4_Chaos_sf2_file', + '48_0_SBLive_sf2', + '48_12_JCLive_sf2_file', + '48_16_JCLive_sf2_file', + '48_18_JCLive_sf2_file', + '48_4_Chaos_sf2_file', + '49_0_SBLive_sf2', + '49_12_JCLive_sf2_file', + '49_16_JCLive_sf2_file', + '49_18_JCLive_sf2_file', + '49_4_Chaos_sf2_file', + '50_0_SBLive_sf2', + '50_12_JCLive_sf2_file', + '50_16_JCLive_sf2_file', + '50_18_JCLive_sf2_file', + '50_4_Chaos_sf2_file', + '51_0_SBLive_sf2', + '51_12_JCLive_sf2_file', + '51_16_JCLive_sf2_file', + '51_18_JCLive_sf2_file', + '51_4_Chaos_sf2_file', + '52_0_SBLive_sf2', + '52_12_JCLive_sf2_file', + '52_16_JCLive_sf2_file', + '52_18_JCLive_sf2_file', + '52_4_Chaos_sf2_file', + '53_0_SBLive_sf2', + '53_12_JCLive_sf2_file', + '53_16_JCLive_sf2_file', + '53_18_JCLive_sf2_file', + '53_4_Chaos_sf2_file', + '54_0_SBLive_sf2', + '54_12_JCLive_sf2_file', + '54_16_JCLive_sf2_file', + '54_18_JCLive_sf2_file', + '54_4_Chaos_sf2_file', + '55_0_SBLive_sf2', + '55_12_JCLive_sf2_file', + '55_16_JCLive_sf2_file', + '55_18_JCLive_sf2_file', + '55_4_Chaos_sf2_file', + '56_0_SBLive_sf2', + '56_12_JCLive_sf2_file', + '56_16_JCLive_sf2_file', + '56_18_JCLive_sf2_file', + '56_4_Chaos_sf2_file', + '57_0_SBLive_sf2', + '57_12_JCLive_sf2_file', + '57_16_JCLive_sf2_file', + '57_18_JCLive_sf2_file', + '57_4_Chaos_sf2_file', + '58_0_SBLive_sf2', + '58_12_JCLive_sf2_file', + '58_16_JCLive_sf2_file', + '58_18_JCLive_sf2_file', + '58_4_Chaos_sf2_file', + '59_0_SBLive_sf2', + '59_12_JCLive_sf2_file', + '59_16_JCLive_sf2_file', + '59_18_JCLive_sf2_file', + '59_4_Chaos_sf2_file', + '60_0_SBLive_sf2', + '60_12_JCLive_sf2_file', + '60_16_JCLive_sf2_file', + '60_18_JCLive_sf2_file', + '60_4_Chaos_sf2_file', + '61_0_SBLive_sf2', + '61_12_JCLive_sf2_file', + '61_16_JCLive_sf2_file', + '61_18_JCLive_sf2_file', + '61_4_Chaos_sf2_file', + '62_0_SBLive_sf2', + '62_12_JCLive_sf2_file', + '62_16_JCLive_sf2_file', + '62_18_JCLive_sf2_file', + '62_4_Chaos_sf2_file', + '63_0_SBLive_sf2', + '63_12_JCLive_sf2_file', + '63_16_JCLive_sf2_file', + '63_18_JCLive_sf2_file', + '63_4_Chaos_sf2_file', + '64_0_SBLive_sf2', + '64_12_JCLive_sf2_file', + '64_16_JCLive_sf2_file', + '64_18_JCLive_sf2_file', + '64_4_Chaos_sf2_file', + '65_0_SBLive_sf2', + '65_12_JCLive_sf2_file', + '65_16_JCLive_sf2_file', + '65_18_JCLive_sf2_file', + '65_4_Chaos_sf2_file', + '66_0_SBLive_sf2', + '66_12_JCLive_sf2_file', + '66_16_JCLive_sf2_file', + '66_18_JCLive_sf2_file', + '66_4_Chaos_sf2_file', + '67_0_SBLive_sf2', + '67_12_JCLive_sf2_file', + '67_16_JCLive_sf2_file', + '67_18_JCLive_sf2_file', + '67_4_Chaos_sf2_file', + '68_0_SBLive_sf2', + '68_12_JCLive_sf2_file', + '68_16_JCLive_sf2_file', + '68_18_JCLive_sf2_file', + '68_4_Chaos_sf2_file', + '69_0_SBLive_sf2', + '69_12_JCLive_sf2_file', + '69_16_JCLive_sf2_file', + '69_18_JCLive_sf2_file', + '69_4_Chaos_sf2_file', + '70_0_SBLive_sf2', + '70_12_JCLive_sf2_file', + '70_16_JCLive_sf2_file', + '70_18_JCLive_sf2_file', + '70_4_Chaos_sf2_file', + '71_0_SBLive_sf2', + '71_12_JCLive_sf2_file', + '71_16_JCLive_sf2_file', + '71_18_JCLive_sf2_file', + '71_4_Chaos_sf2_file', + '72_0_SBLive_sf2', + '72_12_JCLive_sf2_file', + '72_16_JCLive_sf2_file', + '72_18_JCLive_sf2_file', + '72_4_Chaos_sf2_file', + '73_0_SBLive_sf2', + '73_12_JCLive_sf2_file', + '73_16_JCLive_sf2_file', + '73_18_JCLive_sf2_file', + '73_4_Chaos_sf2_file', + '74_0_SBLive_sf2', + '74_12_JCLive_sf2_file', + '74_16_JCLive_sf2_file', + '74_18_JCLive_sf2_file', + '74_4_Chaos_sf2_file', + '75_0_SBLive_sf2', + '75_12_JCLive_sf2_file', + '75_16_JCLive_sf2_file', + '75_18_JCLive_sf2_file', + '75_4_Chaos_sf2_file', + '76_0_SBLive_sf2', + '76_12_JCLive_sf2_file', + '76_16_JCLive_sf2_file', + '76_18_JCLive_sf2_file', + '76_4_Chaos_sf2_file', + '77_0_SBLive_sf2', + '77_12_JCLive_sf2_file', + '77_16_JCLive_sf2_file', + '77_18_JCLive_sf2_file', + '77_4_Chaos_sf2_file', + '78_0_SBLive_sf2', + '78_12_JCLive_sf2_file', + '78_16_JCLive_sf2_file', + '78_18_JCLive_sf2_file', + '78_4_Chaos_sf2_file', + '79_0_SBLive_sf2', + '79_12_JCLive_sf2_file', + '79_16_JCLive_sf2_file', + '79_18_JCLive_sf2_file', + '79_4_Chaos_sf2_file', + '80_0_SBLive_sf2', + '80_12_JCLive_sf2_file', + '80_16_JCLive_sf2_file', + '80_18_JCLive_sf2_file', + '80_4_Chaos_sf2_file', + '81_0_SBLive_sf2', + '81_12_JCLive_sf2_file', + '81_16_JCLive_sf2_file', + '81_18_JCLive_sf2_file', + '81_4_Chaos_sf2_file', +]; + +// see https://www.midi.org/specifications-old/item/gm-level-1-sound-set +export const instrumentNames = []; +instrumentNames[0] = 'Acoustic Grand Piano: Piano'; +instrumentNames[1] = 'Bright Acoustic Piano: Piano'; +instrumentNames[2] = 'Electric Grand Piano: Piano'; +instrumentNames[3] = 'Honky-tonk Piano: Piano'; +instrumentNames[4] = 'Electric Piano 1: Piano'; +instrumentNames[5] = 'Electric Piano 2: Piano'; +instrumentNames[6] = 'Harpsichord: Piano'; +instrumentNames[7] = 'Clavinet: Piano'; +instrumentNames[8] = 'Celesta: Chromatic Percussion'; +instrumentNames[9] = 'Glockenspiel: Chromatic Percussion'; +instrumentNames[10] = 'Music Box: Chromatic Percussion'; +instrumentNames[11] = 'Vibraphone: Chromatic Percussion'; +instrumentNames[12] = 'Marimba: Chromatic Percussion'; +instrumentNames[13] = 'Xylophone: Chromatic Percussion'; +instrumentNames[14] = 'Tubular Bells: Chromatic Percussion'; +instrumentNames[15] = 'Dulcimer: Chromatic Percussion'; +instrumentNames[16] = 'Drawbar Organ: Organ'; +instrumentNames[17] = 'Percussive Organ: Organ'; +instrumentNames[18] = 'Rock Organ: Organ'; +instrumentNames[19] = 'Church Organ: Organ'; +instrumentNames[20] = 'Reed Organ: Organ'; +instrumentNames[21] = 'Accordion: Organ'; +instrumentNames[22] = 'Harmonica: Organ'; +instrumentNames[23] = 'Tango Accordion: Organ'; +instrumentNames[24] = 'Acoustic Guitar (nylon): Guitar'; +instrumentNames[25] = 'Acoustic Guitar (steel): Guitar'; +instrumentNames[26] = 'Electric Guitar (jazz): Guitar'; +instrumentNames[27] = 'Electric Guitar (clean): Guitar'; +instrumentNames[28] = 'Electric Guitar (muted): Guitar'; +instrumentNames[29] = 'Overdriven Guitar: Guitar'; +instrumentNames[30] = 'Distortion Guitar: Guitar'; +instrumentNames[31] = 'Guitar Harmonics: Guitar'; +instrumentNames[32] = 'Acoustic Bass: Bass'; +instrumentNames[33] = 'Electric Bass (finger): Bass'; +instrumentNames[34] = 'Electric Bass (pick): Bass'; +instrumentNames[35] = 'Fretless Bass: Bass'; +instrumentNames[36] = 'Slap Bass 1: Bass'; +instrumentNames[37] = 'Slap Bass 2: Bass'; +instrumentNames[38] = 'Synth Bass 1: Bass'; +instrumentNames[39] = 'Synth Bass 2: Bass'; +instrumentNames[40] = 'Violin: Strings'; +instrumentNames[41] = 'Viola: Strings'; +instrumentNames[42] = 'Cello: Strings'; +instrumentNames[43] = 'Contrabass: Strings'; +instrumentNames[44] = 'Tremolo Strings: Strings'; +instrumentNames[45] = 'Pizzicato Strings: Strings'; +instrumentNames[46] = 'Orchestral Harp: Strings'; +instrumentNames[47] = 'Timpani: Strings'; +instrumentNames[48] = 'String Ensemble 1: Ensemble'; +instrumentNames[49] = 'String Ensemble 2: Ensemble'; +instrumentNames[50] = 'Synth Strings 1: Ensemble'; +instrumentNames[51] = 'Synth Strings 2: Ensemble'; +instrumentNames[52] = 'Choir Aahs: Ensemble'; +instrumentNames[53] = 'Voice Oohs: Ensemble'; +instrumentNames[54] = 'Synth Choir: Ensemble'; +instrumentNames[55] = 'Orchestra Hit: Ensemble'; +instrumentNames[56] = 'Trumpet: Brass'; +instrumentNames[57] = 'Trombone: Brass'; +instrumentNames[58] = 'Tuba: Brass'; +instrumentNames[59] = 'Muted Trumpet: Brass'; +instrumentNames[60] = 'French Horn: Brass'; +instrumentNames[61] = 'Brass Section: Brass'; +instrumentNames[62] = 'Synth Brass 1: Brass'; +instrumentNames[63] = 'Synth Brass 2: Brass'; +instrumentNames[64] = 'Soprano Sax: Reed'; +instrumentNames[65] = 'Alto Sax: Reed'; +instrumentNames[66] = 'Tenor Sax: Reed'; +instrumentNames[67] = 'Baritone Sax: Reed'; +instrumentNames[68] = 'Oboe: Reed'; +instrumentNames[69] = 'English Horn: Reed'; +instrumentNames[70] = 'Bassoon: Reed'; +instrumentNames[71] = 'Clarinet: Reed'; +instrumentNames[72] = 'Piccolo: Pipe'; +instrumentNames[73] = 'Flute: Pipe'; +instrumentNames[74] = 'Recorder: Pipe'; +instrumentNames[75] = 'Pan Flute: Pipe'; +instrumentNames[76] = 'Blown bottle: Pipe'; +instrumentNames[77] = 'Shakuhachi: Pipe'; +instrumentNames[78] = 'Whistle: Pipe'; +instrumentNames[79] = 'Ocarina: Pipe'; +instrumentNames[80] = 'Lead 1 (square): Synth Lead'; +instrumentNames[81] = 'Lead 2 (sawtooth): Synth Lead'; +instrumentNames[82] = 'Lead 3 (calliope): Synth Lead'; +instrumentNames[83] = 'Lead 4 (chiff): Synth Lead'; +instrumentNames[84] = 'Lead 5 (charang): Synth Lead'; +instrumentNames[85] = 'Lead 6 (voice): Synth Lead'; +instrumentNames[86] = 'Lead 7 (fifths): Synth Lead'; +instrumentNames[87] = 'Lead 8 (bass + lead): Synth Lead'; +instrumentNames[88] = 'Pad 1 (new age): Synth Pad'; +instrumentNames[89] = 'Pad 2 (warm): Synth Pad'; +instrumentNames[90] = 'Pad 3 (polysynth): Synth Pad'; +instrumentNames[91] = 'Pad 4 (choir): Synth Pad'; +instrumentNames[92] = 'Pad 5 (bowed): Synth Pad'; +instrumentNames[93] = 'Pad 6 (metallic): Synth Pad'; +instrumentNames[94] = 'Pad 7 (halo): Synth Pad'; +instrumentNames[95] = 'Pad 8 (sweep): Synth Pad'; +instrumentNames[96] = 'FX 1 (rain): Synth Effects'; +instrumentNames[97] = 'FX 2 (soundtrack): Synth Effects'; +instrumentNames[98] = 'FX 3 (crystal): Synth Effects'; +instrumentNames[99] = 'FX 4 (atmosphere): Synth Effects'; +instrumentNames[100] = 'FX 5 (brightness): Synth Effects'; +instrumentNames[101] = 'FX 6 (goblins): Synth Effects'; +instrumentNames[102] = 'FX 7 (echoes): Synth Effects'; +instrumentNames[103] = 'FX 8 (sci-fi): Synth Effects'; +instrumentNames[104] = 'Sitar: Ethnic'; +instrumentNames[105] = 'Banjo: Ethnic'; +instrumentNames[106] = 'Shamisen: Ethnic'; +instrumentNames[107] = 'Koto: Ethnic'; +instrumentNames[108] = 'Kalimba: Ethnic'; +instrumentNames[109] = 'Bagpipe: Ethnic'; +instrumentNames[110] = 'Fiddle: Ethnic'; +instrumentNames[111] = 'Shanai: Ethnic'; +instrumentNames[112] = 'Tinkle Bell: Percussive'; +instrumentNames[113] = 'Agogo: Percussive'; +instrumentNames[114] = 'Steel Drums: Percussive'; +instrumentNames[115] = 'Woodblock: Percussive'; +instrumentNames[116] = 'Taiko Drum: Percussive'; +instrumentNames[117] = 'Melodic Tom: Percussive'; +instrumentNames[118] = 'Synth Drum: Percussive'; +instrumentNames[119] = 'Reverse Cymbal: Percussive'; +instrumentNames[120] = 'Guitar Fret Noise: Sound effects'; +instrumentNames[121] = 'Breath Noise: Sound effects'; +instrumentNames[122] = 'Seashore: Sound effects'; +instrumentNames[123] = 'Bird Tweet: Sound effects'; +instrumentNames[124] = 'Telephone Ring: Sound effects'; +instrumentNames[125] = 'Helicopter: Sound effects'; +instrumentNames[126] = 'Applause: Sound effects'; +instrumentNames[127] = 'Gunshot: Sound effects'; diff --git a/packages/soundfonts/package.json b/packages/soundfonts/package.json index accb43e5..bf4f7527 100644 --- a/packages/soundfonts/package.json +++ b/packages/soundfonts/package.json @@ -6,6 +6,7 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, + "type": "module", "repository": { "type": "git", "url": "git+https://github.com/tidalcycles/strudel.git" @@ -24,8 +25,10 @@ }, "homepage": "https://github.com/tidalcycles/strudel#readme", "dependencies": { - "webaudiofont": "^3.0.1", "@strudel.cycles/core": "*", "@strudel.cycles/webaudio": "*" + }, + "devDependencies": { + "node-fetch": "^3.2.6" } } diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 77d7e235..bdd38bbc 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -39,6 +39,54 @@ const getADSR = (attack, decay, sustain, release, velocity, begin, end) => { return gainNode; }; +const getOscillator = ({ s, freq, t, duration, release }) => { + // make oscillator + const o = getAudioContext().createOscillator(); + o.type = s || 'triangle'; + o.frequency.value = Number(freq); + o.start(t); + o.stop(t + duration + release); + return o; +}; + +const getSoundfontKey = (s) => { + if (!globalThis.soundfontList) { + // soundfont package not loaded + return false; + } + if (globalThis.soundfontList?.instruments?.includes(s)) { + return s; + } + // check if s is one of the soundfonts, which are loaded into globalThis, to avoid coupling both packages + const nameIndex = globalThis.soundfontList?.instrumentNames?.indexOf(s); + // convert number nameIndex (0-128) to 3 digit string (001-128) + const name = nameIndex < 10 ? `00${nameIndex}` : nameIndex < 100 ? `0${nameIndex}` : nameIndex; + if (nameIndex !== -1) { + // TODO: indices of instrumentNames do not seem to match instruments + s = globalThis.soundfontList.instruments.find((instrument) => instrument.startsWith(name)); + // console.log('match', nameIndex, s); + } + return globalThis.soundfontList?.instruments?.[nameIndex]; +}; + +const getSampleBufferSource = async (s, n) => { + const ac = getAudioContext(); + // is sample from loaded samples(..) + const samples = getLoadedSamples(); + if (!samples) { + throw new Error('no samples loaded'); + } + const bank = samples?.[s]; + if (!bank) { + throw new Error('sample not found:', s, 'try one of ' + Object.keys(samples)); + } + const sampleUrl = bank[n % bank.length]; + const buffer = await loadBuffer(sampleUrl, ac); + const bufferSource = ac.createBufferSource(); + bufferSource.buffer = buffer; + return bufferSource; +}; + Pattern.prototype.out = function () { return this.onTrigger(async (t, hap, ct) => { const ac = getAudioContext(); @@ -48,6 +96,7 @@ Pattern.prototype.out = function () { let { freq, s, + sf, n = 0, gain = 1, cutoff, @@ -67,20 +116,16 @@ Pattern.prototype.out = function () { } = hap.value; // the chain will hold all audio nodes that connect to each other const chain = []; + if (typeof n === 'string') { + n = toMidi(n); // e.g. c3 => 48 + } if (!s || ['sine', 'square', 'triangle', 'sawtooth'].includes(s)) { // get frequency if (!freq && typeof n === 'number') { freq = fromMidi(n); // + 48); } - if (!freq && typeof n === 'string') { - freq = fromMidi(toMidi(n)); - } // make oscillator - const o = ac.createOscillator(); - o.type = s || 'triangle'; - o.frequency.value = Number(freq); - o.start(t); - o.stop(t + hap.duration + release); + const o = getOscillator({ t, s, freq, duration: hap.duration, release }); chain.push(o); // level down oscillators as they are really loud compared to samples i've tested const g = ac.createGain(); @@ -92,42 +137,57 @@ Pattern.prototype.out = function () { chain.push(adsr); } else { // load sample - const samples = getLoadedSamples(); - if (!samples) { - console.warn('no samples loaded'); + if (speed === 0) { + // no playback return; } - const bank = samples?.[s]; - if (!bank) { - console.warn('sample not found:', s, 'try one of ' + Object.keys(samples)); + if (!s) { + console.warn('no sample specified'); return; - } else { - if (speed === 0) { - // no playback - return; - } - if (!s) { - console.warn('no sample specified'); - return; - } - const bank = samples[s]; - const sampleUrl = bank[n % bank.length]; - let buffer = await loadBuffer(sampleUrl, ac); - if (ac.currentTime > t) { - console.warn('sample still loading:', s, n); - return; - } - const src = ac.createBufferSource(); - src.buffer = buffer; - src.playbackRate.value = Math.abs(speed); - // TODO: nudge, unit, cut, loop + } + const soundfont = getSoundfontKey(s); + let bufferSource; - let duration = src.buffer.duration; - const offset = begin * duration; - duration = ((end - begin) * duration) / Math.abs(speed); - src.start(t, offset, duration); - src.stop(t + duration); - chain.push(src); + try { + if (soundfont) { + // is soundfont + bufferSource = await globalThis.getFontBufferSource(soundfont, n, ac); + } else { + // is sample from loaded samples(..) + bufferSource = await getSampleBufferSource(s, n); + } + } catch (err) { + console.warn(err); + return; + } + // asny stuff above took too long? + if (ac.currentTime > t) { + console.warn('sample still loading:', s, n); + return; + } + if (!bufferSource) { + console.warn('no buffer source'); + return; + } + // bufferSource.playbackRate.value = Math.abs(speed) * playbackRate; + bufferSource.playbackRate.value = Math.abs(speed) * bufferSource.playbackRate.value; + // TODO: nudge, unit, cut, loop + + let duration = soundfont ? hap.duration : bufferSource.buffer.duration; + // let duration = bufferSource.buffer.duration; + const offset = begin * duration; + duration = ((end - begin) * duration) / Math.abs(speed); + bufferSource.start(t, offset, duration); + bufferSource.stop(t + duration); + chain.push(bufferSource); + if (soundfont) { + const env = ac.createGain(); + env.gain.value = 1; + const fadeLength = 0.1; + env.gain.value = 0.5; + env.gain.setValueAtTime(0.5, t + duration - fadeLength); + env.gain.linearRampToValueAtTime(0, t + duration); + chain.push(env); } } // filters From d5938a016c46c20c426d23504eddd908292c3155 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 20 Jun 2022 20:55:20 +0200 Subject: [PATCH 3/5] fix looping fonts --- packages/soundfonts/fontloader.mjs | 53 ++++++++++++++------------ packages/soundfonts/package.json | 3 -- packages/webaudio/webaudio.mjs | 13 ++++--- repl/src/tunes.mjs | 61 ++++++++++++++++++++++++++++++ repl/src/tunes.snapshot.mjs | 1 + 5 files changed, 97 insertions(+), 34 deletions(-) diff --git a/packages/soundfonts/fontloader.mjs b/packages/soundfonts/fontloader.mjs index 09841780..953c2695 100644 --- a/packages/soundfonts/fontloader.mjs +++ b/packages/soundfonts/fontloader.mjs @@ -15,11 +15,35 @@ async function loadFont(name) { return loadCache[name]; } -let bufferCache = {}; export async function getFontBufferSource(name, pitch, ac) { + const { buffer, zone } = await getFontPitch(name, pitch, ac); + const src = ac.createBufferSource(); + src.buffer = buffer; + const baseDetune = zone.originalPitch - 100.0 * zone.coarseTune - zone.fineTune; + const playbackRate = 1.0 * Math.pow(2, (100.0 * pitch - baseDetune) / 1200.0); + // src detune? + src.playbackRate.value = playbackRate; + const loop = zone.loopStart > 1 && zone.loopStart < zone.loopEnd; + if (!loop) { + /* const waveDuration = duration + this.afterTime; + if (waveDuration > zone.buffer.duration / playbackRate) { + waveDuration = zone.buffer.duration / playbackRate; + // TODO: do sth with waveduration + } */ + } else { + src.loop = true; + src.loopStart = zone.loopStart / zone.sampleRate; + src.loopEnd = zone.loopEnd / zone.sampleRate; + //+ (zone.delay ? zone.delay : 0); + } + return src; +} + +let bufferCache = {}; +export async function getFontPitch(name, pitch, ac) { const key = `${name}:::${pitch}`; if (bufferCache[key]) { - return (await bufferCache[key])(); + return bufferCache[key]; } // console.log('load buffer', key); const load = async () => { @@ -35,31 +59,10 @@ export async function getFontBufferSource(name, pitch, ac) { if (!buffer) { throw new Error(`no soundfont buffer found for preset ${name}, pitch: ${pitch}`); } - return () => { - const src = ac.createBufferSource(); - src.buffer = buffer; - const baseDetune = zone.originalPitch - 100.0 * zone.coarseTune - zone.fineTune; - const playbackRate = 1.0 * Math.pow(2, (100.0 * pitch - baseDetune) / 1200.0); - // src detune? - src.playbackRate.value = playbackRate; - const loop = zone.loopStart > 1 && zone.loopStart < zone.loopEnd; - if (!loop) { - /* const waveDuration = duration + this.afterTime; - if (waveDuration > zone.buffer.duration / playbackRate) { - waveDuration = zone.buffer.duration / playbackRate; - // TODO: do sth with waveduration - } */ - } else { - src.loop = true; - /* src.loopStart = zone.loopStart / zone.sampleRate + (zone.delay ? zone.delay : 0); - src.loopEnd = zone.loopEnd / zone.sampleRate + (zone.delay ? zone.delay : 0); */ - } - - return src; - }; + return { buffer, zone }; }; bufferCache[key] = load(); // dont await here to cache promise immediately! - return (await bufferCache[key])(); + return bufferCache[key]; } function findZone(preset, pitch) { diff --git a/packages/soundfonts/package.json b/packages/soundfonts/package.json index bf4f7527..33c032ac 100644 --- a/packages/soundfonts/package.json +++ b/packages/soundfonts/package.json @@ -3,9 +3,6 @@ "version": "0.1.0", "description": "Soundsfont support for strudel", "main": "index.mjs", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, "type": "module", "repository": { "type": "git", diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index bdd38bbc..fea9df25 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -63,10 +63,9 @@ const getSoundfontKey = (s) => { const name = nameIndex < 10 ? `00${nameIndex}` : nameIndex < 100 ? `0${nameIndex}` : nameIndex; if (nameIndex !== -1) { // TODO: indices of instrumentNames do not seem to match instruments - s = globalThis.soundfontList.instruments.find((instrument) => instrument.startsWith(name)); - // console.log('match', nameIndex, s); + return globalThis.soundfontList.instruments.find((instrument) => instrument.startsWith(name)); } - return globalThis.soundfontList?.instruments?.[nameIndex]; + return; }; const getSampleBufferSource = async (s, n) => { @@ -169,15 +168,17 @@ Pattern.prototype.out = function () { console.warn('no buffer source'); return; } - // bufferSource.playbackRate.value = Math.abs(speed) * playbackRate; bufferSource.playbackRate.value = Math.abs(speed) * bufferSource.playbackRate.value; // TODO: nudge, unit, cut, loop - let duration = soundfont ? hap.duration : bufferSource.buffer.duration; // let duration = bufferSource.buffer.duration; const offset = begin * duration; duration = ((end - begin) * duration) / Math.abs(speed); - bufferSource.start(t, offset, duration); + if (soundfont) { + bufferSource.start(t, offset); // duration does not work here for some reason + } else { + bufferSource.start(t, offset, duration); + } bufferSource.stop(t + duration); chain.push(bufferSource); if (soundfont) { diff --git a/repl/src/tunes.mjs b/repl/src/tunes.mjs index 6bfa3b84..60663078 100644 --- a/repl/src/tunes.mjs +++ b/repl/src/tunes.mjs @@ -906,3 +906,64 @@ stack( ) .out() .slow(3/2)`; + +export const swimmingWithSoundfonts = `stack( + n( + "~", + "~", + "~", + "A5 [F5@2 C5] [D5@2 F5] F5", + "[C5@2 F5] [F5@2 C6] A5 G5", + "A5 [F5@2 C5] [D5@2 F5] F5", + "[C5@2 F5] [Bb5 A5 G5] F5@2", + "A5 [F5@2 C5] [D5@2 F5] F5", + "[C5@2 F5] [F5@2 C6] A5 G5", + "A5 [F5@2 C5] [D5@2 F5] F5", + "[C5@2 F5] [Bb5 A5 G5] F5@2", + "A5 [F5@2 C5] A5 F5", + "Ab5 [F5@2 Ab5] G5@2", + "A5 [F5@2 C5] A5 F5", + "Ab5 [F5@2 C5] C6@2", + "A5 [F5@2 C5] [D5@2 F5] F5", + "[C5@2 F5] [Bb5 A5 G5] F5@2" + ).s('Sitar: Ethnic'), + n( + "[F4,Bb4,D5] [[D4,G4,Bb4]@2 [Bb3,D4,F4]] [[G3,C4,E4]@2 [[Ab3,F4] [A3,Gb4]]] [Bb3,E4,G4]", + "[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, Bb3, Db3] [F3, Bb3, Db3]]", + "[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]", + "[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]", + "[~ [A3, C4, E4] [A3, C4, E4]] [~ [Ab3, C4, Eb4] [Ab3, C4, Eb4]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [G3, C4, E4] [G3, C4, E4]]", + "[~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]", + "[~ [F3, Bb3, D4] [F3, Bb3, D4]] [~ [F3, Bb3, C4] [F3, Bb3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]]", + "[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]", + "[~ [A3, C4, E4] [A3, C4, E4]] [~ [Ab3, C4, Eb4] [Ab3, C4, Eb4]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [G3, C4, E4] [G3, C4, E4]]", + "[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]", + "[~ [F3, Bb3, D4] [F3, Bb3, D4]] [~ [F3, Bb3, C4] [F3, Bb3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]]", + "[~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [A3, C4, F4] [A3, C4, F4]] [~ [A3, C4, F4] [A3, C4, F4]]", + "[~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [G3, Bb3, F4] [G3, Bb3, F4]] [~ [G3, Bb3, E4] [G3, Bb3, E4]]", + "[~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [A3, C4, F4] [A3, C4, F4]] [~ [A3, C4, F4] [A3, C4, F4]]", + "[~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [G3, Bb3, F4] [G3, Bb3, F4]] [~ [G3, Bb3, E4] [G3, Bb3, E4]]", + "[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]", + "[~ [F3, Bb3, D4] [F3, Bb3, D4]] [~ [F3, Bb3, C4] [F3, Bb3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]]" + ).s('Kalimba: Ethnic'), + n( + "[G3 G3 C3 E3]", + "[F2 D2 G2 C2]", + "[F2 D2 G2 C2]", + "[F2 A2 Bb2 B2]", + "[A2 Ab2 G2 C2]", + "[F2 A2 Bb2 B2]", + "[G2 C2 F2 F2]", + "[F2 A2 Bb2 B2]", + "[A2 Ab2 G2 C2]", + "[F2 A2 Bb2 B2]", + "[G2 C2 F2 F2]", + "[Bb2 Bb2 A2 A2]", + "[Ab2 Ab2 G2 [C2 D2 E2]]", + "[Bb2 Bb2 A2 A2]", + "[Ab2 Ab2 G2 [C2 D2 E2]]", + "[F2 A2 Bb2 B2]", + "[G2 C2 F2 F2]" + ).s('Acoustic Bass: Bass') + ).slow(51) + .out()`; diff --git a/repl/src/tunes.snapshot.mjs b/repl/src/tunes.snapshot.mjs index ec5a9e98..e4c309fb 100644 --- a/repl/src/tunes.snapshot.mjs +++ b/repl/src/tunes.snapshot.mjs @@ -16,6 +16,7 @@ export const sowhatelse = ["-1666666666666667/7500000000000000 -> 2/9: G3","0/1 export const speakerman = ["-18/5 -> 2/5: c3","-18/5 -> 2/5: e3","-18/5 -> 2/5: g3","2/5 -> 12/5: g3","2/5 -> 12/5: bb3","2/5 -> 12/5: d4","0/1 -> 4/1: Baker man","2/5 -> 12/5: g3","2/5 -> 12/5: bb3","2/5 -> 12/5: d4","0/1 -> 4/1: Baker man","2/5 -> 12/5: g3","2/5 -> 12/5: bb3","2/5 -> 12/5: d4","12/5 -> 22/5: f3","12/5 -> 22/5: a3","12/5 -> 22/5: c4","0/1 -> 4/1: Baker man","12/5 -> 22/5: f3","12/5 -> 22/5: a3","12/5 -> 22/5: c4","0/1 -> 4/1: Baker man","12/5 -> 22/5: f3","12/5 -> 22/5: a3","12/5 -> 22/5: c4","22/5 -> 42/5: c3","22/5 -> 42/5: e3","22/5 -> 42/5: g3","4/1 -> 8/1: is baking bread","22/5 -> 42/5: c3","22/5 -> 42/5: e3","22/5 -> 42/5: g3","4/1 -> 8/1: is baking bread","22/5 -> 42/5: c3","22/5 -> 42/5: e3","22/5 -> 42/5: g3","4/1 -> 8/1: is baking bread","22/5 -> 42/5: c3","22/5 -> 42/5: e3","22/5 -> 42/5: g3","4/1 -> 8/1: is baking bread","22/5 -> 42/5: c3","22/5 -> 42/5: e3","22/5 -> 42/5: g3","42/5 -> 52/5: g3","42/5 -> 52/5: bb3","42/5 -> 52/5: d4","8/1 -> 12/1: Baker man","42/5 -> 52/5: g3","42/5 -> 52/5: bb3","42/5 -> 52/5: d4","8/1 -> 12/1: Baker man","42/5 -> 52/5: g3","42/5 -> 52/5: bb3","42/5 -> 52/5: d4","52/5 -> 62/5: f3","52/5 -> 62/5: a3","52/5 -> 62/5: c4","8/1 -> 12/1: Baker man","52/5 -> 62/5: f3","52/5 -> 62/5: a3","52/5 -> 62/5: c4","8/1 -> 12/1: Baker man","52/5 -> 62/5: f3","52/5 -> 62/5: a3","52/5 -> 62/5: c4","62/5 -> 82/5: c3","62/5 -> 82/5: e3","62/5 -> 82/5: g3","12/1 -> 16/1: is baking bread","62/5 -> 82/5: c3","62/5 -> 82/5: e3","62/5 -> 82/5: g3","12/1 -> 16/1: is baking bread","62/5 -> 82/5: c3","62/5 -> 82/5: e3","62/5 -> 82/5: g3","12/1 -> 16/1: is baking bread","62/5 -> 82/5: c3","62/5 -> 82/5: e3","62/5 -> 82/5: g3","12/1 -> 16/1: is baking bread","62/5 -> 82/5: c3","62/5 -> 82/5: e3","62/5 -> 82/5: g3","82/5 -> 92/5: g3","82/5 -> 92/5: bb3","82/5 -> 92/5: d4","16/1 -> 20/1: Sagabona","82/5 -> 92/5: g3","82/5 -> 92/5: bb3","82/5 -> 92/5: d4","16/1 -> 20/1: Sagabona","82/5 -> 92/5: g3","82/5 -> 92/5: bb3","82/5 -> 92/5: d4","92/5 -> 102/5: f3","92/5 -> 102/5: a3","92/5 -> 102/5: c4","16/1 -> 20/1: Sagabona","92/5 -> 102/5: f3","92/5 -> 102/5: a3","92/5 -> 102/5: c4","16/1 -> 20/1: Sagabona","92/5 -> 102/5: f3","92/5 -> 102/5: a3","92/5 -> 102/5: c4","102/5 -> 122/5: c3","102/5 -> 122/5: e3","102/5 -> 122/5: g3","20/1 -> 24/1: kunjani wena","102/5 -> 122/5: c3","102/5 -> 122/5: e3","102/5 -> 122/5: g3","20/1 -> 24/1: kunjani wena","102/5 -> 122/5: c3","102/5 -> 122/5: e3","102/5 -> 122/5: g3","20/1 -> 24/1: kunjani wena","102/5 -> 122/5: c3","102/5 -> 122/5: e3","102/5 -> 122/5: g3","20/1 -> 24/1: kunjani wena","102/5 -> 122/5: c3","102/5 -> 122/5: e3","102/5 -> 122/5: g3","122/5 -> 132/5: g3","122/5 -> 132/5: bb3","122/5 -> 132/5: d4","24/1 -> 28/1: Sagabona","122/5 -> 132/5: g3","122/5 -> 132/5: bb3","122/5 -> 132/5: d4","24/1 -> 28/1: Sagabona","122/5 -> 132/5: g3","122/5 -> 132/5: bb3","122/5 -> 132/5: d4","132/5 -> 142/5: f3","132/5 -> 142/5: a3","132/5 -> 142/5: c4","24/1 -> 28/1: Sagabona","132/5 -> 142/5: f3","132/5 -> 142/5: a3","132/5 -> 142/5: c4","24/1 -> 28/1: Sagabona","132/5 -> 142/5: f3","132/5 -> 142/5: a3","132/5 -> 142/5: c4","142/5 -> 162/5: c3","142/5 -> 162/5: e3","142/5 -> 162/5: g3","28/1 -> 32/1: kunjani wena","142/5 -> 162/5: c3","142/5 -> 162/5: e3","142/5 -> 162/5: g3","28/1 -> 32/1: kunjani wena","142/5 -> 162/5: c3","142/5 -> 162/5: e3","142/5 -> 162/5: g3","28/1 -> 32/1: kunjani wena","142/5 -> 162/5: c3","142/5 -> 162/5: e3","142/5 -> 162/5: g3","28/1 -> 32/1: kunjani wena","142/5 -> 162/5: c3","142/5 -> 162/5: e3","142/5 -> 162/5: g3","162/5 -> 172/5: g3","162/5 -> 172/5: bb3","162/5 -> 172/5: d4","32/1 -> 36/1: The night train, is coming","162/5 -> 172/5: g3","162/5 -> 172/5: bb3","162/5 -> 172/5: d4","32/1 -> 36/1: The night train, is coming","162/5 -> 172/5: g3","162/5 -> 172/5: bb3","162/5 -> 172/5: d4","172/5 -> 182/5: f3","172/5 -> 182/5: a3","172/5 -> 182/5: c4","32/1 -> 36/1: The night train, is coming","172/5 -> 182/5: f3","172/5 -> 182/5: a3","172/5 -> 182/5: c4","32/1 -> 36/1: The night train, is coming","172/5 -> 182/5: f3","172/5 -> 182/5: a3","172/5 -> 182/5: c4","182/5 -> 202/5: c3","182/5 -> 202/5: e3","182/5 -> 202/5: g3","36/1 -> 40/1: got to keep on running","182/5 -> 202/5: c3","182/5 -> 202/5: e3","182/5 -> 202/5: g3","36/1 -> 40/1: got to keep on running","182/5 -> 202/5: c3","182/5 -> 202/5: e3","182/5 -> 202/5: g3","36/1 -> 40/1: got to keep on running","182/5 -> 202/5: c3","182/5 -> 202/5: e3","182/5 -> 202/5: g3","36/1 -> 40/1: got to keep on running","182/5 -> 202/5: c3","182/5 -> 202/5: e3","182/5 -> 202/5: g3","202/5 -> 212/5: g3","202/5 -> 212/5: bb3","202/5 -> 212/5: d4","40/1 -> 44/1: The night train, is coming","202/5 -> 212/5: g3","202/5 -> 212/5: bb3","202/5 -> 212/5: d4","40/1 -> 44/1: The night train, is coming","202/5 -> 212/5: g3","202/5 -> 212/5: bb3","202/5 -> 212/5: d4","212/5 -> 222/5: f3","212/5 -> 222/5: a3","212/5 -> 222/5: c4","40/1 -> 44/1: The night train, is coming","212/5 -> 222/5: f3","212/5 -> 222/5: a3","212/5 -> 222/5: c4","40/1 -> 44/1: The night train, is coming","212/5 -> 222/5: f3","212/5 -> 222/5: a3","212/5 -> 222/5: c4","222/5 -> 242/5: c3","222/5 -> 242/5: e3","222/5 -> 242/5: g3","44/1 -> 48/1: got to keep on running","222/5 -> 242/5: c3","222/5 -> 242/5: e3","222/5 -> 242/5: g3","44/1 -> 48/1: got to keep on running","222/5 -> 242/5: c3","222/5 -> 242/5: e3","222/5 -> 242/5: g3","44/1 -> 48/1: got to keep on running","222/5 -> 242/5: c3","222/5 -> 242/5: e3","222/5 -> 242/5: g3","44/1 -> 48/1: got to keep on running"] export const struct = ["0/1 -> 1/2: c2","1/2 -> 1/1: g2","0/1 -> 1/3: B3","0/1 -> 1/3: D4","0/1 -> 1/3: E4","0/1 -> 1/3: G4","1/3 -> 1/2: B3","1/3 -> 1/2: D4","1/3 -> 1/2: E4","1/3 -> 1/2: G4","5/6 -> 1/1: B3","5/6 -> 1/1: D4","5/6 -> 1/1: E4","5/6 -> 1/1: G4","1/1 -> 3/2: a2","3/2 -> 11/6: e2","11/6 -> 2/1: eb2","4/3 -> 2/1: G3","4/3 -> 2/1: B3","4/3 -> 2/1: C#4","4/3 -> 2/1: F#4","2/1 -> 5/2: d2","5/2 -> 3/1: a2","2/1 -> 13/6: C4","2/1 -> 13/6: E4","2/1 -> 13/6: F4","2/1 -> 13/6: A4","3/1 -> 7/2: g2","7/2 -> 11/3: d2","23/6 -> 4/1: db2","10/3 -> 4/1: B3","10/3 -> 4/1: E4","10/3 -> 4/1: F4","10/3 -> 4/1: A4"] export const swimming = ["0/1 -> 3/4: F4","0/1 -> 3/4: Bb4","0/1 -> 3/4: D5","3/4 -> 5/4: D4","3/4 -> 5/4: G4","3/4 -> 5/4: Bb4","0/1 -> 3/4: G3","3/4 -> 3/2: G3","3/4 -> 5/4: D4","3/4 -> 5/4: G4","3/4 -> 5/4: Bb4","5/4 -> 3/2: Bb3","5/4 -> 3/2: D4","5/4 -> 3/2: F4","3/2 -> 2/1: G3","3/2 -> 2/1: C4","3/2 -> 2/1: E4","3/4 -> 3/2: G3","3/2 -> 9/4: C3","2/1 -> 17/8: Ab3","2/1 -> 17/8: F4","17/8 -> 9/4: A3","17/8 -> 9/4: Gb4","9/4 -> 3/1: Bb3","9/4 -> 3/1: E4","9/4 -> 3/1: G4","3/2 -> 9/4: C3","9/4 -> 3/1: E3","13/4 -> 7/2: F3","13/4 -> 7/2: A3","13/4 -> 7/2: C3","7/2 -> 15/4: F3","7/2 -> 15/4: A3","7/2 -> 15/4: C3","3/1 -> 15/4: F2","15/4 -> 9/2: D2","4/1 -> 17/4: F3","4/1 -> 17/4: A3","4/1 -> 17/4: C3","17/4 -> 9/2: F3","17/4 -> 9/2: A3","17/4 -> 9/2: C3","19/4 -> 5/1: F3","19/4 -> 5/1: Bb3","19/4 -> 5/1: D3","15/4 -> 9/2: D2","9/2 -> 21/4: G2","5/1 -> 21/4: F3","5/1 -> 21/4: Bb3","5/1 -> 21/4: D3","11/2 -> 23/4: F3","11/2 -> 23/4: Bb3","11/2 -> 23/4: Db3","23/4 -> 6/1: F3","23/4 -> 6/1: Bb3","23/4 -> 6/1: Db3","9/2 -> 21/4: G2","21/4 -> 6/1: C2","25/4 -> 13/2: F3","25/4 -> 13/2: A3","25/4 -> 13/2: C3","13/2 -> 27/4: F3","13/2 -> 27/4: A3","13/2 -> 27/4: C3","6/1 -> 27/4: F2","27/4 -> 15/2: D2","7/1 -> 29/4: F3","7/1 -> 29/4: A3","7/1 -> 29/4: C3","29/4 -> 15/2: F3","29/4 -> 15/2: A3","29/4 -> 15/2: C3","31/4 -> 8/1: F3","31/4 -> 8/1: Bb3","31/4 -> 8/1: D3","27/4 -> 15/2: D2","15/2 -> 33/4: G2","8/1 -> 33/4: F3","8/1 -> 33/4: Bb3","8/1 -> 33/4: D3","17/2 -> 35/4: F3","17/2 -> 35/4: B3","17/2 -> 35/4: D3","35/4 -> 9/1: F3","35/4 -> 9/1: B3","35/4 -> 9/1: D3","15/2 -> 33/4: G2","33/4 -> 9/1: C2","9/1 -> 39/4: A5","39/4 -> 41/4: F5","37/4 -> 19/2: F3","37/4 -> 19/2: A3","37/4 -> 19/2: C3","19/2 -> 39/4: F3","19/2 -> 39/4: A3","19/2 -> 39/4: C3","9/1 -> 39/4: F2","39/4 -> 21/2: A2","39/4 -> 41/4: F5","41/4 -> 21/2: C5","21/2 -> 11/1: D5","10/1 -> 41/4: F3","10/1 -> 41/4: A3","10/1 -> 41/4: C3","41/4 -> 21/2: F3","41/4 -> 21/2: A3","41/4 -> 21/2: C3","43/4 -> 11/1: F3","43/4 -> 11/1: Bb3","43/4 -> 11/1: D3","39/4 -> 21/2: A2","21/2 -> 45/4: Bb2","11/1 -> 45/4: F5","45/4 -> 12/1: F5","11/1 -> 45/4: F3","11/1 -> 45/4: Bb3","11/1 -> 45/4: D3","23/2 -> 47/4: F3","23/2 -> 47/4: B3","23/2 -> 47/4: D3","47/4 -> 12/1: F3","47/4 -> 12/1: B3","47/4 -> 12/1: D3","21/2 -> 45/4: Bb2","45/4 -> 12/1: B2","12/1 -> 25/2: C5","25/2 -> 51/4: F5","51/4 -> 53/4: F5","49/4 -> 25/2: A3","49/4 -> 25/2: C4","49/4 -> 25/2: E4","25/2 -> 51/4: A3","25/2 -> 51/4: C4","25/2 -> 51/4: E4","12/1 -> 51/4: A2","51/4 -> 27/2: Ab2","51/4 -> 53/4: F5","53/4 -> 27/2: C6","27/2 -> 57/4: A5","13/1 -> 53/4: Ab3","13/1 -> 53/4: C4","13/1 -> 53/4: Eb4","53/4 -> 27/2: Ab3","53/4 -> 27/2: C4","53/4 -> 27/2: Eb4","55/4 -> 14/1: F3","55/4 -> 14/1: Bb3","55/4 -> 14/1: D3","51/4 -> 27/2: Ab2","27/2 -> 57/4: G2","27/2 -> 57/4: A5","57/4 -> 15/1: G5","14/1 -> 57/4: F3","14/1 -> 57/4: Bb3","14/1 -> 57/4: D3","29/2 -> 59/4: G3","29/2 -> 59/4: C4","29/2 -> 59/4: E4","59/4 -> 15/1: G3","59/4 -> 15/1: C4","59/4 -> 15/1: E4","27/2 -> 57/4: G2","57/4 -> 15/1: C2","15/1 -> 63/4: A5","63/4 -> 65/4: F5","61/4 -> 31/2: F3","61/4 -> 31/2: A3","61/4 -> 31/2: C4","31/2 -> 63/4: F3","31/2 -> 63/4: A3","31/2 -> 63/4: C4","15/1 -> 63/4: F2","63/4 -> 33/2: A2","63/4 -> 65/4: F5","65/4 -> 33/2: C5","33/2 -> 17/1: D5","16/1 -> 65/4: F3","16/1 -> 65/4: A3","16/1 -> 65/4: C4","65/4 -> 33/2: F3","65/4 -> 33/2: A3","65/4 -> 33/2: C4","67/4 -> 17/1: F3","67/4 -> 17/1: Bb3","67/4 -> 17/1: D3","63/4 -> 33/2: A2","33/2 -> 69/4: Bb2","17/1 -> 69/4: F5","69/4 -> 18/1: F5","17/1 -> 69/4: F3","17/1 -> 69/4: Bb3","17/1 -> 69/4: D3","35/2 -> 71/4: F3","35/2 -> 71/4: B3","35/2 -> 71/4: D3","71/4 -> 18/1: F3","71/4 -> 18/1: B3","71/4 -> 18/1: D3","33/2 -> 69/4: Bb2","69/4 -> 18/1: B2","18/1 -> 37/2: C5","37/2 -> 75/4: F5","75/4 -> 19/1: Bb5","73/4 -> 37/2: F3","73/4 -> 37/2: Bb3","73/4 -> 37/2: D4","37/2 -> 75/4: F3","37/2 -> 75/4: Bb3","37/2 -> 75/4: D4","18/1 -> 75/4: G2","75/4 -> 39/2: C2","19/1 -> 77/4: A5","77/4 -> 39/2: G5","39/2 -> 21/1: F5","19/1 -> 77/4: F3","19/1 -> 77/4: Bb3","19/1 -> 77/4: C4","77/4 -> 39/2: F3","77/4 -> 39/2: Bb3","77/4 -> 39/2: C4","79/4 -> 20/1: F3","79/4 -> 20/1: A3","79/4 -> 20/1: C4","75/4 -> 39/2: C2","39/2 -> 81/4: F2","39/2 -> 21/1: F5","20/1 -> 81/4: F3","20/1 -> 81/4: A3","20/1 -> 81/4: C4","41/2 -> 83/4: F3","41/2 -> 83/4: A3","41/2 -> 83/4: C4","83/4 -> 21/1: F3","83/4 -> 21/1: A3","83/4 -> 21/1: C4","39/2 -> 81/4: F2","81/4 -> 21/1: F2","21/1 -> 87/4: A5","87/4 -> 89/4: F5","85/4 -> 43/2: F3","85/4 -> 43/2: A3","85/4 -> 43/2: C3","43/2 -> 87/4: F3","43/2 -> 87/4: A3","43/2 -> 87/4: C3","21/1 -> 87/4: F2","87/4 -> 45/2: A2","87/4 -> 89/4: F5","89/4 -> 45/2: C5","45/2 -> 23/1: D5","22/1 -> 89/4: F3","22/1 -> 89/4: A3","22/1 -> 89/4: C3","89/4 -> 45/2: F3","89/4 -> 45/2: A3","89/4 -> 45/2: C3","91/4 -> 23/1: F3","91/4 -> 23/1: Bb3","91/4 -> 23/1: D3","87/4 -> 45/2: A2","45/2 -> 93/4: Bb2","23/1 -> 93/4: F5","93/4 -> 24/1: F5","23/1 -> 93/4: F3","23/1 -> 93/4: Bb3","23/1 -> 93/4: D3","47/2 -> 95/4: F3","47/2 -> 95/4: B3","47/2 -> 95/4: D3","95/4 -> 24/1: F3","95/4 -> 24/1: B3","95/4 -> 24/1: D3","45/2 -> 93/4: Bb2","93/4 -> 24/1: B2","24/1 -> 49/2: C5","49/2 -> 99/4: F5","99/4 -> 101/4: F5","97/4 -> 49/2: A3","97/4 -> 49/2: C4","97/4 -> 49/2: E4","49/2 -> 99/4: A3","49/2 -> 99/4: C4","49/2 -> 99/4: E4","24/1 -> 99/4: A2","99/4 -> 51/2: Ab2","99/4 -> 101/4: F5","101/4 -> 51/2: C6","51/2 -> 105/4: A5","25/1 -> 101/4: Ab3","25/1 -> 101/4: C4","25/1 -> 101/4: Eb4","101/4 -> 51/2: Ab3","101/4 -> 51/2: C4","101/4 -> 51/2: Eb4","103/4 -> 26/1: F3","103/4 -> 26/1: Bb3","103/4 -> 26/1: D3","99/4 -> 51/2: Ab2","51/2 -> 105/4: G2","51/2 -> 105/4: A5","105/4 -> 27/1: G5","26/1 -> 105/4: F3","26/1 -> 105/4: Bb3","26/1 -> 105/4: D3","53/2 -> 107/4: G3","53/2 -> 107/4: C4","53/2 -> 107/4: E4","107/4 -> 27/1: G3","107/4 -> 27/1: C4","107/4 -> 27/1: E4","51/2 -> 105/4: G2","105/4 -> 27/1: C2","27/1 -> 111/4: A5","111/4 -> 113/4: F5","109/4 -> 55/2: F3","109/4 -> 55/2: A3","109/4 -> 55/2: C3","55/2 -> 111/4: F3","55/2 -> 111/4: A3","55/2 -> 111/4: C3","27/1 -> 111/4: F2","111/4 -> 57/2: A2","111/4 -> 113/4: F5","113/4 -> 57/2: C5","57/2 -> 29/1: D5","28/1 -> 113/4: F3","28/1 -> 113/4: A3","28/1 -> 113/4: C3","113/4 -> 57/2: F3","113/4 -> 57/2: A3","113/4 -> 57/2: C3","115/4 -> 29/1: F3","115/4 -> 29/1: Bb3","115/4 -> 29/1: D3","111/4 -> 57/2: A2","57/2 -> 117/4: Bb2","29/1 -> 117/4: F5","117/4 -> 30/1: F5","29/1 -> 117/4: F3","29/1 -> 117/4: Bb3","29/1 -> 117/4: D3","59/2 -> 119/4: F3","59/2 -> 119/4: B3","59/2 -> 119/4: D3","119/4 -> 30/1: F3","119/4 -> 30/1: B3","119/4 -> 30/1: D3","57/2 -> 117/4: Bb2","117/4 -> 30/1: B2","30/1 -> 61/2: C5","61/2 -> 123/4: F5","123/4 -> 31/1: Bb5","121/4 -> 61/2: F3","121/4 -> 61/2: Bb3","121/4 -> 61/2: D4","61/2 -> 123/4: F3","61/2 -> 123/4: Bb3","61/2 -> 123/4: D4","30/1 -> 123/4: G2","123/4 -> 63/2: C2","31/1 -> 125/4: A5","125/4 -> 63/2: G5","63/2 -> 33/1: F5","31/1 -> 125/4: F3","31/1 -> 125/4: Bb3","31/1 -> 125/4: C4","125/4 -> 63/2: F3","125/4 -> 63/2: Bb3","125/4 -> 63/2: C4","127/4 -> 32/1: F3","127/4 -> 32/1: A3","127/4 -> 32/1: C4","123/4 -> 63/2: C2","63/2 -> 129/4: F2","63/2 -> 33/1: F5","32/1 -> 129/4: F3","32/1 -> 129/4: A3","32/1 -> 129/4: C4","65/2 -> 131/4: F3","65/2 -> 131/4: A3","65/2 -> 131/4: C4","131/4 -> 33/1: F3","131/4 -> 33/1: A3","131/4 -> 33/1: C4","63/2 -> 129/4: F2","129/4 -> 33/1: F2","33/1 -> 135/4: A5","135/4 -> 137/4: F5","133/4 -> 67/2: Bb3","133/4 -> 67/2: D3","133/4 -> 67/2: F4","67/2 -> 135/4: Bb3","67/2 -> 135/4: D3","67/2 -> 135/4: F4","33/1 -> 135/4: Bb2","135/4 -> 69/2: Bb2","135/4 -> 137/4: F5","137/4 -> 69/2: C5","69/2 -> 141/4: A5","34/1 -> 137/4: Bb3","34/1 -> 137/4: D3","34/1 -> 137/4: F4","137/4 -> 69/2: Bb3","137/4 -> 69/2: D3","137/4 -> 69/2: F4","139/4 -> 35/1: A3","139/4 -> 35/1: C4","139/4 -> 35/1: F4","135/4 -> 69/2: Bb2","69/2 -> 141/4: A2","69/2 -> 141/4: A5","141/4 -> 36/1: F5","35/1 -> 141/4: A3","35/1 -> 141/4: C4","35/1 -> 141/4: F4","71/2 -> 143/4: A3","71/2 -> 143/4: C4","71/2 -> 143/4: F4","143/4 -> 36/1: A3","143/4 -> 36/1: C4","143/4 -> 36/1: F4","69/2 -> 141/4: A2","141/4 -> 36/1: A2","36/1 -> 147/4: Ab5","147/4 -> 149/4: F5","145/4 -> 73/2: Ab3","145/4 -> 73/2: B3","145/4 -> 73/2: F4","73/2 -> 147/4: Ab3","73/2 -> 147/4: B3","73/2 -> 147/4: F4","36/1 -> 147/4: Ab2","147/4 -> 75/2: Ab2","147/4 -> 149/4: F5","149/4 -> 75/2: Ab5","75/2 -> 39/1: G5","37/1 -> 149/4: Ab3","37/1 -> 149/4: B3","37/1 -> 149/4: F4","149/4 -> 75/2: Ab3","149/4 -> 75/2: B3","149/4 -> 75/2: F4","151/4 -> 38/1: G3","151/4 -> 38/1: Bb3","151/4 -> 38/1: F4","147/4 -> 75/2: Ab2","75/2 -> 153/4: G2","75/2 -> 39/1: G5","38/1 -> 153/4: G3","38/1 -> 153/4: Bb3","38/1 -> 153/4: F4","77/2 -> 155/4: G3","77/2 -> 155/4: Bb3","77/2 -> 155/4: E4","155/4 -> 39/1: G3","155/4 -> 39/1: Bb3","155/4 -> 39/1: E4","75/2 -> 153/4: G2","153/4 -> 77/2: C2","77/2 -> 155/4: D2","155/4 -> 39/1: E2","39/1 -> 159/4: A5","159/4 -> 161/4: F5","157/4 -> 79/2: Bb3","157/4 -> 79/2: D3","157/4 -> 79/2: F4","79/2 -> 159/4: Bb3","79/2 -> 159/4: D3","79/2 -> 159/4: F4","39/1 -> 159/4: Bb2","159/4 -> 81/2: Bb2","159/4 -> 161/4: F5","161/4 -> 81/2: C5","81/2 -> 165/4: A5","40/1 -> 161/4: Bb3","40/1 -> 161/4: D3","40/1 -> 161/4: F4","161/4 -> 81/2: Bb3","161/4 -> 81/2: D3","161/4 -> 81/2: F4","163/4 -> 41/1: A3","163/4 -> 41/1: C4","163/4 -> 41/1: F4","159/4 -> 81/2: Bb2","81/2 -> 165/4: A2","81/2 -> 165/4: A5","165/4 -> 42/1: F5","41/1 -> 165/4: A3","41/1 -> 165/4: C4","41/1 -> 165/4: F4","83/2 -> 167/4: A3","83/2 -> 167/4: C4","83/2 -> 167/4: F4","167/4 -> 42/1: A3","167/4 -> 42/1: C4","167/4 -> 42/1: F4","81/2 -> 165/4: A2","165/4 -> 42/1: A2","42/1 -> 171/4: Ab5","171/4 -> 173/4: F5","169/4 -> 85/2: Ab3","169/4 -> 85/2: B3","169/4 -> 85/2: F4","85/2 -> 171/4: Ab3","85/2 -> 171/4: B3","85/2 -> 171/4: F4","42/1 -> 171/4: Ab2","171/4 -> 87/2: Ab2","171/4 -> 173/4: F5","173/4 -> 87/2: C5","87/2 -> 45/1: C6","43/1 -> 173/4: Ab3","43/1 -> 173/4: B3","43/1 -> 173/4: F4","173/4 -> 87/2: Ab3","173/4 -> 87/2: B3","173/4 -> 87/2: F4","175/4 -> 44/1: G3","175/4 -> 44/1: Bb3","175/4 -> 44/1: F4","171/4 -> 87/2: Ab2","87/2 -> 177/4: G2","87/2 -> 45/1: C6","44/1 -> 177/4: G3","44/1 -> 177/4: Bb3","44/1 -> 177/4: F4","89/2 -> 179/4: G3","89/2 -> 179/4: Bb3","89/2 -> 179/4: E4","179/4 -> 45/1: G3","179/4 -> 45/1: Bb3","179/4 -> 45/1: E4","87/2 -> 177/4: G2","177/4 -> 89/2: C2","89/2 -> 179/4: D2","179/4 -> 45/1: E2","45/1 -> 183/4: A5","183/4 -> 185/4: F5","181/4 -> 91/2: F3","181/4 -> 91/2: A3","181/4 -> 91/2: C3","91/2 -> 183/4: F3","91/2 -> 183/4: A3","91/2 -> 183/4: C3","45/1 -> 183/4: F2","183/4 -> 93/2: A2","183/4 -> 185/4: F5","185/4 -> 93/2: C5","93/2 -> 47/1: D5","46/1 -> 185/4: F3","46/1 -> 185/4: A3","46/1 -> 185/4: C3","185/4 -> 93/2: F3","185/4 -> 93/2: A3","185/4 -> 93/2: C3","187/4 -> 47/1: F3","187/4 -> 47/1: Bb3","187/4 -> 47/1: D3","183/4 -> 93/2: A2","93/2 -> 189/4: Bb2","47/1 -> 189/4: F5","189/4 -> 48/1: F5","47/1 -> 189/4: F3","47/1 -> 189/4: Bb3","47/1 -> 189/4: D3","95/2 -> 191/4: F3","95/2 -> 191/4: B3","95/2 -> 191/4: D3","191/4 -> 48/1: F3","191/4 -> 48/1: B3","191/4 -> 48/1: D3","93/2 -> 189/4: Bb2","189/4 -> 48/1: B2","48/1 -> 97/2: C5","97/2 -> 195/4: F5","195/4 -> 49/1: Bb5","193/4 -> 97/2: F3","193/4 -> 97/2: Bb3","193/4 -> 97/2: D4","97/2 -> 195/4: F3","97/2 -> 195/4: Bb3","97/2 -> 195/4: D4","48/1 -> 195/4: G2","195/4 -> 99/2: C2","49/1 -> 197/4: A5","197/4 -> 99/2: G5","99/2 -> 51/1: F5","49/1 -> 197/4: F3","49/1 -> 197/4: Bb3","49/1 -> 197/4: C4","197/4 -> 99/2: F3","197/4 -> 99/2: Bb3","197/4 -> 99/2: C4","199/4 -> 50/1: F3","199/4 -> 50/1: A3","199/4 -> 50/1: C4","195/4 -> 99/2: C2","99/2 -> 201/4: F2","99/2 -> 51/1: F5","50/1 -> 201/4: F3","50/1 -> 201/4: A3","50/1 -> 201/4: C4","101/2 -> 203/4: F3","101/2 -> 203/4: A3","101/2 -> 203/4: C4","203/4 -> 51/1: F3","203/4 -> 51/1: A3","203/4 -> 51/1: C4","99/2 -> 201/4: F2","201/4 -> 51/1: F2"] +export const swimmingWithSoundfonts = ["0/1 -> 3/4: {\"n\":\"F4\",\"s\":\"Kalimba: Ethnic\"}","0/1 -> 3/4: {\"n\":\"Bb4\",\"s\":\"Kalimba: Ethnic\"}","0/1 -> 3/4: {\"n\":\"D5\",\"s\":\"Kalimba: Ethnic\"}","3/4 -> 5/4: {\"n\":\"D4\",\"s\":\"Kalimba: Ethnic\"}","3/4 -> 5/4: {\"n\":\"G4\",\"s\":\"Kalimba: Ethnic\"}","3/4 -> 5/4: {\"n\":\"Bb4\",\"s\":\"Kalimba: Ethnic\"}","0/1 -> 3/4: {\"n\":\"G3\",\"s\":\"Acoustic Bass: Bass\"}","3/4 -> 3/2: {\"n\":\"G3\",\"s\":\"Acoustic Bass: Bass\"}"] export const synthDrums = ["0/1 -> 1/2: c1","1/2 -> 1/1: c1","1/1 -> 3/2: c1","3/2 -> 2/1: c1","2/1 -> 5/2: c1","5/2 -> 3/1: c1","3/1 -> 7/2: c1","7/2 -> 4/1: c1","1/2 -> 1/1: c3","3/2 -> 2/1: c3","5/2 -> 3/1: c3","7/2 -> 4/1: c3","0/1 -> 1/4: C1","1/4 -> 1/2: C3","1/2 -> 3/4: C1","3/4 -> 1/1: C3","1/1 -> 5/4: C1","5/4 -> 3/2: C3","3/2 -> 7/4: C1","7/4 -> 2/1: C3","2/1 -> 9/4: C1","9/4 -> 5/2: C3","5/2 -> 11/4: C1","11/4 -> 3/1: C3","3/1 -> 13/4: C1","13/4 -> 7/2: C3","7/2 -> 15/4: C1","15/4 -> 4/1: C3"] export const technoDrums = ["0/1 -> 1/2: c1","1/2 -> 1/1: c1","1/1 -> 3/2: c1","3/2 -> 2/1: c1","2/1 -> 5/2: c1","5/2 -> 3/1: c1","3/1 -> 7/2: c1","7/2 -> 4/1: c1","1/2 -> 1/1: x","3/2 -> 2/1: x","5/2 -> 3/1: x","7/2 -> 4/1: x","1/4 -> 1/2: c4","3/4 -> 1/1: c4","5/4 -> 3/2: c4","7/4 -> 2/1: c4","9/4 -> 5/2: c4","11/4 -> 3/1: c4","13/4 -> 7/2: c4","15/4 -> 4/1: c4"] export const tetrisMini = ["0/1 -> 1/2: e5","1/2 -> 3/4: b4","3/4 -> 1/1: c5","0/1 -> 1/4: e2","1/4 -> 1/2: e3","1/2 -> 3/4: e2","3/4 -> 1/1: e3","1/1 -> 3/2: d5","3/2 -> 7/4: c5","7/4 -> 2/1: b4","1/1 -> 5/4: e2","5/4 -> 3/2: e3","3/2 -> 7/4: e2","7/4 -> 2/1: e3","2/1 -> 5/2: a4","5/2 -> 11/4: a4","11/4 -> 3/1: c5","2/1 -> 9/4: a2","9/4 -> 5/2: a3","5/2 -> 11/4: a2","11/4 -> 3/1: a3","3/1 -> 7/2: e5","7/2 -> 15/4: d5","15/4 -> 4/1: c5","3/1 -> 13/4: a2","13/4 -> 7/2: a3","7/2 -> 15/4: a2","15/4 -> 4/1: a3","4/1 -> 9/2: b4","19/4 -> 5/1: c5","4/1 -> 17/4: g#2","17/4 -> 9/2: g#3","9/2 -> 19/4: g#2","19/4 -> 5/1: g#3","5/1 -> 11/2: d5","11/2 -> 6/1: e5","5/1 -> 21/4: e2","21/4 -> 11/2: e3","11/2 -> 23/4: e2","23/4 -> 6/1: e3","6/1 -> 13/2: c5","13/2 -> 7/1: a4","6/1 -> 25/4: a2","25/4 -> 13/2: a3","13/2 -> 27/4: a2","27/4 -> 7/1: a3","7/1 -> 15/2: a4","7/1 -> 29/4: a2","29/4 -> 15/2: a3","15/2 -> 31/4: b1","31/4 -> 8/1: c2","33/4 -> 17/2: d5","35/4 -> 9/1: f5","8/1 -> 33/4: d2","33/4 -> 17/2: d3","17/2 -> 35/4: d2","35/4 -> 9/1: d3","9/1 -> 19/2: a5","19/2 -> 39/4: g5","39/4 -> 10/1: f5","9/1 -> 37/4: d2","37/4 -> 19/2: d3","19/2 -> 39/4: d2","39/4 -> 10/1: d3","10/1 -> 21/2: e5","43/4 -> 11/1: c5","10/1 -> 41/4: c2","41/4 -> 21/2: c3","21/2 -> 43/4: c2","43/4 -> 11/1: c3","11/1 -> 23/2: e5","23/2 -> 47/4: d5","47/4 -> 12/1: c5","11/1 -> 45/4: c2","45/4 -> 23/2: c3","23/2 -> 47/4: c2","47/4 -> 12/1: c3","12/1 -> 25/2: b4","25/2 -> 51/4: b4","51/4 -> 13/1: c5","12/1 -> 49/4: b1","49/4 -> 25/2: b2","25/2 -> 51/4: b1","51/4 -> 13/1: b2","13/1 -> 27/2: d5","27/2 -> 14/1: e5","13/1 -> 53/4: e2","53/4 -> 27/2: e3","27/2 -> 55/4: e2","55/4 -> 14/1: e3","14/1 -> 29/2: c5","29/2 -> 15/1: a4","14/1 -> 57/4: a1","57/4 -> 29/2: a2","29/2 -> 59/4: a1","59/4 -> 15/1: a2","15/1 -> 31/2: a4","15/1 -> 61/4: a1","61/4 -> 31/2: a2","31/2 -> 63/4: a1","63/4 -> 16/1: a2"] From 38b1717faccb25c7b036d998cdd04dd1683db1f0 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 20 Jun 2022 22:00:14 +0200 Subject: [PATCH 4/5] load fonts from forked version --- packages/soundfonts/convert.js | 2 +- packages/soundfonts/fontloader.mjs | 2 +- packages/soundfonts/list.mjs | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/soundfonts/convert.js b/packages/soundfonts/convert.js index 91ecfc6c..ffd80cca 100644 --- a/packages/soundfonts/convert.js +++ b/packages/soundfonts/convert.js @@ -3,7 +3,7 @@ import fetch from 'node-fetch'; const name = '0000_JCLive'; -const js = await fetch(`https://surikov.github.io/webaudiofontdata/sound/${name}_sf2_file.js`).then((res) => +const js = await fetch(`https://felixroos.github.io/webaudiofontdata/sound/${name}_sf2_file.js`).then((res) => res.text(), ); // console.log(js); diff --git a/packages/soundfonts/fontloader.mjs b/packages/soundfonts/fontloader.mjs index 953c2695..d4d165df 100644 --- a/packages/soundfonts/fontloader.mjs +++ b/packages/soundfonts/fontloader.mjs @@ -5,7 +5,7 @@ async function loadFont(name) { } const load = async () => { // TODO: make soundfont source configurable - const url = `https://surikov.github.io/webaudiofontdata/sound/${name}.js`; + const url = `https://felixroos.github.io/webaudiofontdata/sound/${name}.js`; console.log('load font', name, url); const preset = await fetch(url).then((res) => res.text()); let [_, data] = preset.split('={'); diff --git a/packages/soundfonts/list.mjs b/packages/soundfonts/list.mjs index 69396a1d..3d103a96 100644 --- a/packages/soundfonts/list.mjs +++ b/packages/soundfonts/list.mjs @@ -1649,7 +1649,7 @@ instrumentNames[8] = 'Celesta: Chromatic Percussion'; instrumentNames[9] = 'Glockenspiel: Chromatic Percussion'; instrumentNames[10] = 'Music Box: Chromatic Percussion'; instrumentNames[11] = 'Vibraphone: Chromatic Percussion'; -instrumentNames[12] = 'Marimba: Chromatic Percussion'; +instrumentNames[12] = 'Marimba: Chromatic Percussion'; // out of tune instrumentNames[13] = 'Xylophone: Chromatic Percussion'; instrumentNames[14] = 'Tubular Bells: Chromatic Percussion'; instrumentNames[15] = 'Dulcimer: Chromatic Percussion'; @@ -1658,7 +1658,7 @@ instrumentNames[17] = 'Percussive Organ: Organ'; instrumentNames[18] = 'Rock Organ: Organ'; instrumentNames[19] = 'Church Organ: Organ'; instrumentNames[20] = 'Reed Organ: Organ'; -instrumentNames[21] = 'Accordion: Organ'; +instrumentNames[21] = 'Accordion: Organ'; // some notes are one octave up instrumentNames[22] = 'Harmonica: Organ'; instrumentNames[23] = 'Tango Accordion: Organ'; instrumentNames[24] = 'Acoustic Guitar (nylon): Guitar'; @@ -1675,7 +1675,7 @@ instrumentNames[34] = 'Electric Bass (pick): Bass'; instrumentNames[35] = 'Fretless Bass: Bass'; instrumentNames[36] = 'Slap Bass 1: Bass'; instrumentNames[37] = 'Slap Bass 2: Bass'; -instrumentNames[38] = 'Synth Bass 1: Bass'; +instrumentNames[38] = 'Synth Bass 1: Bass'; // not found? instrumentNames[39] = 'Synth Bass 2: Bass'; instrumentNames[40] = 'Violin: Strings'; instrumentNames[41] = 'Viola: Strings'; @@ -1701,7 +1701,7 @@ instrumentNames[60] = 'French Horn: Brass'; instrumentNames[61] = 'Brass Section: Brass'; instrumentNames[62] = 'Synth Brass 1: Brass'; instrumentNames[63] = 'Synth Brass 2: Brass'; -instrumentNames[64] = 'Soprano Sax: Reed'; +instrumentNames[64] = 'Soprano Sax: Reed'; // out of time? instrumentNames[65] = 'Alto Sax: Reed'; instrumentNames[66] = 'Tenor Sax: Reed'; instrumentNames[67] = 'Baritone Sax: Reed'; @@ -1711,7 +1711,7 @@ instrumentNames[70] = 'Bassoon: Reed'; instrumentNames[71] = 'Clarinet: Reed'; instrumentNames[72] = 'Piccolo: Pipe'; instrumentNames[73] = 'Flute: Pipe'; -instrumentNames[74] = 'Recorder: Pipe'; +instrumentNames[74] = 'Recorder: Pipe'; // out of time? instrumentNames[75] = 'Pan Flute: Pipe'; instrumentNames[76] = 'Blown bottle: Pipe'; instrumentNames[77] = 'Shakuhachi: Pipe'; @@ -1722,7 +1722,7 @@ instrumentNames[81] = 'Lead 2 (sawtooth): Synth Lead'; instrumentNames[82] = 'Lead 3 (calliope): Synth Lead'; instrumentNames[83] = 'Lead 4 (chiff): Synth Lead'; instrumentNames[84] = 'Lead 5 (charang): Synth Lead'; -instrumentNames[85] = 'Lead 6 (voice): Synth Lead'; +instrumentNames[85] = 'Lead 6 (voice): Synth Lead'; // terranigma! instrumentNames[86] = 'Lead 7 (fifths): Synth Lead'; instrumentNames[87] = 'Lead 8 (bass + lead): Synth Lead'; instrumentNames[88] = 'Pad 1 (new age): Synth Pad'; From 319400ab13bb40eecac26fbb42d5ad364aa3395f Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 20 Jun 2022 22:20:22 +0200 Subject: [PATCH 5/5] remove unused sf control --- packages/core/controls.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index a04cd706..c6f96263 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -27,7 +27,6 @@ const generic_params = [ * */ ['s', 's', 'sound'], - ['sf', 'sf', 'soundfont'], /** * The note or sample number to choose for a synth or sampleset * Note names currently not working yet, but will hopefully soon. Just stick to numbers for now