From 6059c69995fa016c7eb24d5d66634376c11112a9 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 5 Mar 2023 23:27:37 +0100 Subject: [PATCH 01/24] first draft of soundMap to register keys for s + refactor sampler to use it + refactor synth to use it + add 'source' control + wip: samples tab + wip: webadirt ? + wip: soundfonts --- packages/core/controls.mjs | 9 ++ packages/webaudio/helpers.mjs | 47 +++++++++ packages/webaudio/index.mjs | 2 + packages/webaudio/sampler.mjs | 178 +++++++++++++++++++++++---------- packages/webaudio/synth.mjs | 34 +++++++ packages/webaudio/webaudio.mjs | 177 +++----------------------------- packages/webdirt/webdirt.mjs | 6 +- website/src/repl/Footer.jsx | 6 +- website/src/repl/Repl.jsx | 16 +-- website/src/repl/prebake.mjs | 3 +- 10 files changed, 244 insertions(+), 234 deletions(-) create mode 100644 packages/webaudio/helpers.mjs create mode 100644 packages/webaudio/synth.mjs diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index ff5da74d..ef5bd33f 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -23,6 +23,15 @@ const generic_params = [ * */ [['s', 'n', 'gain'], 'sound'], + /** + * Define a custom webaudio node to use as a sound source. + * + * @name source + * @param {function} getSource + * @synonyms src + * + */ + ['source', 'src'], /** * Selects the given index from the sample map. * Numbers too high will wrap around. diff --git a/packages/webaudio/helpers.mjs b/packages/webaudio/helpers.mjs new file mode 100644 index 00000000..a17b7408 --- /dev/null +++ b/packages/webaudio/helpers.mjs @@ -0,0 +1,47 @@ +import { getAudioContext } from './webaudio.mjs'; + +export function gainNode(value) { + const node = getAudioContext().createGain(); + node.gain.value = value; + return node; +} + +export 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; +}; + +export const getADSR = (attack, decay, sustain, release, velocity, begin, end) => { + const gainNode = getAudioContext().createGain(); + gainNode.gain.setValueAtTime(0, begin); + gainNode.gain.linearRampToValueAtTime(velocity, begin + attack); // attack + gainNode.gain.linearRampToValueAtTime(sustain * velocity, begin + attack + decay); // sustain start + gainNode.gain.setValueAtTime(sustain * velocity, end); // sustain end + gainNode.gain.linearRampToValueAtTime(0, end + release); // release + // for some reason, using exponential ramping creates little cracklings + /* let t = begin; + gainNode.gain.setValueAtTime(0, t); + gainNode.gain.exponentialRampToValueAtTime(velocity, (t += attack)); + const sustainGain = Math.max(sustain * velocity, 0.001); + gainNode.gain.exponentialRampToValueAtTime(sustainGain, (t += decay)); + if (end - begin < attack + decay) { + gainNode.gain.cancelAndHoldAtTime(end); + } else { + gainNode.gain.setValueAtTime(sustainGain, end); + } + gainNode.gain.exponentialRampToValueAtTime(0.001, end + release); // release */ + return gainNode; +}; + +export const getFilter = (type, frequency, Q) => { + const filter = getAudioContext().createBiquadFilter(); + filter.type = type; + filter.frequency.value = frequency; + filter.Q.value = Q; + return filter; +}; diff --git a/packages/webaudio/index.mjs b/packages/webaudio/index.mjs index 5fa1e36e..2ab74c72 100644 --- a/packages/webaudio/index.mjs +++ b/packages/webaudio/index.mjs @@ -6,3 +6,5 @@ This program is free software: you can redistribute it and/or modify it under th export * from './webaudio.mjs'; export * from './sampler.mjs'; +export * from './helpers.mjs'; +export * from './synth.mjs'; diff --git a/packages/webaudio/sampler.mjs b/packages/webaudio/sampler.mjs index 40a69376..219b0581 100644 --- a/packages/webaudio/sampler.mjs +++ b/packages/webaudio/sampler.mjs @@ -1,5 +1,6 @@ import { logger, toMidi, valueToMidi } from '@strudel.cycles/core'; -import { getAudioContext } from './index.mjs'; +import { getAudioContext, setSound } from './index.mjs'; +import { getADSR } from './helpers.mjs'; const bufferCache = {}; // string: Promise const loadCache = {}; // string: Promise @@ -20,7 +21,7 @@ function humanFileSize(bytes, si) { return bytes.toFixed(1) + ' ' + units[u]; } -export const getSampleBufferSource = async (s, n, note, speed, freq) => { +export const getSampleBufferSource = async (s, n, note, speed, freq, bank) => { let transpose = 0; if (freq !== undefined && note !== undefined) { logger('[sampler] hap has note and freq. ignoring note', 'warning'); @@ -29,23 +30,6 @@ export const getSampleBufferSource = async (s, n, note, speed, freq) => { transpose = midi - 36; // C3 is middle C 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) - // .map((s) => `"${s}"`) - // .join(', ')}. - ); - } - if (typeof bank !== 'object') { - throw new Error('wrong format for sample bank:', s); - } let sampleUrl; if (Array.isArray(bank)) { sampleUrl = bank[n % bank.length]; @@ -107,8 +91,6 @@ export const getLoadedBuffer = (url) => { return bufferCache[url]; }; -let sampleCache = { current: undefined }; - /** * Loads a collection of samples to use with `s` * @example @@ -147,37 +129,129 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '') => { throw new Error(`error loading "${sampleMap}"`); }); } - sampleCache.current = { - ...sampleCache.current, - ...Object.fromEntries( - Object.entries(sampleMap).map(([key, value]) => { - if (typeof value === 'string') { - value = [value]; - } - if (typeof value !== 'object') { - throw new Error('wrong sample map format for ' + key); - } - baseUrl = value._base || baseUrl; - const replaceUrl = (v) => (baseUrl + v).replace('github:', 'https://raw.githubusercontent.com/'); - if (Array.isArray(value)) { - return [key, value.map(replaceUrl)]; - } - // must be object - return [ - key, - Object.fromEntries( - Object.entries(value).map(([note, samples]) => { - return [note, (typeof samples === 'string' ? [samples] : samples).map(replaceUrl)]; - }), - ), - ]; - }), - ), - }; + Object.entries(sampleMap).forEach(([key, value]) => { + if (typeof value === 'string') { + value = [value]; + } + if (typeof value !== 'object') { + throw new Error('wrong sample map format for ' + key); + } + baseUrl = value._base || baseUrl; + const replaceUrl = (v) => (baseUrl + v).replace('github:', 'https://raw.githubusercontent.com/'); + if (Array.isArray(value)) { + //return [key, value.map(replaceUrl)]; + value = value.map(replaceUrl); + } else { + // must be object + value = Object.fromEntries( + Object.entries(value).map(([note, samples]) => { + return [note, (typeof samples === 'string' ? [samples] : samples).map(replaceUrl)]; + }), + ); + } + setSound(key, (options) => onTriggerSample(options, value)); + }); }; -export const resetLoadedSamples = () => { - sampleCache.current = undefined; -}; +const cutGroups = []; -export const getLoadedSamples = () => sampleCache.current; +export async function onTriggerSample(options, bank) { + const { hap, duration: hapDuration, t, cps } = options; + const { + s, + freq, + unit, + nudge = 0, // TODO: is this in seconds? + cut, + loop, + clip = 0, // if 1, samples will be cut off when the hap ends + n = 0, + note, + speed = 1, // sample playback speed + begin = 0, + end = 1, + } = hap.value; + const ac = getAudioContext(); + // destructure adsr here, because the default should be different for synths and samples + const { attack = 0.001, decay = 0.001, sustain = 1, release = 0.001 } = hap.value; + // load sample + if (speed === 0) { + // no playback + return; + } + if (!s) { + // is this check really needed? + console.warn('no sample specified'); + return; + } + //const soundfont = getSoundfontKey(s); + let bufferSource; + + //if (soundfont) { + // is soundfont + //bufferSource = await globalThis.getFontBufferSource(soundfont, note || n, ac, freq); + //} else { + // is sample from loaded samples(..) + bufferSource = await getSampleBufferSource(s, n, note, speed, freq, bank); + //} + // asny stuff above took too long? + if (ac.currentTime > t) { + logger(`[sampler] still loading sound "${s}:${n}"`, 'highlight'); + // console.warn('sample still loading:', s, n); + return; + } + if (!bufferSource) { + console.warn('no buffer source'); + return; + } + bufferSource.playbackRate.value = Math.abs(speed) * bufferSource.playbackRate.value; + if (unit === 'c') { + // are there other units? + bufferSource.playbackRate.value = bufferSource.playbackRate.value * bufferSource.buffer.duration * cps; + } + const shouldClip = /* soundfont || */ clip; + let duration = shouldClip ? hapDuration : bufferSource.buffer.duration / bufferSource.playbackRate.value; + // "The computation of the offset into the sound is performed using the sound buffer's natural sample rate, + // rather than the current playback rate, so even if the sound is playing at twice its normal speed, + // the midway point through a 10-second audio buffer is still 5." + const offset = begin * duration * bufferSource.playbackRate.value; + duration = (end - begin) * duration; + if (loop) { + bufferSource.loop = true; + bufferSource.loopStart = offset; + bufferSource.loopEnd = offset + duration; + duration = loop * duration; + } + const time = t + nudge; + + bufferSource.start(time, offset); + if (cut !== undefined) { + cutGroups[cut]?.stop(time); // fade out? + cutGroups[cut] = bufferSource; + } + //chain.push(bufferSource); + bufferSource.stop(t + duration + release); + const adsr = getADSR(attack, decay, sustain, release, 1, time, time + duration); + bufferSource.connect(adsr); + //chain.push(adsr); + return adsr; +} + +/*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 + return globalThis.soundfontList.instruments.find((instrument) => instrument.startsWith(name)); + } + return; +};*/ diff --git a/packages/webaudio/synth.mjs b/packages/webaudio/synth.mjs new file mode 100644 index 00000000..abc05b63 --- /dev/null +++ b/packages/webaudio/synth.mjs @@ -0,0 +1,34 @@ +import { fromMidi, toMidi } from '@strudel.cycles/core'; +import { setSound } from './webaudio.mjs'; +import { getOscillator, gainNode, getADSR } from './helpers.mjs'; + +export function loadSynthSounds() { + ['sine', 'square', 'triangle', 'sawtooth'].forEach((wave) => { + setSound(wave, ({ hap, duration, t }) => { + // destructure adsr here, because the default should be different for synths and samples + const { attack = 0.001, decay = 0.05, sustain = 0.6, release = 0.01 } = hap.value; + let { n, note, freq } = hap.value; + // with synths, n and note are the same thing + n = note || n || 36; + if (typeof n === 'string') { + n = toMidi(n); // e.g. c3 => 48 + } + // get frequency + if (!freq && typeof n === 'number') { + freq = fromMidi(n); // + 48); + } + // maybe pull out the above frequency resolution?? (there is also getFrequency but it has no default) + // make oscillator + const o = getOscillator({ t, s: wave, freq, duration, release }); + // chain.push(o); + // level down oscillators as they are really loud compared to samples i've tested + //chain.push(gainNode(0.3)); + const g = gainNode(0.3); + // TODO: make adsr work with samples without pops + // envelope + const adsr = getADSR(attack, decay, sustain, release, 1, t, t + duration); + //chain.push(adsr); + return o.connect(g).connect(adsr); + }); + }); +} diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 50436d09..f515763a 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -5,16 +5,22 @@ This program is free software: you can redistribute it and/or modify it under th */ import * as strudel from '@strudel.cycles/core'; -import { fromMidi, logger, toMidi } from '@strudel.cycles/core'; import './feedbackdelay.mjs'; import './reverb.mjs'; -import { getSampleBufferSource } from './sampler.mjs'; const { Pattern } = strudel; import './vowel.mjs'; import workletsUrl from './worklets.mjs?url'; +import { getFilter, gainNode } from './helpers.mjs'; // export const getAudioContext = () => Tone.getContext().rawContext; +export const soundMap = new Map(); +// onTrigger = ({ hap: Hap, t: number, deadline: number, duration: number, cps: number }) => AudioNode +export function setSound(key, onTrigger) { + soundMap.set(key, onTrigger); +} +export const resetLoadedSounds = () => soundMap.clear(); + let audioContext; export const getAudioContext = () => { if (!audioContext) { @@ -38,65 +44,6 @@ export const panic = () => { destination = null; }; -const getFilter = (type, frequency, Q) => { - const filter = getAudioContext().createBiquadFilter(); - filter.type = type; - filter.frequency.value = frequency; - filter.Q.value = Q; - return filter; -}; - -const getADSR = (attack, decay, sustain, release, velocity, begin, end) => { - const gainNode = getAudioContext().createGain(); - gainNode.gain.setValueAtTime(0, begin); - gainNode.gain.linearRampToValueAtTime(velocity, begin + attack); // attack - gainNode.gain.linearRampToValueAtTime(sustain * velocity, begin + attack + decay); // sustain start - gainNode.gain.setValueAtTime(sustain * velocity, end); // sustain end - gainNode.gain.linearRampToValueAtTime(0, end + release); // release - // for some reason, using exponential ramping creates little cracklings - /* let t = begin; - gainNode.gain.setValueAtTime(0, t); - gainNode.gain.exponentialRampToValueAtTime(velocity, (t += attack)); - const sustainGain = Math.max(sustain * velocity, 0.001); - gainNode.gain.exponentialRampToValueAtTime(sustainGain, (t += decay)); - if (end - begin < attack + decay) { - gainNode.gain.cancelAndHoldAtTime(end); - } else { - gainNode.gain.setValueAtTime(sustainGain, end); - } - gainNode.gain.exponentialRampToValueAtTime(0.001, end + release); // release */ - 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 - return globalThis.soundfontList.instruments.find((instrument) => instrument.startsWith(name)); - } - return; -}; - let workletsLoading; function loadWorklets() { if (workletsLoading) { @@ -136,13 +83,6 @@ export async function initAudioOnFirstClick() { }); } -function gainNode(value) { - const node = getAudioContext().createGain(); - node.gain.value = value; - return node; -} -const cutGroups = []; - let delays = {}; function getDelay(orbit, delaytime, delayfeedback, t) { if (!delays[orbit]) { @@ -188,13 +128,9 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => { let t = ac.currentTime + deadline; // destructure value let { - freq, - s, + s = 'triangle', bank, - sf, - clip = 0, // if 1, samples will be cut off when the hap ends - n = 0, - note, + source, gain = 0.8, // low pass cutoff, @@ -210,17 +146,10 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => { crush, shape, pan, - speed = 1, // sample playback speed - begin = 0, - end = 1, vowel, delay = 0, delayfeedback = 0.5, delaytime = 0.25, - unit, - nudge = 0, // TODO: is this in seconds? - cut, - loop, orbit = 1, room, size = 2, @@ -232,87 +161,13 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => { if (bank && s) { s = `${bank}_${s}`; } - if (!s || ['sine', 'square', 'triangle', 'sawtooth'].includes(s)) { - // destructure adsr here, because the default should be different for synths and samples - const { attack = 0.001, decay = 0.05, sustain = 0.6, release = 0.01 } = hap.value; - // with synths, n and note are the same thing - n = note || n || 36; - if (typeof n === 'string') { - n = toMidi(n); // e.g. c3 => 48 - } - // get frequency - if (!freq && typeof n === 'number') { - freq = fromMidi(n); // + 48); - } - // make oscillator - const o = getOscillator({ t, s, freq, duration: hapDuration, release }); - chain.push(o); - // level down oscillators as they are really loud compared to samples i've tested - chain.push(gainNode(0.3)); - // TODO: make adsr work with samples without pops - // envelope - const adsr = getADSR(attack, decay, sustain, release, 1, t, t + hapDuration); - chain.push(adsr); + if (soundMap.has(s)) { + const node = await soundMap.get(s)({ hap, t, deadline, duration: hapDuration, cps }); + chain.push(node); + } else if (source) { + chain.push(source({ hap, t, deadline, duration: hapDuration, cps })); } else { - // destructure adsr here, because the default should be different for synths and samples - const { attack = 0.001, decay = 0.001, sustain = 1, release = 0.001 } = hap.value; - // load sample - if (speed === 0) { - // no playback - return; - } - if (!s) { - console.warn('no sample specified'); - return; - } - const soundfont = getSoundfontKey(s); - let bufferSource; - - if (soundfont) { - // is soundfont - bufferSource = await globalThis.getFontBufferSource(soundfont, note || n, ac, freq); - } else { - // is sample from loaded samples(..) - bufferSource = await getSampleBufferSource(s, n, note, speed, freq); - } - // asny stuff above took too long? - if (ac.currentTime > t) { - logger(`[sampler] still loading sound "${s}:${n}"`, 'highlight'); - // console.warn('sample still loading:', s, n); - return; - } - if (!bufferSource) { - console.warn('no buffer source'); - return; - } - bufferSource.playbackRate.value = Math.abs(speed) * bufferSource.playbackRate.value; - if (unit === 'c') { - // are there other units? - bufferSource.playbackRate.value = bufferSource.playbackRate.value * bufferSource.buffer.duration * cps; - } - let duration = soundfont || clip ? hapDuration : bufferSource.buffer.duration / bufferSource.playbackRate.value; - // "The computation of the offset into the sound is performed using the sound buffer's natural sample rate, - // rather than the current playback rate, so even if the sound is playing at twice its normal speed, - // the midway point through a 10-second audio buffer is still 5." - const offset = begin * duration * bufferSource.playbackRate.value; - duration = (end - begin) * duration; - if (loop) { - bufferSource.loop = true; - bufferSource.loopStart = offset; - bufferSource.loopEnd = offset + duration; - duration = loop * duration; - } - t += nudge; - - bufferSource.start(t, offset); - if (cut !== undefined) { - cutGroups[cut]?.stop(t); // fade out? - cutGroups[cut] = bufferSource; - } - chain.push(bufferSource); - bufferSource.stop(t + duration + release); - const adsr = getADSR(attack, decay, sustain, release, 1, t, t + duration); - chain.push(adsr); + throw new Error(`sound ${s} not found! Is it loaded?`); } // gain stage diff --git a/packages/webdirt/webdirt.mjs b/packages/webdirt/webdirt.mjs index 6ae2ff9f..c106bf17 100644 --- a/packages/webdirt/webdirt.mjs +++ b/packages/webdirt/webdirt.mjs @@ -1,7 +1,7 @@ import * as strudel from '@strudel.cycles/core'; const { Pattern } = strudel; import * as WebDirt from 'WebDirt'; -import { getLoadedSamples, loadBuffer, getLoadedBuffer } from '@strudel.cycles/webaudio'; +//import { loadBuffer, getLoadedBuffer } from '@strudel.cycles/webaudio'; let webDirt; @@ -63,7 +63,7 @@ export function loadWebDirt(config) { */ Pattern.prototype.webdirt = function () { // create a WebDirt object and initialize Web Audio context - return this.onTrigger(async (time, e, currentTime) => { + /* return this.onTrigger(async (time, e, currentTime) => { if (!webDirt) { throw new Error('WebDirt not initialized!'); } @@ -92,5 +92,5 @@ Pattern.prototype.webdirt = function () { webDirt.playSample(msg, deadline); } } - }); + }); */ }; diff --git a/website/src/repl/Footer.jsx b/website/src/repl/Footer.jsx index 08ab967e..fe2eddc9 100644 --- a/website/src/repl/Footer.jsx +++ b/website/src/repl/Footer.jsx @@ -4,7 +4,6 @@ import { useEvent, cx } from '@strudel.cycles/react'; // import { cx } from '@strudel.cycles/react'; import { nanoid } from 'nanoid'; import React, { useCallback, useLayoutEffect, useRef, useState } from 'react'; -import { loadedSamples } from './Repl'; import { Reference } from './Reference'; import { themes } from './themes.mjs'; import { useSettings, settingsMap, setActiveFooter, defaultSettings } from '../settings.mjs'; @@ -196,14 +195,15 @@ function ConsoleTab({ log }) { function SamplesTab() { return (
- {loadedSamples.length} banks loaded: + TODO: use nanostore with sampleMap + {/* {loadedSamples.length} banks loaded: {loadedSamples.map(([name, samples]) => ( {}}> {' '} {name}( {Array.isArray(samples) ? samples.length : typeof samples === 'object' ? Object.values(samples).length : 1}){' '} - ))} + ))} */}
); } diff --git a/website/src/repl/Repl.jsx b/website/src/repl/Repl.jsx index ce21f1c1..186e1628 100644 --- a/website/src/repl/Repl.jsx +++ b/website/src/repl/Repl.jsx @@ -6,13 +6,7 @@ This program is free software: you can redistribute it and/or modify it under th import { cleanupDraw, cleanupUi, controls, evalScope, getDrawContext, logger } from '@strudel.cycles/core'; import { CodeMirror, cx, flash, useHighlighting, useStrudel, useKeydown } from '@strudel.cycles/react'; -import { - getAudioContext, - getLoadedSamples, - initAudioOnFirstClick, - resetLoadedSamples, - webaudioOutput, -} from '@strudel.cycles/webaudio'; +import { getAudioContext, initAudioOnFirstClick, resetLoadedSounds, webaudioOutput } from '@strudel.cycles/webaudio'; import { createClient } from '@supabase/supabase-js'; import { nanoid } from 'nanoid'; import React, { createContext, useCallback, useEffect, useState } from 'react'; @@ -53,7 +47,6 @@ evalScope( ...modules, ); -export let loadedSamples = []; const presets = prebake(); let drawContext, clearCanvas; @@ -62,11 +55,6 @@ if (typeof window !== 'undefined') { clearCanvas = () => drawContext.clearRect(0, 0, drawContext.canvas.height, drawContext.canvas.width); } -Promise.all([...modules, presets]).then((data) => { - // console.log('modules and sample registry loade', data); - loadedSamples = Object.entries(getLoadedSamples() || {}); -}); - const getTime = () => getAudioContext().currentTime; async function initCode() { @@ -211,7 +199,7 @@ export function Repl({ embedded = false }) { const { code, name } = getRandomTune(); logger(`[repl] ✨ loading random tune "${name}"`); clearCanvas(); - resetLoadedSamples(); + resetLoadedSounds(); await prebake(); // declare default samples await evaluate(code, false); }; diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index b0e1cc96..e1a8ac9a 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -1,9 +1,10 @@ import { Pattern, toMidi, valueToMidi } from '@strudel.cycles/core'; -import { samples } from '@strudel.cycles/webaudio'; +import { loadSynthSounds, samples } from '@strudel.cycles/webaudio'; export async function prebake() { // https://archive.org/details/SalamanderGrandPianoV3 // License: CC-by http://creativecommons.org/licenses/by/3.0/ Author: Alexander Holm + loadSynthSounds(); return await Promise.all([ samples(`./piano.json`, `./piano/`), // https://github.com/sgossner/VCSL/ From b08a0b8102611f62ea60a75df5da5047698693a2 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 6 Mar 2023 23:11:09 +0100 Subject: [PATCH 02/24] use nanostore for soundmap + rename tab samples to sounds + listed sounds are now reactive --- packages/webaudio/package.json | 3 ++- packages/webaudio/sampler.mjs | 5 ----- packages/webaudio/synth.mjs | 2 +- packages/webaudio/webaudio.mjs | 22 ++++++++++++---------- pnpm-lock.yaml | 2 ++ website/src/repl/Footer.jsx | 23 +++++++++++++---------- website/src/repl/prebake.mjs | 6 +++--- website/src/styles/index.css | 2 +- 8 files changed, 34 insertions(+), 31 deletions(-) diff --git a/packages/webaudio/package.json b/packages/webaudio/package.json index 3bc7de38..74b155da 100644 --- a/packages/webaudio/package.json +++ b/packages/webaudio/package.json @@ -34,7 +34,8 @@ }, "homepage": "https://github.com/tidalcycles/strudel#readme", "dependencies": { - "@strudel.cycles/core": "workspace:*" + "@strudel.cycles/core": "workspace:*", + "nanostores": "^0.7.4" }, "devDependencies": { "vite": "^3.2.2" diff --git a/packages/webaudio/sampler.mjs b/packages/webaudio/sampler.mjs index 219b0581..44fbef0b 100644 --- a/packages/webaudio/sampler.mjs +++ b/packages/webaudio/sampler.mjs @@ -179,11 +179,6 @@ export async function onTriggerSample(options, bank) { // no playback return; } - if (!s) { - // is this check really needed? - console.warn('no sample specified'); - return; - } //const soundfont = getSoundfontKey(s); let bufferSource; diff --git a/packages/webaudio/synth.mjs b/packages/webaudio/synth.mjs index abc05b63..e43ed7a0 100644 --- a/packages/webaudio/synth.mjs +++ b/packages/webaudio/synth.mjs @@ -2,7 +2,7 @@ import { fromMidi, toMidi } from '@strudel.cycles/core'; import { setSound } from './webaudio.mjs'; import { getOscillator, gainNode, getADSR } from './helpers.mjs'; -export function loadSynthSounds() { +export function registerSynthSounds() { ['sine', 'square', 'triangle', 'sawtooth'].forEach((wave) => { setSound(wave, ({ hap, duration, t }) => { // destructure adsr here, because the default should be different for synths and samples diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index f515763a..0b83dd24 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -11,15 +11,14 @@ const { Pattern } = strudel; import './vowel.mjs'; import workletsUrl from './worklets.mjs?url'; import { getFilter, gainNode } from './helpers.mjs'; +import { map } from 'nanostores'; -// export const getAudioContext = () => Tone.getContext().rawContext; - -export const soundMap = new Map(); +export const soundMap = map(); // onTrigger = ({ hap: Hap, t: number, deadline: number, duration: number, cps: number }) => AudioNode export function setSound(key, onTrigger) { - soundMap.set(key, onTrigger); + soundMap.setKey(key, onTrigger); } -export const resetLoadedSounds = () => soundMap.clear(); +export const resetLoadedSounds = () => soundMap.set({}); let audioContext; export const getAudioContext = () => { @@ -161,14 +160,17 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => { if (bank && s) { s = `${bank}_${s}`; } - if (soundMap.has(s)) { - const node = await soundMap.get(s)({ hap, t, deadline, duration: hapDuration, cps }); - chain.push(node); - } else if (source) { - chain.push(source({ hap, t, deadline, duration: hapDuration, cps })); + // get source AudioNode + let node; + const options = { hap, t, deadline, duration: hapDuration, cps }; + if (source) { + node = source(options); + } else if (soundMap.get()[s]) { + node = await soundMap.get()[s](options); } else { throw new Error(`sound ${s} not found! Is it loaded?`); } + chain.push(node); // gain stage chain.push(gainNode(gain)); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 473c8f3b..b325c96c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -321,9 +321,11 @@ importers: packages/webaudio: specifiers: '@strudel.cycles/core': workspace:* + nanostores: ^0.7.4 vite: ^3.2.2 dependencies: '@strudel.cycles/core': link:../core + nanostores: 0.7.4 devDependencies: vite: 3.2.5 diff --git a/website/src/repl/Footer.jsx b/website/src/repl/Footer.jsx index fe2eddc9..9ce1d859 100644 --- a/website/src/repl/Footer.jsx +++ b/website/src/repl/Footer.jsx @@ -7,6 +7,8 @@ import React, { useCallback, useLayoutEffect, useRef, useState } from 'react'; import { Reference } from './Reference'; import { themes } from './themes.mjs'; import { useSettings, settingsMap, setActiveFooter, defaultSettings } from '../settings.mjs'; +import { soundMap } from '@strudel.cycles/webaudio'; +import { useStore } from '@nanostores/react'; export function Footer({ context }) { const footerContent = useRef(); @@ -71,7 +73,7 @@ export function Footer({ context }) {
- + @@ -89,7 +91,7 @@ export function Footer({ context }) { > {activeFooter === 'intro' && } {activeFooter === 'console' && } - {activeFooter === 'samples' && } + {activeFooter === 'sounds' && } {activeFooter === 'reference' && } {activeFooter === 'settings' && }
@@ -192,18 +194,19 @@ function ConsoleTab({ log }) { ); } -function SamplesTab() { +function SoundsTab() { + const sounds = useStore(soundMap); return ( -
- TODO: use nanostore with sampleMap - {/* {loadedSamples.length} banks loaded: - {loadedSamples.map(([name, samples]) => ( +
+ {/* {loadedSamples.length} banks loaded: */} + {Object.entries(sounds).map(([name, samples]) => ( {}}> {' '} - {name}( - {Array.isArray(samples) ? samples.length : typeof samples === 'object' ? Object.values(samples).length : 1}){' '} + {name} + {/* ( + {Array.isArray(samples) ? samples.length : typeof samples === 'object' ? Object.values(samples).length : 1}) */} - ))} */} + ))}
); } diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index e1a8ac9a..c9f92249 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -1,11 +1,10 @@ import { Pattern, toMidi, valueToMidi } from '@strudel.cycles/core'; -import { loadSynthSounds, samples } from '@strudel.cycles/webaudio'; +import { registerSynthSounds, samples } from '@strudel.cycles/webaudio'; export async function prebake() { // https://archive.org/details/SalamanderGrandPianoV3 // License: CC-by http://creativecommons.org/licenses/by/3.0/ Author: Alexander Holm - loadSynthSounds(); - return await Promise.all([ + await Promise.all([ samples(`./piano.json`, `./piano/`), // https://github.com/sgossner/VCSL/ // https://api.github.com/repositories/126427031/contents/ @@ -15,6 +14,7 @@ export async function prebake() { samples(`./EmuSP12.json`, `./EmuSP12/`), // samples('github:tidalcycles/Dirt-Samples/master'), ]); + registerSynthSounds(); } const maxPan = toMidi('C8'); diff --git a/website/src/styles/index.css b/website/src/styles/index.css index 2657bab7..61940e02 100644 --- a/website/src/styles/index.css +++ b/website/src/styles/index.css @@ -23,6 +23,6 @@ } #console-tab, -#samples-tab { +#sounds-tab { font-family: BigBlueTerminal, monospace; } From 35ef26c01375577c3de69a0c9a009e8d2edaa810 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Tue, 7 Mar 2023 21:43:01 +0100 Subject: [PATCH 03/24] can now pass meta data to setSound + added types for synth and sample + list sample count for samples in sounds tab (as before) --- packages/webaudio/sampler.mjs | 2 +- packages/webaudio/synth.mjs | 56 ++++++++++++++++++---------------- packages/webaudio/webaudio.mjs | 7 +++-- website/src/repl/Footer.jsx | 8 ++--- 4 files changed, 39 insertions(+), 34 deletions(-) diff --git a/packages/webaudio/sampler.mjs b/packages/webaudio/sampler.mjs index 44fbef0b..eaaaf8dd 100644 --- a/packages/webaudio/sampler.mjs +++ b/packages/webaudio/sampler.mjs @@ -149,7 +149,7 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '') => { }), ); } - setSound(key, (options) => onTriggerSample(options, value)); + setSound(key, (options) => onTriggerSample(options, value), { type: 'sample', samples: value }); }); }; diff --git a/packages/webaudio/synth.mjs b/packages/webaudio/synth.mjs index e43ed7a0..b840a6aa 100644 --- a/packages/webaudio/synth.mjs +++ b/packages/webaudio/synth.mjs @@ -4,31 +4,35 @@ import { getOscillator, gainNode, getADSR } from './helpers.mjs'; export function registerSynthSounds() { ['sine', 'square', 'triangle', 'sawtooth'].forEach((wave) => { - setSound(wave, ({ hap, duration, t }) => { - // destructure adsr here, because the default should be different for synths and samples - const { attack = 0.001, decay = 0.05, sustain = 0.6, release = 0.01 } = hap.value; - let { n, note, freq } = hap.value; - // with synths, n and note are the same thing - n = note || n || 36; - if (typeof n === 'string') { - n = toMidi(n); // e.g. c3 => 48 - } - // get frequency - if (!freq && typeof n === 'number') { - freq = fromMidi(n); // + 48); - } - // maybe pull out the above frequency resolution?? (there is also getFrequency but it has no default) - // make oscillator - const o = getOscillator({ t, s: wave, freq, duration, release }); - // chain.push(o); - // level down oscillators as they are really loud compared to samples i've tested - //chain.push(gainNode(0.3)); - const g = gainNode(0.3); - // TODO: make adsr work with samples without pops - // envelope - const adsr = getADSR(attack, decay, sustain, release, 1, t, t + duration); - //chain.push(adsr); - return o.connect(g).connect(adsr); - }); + setSound( + wave, + ({ hap, duration, t }) => { + // destructure adsr here, because the default should be different for synths and samples + const { attack = 0.001, decay = 0.05, sustain = 0.6, release = 0.01 } = hap.value; + let { n, note, freq } = hap.value; + // with synths, n and note are the same thing + n = note || n || 36; + if (typeof n === 'string') { + n = toMidi(n); // e.g. c3 => 48 + } + // get frequency + if (!freq && typeof n === 'number') { + freq = fromMidi(n); // + 48); + } + // maybe pull out the above frequency resolution?? (there is also getFrequency but it has no default) + // make oscillator + const o = getOscillator({ t, s: wave, freq, duration, release }); + // chain.push(o); + // level down oscillators as they are really loud compared to samples i've tested + //chain.push(gainNode(0.3)); + const g = gainNode(0.3); + // TODO: make adsr work with samples without pops + // envelope + const adsr = getADSR(attack, decay, sustain, release, 1, t, t + duration); + //chain.push(adsr); + return o.connect(g).connect(adsr); + }, + { type: 'synth' }, + ); }); } diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 0b83dd24..077a2de0 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -15,8 +15,8 @@ import { map } from 'nanostores'; export const soundMap = map(); // onTrigger = ({ hap: Hap, t: number, deadline: number, duration: number, cps: number }) => AudioNode -export function setSound(key, onTrigger) { - soundMap.setKey(key, onTrigger); +export function setSound(key, onTrigger, data = {}) { + soundMap.setKey(key, { onTrigger, data }); } export const resetLoadedSounds = () => soundMap.set({}); @@ -166,7 +166,8 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => { if (source) { node = source(options); } else if (soundMap.get()[s]) { - node = await soundMap.get()[s](options); + const { onTrigger } = soundMap.get()[s]; + node = await onTrigger(options); } else { throw new Error(`sound ${s} not found! Is it loaded?`); } diff --git a/website/src/repl/Footer.jsx b/website/src/repl/Footer.jsx index 9ce1d859..947b6b87 100644 --- a/website/src/repl/Footer.jsx +++ b/website/src/repl/Footer.jsx @@ -196,15 +196,15 @@ function ConsoleTab({ log }) { function SoundsTab() { const sounds = useStore(soundMap); + const getSamples = (samples) => + Array.isArray(samples) ? samples.length : typeof samples === 'object' ? Object.values(samples).length : 1; return (
{/* {loadedSamples.length} banks loaded: */} - {Object.entries(sounds).map(([name, samples]) => ( + {Object.entries(sounds).map(([name, { data }]) => ( {}}> {' '} - {name} - {/* ( - {Array.isArray(samples) ? samples.length : typeof samples === 'object' ? Object.values(samples).length : 1}) */} + {name} {data?.type === 'sample' ? `(${getSamples(data.samples)})` : ''} ))}
From cee08ea67d93af531ed42cf6a2d215d92c8b6883 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 8 Mar 2023 00:33:21 +0100 Subject: [PATCH 04/24] sounds list can now filter out defaults --- packages/webaudio/sampler.mjs | 12 +++++-- packages/webaudio/synth.mjs | 2 +- website/public/vcsl.json | 2 +- website/src/repl/Footer.jsx | 68 +++++++++++++++++++++++++++++------ website/src/repl/prebake.mjs | 10 +++--- website/src/settings.mjs | 1 + website/src/styles/index.css | 3 +- 7 files changed, 76 insertions(+), 22 deletions(-) diff --git a/packages/webaudio/sampler.mjs b/packages/webaudio/sampler.mjs index eaaaf8dd..cff090d7 100644 --- a/packages/webaudio/sampler.mjs +++ b/packages/webaudio/sampler.mjs @@ -105,7 +105,7 @@ export const getLoadedBuffer = (url) => { * */ -export const samples = async (sampleMap, baseUrl = sampleMap._base || '') => { +export const samples = async (sampleMap, baseUrl = sampleMap._base || '', options = {}) => { if (typeof sampleMap === 'string') { if (sampleMap.startsWith('github:')) { let [_, path] = sampleMap.split('github:'); @@ -123,12 +123,13 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '') => { } return fetch(sampleMap) .then((res) => res.json()) - .then((json) => samples(json, baseUrl || json._base || base)) + .then((json) => samples(json, baseUrl || json._base || base, options)) .catch((error) => { console.error(error); throw new Error(`error loading "${sampleMap}"`); }); } + const { prebake } = options; Object.entries(sampleMap).forEach(([key, value]) => { if (typeof value === 'string') { value = [value]; @@ -149,7 +150,12 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '') => { }), ); } - setSound(key, (options) => onTriggerSample(options, value), { type: 'sample', samples: value }); + setSound(key, (options) => onTriggerSample(options, value), { + type: 'sample', + samples: value, + baseUrl, + prebake, + }); }); }; diff --git a/packages/webaudio/synth.mjs b/packages/webaudio/synth.mjs index b840a6aa..d615661a 100644 --- a/packages/webaudio/synth.mjs +++ b/packages/webaudio/synth.mjs @@ -32,7 +32,7 @@ export function registerSynthSounds() { //chain.push(adsr); return o.connect(g).connect(adsr); }, - { type: 'synth' }, + { type: 'synth', prebake: true }, ); }); } diff --git a/website/public/vcsl.json b/website/public/vcsl.json index 9ab06549..983cde89 100644 --- a/website/public/vcsl.json +++ b/website/public/vcsl.json @@ -1986,7 +1986,7 @@ "Idiophones/Struck%20Idiophones/Tambourine%202/Tamb2_Shake_rr3_Mid.wav", "Idiophones/Struck%20Idiophones/Tambourine%202/Tamb2_Shake_rr4_Mid.wav" ], - "triangle": [ + "triangles": [ "Idiophones/Struck%20Idiophones/Triangles/Triangle1_HitFM_v1_rr1_Mid.wav", "Idiophones/Struck%20Idiophones/Triangles/Triangle1_HitFM_v1_rr2_Mid.wav", "Idiophones/Struck%20Idiophones/Triangles/Triangle1_HitM_v1_rr2_Mid.wav", diff --git a/website/src/repl/Footer.jsx b/website/src/repl/Footer.jsx index 947b6b87..f5454541 100644 --- a/website/src/repl/Footer.jsx +++ b/website/src/repl/Footer.jsx @@ -3,7 +3,7 @@ import { logger } from '@strudel.cycles/core'; import { useEvent, cx } from '@strudel.cycles/react'; // import { cx } from '@strudel.cycles/react'; import { nanoid } from 'nanoid'; -import React, { useCallback, useLayoutEffect, useRef, useState } from 'react'; +import React, { useMemo, useCallback, useLayoutEffect, useRef, useState } from 'react'; import { Reference } from './Reference'; import { themes } from './themes.mjs'; import { useSettings, settingsMap, setActiveFooter, defaultSettings } from '../settings.mjs'; @@ -194,19 +194,67 @@ function ConsoleTab({ log }) { ); } +/* +function groupBy(obj = {}, getter) { + const grouped = Object.entries(obj).reduce((acc, [key, value]) => { + const propValue = getter(value, key); + if (!acc.has(propValue)) { + acc.set(propValue, new Map()); + } + acc.get(propValue).set(key, value); + return acc; + }, new Map()); + return grouped; +} + const grouped = useMemo(() => { + if (!sounds) { + return {}; + } + return groupBy(sounds, (s) => + s.data.type === 'sample' ? 'Samples from ' + s.data?.baseUrl : 'Type ' + s.data.type, + ); +}, [sounds]); + + {Array.from(grouped).map(([category, sounds]) => ( + +

{category}:

+
+ ))} +*/ + +const getSamples = (samples) => + Array.isArray(samples) ? samples.length : typeof samples === 'object' ? Object.values(samples).length : 1; + function SoundsTab() { const sounds = useStore(soundMap); - const getSamples = (samples) => - Array.isArray(samples) ? samples.length : typeof samples === 'object' ? Object.values(samples).length : 1; + const { soundsFilter } = useSettings(); + + const soundEntries = useMemo(() => { + if (!sounds) { + return []; + } + if (soundsFilter === 'hideDefaults') { + return Object.entries(sounds).filter(([_, { data }]) => !data.prebake); + } + return Object.entries(sounds); + }, [sounds, soundsFilter]); return (
- {/* {loadedSamples.length} banks loaded: */} - {Object.entries(sounds).map(([name, { data }]) => ( - {}}> - {' '} - {name} {data?.type === 'sample' ? `(${getSamples(data.samples)})` : ''} - - ))} + settingsMap.setKey('soundsFilter', value)} + items={{ all: 'All', hideDefaults: 'Hide Defaults' }} + > +
+ {soundEntries.map(([name, { data }]) => ( + {}}> + {' '} + {name} + {data?.type === 'sample' ? `(${getSamples(data.samples)})` : ''} + + ))} + {!soundEntries.length ? 'No Sounds' : ''} +
); } diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index c9f92249..e68274cf 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -4,17 +4,17 @@ import { registerSynthSounds, samples } from '@strudel.cycles/webaudio'; export async function prebake() { // https://archive.org/details/SalamanderGrandPianoV3 // License: CC-by http://creativecommons.org/licenses/by/3.0/ Author: Alexander Holm + registerSynthSounds(); await Promise.all([ - samples(`./piano.json`, `./piano/`), + samples(`./piano.json`, `./piano/`, { prebake: true }), // https://github.com/sgossner/VCSL/ // https://api.github.com/repositories/126427031/contents/ // LICENSE: CC0 general-purpose - samples(`./vcsl.json`, 'github:sgossner/VCSL/master/'), - samples(`./tidal-drum-machines.json`, 'github:ritchse/tidal-drum-machines/main/machines/'), - samples(`./EmuSP12.json`, `./EmuSP12/`), + samples(`./vcsl.json`, 'github:sgossner/VCSL/master/', { prebake: true }), + samples(`./tidal-drum-machines.json`, 'github:ritchse/tidal-drum-machines/main/machines/', { prebake: true }), + samples(`./EmuSP12.json`, `./EmuSP12/`, { prebake: true }), // samples('github:tidalcycles/Dirt-Samples/master'), ]); - registerSynthSounds(); } const maxPan = toMidi('C8'); diff --git a/website/src/settings.mjs b/website/src/settings.mjs index 82888581..583454c7 100644 --- a/website/src/settings.mjs +++ b/website/src/settings.mjs @@ -9,6 +9,7 @@ export const defaultSettings = { fontSize: 18, latestCode: '', isZen: false, + soundsFilter: 'all', }; export const settingsMap = persistentMap('strudel-settings', defaultSettings); diff --git a/website/src/styles/index.css b/website/src/styles/index.css index 61940e02..1e14461b 100644 --- a/website/src/styles/index.css +++ b/website/src/styles/index.css @@ -22,7 +22,6 @@ --app-height: 100vh; } -#console-tab, -#sounds-tab { +#console-tab { font-family: BigBlueTerminal, monospace; } From 65e48c05f0c852feba95b20d6ad496701072a7ab Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 9 Mar 2023 08:35:20 +0100 Subject: [PATCH 05/24] sounds onset and offset can be triggered independently + sounds tab now supports mousedown / mouseup to listen --- packages/webaudio/helpers.mjs | 25 +++++++++++++++-- packages/webaudio/sampler.mjs | 50 +++++++++++++++++++--------------- packages/webaudio/synth.mjs | 25 +++++++++-------- packages/webaudio/webaudio.mjs | 26 +++++++++++++----- packages/webdirt/webdirt.mjs | 1 + website/src/repl/Footer.jsx | 24 +++++++++++++--- 6 files changed, 103 insertions(+), 48 deletions(-) diff --git a/packages/webaudio/helpers.mjs b/packages/webaudio/helpers.mjs index a17b7408..1ed1e637 100644 --- a/packages/webaudio/helpers.mjs +++ b/packages/webaudio/helpers.mjs @@ -6,14 +6,33 @@ export function gainNode(value) { return node; } -export const getOscillator = ({ s, freq, t, duration, release }) => { +export const getOscillator = ({ s, freq, t }) => { // 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; + //o.stop(t + duration + release); + const stop = (time) => o.stop(time); + return { node: o, stop }; +}; + +// alternative to getADSR returning the gain node and a stop handle to trigger the release anytime in the future +export const getEnvelope = (attack, decay, sustain, release, velocity, begin) => { + const gainNode = getAudioContext().createGain(); + gainNode.gain.setValueAtTime(0, begin); + gainNode.gain.linearRampToValueAtTime(velocity, begin + attack); // attack + gainNode.gain.linearRampToValueAtTime(sustain * velocity, begin + attack + decay); // sustain start + // sustain end + return { + node: gainNode, + stop: (t) => { + gainNode.gain.setValueAtTime(sustain * velocity, t); + gainNode.gain.linearRampToValueAtTime(0, t + release); + }, + }; + // gainNode.gain.linearRampToValueAtTime(0, end + release); // release + // return gainNode; }; export const getADSR = (attack, decay, sustain, release, velocity, begin, end) => { diff --git a/packages/webaudio/sampler.mjs b/packages/webaudio/sampler.mjs index cff090d7..e08b1084 100644 --- a/packages/webaudio/sampler.mjs +++ b/packages/webaudio/sampler.mjs @@ -1,6 +1,6 @@ import { logger, toMidi, valueToMidi } from '@strudel.cycles/core'; import { getAudioContext, setSound } from './index.mjs'; -import { getADSR } from './helpers.mjs'; +import { getEnvelope } from './helpers.mjs'; const bufferCache = {}; // string: Promise const loadCache = {}; // string: Promise @@ -150,7 +150,7 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '', option }), ); } - setSound(key, (options) => onTriggerSample(options, value), { + setSound(key, (t, hapValue) => onTriggerSample(t, hapValue, value), { type: 'sample', samples: value, baseUrl, @@ -161,8 +161,7 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '', option const cutGroups = []; -export async function onTriggerSample(options, bank) { - const { hap, duration: hapDuration, t, cps } = options; +export async function onTriggerSample(t, value, bank) { const { s, freq, @@ -176,10 +175,10 @@ export async function onTriggerSample(options, bank) { speed = 1, // sample playback speed begin = 0, end = 1, - } = hap.value; + } = value; const ac = getAudioContext(); // destructure adsr here, because the default should be different for synths and samples - const { attack = 0.001, decay = 0.001, sustain = 1, release = 0.001 } = hap.value; + const { attack = 0.001, decay = 0.001, sustain = 1, release = 0.001 } = value; // load sample if (speed === 0) { // no playback @@ -208,34 +207,41 @@ export async function onTriggerSample(options, bank) { bufferSource.playbackRate.value = Math.abs(speed) * bufferSource.playbackRate.value; if (unit === 'c') { // are there other units? - bufferSource.playbackRate.value = bufferSource.playbackRate.value * bufferSource.buffer.duration * cps; + bufferSource.playbackRate.value = bufferSource.playbackRate.value * bufferSource.buffer.duration * 1; //cps; } - const shouldClip = /* soundfont || */ clip; - let duration = shouldClip ? hapDuration : bufferSource.buffer.duration / bufferSource.playbackRate.value; // "The computation of the offset into the sound is performed using the sound buffer's natural sample rate, // rather than the current playback rate, so even if the sound is playing at twice its normal speed, // the midway point through a 10-second audio buffer is still 5." - const offset = begin * duration * bufferSource.playbackRate.value; - duration = (end - begin) * duration; - if (loop) { + const time = t + nudge; + const offset = begin * bufferSource.buffer.duration; + bufferSource.start(time, offset); + const bufferDuration = bufferSource.buffer.duration / bufferSource.playbackRate.value; + /*if (loop) { + // TODO: idea for loopBegin / loopEnd + // if one of [loopBegin,loopEnd] is <= 1, interpret it as normlized + // if [loopBegin,loopEnd] is bigger >= 1, interpret it as sample number + // this will simplify perfectly looping things, while still keeping the normalized option + // the only drawback is that looping between samples 0 and 1 is not possible (which is not real use case) bufferSource.loop = true; bufferSource.loopStart = offset; bufferSource.loopEnd = offset + duration; duration = loop * duration; - } - const time = t + nudge; - - bufferSource.start(time, offset); + }*/ + const { node: envelope, stop: releaseEnvelope } = getEnvelope(attack, decay, sustain, release, 1, t); + bufferSource.connect(envelope); if (cut !== undefined) { cutGroups[cut]?.stop(time); // fade out? cutGroups[cut] = bufferSource; } - //chain.push(bufferSource); - bufferSource.stop(t + duration + release); - const adsr = getADSR(attack, decay, sustain, release, 1, time, time + duration); - bufferSource.connect(adsr); - //chain.push(adsr); - return adsr; + const stop = (endTime) => { + let releaseTime = endTime; + if (!clip) { + releaseTime = t + (end - begin) * bufferDuration; + } + bufferSource.stop(releaseTime + release); + releaseEnvelope(releaseTime); + }; + return { node: envelope, stop }; } /*const getSoundfontKey = (s) => { diff --git a/packages/webaudio/synth.mjs b/packages/webaudio/synth.mjs index d615661a..426e6573 100644 --- a/packages/webaudio/synth.mjs +++ b/packages/webaudio/synth.mjs @@ -1,15 +1,15 @@ import { fromMidi, toMidi } from '@strudel.cycles/core'; import { setSound } from './webaudio.mjs'; -import { getOscillator, gainNode, getADSR } from './helpers.mjs'; +import { getOscillator, gainNode, getEnvelope } from './helpers.mjs'; export function registerSynthSounds() { ['sine', 'square', 'triangle', 'sawtooth'].forEach((wave) => { setSound( wave, - ({ hap, duration, t }) => { + (t, value) => { // destructure adsr here, because the default should be different for synths and samples - const { attack = 0.001, decay = 0.05, sustain = 0.6, release = 0.01 } = hap.value; - let { n, note, freq } = hap.value; + const { attack = 0.001, decay = 0.05, sustain = 0.6, release = 0.01 } = value; + let { n, note, freq } = value; // with synths, n and note are the same thing n = note || n || 36; if (typeof n === 'string') { @@ -21,16 +21,17 @@ export function registerSynthSounds() { } // maybe pull out the above frequency resolution?? (there is also getFrequency but it has no default) // make oscillator - const o = getOscillator({ t, s: wave, freq, duration, release }); - // chain.push(o); - // level down oscillators as they are really loud compared to samples i've tested - //chain.push(gainNode(0.3)); + const { node: o, stop } = getOscillator({ t, s: wave, freq }); const g = gainNode(0.3); - // TODO: make adsr work with samples without pops // envelope - const adsr = getADSR(attack, decay, sustain, release, 1, t, t + duration); - //chain.push(adsr); - return o.connect(g).connect(adsr); + const { node: envelope, stop: releaseEnvelope } = getEnvelope(attack, decay, sustain, release, 1, t); + return { + node: o.connect(g).connect(envelope), + stop: (t) => { + releaseEnvelope(t); + stop(t + release); + }, + }; }, { type: 'synth', prebake: true }, ); diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 077a2de0..c2bca304 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -7,7 +7,7 @@ This program is free software: you can redistribute it and/or modify it under th import * as strudel from '@strudel.cycles/core'; import './feedbackdelay.mjs'; import './reverb.mjs'; -const { Pattern } = strudel; +const { Pattern, logger } = strudel; import './vowel.mjs'; import workletsUrl from './worklets.mjs?url'; import { getFilter, gainNode } from './helpers.mjs'; @@ -125,7 +125,7 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => { // calculate absolute time let t = ac.currentTime + deadline; - // destructure value + // destructure let { s = 'triangle', bank, @@ -161,17 +161,29 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => { s = `${bank}_${s}`; } // get source AudioNode - let node; - const options = { hap, t, deadline, duration: hapDuration, cps }; + let sourceNode; if (source) { - node = source(options); + sourceNode = source(t, hap.value); } else if (soundMap.get()[s]) { const { onTrigger } = soundMap.get()[s]; - node = await onTrigger(options); + const soundHandle = await onTrigger(t, hap.value); + if (soundHandle) { + sourceNode = soundHandle.node; + soundHandle.stop(t + hapDuration); + } } else { throw new Error(`sound ${s} not found! Is it loaded?`); } - chain.push(node); + if (!sourceNode) { + // if onTrigger does not return anything, we will just silently skip + // this can be used for things like speed(0) in the sampler + return; + } + if (ac.currentTime > t) { + logger('[webaudio] skip hap: still loading', ac.currentTime - t); + return; + } + chain.push(sourceNode); // gain stage chain.push(gainNode(gain)); diff --git a/packages/webdirt/webdirt.mjs b/packages/webdirt/webdirt.mjs index c106bf17..bf1284f8 100644 --- a/packages/webdirt/webdirt.mjs +++ b/packages/webdirt/webdirt.mjs @@ -62,6 +62,7 @@ export function loadWebDirt(config) { * @noAutocomplete */ Pattern.prototype.webdirt = function () { + throw new Error('webdirt support has been dropped..'); // create a WebDirt object and initialize Web Audio context /* return this.onTrigger(async (time, e, currentTime) => { if (!webDirt) { diff --git a/website/src/repl/Footer.jsx b/website/src/repl/Footer.jsx index f5454541..71e255ed 100644 --- a/website/src/repl/Footer.jsx +++ b/website/src/repl/Footer.jsx @@ -7,7 +7,7 @@ import React, { useMemo, useCallback, useLayoutEffect, useRef, useState } from ' import { Reference } from './Reference'; import { themes } from './themes.mjs'; import { useSettings, settingsMap, setActiveFooter, defaultSettings } from '../settings.mjs'; -import { soundMap } from '@strudel.cycles/webaudio'; +import { getAudioContext, soundMap } from '@strudel.cycles/webaudio'; import { useStore } from '@nanostores/react'; export function Footer({ context }) { @@ -238,6 +238,12 @@ function SoundsTab() { } return Object.entries(sounds); }, [sounds, soundsFilter]); + // holds mutable ref to current triggered sound + const trigRef = useRef(); + // stop current sound on mouseup + useEvent('mouseup', () => { + trigRef.current?.then((ref) => ref?.stop(getAudioContext().currentTime + 0.01)); + }); return (
settingsMap.setKey('soundsFilter', value)} items={{ all: 'All', hideDefaults: 'Hide Defaults' }} > -
- {soundEntries.map(([name, { data }]) => ( - {}}> +
+ {soundEntries.map(([name, { data, onTrigger }]) => ( + { + const ctx = getAudioContext(); + trigRef.current = Promise.resolve(onTrigger(ctx.currentTime + 0.05, { freq: 220, s: name, clip: 1 })); + trigRef.current.then((ref) => { + ref?.node.connect(ctx.destination); + }); + }} + > {' '} {name} {data?.type === 'sample' ? `(${getSamples(data.samples)})` : ''} From be6b0112040762f9c96dd38eaab4c7187402d783 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 9 Mar 2023 10:46:45 +0100 Subject: [PATCH 06/24] proper audio node cleanup + cleanup onTriggerSample --- packages/webaudio/sampler.mjs | 53 ++++++++++++++++++++-------------- packages/webaudio/synth.mjs | 7 ++++- packages/webaudio/webaudio.mjs | 14 +++++---- 3 files changed, 46 insertions(+), 28 deletions(-) diff --git a/packages/webaudio/sampler.mjs b/packages/webaudio/sampler.mjs index e08b1084..141dd5f7 100644 --- a/packages/webaudio/sampler.mjs +++ b/packages/webaudio/sampler.mjs @@ -150,7 +150,7 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '', option }), ); } - setSound(key, (t, hapValue) => onTriggerSample(t, hapValue, value), { + setSound(key, (t, hapValue, onended) => onTriggerSample(t, hapValue, onended, value), { type: 'sample', samples: value, baseUrl, @@ -161,7 +161,7 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '', option const cutGroups = []; -export async function onTriggerSample(t, value, bank) { +export async function onTriggerSample(t, value, onended, bank) { const { s, freq, @@ -176,24 +176,19 @@ export async function onTriggerSample(t, value, bank) { begin = 0, end = 1, } = value; - const ac = getAudioContext(); - // destructure adsr here, because the default should be different for synths and samples - const { attack = 0.001, decay = 0.001, sustain = 1, release = 0.001 } = value; // load sample if (speed === 0) { // no playback return; } + const ac = getAudioContext(); + // destructure adsr here, because the default should be different for synths and samples + const { attack = 0.001, decay = 0.001, sustain = 1, release = 0.001 } = value; //const soundfont = getSoundfontKey(s); - let bufferSource; + const time = t + nudge; + + const bufferSource = await getSampleBufferSource(s, n, note, speed, freq, bank); - //if (soundfont) { - // is soundfont - //bufferSource = await globalThis.getFontBufferSource(soundfont, note || n, ac, freq); - //} else { - // is sample from loaded samples(..) - bufferSource = await getSampleBufferSource(s, n, note, speed, freq, bank); - //} // asny stuff above took too long? if (ac.currentTime > t) { logger(`[sampler] still loading sound "${s}:${n}"`, 'highlight'); @@ -201,7 +196,7 @@ export async function onTriggerSample(t, value, bank) { return; } if (!bufferSource) { - console.warn('no buffer source'); + logger(`[sampler] could not load "${s}:${n}"`, 'error'); return; } bufferSource.playbackRate.value = Math.abs(speed) * bufferSource.playbackRate.value; @@ -212,7 +207,6 @@ export async function onTriggerSample(t, value, bank) { // "The computation of the offset into the sound is performed using the sound buffer's natural sample rate, // rather than the current playback rate, so even if the sound is playing at twice its normal speed, // the midway point through a 10-second audio buffer is still 5." - const time = t + nudge; const offset = begin * bufferSource.buffer.duration; bufferSource.start(time, offset); const bufferDuration = bufferSource.buffer.duration / bufferSource.playbackRate.value; @@ -229,19 +223,33 @@ export async function onTriggerSample(t, value, bank) { }*/ const { node: envelope, stop: releaseEnvelope } = getEnvelope(attack, decay, sustain, release, 1, t); bufferSource.connect(envelope); - if (cut !== undefined) { - cutGroups[cut]?.stop(time); // fade out? - cutGroups[cut] = bufferSource; - } - const stop = (endTime) => { + bufferSource.onended = function () { + bufferSource.disconnect(); + envelope.disconnect(); + onended(); + }; + const stop = (endTime, playWholeBuffer = !clip) => { let releaseTime = endTime; - if (!clip) { + if (playWholeBuffer) { releaseTime = t + (end - begin) * bufferDuration; } bufferSource.stop(releaseTime + release); releaseEnvelope(releaseTime); }; - return { node: envelope, stop }; + const handle = { node: envelope, bufferSource, stop }; + + // cut groups + // TODO: sometimes, the cutting won't work for very fast triggering... + // it worked before :-/ + if (cut !== undefined) { + const prev = cutGroups[cut]; + if (prev) { + prev.stop(time, false); + } + cutGroups[cut] = handle; + } + + return handle; } /*const getSoundfontKey = (s) => { @@ -262,3 +270,4 @@ export async function onTriggerSample(t, value, bank) { } return; };*/ +// bufferSource = await globalThis.getFontBufferSource(soundfont, note || n, ac, freq); diff --git a/packages/webaudio/synth.mjs b/packages/webaudio/synth.mjs index 426e6573..f3be1ce6 100644 --- a/packages/webaudio/synth.mjs +++ b/packages/webaudio/synth.mjs @@ -6,7 +6,7 @@ export function registerSynthSounds() { ['sine', 'square', 'triangle', 'sawtooth'].forEach((wave) => { setSound( wave, - (t, value) => { + (t, value, onended) => { // destructure adsr here, because the default should be different for synths and samples const { attack = 0.001, decay = 0.05, sustain = 0.6, release = 0.01 } = value; let { n, note, freq } = value; @@ -25,6 +25,11 @@ export function registerSynthSounds() { const g = gainNode(0.3); // envelope const { node: envelope, stop: releaseEnvelope } = getEnvelope(attack, decay, sustain, release, 1, t); + o.onended = () => { + o.disconnect(); + g.disconnect(); + onended(); + }; return { node: o.connect(g).connect(envelope), stop: (t) => { diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index c2bca304..06b2ab49 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -155,8 +155,10 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => { } = hap.value; const { velocity = 1 } = hap.context; gain *= velocity; // legacy fix for velocity - // the chain will hold all audio nodes that connect to each other - const chain = []; + let toDisconnect = []; // audio nodes that will be disconnected when the source has ended + const onended = () => { + toDisconnect.forEach((n) => n?.disconnect()); + }; if (bank && s) { s = `${bank}_${s}`; } @@ -166,7 +168,7 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => { sourceNode = source(t, hap.value); } else if (soundMap.get()[s]) { const { onTrigger } = soundMap.get()[s]; - const soundHandle = await onTrigger(t, hap.value); + const soundHandle = await onTrigger(t, hap.value, onended); if (soundHandle) { sourceNode = soundHandle.node; soundHandle.stop(t + hapDuration); @@ -183,6 +185,7 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => { logger('[webaudio] skip hap: still loading', ac.currentTime - t); return; } + const chain = []; // audio nodes that will be connected to each other sequentially chain.push(sourceNode); // gain stage @@ -227,8 +230,9 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => { // connect chain elements together chain.slice(1).reduce((last, current) => last.connect(current), chain[0]); - // disconnect all nodes when source node has ended: - chain[0].onended = () => chain.concat([delaySend, reverbSend]).forEach((n) => n?.disconnect()); + // toDisconnect = all the node that should be disconnected in onended callback + // this is crucial for performance + toDisconnect = chain.concat([delaySend, reverbSend]); }; export const webaudioOutputTrigger = (t, hap, ct, cps) => webaudioOutput(hap, t - ct, hap.duration / cps, cps); From 41d82eaadf28becd8b30b29ef37d42754d0a2690 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 9 Mar 2023 10:53:35 +0100 Subject: [PATCH 07/24] add cleanup to sound tab --- website/src/repl/Footer.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/website/src/repl/Footer.jsx b/website/src/repl/Footer.jsx index 71e255ed..4fee856d 100644 --- a/website/src/repl/Footer.jsx +++ b/website/src/repl/Footer.jsx @@ -258,7 +258,10 @@ function SoundsTab() { className="cursor-pointer hover:opacity-50" onMouseDown={async () => { const ctx = getAudioContext(); - trigRef.current = Promise.resolve(onTrigger(ctx.currentTime + 0.05, { freq: 220, s: name, clip: 1 })); + const params = { freq: 220, s: name, clip: 1, release: 0.5 }; + const time = ctx.currentTime + 0.05; + const onended = () => trigRef.current?.node?.disconnect(); + trigRef.current = Promise.resolve(onTrigger(time, params, onended)); trigRef.current.then((ref) => { ref?.node.connect(ctx.destination); }); From ff1e6714c69f90b054ac9f2ae543f782d9912ef4 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 9 Mar 2023 21:27:24 +0100 Subject: [PATCH 08/24] document setSound api --- packages/webaudio/webaudio.mjs | 7 +- website/src/config.ts | 1 + website/src/pages/technical-manual/sounds.mdx | 75 +++++++++++++++++++ 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 website/src/pages/technical-manual/sounds.mdx diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 06b2ab49..ce68cb33 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -18,6 +18,9 @@ export const soundMap = map(); export function setSound(key, onTrigger, data = {}) { soundMap.setKey(key, { onTrigger, data }); } +export function getSound(s) { + return soundMap.get()[s]; +} export const resetLoadedSounds = () => soundMap.set({}); let audioContext; @@ -166,8 +169,8 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => { let sourceNode; if (source) { sourceNode = source(t, hap.value); - } else if (soundMap.get()[s]) { - const { onTrigger } = soundMap.get()[s]; + } else if (getSound(s)) { + const { onTrigger } = getSound(s); const soundHandle = await onTrigger(t, hap.value, onended); if (soundHandle) { sourceNode = soundHandle.node; diff --git a/website/src/config.ts b/website/src/config.ts index 266d60c0..bf26fff1 100644 --- a/website/src/config.ts +++ b/website/src/config.ts @@ -73,6 +73,7 @@ export const SIDEBAR: Sidebar = { ], Development: [ { text: 'REPL', link: 'technical-manual/repl' }, + { text: 'Sounds', link: 'technical-manual/sounds' }, { text: 'Packages', link: 'technical-manual/packages' }, { text: 'Docs', link: 'technical-manual/docs' }, { text: 'Testing', link: 'technical-manual/testing' }, diff --git a/website/src/pages/technical-manual/sounds.mdx b/website/src/pages/technical-manual/sounds.mdx new file mode 100644 index 00000000..b2f81ca7 --- /dev/null +++ b/website/src/pages/technical-manual/sounds.mdx @@ -0,0 +1,75 @@ +--- +title: Sounds +layout: ../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '../../docs/MiniRepl'; + +# Sounds + +Let's take a closer look about how sounds are implemented in the webaudio output. + +## Registering a sound via setSound + +All sounds are registered in the sound map, using the the `setSound` function: + +```ts +function setSound( + name: string, // The name of the sound that should be given to `s`, e.g. `mysaw` + // The function called by the scheduler to trigger the sound: + ( + time: number, // The audio context time the sound should start + value: object, // The value of the `Hap` + onended: () => void // A callback that should be fired when the sound has ended + ) => { + node: AudioNode, // node to connect to rest of the effects chain + stop: (time:number) => void // a function that will stop the sound + }, + data: object // meta data, only for ui logic in sounds tab +); +``` + +When `setSound` is called, it registers `{ onTrigger, data }` under the given `name` in a [nanostore map](https://github.com/nanostores/nanostores#maps). + +### Example + +This might be a bit abstract, so here is a minimal example: + +```js +setSound( + 'mysaw', + (time, value, onended) => { + let { freq } = value; // destructure control params + const ctx = getAudioContext(); + // create oscillator + const o = new OscillatorNode(ctx, { type: 'sawtooth', frequency: Number(freq) }); + o.start(time); + // add gain node to level down osc + const g = new GainNode(ctx, { gain: 0.3 }); + // connect osc to gain + const node = o.connect(g); + // this function can be called from outside to stop the sound + const stop = (time) => o.stop(time); + // ended will be fired when stop has been fired + o.addEventListener('ended', () => { + o.disconnect(); + g.disconnect(); + onended(); + }); + return { node, stop }; + }, + { type: 'synth' }, +); +// use the sound +freq(220, 440, 330).s('mysaw'); +``` + +You can actually use this code in the [REPL](https://strudel.tidalcycles.org/) and it'll work. +After evaluating the code, you should see `mysaw` in listed in the sounds tab. + +## Playing sounds + +Now here is what happens when a sound is played: +When the webaudio output plays a `Hap`, it will lookup and call the `onTrigger` function for the given `s`. +The returned `node` can then be connected to the rest of the standard effects chain +Having the stop function separate allows playing sounds via midi too, where you don't know how long the noteon will last From 6f5d096e6d41bdc2c6ba92fa2954e18525df29a2 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 9 Mar 2023 21:32:40 +0100 Subject: [PATCH 09/24] rename setSound to registerSound --- packages/webaudio/sampler.mjs | 4 ++-- packages/webaudio/synth.mjs | 4 ++-- packages/webaudio/webaudio.mjs | 3 +-- website/src/pages/technical-manual/sounds.mdx | 10 +++++----- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/webaudio/sampler.mjs b/packages/webaudio/sampler.mjs index 141dd5f7..e153dd8b 100644 --- a/packages/webaudio/sampler.mjs +++ b/packages/webaudio/sampler.mjs @@ -1,5 +1,5 @@ import { logger, toMidi, valueToMidi } from '@strudel.cycles/core'; -import { getAudioContext, setSound } from './index.mjs'; +import { getAudioContext, registerSound } from './index.mjs'; import { getEnvelope } from './helpers.mjs'; const bufferCache = {}; // string: Promise @@ -150,7 +150,7 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '', option }), ); } - setSound(key, (t, hapValue, onended) => onTriggerSample(t, hapValue, onended, value), { + registerSound(key, (t, hapValue, onended) => onTriggerSample(t, hapValue, onended, value), { type: 'sample', samples: value, baseUrl, diff --git a/packages/webaudio/synth.mjs b/packages/webaudio/synth.mjs index f3be1ce6..6d16fae8 100644 --- a/packages/webaudio/synth.mjs +++ b/packages/webaudio/synth.mjs @@ -1,10 +1,10 @@ import { fromMidi, toMidi } from '@strudel.cycles/core'; -import { setSound } from './webaudio.mjs'; +import { registerSound } from './webaudio.mjs'; import { getOscillator, gainNode, getEnvelope } from './helpers.mjs'; export function registerSynthSounds() { ['sine', 'square', 'triangle', 'sawtooth'].forEach((wave) => { - setSound( + registerSound( wave, (t, value, onended) => { // destructure adsr here, because the default should be different for synths and samples diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index ce68cb33..8b694e93 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -14,8 +14,7 @@ import { getFilter, gainNode } from './helpers.mjs'; import { map } from 'nanostores'; export const soundMap = map(); -// onTrigger = ({ hap: Hap, t: number, deadline: number, duration: number, cps: number }) => AudioNode -export function setSound(key, onTrigger, data = {}) { +export function registerSound(key, onTrigger, data = {}) { soundMap.setKey(key, { onTrigger, data }); } export function getSound(s) { diff --git a/website/src/pages/technical-manual/sounds.mdx b/website/src/pages/technical-manual/sounds.mdx index b2f81ca7..ede7a426 100644 --- a/website/src/pages/technical-manual/sounds.mdx +++ b/website/src/pages/technical-manual/sounds.mdx @@ -9,12 +9,12 @@ import { MiniRepl } from '../../docs/MiniRepl'; Let's take a closer look about how sounds are implemented in the webaudio output. -## Registering a sound via setSound +## Registering a sound -All sounds are registered in the sound map, using the the `setSound` function: +All sounds are registered in the sound map, using the the `registerSound` function: ```ts -function setSound( +function registerSound( name: string, // The name of the sound that should be given to `s`, e.g. `mysaw` // The function called by the scheduler to trigger the sound: ( @@ -29,14 +29,14 @@ function setSound( ); ``` -When `setSound` is called, it registers `{ onTrigger, data }` under the given `name` in a [nanostore map](https://github.com/nanostores/nanostores#maps). +When `registerSound` is called, it registers `{ onTrigger, data }` under the given `name` in a [nanostore map](https://github.com/nanostores/nanostores#maps). ### Example This might be a bit abstract, so here is a minimal example: ```js -setSound( +registerSound( 'mysaw', (time, value, onended) => { let { freq } = value; // destructure control params From ac148b2f32a8d3a8b4ffcba21e8bc2a4263d916c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 9 Mar 2023 22:48:40 +0100 Subject: [PATCH 10/24] register soundfonts as sounds too --- packages/soundfonts/fontloader.mjs | 24 +- packages/soundfonts/index.mjs | 4 +- packages/soundfonts/list.mjs | 700 ++++++++++++++--------------- packages/soundfonts/sfumato.mjs | 26 +- packages/webaudio/sampler.mjs | 20 - website/src/repl/Footer.jsx | 24 +- website/src/repl/prebake.mjs | 2 + 7 files changed, 421 insertions(+), 379 deletions(-) diff --git a/packages/soundfonts/fontloader.mjs b/packages/soundfonts/fontloader.mjs index 9f88b0fe..a13eb764 100644 --- a/packages/soundfonts/fontloader.mjs +++ b/packages/soundfonts/fontloader.mjs @@ -1,4 +1,6 @@ import { toMidi } from '@strudel.cycles/core'; +import { getAudioContext, registerSound } from '@strudel.cycles/webaudio'; +import { instruments } from './list.mjs'; let loadCache = {}; async function loadFont(name) { @@ -8,7 +10,6 @@ async function loadFont(name) { const load = async () => { // TODO: make soundfont source configurable 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('={'); return eval('{' + data); @@ -114,3 +115,24 @@ async function getBuffer(zone, audioContext) { } } } + +export function registerSoundfonts() { + instruments.forEach((instrument) => { + registerSound( + instrument, + async (time, value, onended) => { + const { note, n } = value; + const ctx = getAudioContext(); + const bufferSource = await getFontBufferSource(instrument, note || n, ctx); + bufferSource.start(time); + const stop = (time) => bufferSource.stop(time); + bufferSource.onended = () => { + bufferSource.disconnect(); + onended(); + }; + return { node: bufferSource, stop }; + }, + { type: 'soundfont', prebake: true }, + ); + }); +} diff --git a/packages/soundfonts/index.mjs b/packages/soundfonts/index.mjs index 3c5c226c..c54297b5 100644 --- a/packages/soundfonts/index.mjs +++ b/packages/soundfonts/index.mjs @@ -1,6 +1,6 @@ -import { getFontBufferSource } from './fontloader.mjs'; +import { getFontBufferSource, registerSoundfonts } from './fontloader.mjs'; import * as soundfontList from './list.mjs'; import { startPresetNote } from 'sfumato'; import { loadSoundfont } from './sfumato.mjs'; -export { loadSoundfont, startPresetNote, getFontBufferSource, soundfontList }; +export { loadSoundfont, startPresetNote, getFontBufferSource, soundfontList, registerSoundfonts }; diff --git a/packages/soundfonts/list.mjs b/packages/soundfonts/list.mjs index 527ef024..96e5fd7c 100644 --- a/packages/soundfonts/list.mjs +++ b/packages/soundfonts/list.mjs @@ -4,8 +4,8 @@ export const instruments = [ '0000_Chaos_sf2_file', '0000_FluidR3_GM_sf2_file', '0000_GeneralUserGS_sf2_file', - '0000_SBLive_sf2', - '0000_SoundBlasterOld_sf2', + //'0000_SBLive_sf2', + //'0000_SoundBlasterOld_sf2', '0001_FluidR3_GM_sf2_file', '0001_GeneralUserGS_sf2_file', '0002_GeneralUserGS_sf2_file', @@ -15,8 +15,8 @@ export const instruments = [ '0010_FluidR3_GM_sf2_file', '0010_GeneralUserGS_sf2_file', '0010_JCLive_sf2_file', - '0010_SBLive_sf2', - '0010_SoundBlasterOld_sf2', + //'0010_SBLive_sf2', + //'0010_SoundBlasterOld_sf2', '0011_Aspirin_sf2_file', '0011_FluidR3_GM_sf2_file', '0011_GeneralUserGS_sf2_file', @@ -26,8 +26,8 @@ export const instruments = [ '0020_FluidR3_GM_sf2_file', '0020_GeneralUserGS_sf2_file', '0020_JCLive_sf2_file', - '0020_SBLive_sf2', - '0020_SoundBlasterOld_sf2', + //'0020_SBLive_sf2', + //'0020_SoundBlasterOld_sf2', '0021_Aspirin_sf2_file', '0021_GeneralUserGS_sf2_file', '0022_Aspirin_sf2_file', @@ -36,22 +36,22 @@ export const instruments = [ '0030_FluidR3_GM_sf2_file', '0030_GeneralUserGS_sf2_file', '0030_JCLive_sf2_file', - '0030_SBLive_sf2', - '0030_SoundBlasterOld_sf2', + //'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 + //'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', // ? + //'0040_SBLive_sf2', // ? + //'0040_SoundBlasterOld_sf2', // ? '0041_FluidR3_GM_sf2_file', // rhodes '0041_GeneralUserGS_sf2_file', // staccato rhodes - '0041_SoundBlasterOld_sf2', // ? + //'0041_SoundBlasterOld_sf2', // ? '0042_GeneralUserGS_sf2_file', // staccato wurly '0043_GeneralUserGS_sf2_file', // high bell '0044_GeneralUserGS_sf2_file', // reed organ @@ -62,8 +62,8 @@ export const instruments = [ '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', // ? + //'0050_SBLive_sf2', // ? + //'0050_SoundBlasterOld_sf2', // ? '0051_FluidR3_GM_sf2_file', // long lass organ '0051_GeneralUserGS_sf2_file', '0052_GeneralUserGS_sf2_file', // ? @@ -74,62 +74,62 @@ export const instruments = [ '0060_FluidR3_GM_sf2_file', // harpsichord ! '0060_GeneralUserGS_sf2_file', '0060_JCLive_sf2_file', - '0060_SBLive_sf2', - '0060_SoundBlasterOld_sf2', + //'0060_SBLive_sf2', + //'0060_SoundBlasterOld_sf2', '0061_Aspirin_sf2_file', '0061_GeneralUserGS_sf2_file', - '0061_SoundBlasterOld_sf2', + //'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', + //'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', + //'0080_SBLive_sf2', + //'0080_SoundBlasterOld_sf2', '0081_FluidR3_GM_sf2_file', '0081_GeneralUserGS_sf2_file', - '0081_SoundBlasterOld_sf2', + //'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', + //'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', + //'0100_SBLive_sf2', + //'0100_SoundBlasterOld_sf2', '0101_GeneralUserGS_sf2_file', - '0101_SoundBlasterOld_sf2', + //'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', + //'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', + //'0120_SBLive_sf2', + //'0120_SoundBlasterOld_sf2', '0121_FluidR3_GM_sf2_file', '0121_GeneralUserGS_sf2_file', '0130_Aspirin_sf2_file', @@ -137,16 +137,16 @@ export const instruments = [ '0130_FluidR3_GM_sf2_file', '0130_GeneralUserGS_sf2_file', '0130_JCLive_sf2_file', - '0130_SBLive_sf2', - '0130_SoundBlasterOld_sf2', + //'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', + //'0140_SBLive_sf2', + //'0140_SoundBlasterOld_sf2', '0141_FluidR3_GM_sf2_file', '0141_GeneralUserGS_sf2_file', '0142_GeneralUserGS_sf2_file', @@ -156,26 +156,26 @@ export const instruments = [ '0150_FluidR3_GM_sf2_file', '0150_GeneralUserGS_sf2_file', '0150_JCLive_sf2_file', - '0150_SBLive_sf2', - '0150_SoundBlasterOld_sf2', + //'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', + //'0160_SBLive_sf2', + //'0160_SoundBlasterOld_sf2', '0161_Aspirin_sf2_file', '0161_FluidR3_GM_sf2_file', - '0161_SoundBlasterOld_sf2', + //'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', + //'0170_SBLive_sf2', + //'0170_SoundBlasterOld_sf2', '0171_FluidR3_GM_sf2_file', '0171_GeneralUserGS_sf2_file', '0172_FluidR3_GM_sf2_file', @@ -184,63 +184,63 @@ export const instruments = [ '0180_FluidR3_GM_sf2_file', '0180_GeneralUserGS_sf2_file', '0180_JCLive_sf2_file', - '0180_SBLive_sf2', - '0180_SoundBlasterOld_sf2', + //'0180_SBLive_sf2', + //'0180_SoundBlasterOld_sf2', '0181_Aspirin_sf2_file', '0181_GeneralUserGS_sf2_file', - '0181_SoundBlasterOld_sf2', + //'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', + //'0190_SBLive_sf2', + //'0190_SoundBlasterOld_sf2', '0191_Aspirin_sf2_file', '0191_GeneralUserGS_sf2_file', - '0191_SoundBlasterOld_sf2', + //'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', + //'0200_SBLive_sf2', + //'0200_SoundBlasterOld_sf2', '0201_Aspirin_sf2_file', '0201_FluidR3_GM_sf2_file', '0201_GeneralUserGS_sf2_file', - '0201_SoundBlasterOld_sf2', + //'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', + //'0210_SBLive_sf2', + //'0210_SoundBlasterOld_sf2', '0211_Aspirin_sf2_file', '0211_FluidR3_GM_sf2_file', '0211_GeneralUserGS_sf2_file', - '0211_SoundBlasterOld_sf2', + //'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', + //'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', + //'0230_SBLive_sf2', + //'0230_SoundBlasterOld_sf2', '0231_FluidR3_GM_sf2_file', '0231_GeneralUserGS_sf2_file', '0231_JCLive_sf2_file', - '0231_SoundBlasterOld_sf2', + //'0231_SoundBlasterOld_sf2', '0232_FluidR3_GM_sf2_file', '0233_FluidR3_GM_sf2_file', '0240_Aspirin_sf2_file', @@ -249,8 +249,8 @@ export const instruments = [ '0240_GeneralUserGS_sf2_file', '0240_JCLive_sf2_file', '0240_LK_Godin_Nylon_SF2_file', - '0240_SBLive_sf2', - '0240_SoundBlasterOld_sf2', + //'0240_SBLive_sf2', + //'0240_SoundBlasterOld_sf2', '0241_GeneralUserGS_sf2_file', '0241_JCLive_sf2_file', '0242_JCLive_sf2_file', @@ -262,8 +262,8 @@ export const instruments = [ '0250_GeneralUserGS_sf2_file', '0250_JCLive_sf2_file', '0250_LK_AcousticSteel_SF2_file', - '0250_SBLive_sf2', - '0250_SoundBlasterOld_sf2', + //'0250_SBLive_sf2', + //'0250_SoundBlasterOld_sf2', '0251_Acoustic_Guitar_sf2_file', '0251_GeneralUserGS_sf2_file', '0252_Acoustic_Guitar_sf2_file', @@ -278,11 +278,11 @@ export const instruments = [ '0260_FluidR3_GM_sf2_file', '0260_GeneralUserGS_sf2_file', '0260_JCLive_sf2_file', - '0260_SBLive_sf2', - '0260_SoundBlasterOld_sf2', + //'0260_SBLive_sf2', + //'0260_SoundBlasterOld_sf2', '0260_Stratocaster_sf2_file', '0261_GeneralUserGS_sf2_file', - '0261_SoundBlasterOld_sf2', + //'0261_SoundBlasterOld_sf2', '0261_Stratocaster_sf2_file', '0262_Stratocaster_sf2_file', '0270_Aspirin_sf2_file', @@ -292,8 +292,8 @@ export const instruments = [ '0270_Gibson_Les_Paul_sf2_file', '0270_JCLive_sf2_file', '0270_SBAWE32_sf2_file', - '0270_SBLive_sf2', - '0270_SoundBlasterOld_sf2', + //'0270_SBLive_sf2', + //'0270_SoundBlasterOld_sf2', '0270_Stratocaster_sf2_file', '0271_GeneralUserGS_sf2_file', '0271_Stratocaster_sf2_file', @@ -306,8 +306,8 @@ export const instruments = [ '0280_LesPaul_sf2', '0280_LesPaul_sf2_file', '0280_SBAWE32_sf2_file', - '0280_SBLive_sf2', - '0280_SoundBlasterOld_sf2', + //'0280_SBLive_sf2', + //'0280_SoundBlasterOld_sf2', '0281_Aspirin_sf2_file', '0281_FluidR3_GM_sf2_file', '0281_GeneralUserGS_sf2_file', @@ -322,13 +322,13 @@ export const instruments = [ '0290_LesPaul_sf2', '0290_LesPaul_sf2_file', '0290_SBAWE32_sf2_file', - '0290_SBLive_sf2', - '0290_SoundBlasterOld_sf2', + //'0290_SBLive_sf2', + //'0290_SoundBlasterOld_sf2', '0291_Aspirin_sf2_file', '0291_LesPaul_sf2', '0291_LesPaul_sf2_file', '0291_SBAWE32_sf2_file', - '0291_SoundBlasterOld_sf2', + //'0291_SoundBlasterOld_sf2', '0292_Aspirin_sf2_file', '0292_LesPaul_sf2', '0292_LesPaul_sf2_file', @@ -340,8 +340,8 @@ export const instruments = [ '0300_LesPaul_sf2', '0300_LesPaul_sf2_file', '0300_SBAWE32_sf2_file', - '0300_SBLive_sf2', - '0300_SoundBlasterOld_sf2', + //'0300_SBLive_sf2', + //'0300_SoundBlasterOld_sf2', '0301_Aspirin_sf2_file', '0301_FluidR3_GM_sf2_file', '0301_GeneralUserGS_sf2_file', @@ -361,8 +361,8 @@ export const instruments = [ '0310_LesPaul_sf2', '0310_LesPaul_sf2_file', '0310_SBAWE32_sf2_file', - '0310_SBLive_sf2', - '0310_SoundBlasterOld_sf2', + //'0310_SBLive_sf2', + //'0310_SoundBlasterOld_sf2', '0311_FluidR3_GM_sf2_file', '0311_GeneralUserGS_sf2_file', '0320_Aspirin_sf2_file', @@ -370,8 +370,8 @@ export const instruments = [ '0320_FluidR3_GM_sf2_file', '0320_GeneralUserGS_sf2_file', '0320_JCLive_sf2_file', - '0320_SBLive_sf2', - '0320_SoundBlasterOld_sf2', + //'0320_SBLive_sf2', + //'0320_SoundBlasterOld_sf2', '0321_GeneralUserGS_sf2_file', '0322_GeneralUserGS_sf2_file', '0330_Aspirin_sf2_file', @@ -379,8 +379,8 @@ export const instruments = [ '0330_FluidR3_GM_sf2_file', '0330_GeneralUserGS_sf2_file', '0330_JCLive_sf2_file', - '0330_SBLive_sf2', - '0330_SoundBlasterOld_sf2', + //'0330_SBLive_sf2', + //'0330_SoundBlasterOld_sf2', '0331_GeneralUserGS_sf2_file', '0332_GeneralUserGS_sf2_file', '0340_Aspirin_sf2_file', @@ -388,8 +388,8 @@ export const instruments = [ '0340_FluidR3_GM_sf2_file', '0340_GeneralUserGS_sf2_file', '0340_JCLive_sf2_file', - '0340_SBLive_sf2', - '0340_SoundBlasterOld_sf2', + //'0340_SBLive_sf2', + //'0340_SoundBlasterOld_sf2', '0341_Aspirin_sf2_file', '0341_GeneralUserGS_sf2_file', '0350_Aspirin_sf2_file', @@ -397,24 +397,24 @@ export const instruments = [ '0350_FluidR3_GM_sf2_file', '0350_GeneralUserGS_sf2_file', '0350_JCLive_sf2_file', - '0350_SBLive_sf2', - '0350_SoundBlasterOld_sf2', + //'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', + //'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', + //'0370_SBLive_sf2', + //'0370_SoundBlasterOld_sf2', '0371_GeneralUserGS_sf2_file', '0372_GeneralUserGS_sf2_file', '0385_GeneralUserGS_sf2_file', @@ -423,8 +423,8 @@ export const instruments = [ '0380_FluidR3_GM_sf2_file', '0380_GeneralUserGS_sf2_file', '0380_JCLive_sf2_file', - '0380_SBLive_sf2', - '0380_SoundBlasterOld_sf2', + //'0380_SBLive_sf2', + //'0380_SoundBlasterOld_sf2', '0381_FluidR3_GM_sf2_file', '0381_GeneralUserGS_sf2_file', '0382_FluidR3_GM_sf2_file', @@ -438,11 +438,11 @@ export const instruments = [ '0390_FluidR3_GM_sf2_file', '0390_GeneralUserGS_sf2_file', '0390_JCLive_sf2_file', - '0390_SBLive_sf2', - '0390_SoundBlasterOld_sf2', + //'0390_SBLive_sf2', + //'0390_SoundBlasterOld_sf2', '0391_FluidR3_GM_sf2_file', '0391_GeneralUserGS_sf2_file', - '0391_SoundBlasterOld_sf2', + //'0391_SoundBlasterOld_sf2', '0392_FluidR3_GM_sf2_file', '0392_GeneralUserGS_sf2_file', '0393_GeneralUserGS_sf2_file', @@ -451,8 +451,8 @@ export const instruments = [ '0400_FluidR3_GM_sf2_file', '0400_GeneralUserGS_sf2_file', '0400_JCLive_sf2_file', - '0400_SBLive_sf2', - '0400_SoundBlasterOld_sf2', + //'0400_SBLive_sf2', + //'0400_SoundBlasterOld_sf2', '0401_Aspirin_sf2_file', '0401_FluidR3_GM_sf2_file', '0401_GeneralUserGS_sf2_file', @@ -462,16 +462,16 @@ export const instruments = [ '0410_FluidR3_GM_sf2_file', '0410_GeneralUserGS_sf2_file', '0410_JCLive_sf2_file', - '0410_SBLive_sf2', - '0410_SoundBlasterOld_sf2', + //'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', + //'0420_SBLive_sf2', + //'0420_SoundBlasterOld_sf2', '0421_FluidR3_GM_sf2_file', '0421_GeneralUserGS_sf2_file', '0430_Aspirin_sf2_file', @@ -479,16 +479,16 @@ export const instruments = [ '0430_FluidR3_GM_sf2_file', '0430_GeneralUserGS_sf2_file', '0430_JCLive_sf2_file', - '0430_SBLive_sf2', - '0430_SoundBlasterOld_sf2', + //'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', + //'0440_SBLive_sf2', + //'0440_SoundBlasterOld_sf2', '0441_GeneralUserGS_sf2_file', '0442_GeneralUserGS_sf2_file', '0450_Aspirin_sf2_file', @@ -496,24 +496,24 @@ export const instruments = [ '0450_FluidR3_GM_sf2_file', '0450_GeneralUserGS_sf2_file', '0450_JCLive_sf2_file', - '0450_SBLive_sf2', - '0450_SoundBlasterOld_sf2', + //'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', + //'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', + //'0470_SBLive_sf2', + //'0470_SoundBlasterOld_sf2', '0471_FluidR3_GM_sf2_file', '0471_GeneralUserGS_sf2_file', '0480_Aspirin_sf2_file', @@ -521,8 +521,8 @@ export const instruments = [ '0480_FluidR3_GM_sf2_file', '0480_GeneralUserGS_sf2_file', '0480_JCLive_sf2_file', - '0480_SBLive_sf2', - '0480_SoundBlasterOld_sf2', + //'0480_SBLive_sf2', + //'0480_SoundBlasterOld_sf2', '04810_GeneralUserGS_sf2_file', '04811_GeneralUserGS_sf2_file', '04812_GeneralUserGS_sf2_file', @@ -548,8 +548,8 @@ export const instruments = [ '0490_FluidR3_GM_sf2_file', '0490_GeneralUserGS_sf2_file', '0490_JCLive_sf2_file', - '0490_SBLive_sf2', - '0490_SoundBlasterOld_sf2', + //'0490_SBLive_sf2', + //'0490_SoundBlasterOld_sf2', '0491_GeneralUserGS_sf2_file', '0492_GeneralUserGS_sf2_file', '0500_Aspirin_sf2_file', @@ -557,8 +557,8 @@ export const instruments = [ '0500_FluidR3_GM_sf2_file', '0500_GeneralUserGS_sf2_file', '0500_JCLive_sf2_file', - '0500_SBLive_sf2', - '0500_SoundBlasterOld_sf2', + //'0500_SBLive_sf2', + //'0500_SoundBlasterOld_sf2', '0501_FluidR3_GM_sf2_file', '0501_GeneralUserGS_sf2_file', '0502_FluidR3_GM_sf2_file', @@ -571,49 +571,49 @@ export const instruments = [ '0510_FluidR3_GM_sf2_file', '0510_GeneralUserGS_sf2_file', '0510_JCLive_sf2_file', - '0510_SBLive_sf2', - '0510_SoundBlasterOld_sf2', + //'0510_SBLive_sf2', + //'0510_SoundBlasterOld_sf2', '0511_GeneralUserGS_sf2_file', - '0511_SoundBlasterOld_sf2', + //'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_SBLive_sf2', '0520_Soul_Ahhs_sf2_file', - '0520_SoundBlasterOld_sf2', + //'0520_SoundBlasterOld_sf2', '0521_FluidR3_GM_sf2_file', '0521_Soul_Ahhs_sf2_file', - '0521_SoundBlasterOld_sf2', + //'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_SBLive_sf2', '0530_Soul_Ahhs_sf2_file', - '0530_SoundBlasterOld_sf2', + //'0530_SoundBlasterOld_sf2', '0531_FluidR3_GM_sf2_file', '0531_GeneralUserGS_sf2_file', '0531_JCLive_sf2_file', - '0531_SoundBlasterOld_sf2', + //'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', + //'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', + //'0550_SBLive_sf2', + //'0550_SoundBlasterOld_sf2', '0551_Aspirin_sf2_file', '0551_FluidR3_GM_sf2_file', '0560_Aspirin_sf2_file', @@ -621,39 +621,39 @@ export const instruments = [ '0560_FluidR3_GM_sf2_file', '0560_GeneralUserGS_sf2_file', '0560_JCLive_sf2_file', - '0560_SBLive_sf2', - '0560_SoundBlasterOld_sf2', + //'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', + //'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', + //'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', + //'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', + //'0600_SBLive_sf2', + //'0600_SoundBlasterOld_sf2', '0601_FluidR3_GM_sf2_file', '0601_GeneralUserGS_sf2_file', '0602_GeneralUserGS_sf2_file', @@ -663,8 +663,8 @@ export const instruments = [ '0610_FluidR3_GM_sf2_file', '0610_GeneralUserGS_sf2_file', '0610_JCLive_sf2_file', - '0610_SBLive_sf2', - '0610_SoundBlasterOld_sf2', + //'0610_SBLive_sf2', + //'0610_SoundBlasterOld_sf2', '0611_GeneralUserGS_sf2_file', '0612_GeneralUserGS_sf2_file', '0613_GeneralUserGS_sf2_file', @@ -675,8 +675,8 @@ export const instruments = [ '0620_FluidR3_GM_sf2_file', '0620_GeneralUserGS_sf2_file', '0620_JCLive_sf2_file', - '0620_SBLive_sf2', - '0620_SoundBlasterOld_sf2', + //'0620_SBLive_sf2', + //'0620_SoundBlasterOld_sf2', '0621_Aspirin_sf2_file', '0621_FluidR3_GM_sf2_file', '0621_GeneralUserGS_sf2_file', @@ -687,8 +687,8 @@ export const instruments = [ '0630_FluidR3_GM_sf2_file', '0630_GeneralUserGS_sf2_file', '0630_JCLive_sf2_file', - '0630_SBLive_sf2', - '0630_SoundBlasterOld_sf2', + //'0630_SBLive_sf2', + //'0630_SoundBlasterOld_sf2', '0631_Aspirin_sf2_file', '0631_FluidR3_GM_sf2_file', '0631_GeneralUserGS_sf2_file', @@ -699,16 +699,16 @@ export const instruments = [ '0640_FluidR3_GM_sf2_file', '0640_GeneralUserGS_sf2_file', '0640_JCLive_sf2_file', - '0640_SBLive_sf2', - '0640_SoundBlasterOld_sf2', + //'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', + //'0650_SBLive_sf2', + //'0650_SoundBlasterOld_sf2', '0651_Aspirin_sf2_file', '0651_FluidR3_GM_sf2_file', '0660_Aspirin_sf2_file', @@ -716,8 +716,8 @@ export const instruments = [ '0660_FluidR3_GM_sf2_file', '0660_GeneralUserGS_sf2_file', '0660_JCLive_sf2_file', - '0660_SBLive_sf2', - '0660_SoundBlasterOld_sf2', + //'0660_SBLive_sf2', + //'0660_SoundBlasterOld_sf2', '0661_FluidR3_GM_sf2_file', '0661_GeneralUserGS_sf2_file', '0670_Aspirin_sf2_file', @@ -725,32 +725,32 @@ export const instruments = [ '0670_FluidR3_GM_sf2_file', '0670_GeneralUserGS_sf2_file', '0670_JCLive_sf2_file', - '0670_SBLive_sf2', - '0670_SoundBlasterOld_sf2', + //'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', + //'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', + //'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', + //'0700_SBLive_sf2', + //'0700_SoundBlasterOld_sf2', '0701_FluidR3_GM_sf2_file', '0701_GeneralUserGS_sf2_file', '0710_Aspirin_sf2_file', @@ -758,65 +758,65 @@ export const instruments = [ '0710_FluidR3_GM_sf2_file', '0710_GeneralUserGS_sf2_file', '0710_JCLive_sf2_file', - '0710_SBLive_sf2', - '0710_SoundBlasterOld_sf2', + //'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', + //'0720_SBLive_sf2', + //'0720_SoundBlasterOld_sf2', '0721_FluidR3_GM_sf2_file', - '0721_SoundBlasterOld_sf2', + //'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', + //'0730_SBLive_sf2', + //'0730_SoundBlasterOld_sf2', '0731_Aspirin_sf2_file', '0731_FluidR3_GM_sf2_file', - '0731_SoundBlasterOld_sf2', + //'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', + //'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', + //'0750_SBLive_sf2', + //'0750_SoundBlasterOld_sf2', '0751_Aspirin_sf2_file', '0751_FluidR3_GM_sf2_file', '0751_GeneralUserGS_sf2_file', - '0751_SoundBlasterOld_sf2', + //'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', + //'0760_SBLive_sf2', + //'0760_SoundBlasterOld_sf2', '0761_FluidR3_GM_sf2_file', '0761_GeneralUserGS_sf2_file', - '0761_SoundBlasterOld_sf2', + //'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', + //'0770_SBLive_sf2', + //'0770_SoundBlasterOld_sf2', '0771_FluidR3_GM_sf2_file', '0771_GeneralUserGS_sf2_file', '0772_GeneralUserGS_sf2_file', @@ -825,24 +825,24 @@ export const instruments = [ '0780_FluidR3_GM_sf2_file', '0780_GeneralUserGS_sf2_file', '0780_JCLive_sf2_file', - '0780_SBLive_sf2', - '0780_SoundBlasterOld_sf2', + //'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', + //'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', + //'0800_SBLive_sf2', + //'0800_SoundBlasterOld_sf2', '0801_FluidR3_GM_sf2_file', '0801_GeneralUserGS_sf2_file', '0810_Aspirin_sf2_file', @@ -850,21 +850,21 @@ export const instruments = [ '0810_FluidR3_GM_sf2_file', '0810_GeneralUserGS_sf2_file', '0810_JCLive_sf2_file', - '0810_SBLive_sf2', - '0810_SoundBlasterOld_sf2', + //'0810_SBLive_sf2', + //'0810_SoundBlasterOld_sf2', '0811_Aspirin_sf2_file', '0811_GeneralUserGS_sf2_file', - '0811_SoundBlasterOld_sf2', + //'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', + //'0820_SBLive_sf2', + //'0820_SoundBlasterOld_sf2', '0821_FluidR3_GM_sf2_file', '0821_GeneralUserGS_sf2_file', - '0821_SoundBlasterOld_sf2', + //'0821_SoundBlasterOld_sf2', '0822_GeneralUserGS_sf2_file', '0823_GeneralUserGS_sf2_file', '0830_Aspirin_sf2_file', @@ -872,53 +872,53 @@ export const instruments = [ '0830_FluidR3_GM_sf2_file', '0830_GeneralUserGS_sf2_file', '0830_JCLive_sf2_file', - '0830_SBLive_sf2', - '0830_SoundBlasterOld_sf2', + //'0830_SBLive_sf2', + //'0830_SoundBlasterOld_sf2', '0831_FluidR3_GM_sf2_file', '0831_GeneralUserGS_sf2_file', - '0831_SoundBlasterOld_sf2', + //'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', + //'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', + //'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', + //'0850_SBLive_sf2', + //'0850_SoundBlasterOld_sf2', '0851_FluidR3_GM_sf2_file', '0851_GeneralUserGS_sf2_file', '0851_JCLive_sf2_file', - '0851_SoundBlasterOld_sf2', + //'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', + //'0860_SBLive_sf2', + //'0860_SoundBlasterOld_sf2', '0861_Aspirin_sf2_file', '0861_FluidR3_GM_sf2_file', - '0861_SoundBlasterOld_sf2', + //'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', + //'0870_SBLive_sf2', + //'0870_SoundBlasterOld_sf2', '0871_GeneralUserGS_sf2_file', '0872_GeneralUserGS_sf2_file', '0873_GeneralUserGS_sf2_file', @@ -927,12 +927,12 @@ export const instruments = [ '0880_FluidR3_GM_sf2_file', '0880_GeneralUserGS_sf2_file', '0880_JCLive_sf2_file', - '0880_SBLive_sf2', - '0880_SoundBlasterOld_sf2', + //'0880_SBLive_sf2', + //'0880_SoundBlasterOld_sf2', '0881_Aspirin_sf2_file', '0881_FluidR3_GM_sf2_file', '0881_GeneralUserGS_sf2_file', - '0881_SoundBlasterOld_sf2', + //'0881_SoundBlasterOld_sf2', '0882_Aspirin_sf2_file', '0882_FluidR3_GM_sf2_file', '0882_GeneralUserGS_sf2_file', @@ -948,8 +948,8 @@ export const instruments = [ '0890_FluidR3_GM_sf2_file', '0890_GeneralUserGS_sf2_file', '0890_JCLive_sf2_file', - '0890_SBLive_sf2', - '0890_SoundBlasterOld_sf2', + //'0890_SBLive_sf2', + //'0890_SoundBlasterOld_sf2', '0891_Aspirin_sf2_file', '0891_FluidR3_GM_sf2_file', '0891_GeneralUserGS_sf2_file', @@ -958,51 +958,51 @@ export const instruments = [ '0900_FluidR3_GM_sf2_file', '0900_GeneralUserGS_sf2_file', '0900_JCLive_sf2_file', - '0900_SBLive_sf2', - '0900_SoundBlasterOld_sf2', + //'0900_SBLive_sf2', + //'0900_SoundBlasterOld_sf2', '0901_Aspirin_sf2_file', '0901_FluidR3_GM_sf2_file', '0901_GeneralUserGS_sf2_file', - '0901_SoundBlasterOld_sf2', + //'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', + //'0910_SBLive_sf2', + //'0910_SoundBlasterOld_sf2', '0911_Aspirin_sf2_file', '0911_GeneralUserGS_sf2_file', '0911_JCLive_sf2_file', - '0911_SoundBlasterOld_sf2', + //'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', + //'0920_SBLive_sf2', + //'0920_SoundBlasterOld_sf2', '0921_Aspirin_sf2_file', '0921_GeneralUserGS_sf2_file', - '0921_SoundBlasterOld_sf2', + //'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', + //'0930_SBLive_sf2', + //'0930_SoundBlasterOld_sf2', '0931_Aspirin_sf2_file', '0931_FluidR3_GM_sf2_file', '0931_GeneralUserGS_sf2_file', - '0931_SoundBlasterOld_sf2', + //'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', + //'0940_SBLive_sf2', + //'0940_SoundBlasterOld_sf2', '0941_Aspirin_sf2_file', '0941_FluidR3_GM_sf2_file', '0941_GeneralUserGS_sf2_file', @@ -1012,8 +1012,8 @@ export const instruments = [ '0950_FluidR3_GM_sf2_file', '0950_GeneralUserGS_sf2_file', '0950_JCLive_sf2_file', - '0950_SBLive_sf2', - '0950_SoundBlasterOld_sf2', + //'0950_SBLive_sf2', + //'0950_SoundBlasterOld_sf2', '0951_FluidR3_GM_sf2_file', '0951_GeneralUserGS_sf2_file', '0960_Aspirin_sf2_file', @@ -1021,34 +1021,34 @@ export const instruments = [ '0960_FluidR3_GM_sf2_file', '0960_GeneralUserGS_sf2_file', '0960_JCLive_sf2_file', - '0960_SBLive_sf2', - '0960_SoundBlasterOld_sf2', + //'0960_SBLive_sf2', + //'0960_SoundBlasterOld_sf2', '0961_Aspirin_sf2_file', '0961_FluidR3_GM_sf2_file', '0961_GeneralUserGS_sf2_file', - '0961_SoundBlasterOld_sf2', + //'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', + //'0970_SBLive_sf2', + //'0970_SoundBlasterOld_sf2', '0971_FluidR3_GM_sf2_file', '0971_GeneralUserGS_sf2_file', - '0971_SoundBlasterOld_sf2', + //'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', + //'0980_SBLive_sf2', + //'0980_SoundBlasterOld_sf2', '0981_Aspirin_sf2_file', '0981_FluidR3_GM_sf2_file', '0981_GeneralUserGS_sf2_file', - '0981_SoundBlasterOld_sf2', + //'0981_SoundBlasterOld_sf2', '0982_GeneralUserGS_sf2_file', '0983_GeneralUserGS_sf2_file', '0984_GeneralUserGS_sf2_file', @@ -1057,13 +1057,13 @@ export const instruments = [ '0990_FluidR3_GM_sf2_file', '0990_GeneralUserGS_sf2_file', '0990_JCLive_sf2_file', - '0990_SBLive_sf2', - '0990_SoundBlasterOld_sf2', + //'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', + //'0991_SoundBlasterOld_sf2', '0992_FluidR3_GM_sf2_file', '0992_JCLive_sf2_file', '0993_JCLive_sf2_file', @@ -1073,13 +1073,13 @@ export const instruments = [ '1000_FluidR3_GM_sf2_file', '1000_GeneralUserGS_sf2_file', '1000_JCLive_sf2_file', - '1000_SBLive_sf2', - '1000_SoundBlasterOld_sf2', + //'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', + //'1001_SoundBlasterOld_sf2', '1002_Aspirin_sf2_file', '1002_FluidR3_GM_sf2_file', '1002_GeneralUserGS_sf2_file', @@ -1088,8 +1088,8 @@ export const instruments = [ '1010_FluidR3_GM_sf2_file', '1010_GeneralUserGS_sf2_file', '1010_JCLive_sf2_file', - '1010_SBLive_sf2', - '1010_SoundBlasterOld_sf2', + //'1010_SBLive_sf2', + //'1010_SoundBlasterOld_sf2', '1011_Aspirin_sf2_file', '1011_FluidR3_GM_sf2_file', '1011_JCLive_sf2_file', @@ -1099,33 +1099,33 @@ export const instruments = [ '1020_FluidR3_GM_sf2_file', '1020_GeneralUserGS_sf2_file', '1020_JCLive_sf2_file', - '1020_SBLive_sf2', - '1020_SoundBlasterOld_sf2', + //'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', + //'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', + //'1030_SBLive_sf2', + //'1030_SoundBlasterOld_sf2', '1031_Aspirin_sf2_file', '1031_FluidR3_GM_sf2_file', '1031_GeneralUserGS_sf2_file', - '1031_SoundBlasterOld_sf2', + //'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', + //'1040_SBLive_sf2', + //'1040_SoundBlasterOld_sf2', '1041_FluidR3_GM_sf2_file', '1041_GeneralUserGS_sf2_file', '1050_Aspirin_sf2_file', @@ -1133,26 +1133,26 @@ export const instruments = [ '1050_FluidR3_GM_sf2_file', '1050_GeneralUserGS_sf2_file', '1050_JCLive_sf2_file', - '1050_SBLive_sf2', - '1050_SoundBlasterOld_sf2', + //'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', + //'1060_SBLive_sf2', + //'1060_SoundBlasterOld_sf2', '1061_FluidR3_GM_sf2_file', '1061_GeneralUserGS_sf2_file', - '1061_SoundBlasterOld_sf2', + //'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', + //'1070_SBLive_sf2', + //'1070_SoundBlasterOld_sf2', '1071_FluidR3_GM_sf2_file', '1071_GeneralUserGS_sf2_file', '1072_GeneralUserGS_sf2_file', @@ -1162,24 +1162,24 @@ export const instruments = [ '1080_FluidR3_GM_sf2_file', '1080_GeneralUserGS_sf2_file', '1080_JCLive_sf2_file', - '1080_SBLive_sf2', - '1080_SoundBlasterOld_sf2', - '1081_SoundBlasterOld_sf2', + //'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', + //'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', + //'1100_SBLive_sf2', + //'1100_SoundBlasterOld_sf2', '1101_Aspirin_sf2_file', '1101_FluidR3_GM_sf2_file', '1101_GeneralUserGS_sf2_file', @@ -1189,40 +1189,40 @@ export const instruments = [ '1110_FluidR3_GM_sf2_file', '1110_GeneralUserGS_sf2_file', '1110_JCLive_sf2_file', - '1110_SBLive_sf2', - '1110_SoundBlasterOld_sf2', + //'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', + //'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', + //'1130_SBLive_sf2', + //'1130_SoundBlasterOld_sf2', '1131_FluidR3_GM_sf2_file', - '1131_SoundBlasterOld_sf2', + //'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', + //'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', + //'1150_SBLive_sf2', + //'1150_SoundBlasterOld_sf2', '1151_FluidR3_GM_sf2_file', '1151_GeneralUserGS_sf2_file', '1152_FluidR3_GM_sf2_file', @@ -1232,11 +1232,11 @@ export const instruments = [ '1160_FluidR3_GM_sf2_file', '1160_GeneralUserGS_sf2_file', '1160_JCLive_sf2_file', - '1160_SBLive_sf2', - '1160_SoundBlasterOld_sf2', + //'1160_SBLive_sf2', + //'1160_SoundBlasterOld_sf2', '1161_FluidR3_GM_sf2_file', '1161_GeneralUserGS_sf2_file', - '1161_SoundBlasterOld_sf2', + //'1161_SoundBlasterOld_sf2', '1162_FluidR3_GM_sf2_file', '1162_GeneralUserGS_sf2_file', '1163_FluidR3_GM_sf2_file', @@ -1245,8 +1245,8 @@ export const instruments = [ '1170_FluidR3_GM_sf2_file', '1170_GeneralUserGS_sf2_file', '1170_JCLive_sf2_file', - '1170_SBLive_sf2', - '1170_SoundBlasterOld_sf2', + //'1170_SBLive_sf2', + //'1170_SoundBlasterOld_sf2', '1171_FluidR3_GM_sf2_file', '1171_GeneralUserGS_sf2_file', '1172_FluidR3_GM_sf2_file', @@ -1256,18 +1256,18 @@ export const instruments = [ '1180_FluidR3_GM_sf2_file', '1180_GeneralUserGS_sf2_file', '1180_JCLive_sf2_file', - '1180_SBLive_sf2', - '1180_SoundBlasterOld_sf2', + //'1180_SBLive_sf2', + //'1180_SoundBlasterOld_sf2', '1181_FluidR3_GM_sf2_file', '1181_GeneralUserGS_sf2_file', - '1181_SoundBlasterOld_sf2', + //'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', + //'1190_SBLive_sf2', + //'1190_SoundBlasterOld_sf2', '1191_GeneralUserGS_sf2_file', '1192_GeneralUserGS_sf2_file', '1193_GeneralUserGS_sf2_file', @@ -1277,8 +1277,8 @@ export const instruments = [ '1200_FluidR3_GM_sf2_file', '1200_GeneralUserGS_sf2_file', '1200_JCLive_sf2_file', - '1200_SBLive_sf2', - '1200_SoundBlasterOld_sf2', + //'1200_SBLive_sf2', + //'1200_SoundBlasterOld_sf2', '1201_Aspirin_sf2_file', '1201_GeneralUserGS_sf2_file', '1202_GeneralUserGS_sf2_file', @@ -1287,8 +1287,8 @@ export const instruments = [ '1210_FluidR3_GM_sf2_file', '1210_GeneralUserGS_sf2_file', '1210_JCLive_sf2_file', - '1210_SBLive_sf2', - '1210_SoundBlasterOld_sf2', + //'1210_SBLive_sf2', + //'1210_SoundBlasterOld_sf2', '1211_Aspirin_sf2_file', '1211_GeneralUserGS_sf2_file', '1212_GeneralUserGS_sf2_file', @@ -1297,8 +1297,8 @@ export const instruments = [ '1220_FluidR3_GM_sf2_file', '1220_GeneralUserGS_sf2_file', '1220_JCLive_sf2_file', - '1220_SBLive_sf2', - '1220_SoundBlasterOld_sf2', + //'1220_SBLive_sf2', + //'1220_SoundBlasterOld_sf2', '1221_Aspirin_sf2_file', '1221_GeneralUserGS_sf2_file', '1221_JCLive_sf2_file', @@ -1315,8 +1315,8 @@ export const instruments = [ '1230_FluidR3_GM_sf2_file', '1230_GeneralUserGS_sf2_file', '1230_JCLive_sf2_file', - '1230_SBLive_sf2', - '1230_SoundBlasterOld_sf2', + //'1230_SBLive_sf2', + //'1230_SoundBlasterOld_sf2', '1231_Aspirin_sf2_file', '1231_GeneralUserGS_sf2_file', '1232_Aspirin_sf2_file', @@ -1328,8 +1328,8 @@ export const instruments = [ '1240_FluidR3_GM_sf2_file', '1240_GeneralUserGS_sf2_file', '1240_JCLive_sf2_file', - '1240_SBLive_sf2', - '1240_SoundBlasterOld_sf2', + //'1240_SBLive_sf2', + //'1240_SoundBlasterOld_sf2', '1241_Aspirin_sf2_file', '1241_GeneralUserGS_sf2_file', '1242_Aspirin_sf2_file', @@ -1343,8 +1343,8 @@ export const instruments = [ '1250_FluidR3_GM_sf2_file', '1250_GeneralUserGS_sf2_file', '1250_JCLive_sf2_file', - '1250_SBLive_sf2', - '1250_SoundBlasterOld_sf2', + //'1250_SBLive_sf2', + //'1250_SoundBlasterOld_sf2', '1251_Aspirin_sf2_file', '1251_FluidR3_GM_sf2_file', '1251_GeneralUserGS_sf2_file', @@ -1369,8 +1369,8 @@ export const instruments = [ '1260_FluidR3_GM_sf2_file', '1260_GeneralUserGS_sf2_file', '1260_JCLive_sf2_file', - '1260_SBLive_sf2', - '1260_SoundBlasterOld_sf2', + //'1260_SBLive_sf2', + //'1260_SoundBlasterOld_sf2', '1261_Aspirin_sf2_file', '1261_GeneralUserGS_sf2_file', '1262_Aspirin_sf2_file', @@ -1386,8 +1386,8 @@ export const instruments = [ '1270_FluidR3_GM_sf2_file', '1270_GeneralUserGS_sf2_file', '1270_JCLive_sf2_file', - '1270_SBLive_sf2', - '1270_SoundBlasterOld_sf2', + //'1270_SBLive_sf2', + //'1270_SoundBlasterOld_sf2', '1271_Aspirin_sf2_file', '1271_GeneralUserGS_sf2_file', '1272_Aspirin_sf2_file', @@ -1397,238 +1397,238 @@ export const instruments = [ ]; export const drums = [ - //'35_0_SBLive_sf2' + ////'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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_0_SBLive_sf2', '81_12_JCLive_sf2_file', '81_16_JCLive_sf2_file', '81_18_JCLive_sf2_file', diff --git a/packages/soundfonts/sfumato.mjs b/packages/soundfonts/sfumato.mjs index b4037c65..926999f3 100644 --- a/packages/soundfonts/sfumato.mjs +++ b/packages/soundfonts/sfumato.mjs @@ -1,5 +1,5 @@ import { Pattern, getPlayableNoteValue, toMidi } from '@strudel.cycles/core'; -import { getAudioContext } from '@strudel.cycles/webaudio'; +import { getAudioContext, registerSound } from '@strudel.cycles/webaudio'; import { loadSoundfont as _loadSoundfont, startPresetNote } from 'sfumato'; Pattern.prototype.soundfont = function (sf, n = 0) { @@ -21,5 +21,29 @@ export function loadSoundfont(url) { } const sf = _loadSoundfont(url); soundfontCache.set(url, sf); + /*sf.then((font) => { + font.presets.forEach((preset) => { + console.log('preset', preset.header.name); + registerSound( + preset.header.name.replaceAll(' ', '_'), + (time, value, onended) => { + const ctx = getAudioContext(); + let { note } = value; // freq ? + + const p = font.presets.find((p) => p.header.name === preset.header.name); + + if (!p) { + throw new Error('preset not found'); + } + const deadline = time; // - ctx.currentTime; + const args = [ctx, p, toMidi(note), deadline]; + const stop = startPresetNote(...args); + return { node: undefined, stop }; + }, + { type: 'soundfont' }, + ); + }); + //console.log('f', f); + });*/ return sf; } diff --git a/packages/webaudio/sampler.mjs b/packages/webaudio/sampler.mjs index e153dd8b..4266455a 100644 --- a/packages/webaudio/sampler.mjs +++ b/packages/webaudio/sampler.mjs @@ -251,23 +251,3 @@ export async function onTriggerSample(t, value, onended, bank) { return handle; } - -/*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 - return globalThis.soundfontList.instruments.find((instrument) => instrument.startsWith(name)); - } - return; -};*/ -// bufferSource = await globalThis.getFontBufferSource(soundfont, note || n, ac, freq); diff --git a/website/src/repl/Footer.jsx b/website/src/repl/Footer.jsx index 4fee856d..14789234 100644 --- a/website/src/repl/Footer.jsx +++ b/website/src/repl/Footer.jsx @@ -233,9 +233,18 @@ function SoundsTab() { if (!sounds) { return []; } - if (soundsFilter === 'hideDefaults') { + if (soundsFilter === 'user') { return Object.entries(sounds).filter(([_, { data }]) => !data.prebake); } + if (soundsFilter === 'samples') { + return Object.entries(sounds).filter(([_, { data }]) => data.type === 'sample'); + } + if (soundsFilter === 'synths') { + return Object.entries(sounds).filter(([_, { data }]) => data.type === 'synth'); + } + if (soundsFilter === 'soundfonts') { + return Object.entries(sounds).filter(([_, { data }]) => data.type === 'soundfont'); + } return Object.entries(sounds); }, [sounds, soundsFilter]); // holds mutable ref to current triggered sound @@ -249,16 +258,21 @@ function SoundsTab() { settingsMap.setKey('soundsFilter', value)} - items={{ all: 'All', hideDefaults: 'Hide Defaults' }} + items={{ samples: 'Samples', synths: 'Synths', soundfonts: 'Soundfonts', user: 'Custom' }} > -
+
{soundEntries.map(([name, { data, onTrigger }]) => ( { const ctx = getAudioContext(); - const params = { freq: 220, s: name, clip: 1, release: 0.5 }; + const params = { + note: ['synth', 'soundfont'].includes(data.type) ? 'a3' : undefined, + s: name, + clip: 1, + release: 0.5, + }; const time = ctx.currentTime + 0.05; const onended = () => trigRef.current?.node?.disconnect(); trigRef.current = Promise.resolve(onTrigger(time, params, onended)); @@ -272,7 +286,7 @@ function SoundsTab() { {data?.type === 'sample' ? `(${getSamples(data.samples)})` : ''} ))} - {!soundEntries.length ? 'No Sounds' : ''} + {!soundEntries.length ? 'No custom sounds loaded in this pattern (yet).' : ''}
); diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index e68274cf..5c86dd08 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -1,10 +1,12 @@ import { Pattern, toMidi, valueToMidi } from '@strudel.cycles/core'; +import { registerSoundfonts } from '@strudel.cycles/soundfonts'; import { registerSynthSounds, samples } from '@strudel.cycles/webaudio'; export async function prebake() { // https://archive.org/details/SalamanderGrandPianoV3 // License: CC-by http://creativecommons.org/licenses/by/3.0/ Author: Alexander Holm registerSynthSounds(); + registerSoundfonts(); await Promise.all([ samples(`./piano.json`, `./piano/`, { prebake: true }), // https://github.com/sgossner/VCSL/ From ff412f6396148dbe20cdceb63565e942d00e369a Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 9 Mar 2023 23:19:19 +0100 Subject: [PATCH 11/24] level down soundfonts + do not load in prebake (breaks static rendering) + instead load on import --- packages/soundfonts/fontloader.mjs | 7 ++++++- website/src/docs/MiniRepl.jsx | 1 + website/src/repl/prebake.mjs | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/soundfonts/fontloader.mjs b/packages/soundfonts/fontloader.mjs index a13eb764..45fae951 100644 --- a/packages/soundfonts/fontloader.mjs +++ b/packages/soundfonts/fontloader.mjs @@ -126,13 +126,18 @@ export function registerSoundfonts() { const bufferSource = await getFontBufferSource(instrument, note || n, ctx); bufferSource.start(time); const stop = (time) => bufferSource.stop(time); + const g = new GainNode(ctx, { gain: 0.3 }); + bufferSource.connect(g); bufferSource.onended = () => { bufferSource.disconnect(); + g.disconnect(); onended(); }; - return { node: bufferSource, stop }; + return { node: g, stop }; }, { type: 'soundfont', prebake: true }, ); }); } + +registerSoundfonts(); diff --git a/website/src/docs/MiniRepl.jsx b/website/src/docs/MiniRepl.jsx index 83106a53..cce24623 100644 --- a/website/src/docs/MiniRepl.jsx +++ b/website/src/docs/MiniRepl.jsx @@ -18,6 +18,7 @@ if (typeof window !== 'undefined') { import('@strudel.cycles/webaudio'), import('@strudel.cycles/osc'), import('@strudel.cycles/csound'), + import('@strudel.cycles/soundfonts'), ); } diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index 5c86dd08..04ec66a7 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -1,12 +1,12 @@ import { Pattern, toMidi, valueToMidi } from '@strudel.cycles/core'; -import { registerSoundfonts } from '@strudel.cycles/soundfonts'; +//import { registerSoundfonts } from '@strudel.cycles/soundfonts'; import { registerSynthSounds, samples } from '@strudel.cycles/webaudio'; export async function prebake() { // https://archive.org/details/SalamanderGrandPianoV3 // License: CC-by http://creativecommons.org/licenses/by/3.0/ Author: Alexander Holm registerSynthSounds(); - registerSoundfonts(); + //registerSoundfonts(); await Promise.all([ samples(`./piano.json`, `./piano/`, { prebake: true }), // https://github.com/sgossner/VCSL/ From aa324ae25d5eb0f8544ae76b644709fbe5ab5429 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 10 Mar 2023 11:33:55 +0100 Subject: [PATCH 12/24] start curating the soundfont list --- packages/soundfonts/list.mjs | 733 ++++++++++++++++++++++------------- website/src/repl/Footer.jsx | 7 +- 2 files changed, 468 insertions(+), 272 deletions(-) diff --git a/packages/soundfonts/list.mjs b/packages/soundfonts/list.mjs index 96e5fd7c..6c162206 100644 --- a/packages/soundfonts/list.mjs +++ b/packages/soundfonts/list.mjs @@ -1,4 +1,5 @@ export const instruments = [ + // Acoustic Grand Piano: Piano '0000_JCLive_sf2_file', '0000_Aspirin_sf2_file', '0000_Chaos_sf2_file', @@ -8,8 +9,12 @@ export const instruments = [ //'0000_SoundBlasterOld_sf2', '0001_FluidR3_GM_sf2_file', '0001_GeneralUserGS_sf2_file', - '0002_GeneralUserGS_sf2_file', - '0003_GeneralUserGS_sf2_file', + + // ?? + '0002_GeneralUserGS_sf2_file', // strring + '0003_GeneralUserGS_sf2_file', // vibraphone like + + // Bright Acoustic Piano: Piano '0010_Aspirin_sf2_file', '0010_Chaos_sf2_file', '0010_FluidR3_GM_sf2_file', @@ -20,7 +25,10 @@ export const instruments = [ '0011_Aspirin_sf2_file', '0011_FluidR3_GM_sf2_file', '0011_GeneralUserGS_sf2_file', - '0012_GeneralUserGS_sf2_file', + + '0012_GeneralUserGS_sf2_file', // string?? + + // Electric Grand Piano: Piano '0020_Aspirin_sf2_file', '0020_Chaos_sf2_file', '0020_FluidR3_GM_sf2_file', @@ -30,7 +38,10 @@ export const instruments = [ //'0020_SoundBlasterOld_sf2', '0021_Aspirin_sf2_file', '0021_GeneralUserGS_sf2_file', - '0022_Aspirin_sf2_file', + // ? + '0022_Aspirin_sf2_file', // dx7 epiano like + + // Honky-tonk Piano: Piano '0030_Aspirin_sf2_file', '0030_Chaos_sf2_file', '0030_FluidR3_GM_sf2_file', @@ -42,6 +53,8 @@ export const instruments = [ '0031_FluidR3_GM_sf2_file', '0031_GeneralUserGS_sf2_file', //'0031_SoundBlasterOld_sf2', // pianos until here + + // Electric Piano 1: Piano '0040_Aspirin_sf2_file', '0040_Chaos_sf2_file', '0040_FluidR3_GM_sf2_file', // rhodes @@ -53,22 +66,31 @@ export const instruments = [ '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 + //'0045_GeneralUserGS_sf2_file', // ? + '0046_GeneralUserGS_sf2_file', // reed organ + + // Electric Piano 2: Piano + '0050_Aspirin_sf2_file', // glass piano + '0050_Chaos_sf2_file', // short glass piano + '0050_FluidR3_GM_sf2_file', // long glass piano ! + // ? + '0050_GeneralUserGS_sf2_file', // short glass piano + // cont + '0050_JCLive_sf2_file', // glass piano //'0050_SBLive_sf2', // ? //'0050_SoundBlasterOld_sf2', // ? '0051_FluidR3_GM_sf2_file', // long lass organ '0051_GeneralUserGS_sf2_file', - '0052_GeneralUserGS_sf2_file', // ? + //'0052_GeneralUserGS_sf2_file', // ? '0053_GeneralUserGS_sf2_file', + // normal piano... '0054_GeneralUserGS_sf2_file', // piano + + // Harpsichord: Piano '0060_Aspirin_sf2_file', // harpsichord '0060_Chaos_sf2_file', '0060_FluidR3_GM_sf2_file', // harpsichord ! @@ -80,14 +102,18 @@ export const instruments = [ '0061_GeneralUserGS_sf2_file', //'0061_SoundBlasterOld_sf2', '0062_GeneralUserGS_sf2_file', + + // Clavinet: Piano '0070_Aspirin_sf2_file', '0070_Chaos_sf2_file', '0070_FluidR3_GM_sf2_file', - '0070_GeneralUserGS_sf2_file', + // '0070_GeneralUserGS_sf2_file', // half broken '0070_JCLive_sf2_file', //'0070_SBLive_sf2', //'0070_SoundBlasterOld_sf2', - '0071_GeneralUserGS_sf2_file', + // '0071_GeneralUserGS_sf2_file', // half broken + + // Celesta: Chromatic Percussion '0080_Aspirin_sf2_file', '0080_Chaos_sf2_file', '0080_FluidR3_GM_sf2_file', @@ -96,8 +122,10 @@ export const instruments = [ //'0080_SBLive_sf2', //'0080_SoundBlasterOld_sf2', '0081_FluidR3_GM_sf2_file', - '0081_GeneralUserGS_sf2_file', + // '0081_GeneralUserGS_sf2_file', // weird detuned //'0081_SoundBlasterOld_sf2', + + // Glockenspiel: Chromatic Percussion '0090_Aspirin_sf2_file', '0090_Chaos_sf2_file', '0090_FluidR3_GM_sf2_file', @@ -106,6 +134,8 @@ export const instruments = [ //'0090_SBLive_sf2', //'0090_SoundBlasterOld_sf2', //'0091_SoundBlasterOld_sf2', + + // Music Box: Chromatic Percussion '0100_Aspirin_sf2_file', '0100_Chaos_sf2_file', '0100_FluidR3_GM_sf2_file', @@ -113,8 +143,10 @@ export const instruments = [ '0100_JCLive_sf2_file', //'0100_SBLive_sf2', //'0100_SoundBlasterOld_sf2', - '0101_GeneralUserGS_sf2_file', + // '0101_GeneralUserGS_sf2_file', // weird detuned //'0101_SoundBlasterOld_sf2', + + // Vibraphone: Chromatic Percussion '0110_Aspirin_sf2_file', '0110_Chaos_sf2_file', '0110_FluidR3_GM_sf2_file', @@ -123,6 +155,8 @@ export const instruments = [ //'0110_SBLive_sf2', //'0110_SoundBlasterOld_sf2', '0111_FluidR3_GM_sf2_file', + + // Marimba: Chromatic Percussion '0120_Aspirin_sf2_file', '0120_Chaos_sf2_file', '0120_FluidR3_GM_sf2_file', @@ -131,7 +165,9 @@ export const instruments = [ //'0120_SBLive_sf2', //'0120_SoundBlasterOld_sf2', '0121_FluidR3_GM_sf2_file', - '0121_GeneralUserGS_sf2_file', + '0121_GeneralUserGS_sf2_file', // not really a marimba + + // Xylophone: Chromatic Percussion '0130_Aspirin_sf2_file', '0130_Chaos_sf2_file', '0130_FluidR3_GM_sf2_file', @@ -140,25 +176,31 @@ export const instruments = [ //'0130_SBLive_sf2', //'0130_SoundBlasterOld_sf2', '0131_FluidR3_GM_sf2_file', + + // Tubular Bells: Chromatic Percussion '0140_Aspirin_sf2_file', - '0140_Chaos_sf2_file', + // '0140_Chaos_sf2_file', // same as aspirin? '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', + //'0141_GeneralUserGS_sf2_file', + '0142_GeneralUserGS_sf2_file', // epiano.. + // '0143_GeneralUserGS_sf2_file', // buggy + + // Dulcimer: Chromatic Percussion '0150_Aspirin_sf2_file', - '0150_Chaos_sf2_file', + '0150_Chaos_sf2_file', // long load? '0150_FluidR3_GM_sf2_file', '0150_GeneralUserGS_sf2_file', - '0150_JCLive_sf2_file', + // '0150_JCLive_sf2_file', // detuned??? //'0150_SBLive_sf2', //'0150_SoundBlasterOld_sf2', '0151_FluidR3_GM_sf2_file', + + // Drawbar Organ: Organ '0160_Aspirin_sf2_file', '0160_Chaos_sf2_file', '0160_FluidR3_GM_sf2_file', @@ -169,16 +211,20 @@ export const instruments = [ '0161_Aspirin_sf2_file', '0161_FluidR3_GM_sf2_file', //'0161_SoundBlasterOld_sf2', + + // Percussive Organ: Organ '0170_Aspirin_sf2_file', '0170_Chaos_sf2_file', '0170_FluidR3_GM_sf2_file', - '0170_GeneralUserGS_sf2_file', + // '0170_GeneralUserGS_sf2_file', // repitched '0170_JCLive_sf2_file', //'0170_SBLive_sf2', //'0170_SoundBlasterOld_sf2', '0171_FluidR3_GM_sf2_file', - '0171_GeneralUserGS_sf2_file', + // '0171_GeneralUserGS_sf2_file', // repitched '0172_FluidR3_GM_sf2_file', + + // Rock Organ: Organ '0180_Aspirin_sf2_file', '0180_Chaos_sf2_file', '0180_FluidR3_GM_sf2_file', @@ -186,9 +232,13 @@ export const instruments = [ '0180_JCLive_sf2_file', //'0180_SBLive_sf2', //'0180_SoundBlasterOld_sf2', - '0181_Aspirin_sf2_file', - '0181_GeneralUserGS_sf2_file', + + // ??? + //'0181_Aspirin_sf2_file', // flute + //'0181_GeneralUserGS_sf2_file', // marimbalike //'0181_SoundBlasterOld_sf2', + + // Church Organ: Organ '0190_Aspirin_sf2_file', '0190_Chaos_sf2_file', '0190_FluidR3_GM_sf2_file', @@ -196,32 +246,38 @@ export const instruments = [ '0190_JCLive_sf2_file', //'0190_SBLive_sf2', //'0190_SoundBlasterOld_sf2', - '0191_Aspirin_sf2_file', - '0191_GeneralUserGS_sf2_file', + //'0191_Aspirin_sf2_file', // string?? + //'0191_GeneralUserGS_sf2_file', // weird organ //'0191_SoundBlasterOld_sf2', + + // Reed Organ: Organ '0200_Aspirin_sf2_file', '0200_Chaos_sf2_file', '0200_FluidR3_GM_sf2_file', '0200_GeneralUserGS_sf2_file', - '0200_JCLive_sf2_file', + '0200_JCLive_sf2_file', // stringy //'0200_SBLive_sf2', //'0200_SoundBlasterOld_sf2', - '0201_Aspirin_sf2_file', + '0201_Aspirin_sf2_file', // stringy '0201_FluidR3_GM_sf2_file', '0201_GeneralUserGS_sf2_file', //'0201_SoundBlasterOld_sf2', - '0210_Aspirin_sf2_file', - '0210_Chaos_sf2_file', + //'0210_Aspirin_sf2_file', // buggy + //'0210_Chaos_sf2_file', // buggy + + // Accordion: Organ '0210_FluidR3_GM_sf2_file', '0210_GeneralUserGS_sf2_file', '0210_JCLive_sf2_file', //'0210_SBLive_sf2', //'0210_SoundBlasterOld_sf2', - '0211_Aspirin_sf2_file', + '0211_Aspirin_sf2_file', // stringy '0211_FluidR3_GM_sf2_file', '0211_GeneralUserGS_sf2_file', //'0211_SoundBlasterOld_sf2', '0212_GeneralUserGS_sf2_file', + + // Harmonica: Organ '0220_Aspirin_sf2_file', '0220_Chaos_sf2_file', '0220_FluidR3_GM_sf2_file', @@ -230,6 +286,8 @@ export const instruments = [ //'0220_SBLive_sf2', //'0220_SoundBlasterOld_sf2', '0221_FluidR3_GM_sf2_file', + + // Tango Accordion: Organ '0230_Aspirin_sf2_file', '0230_Chaos_sf2_file', '0230_FluidR3_GM_sf2_file', @@ -238,11 +296,13 @@ export const instruments = [ //'0230_SBLive_sf2', //'0230_SoundBlasterOld_sf2', '0231_FluidR3_GM_sf2_file', - '0231_GeneralUserGS_sf2_file', + '0231_GeneralUserGS_sf2_file', // warbly '0231_JCLive_sf2_file', //'0231_SoundBlasterOld_sf2', '0232_FluidR3_GM_sf2_file', '0233_FluidR3_GM_sf2_file', + + // Acoustic Guitar (nylon): Guitar '0240_Aspirin_sf2_file', '0240_Chaos_sf2_file', '0240_FluidR3_GM_sf2_file', @@ -251,60 +311,68 @@ export const instruments = [ '0240_LK_Godin_Nylon_SF2_file', //'0240_SBLive_sf2', //'0240_SoundBlasterOld_sf2', - '0241_GeneralUserGS_sf2_file', + // '0241_GeneralUserGS_sf2_file', // organ like '0241_JCLive_sf2_file', '0242_JCLive_sf2_file', '0243_JCLive_sf2_file', + + // Acoustic Guitar (steel): Guitar '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_JCLive_sf2_file', // detuned '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', + //'0251_Acoustic_Guitar_sf2_file', // detuned? + // '0251_GeneralUserGS_sf2_file', // broken: missing pitches + // '0252_Acoustic_Guitar_sf2_file', // detuned.. + // '0252_GeneralUserGS_sf2_file', // broken: missing pitches '0253_Acoustic_Guitar_sf2_file', '0253_GeneralUserGS_sf2_file', - '0254_Acoustic_Guitar_sf2_file', + '0254_Acoustic_Guitar_sf2_file', // bends.. detuned '0254_GeneralUserGS_sf2_file', - '0255_GeneralUserGS_sf2_file', - '0260_Aspirin_sf2_file', - '0260_Chaos_sf2_file', + //'0255_GeneralUserGS_sf2_file', // no guitar.. + + // Electric Guitar (jazz): Guitar + '0260_Aspirin_sf2_file', // sounds like an epiano + '0260_Chaos_sf2_file', // weird but cool detune '0260_FluidR3_GM_sf2_file', '0260_GeneralUserGS_sf2_file', '0260_JCLive_sf2_file', //'0260_SBLive_sf2', //'0260_SoundBlasterOld_sf2', - '0260_Stratocaster_sf2_file', + '0260_Stratocaster_sf2_file', // -1 octave '0261_GeneralUserGS_sf2_file', //'0261_SoundBlasterOld_sf2', - '0261_Stratocaster_sf2_file', - '0262_Stratocaster_sf2_file', + '0261_Stratocaster_sf2_file', // -1 octave + '0262_Stratocaster_sf2_file', // -1 octave + + // Electric Guitar (clean): Guitar '0270_Aspirin_sf2_file', - '0270_Chaos_sf2_file', + '0270_Chaos_sf2_file', // sounds meh '0270_FluidR3_GM_sf2_file', '0270_GeneralUserGS_sf2_file', - '0270_Gibson_Les_Paul_sf2_file', - '0270_JCLive_sf2_file', + //'0270_Gibson_Les_Paul_sf2_file', // detuned + // '0270_JCLive_sf2_file', // broken: missing notes '0270_SBAWE32_sf2_file', //'0270_SBLive_sf2', //'0270_SoundBlasterOld_sf2', - '0270_Stratocaster_sf2_file', + '0270_Stratocaster_sf2_file', // -1 octave '0271_GeneralUserGS_sf2_file', - '0271_Stratocaster_sf2_file', - '0272_Stratocaster_sf2_file', + '0271_Stratocaster_sf2_file', // -1 octave + '0272_Stratocaster_sf2_file', // -1 octave + + // Electric Guitar (muted): Guitar '0280_Aspirin_sf2_file', '0280_Chaos_sf2_file', - '0280_FluidR3_GM_sf2_file', + // '0280_FluidR3_GM_sf2_file', // broken: wrong notes '0280_GeneralUserGS_sf2_file', '0280_JCLive_sf2_file', - '0280_LesPaul_sf2', - '0280_LesPaul_sf2_file', + //'0280_LesPaul_sf2', // missing + '0280_LesPaul_sf2_file', // not really muted.. '0280_SBAWE32_sf2_file', //'0280_SBLive_sf2', //'0280_SoundBlasterOld_sf2', @@ -312,140 +380,165 @@ export const instruments = [ '0281_FluidR3_GM_sf2_file', '0281_GeneralUserGS_sf2_file', '0282_FluidR3_GM_sf2_file', - '0282_GeneralUserGS_sf2_file', - '0283_GeneralUserGS_sf2_file', + // '0282_GeneralUserGS_sf2_file', // broken: missing notes + // '0283_GeneralUserGS_sf2_file', // missing + + // Overdriven Guitar: Guitar '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_JCLive_sf2_file', // detuned.... + //'0290_LesPaul_sf2', // broken '0290_LesPaul_sf2_file', '0290_SBAWE32_sf2_file', //'0290_SBLive_sf2', //'0290_SoundBlasterOld_sf2', - '0291_Aspirin_sf2_file', - '0291_LesPaul_sf2', + // '0291_Aspirin_sf2_file', // broken + // '0291_LesPaul_sf2', // broken '0291_LesPaul_sf2_file', '0291_SBAWE32_sf2_file', //'0291_SoundBlasterOld_sf2', '0292_Aspirin_sf2_file', - '0292_LesPaul_sf2', + // '0292_LesPaul_sf2', // broken '0292_LesPaul_sf2_file', + + // Distortion Guitar: Guitar '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_JCLive_sf2_file', // broken + // '0300_LesPaul_sf2', // broken '0300_LesPaul_sf2_file', - '0300_SBAWE32_sf2_file', + //'0300_SBAWE32_sf2_file', // -2 octave //'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', + // '0301_Aspirin_sf2_file', // missing + + //'0301_FluidR3_GM_sf2_file', // weird broken bell + // '0301_GeneralUserGS_sf2_file', // broken + // '0301_JCLive_sf2_file', // broken + // '0301_LesPaul_sf2', // missing + // '0301_LesPaul_sf2_file', // + 1 oct? '0302_Aspirin_sf2_file', - '0302_GeneralUserGS_sf2_file', - '0302_JCLive_sf2_file', - '0303_Aspirin_sf2_file', + // '0302_GeneralUserGS_sf2_file', // not a guitar.. + //'0302_JCLive_sf2_file', // broken... + // '0303_Aspirin_sf2_file', // guitar harmonic?? '0304_Aspirin_sf2_file', + + // Guitar Harmonics: Guitar '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_FluidR3_GM_sf2_file', // weird.. + //'0310_GeneralUserGS_sf2_file', // weird.. + // '0310_JCLive_sf2_file', // weird + //'0310_LesPaul_sf2', // missing + //'0310_LesPaul_sf2_file', // wrong pitches + //'0310_SBAWE32_sf2_file', // wrong pitches //'0310_SBLive_sf2', //'0310_SoundBlasterOld_sf2', - '0311_FluidR3_GM_sf2_file', - '0311_GeneralUserGS_sf2_file', + //'0311_FluidR3_GM_sf2_file', // knackt + //'0311_GeneralUserGS_sf2_file', // wrong notes + + // Acoustic Bass: Bass '0320_Aspirin_sf2_file', '0320_Chaos_sf2_file', '0320_FluidR3_GM_sf2_file', - '0320_GeneralUserGS_sf2_file', + // '0320_GeneralUserGS_sf2_file', // missing notes '0320_JCLive_sf2_file', //'0320_SBLive_sf2', //'0320_SoundBlasterOld_sf2', - '0321_GeneralUserGS_sf2_file', - '0322_GeneralUserGS_sf2_file', + // '0321_GeneralUserGS_sf2_file', // nice sound but missing notes + // '0322_GeneralUserGS_sf2_file', // missing notes + + // Electric Bass (finger): Bass '0330_Aspirin_sf2_file', - '0330_Chaos_sf2_file', - '0330_FluidR3_GM_sf2_file', - '0330_GeneralUserGS_sf2_file', + //'0330_Chaos_sf2_file', // same as last + '0330_FluidR3_GM_sf2_file', // knackt.. + '0330_GeneralUserGS_sf2_file', // -1 oct '0330_JCLive_sf2_file', //'0330_SBLive_sf2', //'0330_SoundBlasterOld_sf2', - '0331_GeneralUserGS_sf2_file', - '0332_GeneralUserGS_sf2_file', + //'0331_GeneralUserGS_sf2_file', // knackt + // '0332_GeneralUserGS_sf2_file', // missing + + // Electric Bass (pick): Bass '0340_Aspirin_sf2_file', - '0340_Chaos_sf2_file', + //'0340_Chaos_sf2_file', // same as last '0340_FluidR3_GM_sf2_file', - '0340_GeneralUserGS_sf2_file', + '0340_GeneralUserGS_sf2_file', // -1oct '0340_JCLive_sf2_file', //'0340_SBLive_sf2', //'0340_SoundBlasterOld_sf2', '0341_Aspirin_sf2_file', - '0341_GeneralUserGS_sf2_file', + //'0341_GeneralUserGS_sf2_file', // knackt + + // Fretless Bass: Bass '0350_Aspirin_sf2_file', - '0350_Chaos_sf2_file', - '0350_FluidR3_GM_sf2_file', - '0350_GeneralUserGS_sf2_file', - '0350_JCLive_sf2_file', + // '0350_Chaos_sf2_file', // same as last + //'0350_FluidR3_GM_sf2_file', // knackt + //'0350_GeneralUserGS_sf2_file', // -1 oct + knackt + '0350_JCLive_sf2_file', // weird detuned //'0350_SBLive_sf2', //'0350_SoundBlasterOld_sf2', - '0351_GeneralUserGS_sf2_file', + //'0351_GeneralUserGS_sf2_file', // missing + + // Slap Bass 1: Bass '0360_Aspirin_sf2_file', '0360_Chaos_sf2_file', - '0360_FluidR3_GM_sf2_file', - '0360_GeneralUserGS_sf2_file', + '0360_FluidR3_GM_sf2_file', // knackt + //'0360_GeneralUserGS_sf2_file', // -1 oct '0360_JCLive_sf2_file', //'0360_SBLive_sf2', //'0360_SoundBlasterOld_sf2', - '0361_GeneralUserGS_sf2_file', + //'0361_GeneralUserGS_sf2_file', // missing + + // Slap Bass 2: Bass '0370_Aspirin_sf2_file', - '0370_Chaos_sf2_file', + // '0370_Chaos_sf2_file', // same as last '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', + //'0371_GeneralUserGS_sf2_file', // missing + //'0372_GeneralUserGS_sf2_file', // detuned + //'0385_GeneralUserGS_sf2_file', // missing + + // Synth Bass 1: Bass + '0380_Aspirin_sf2_file', // laut! '0380_Chaos_sf2_file', - '0380_FluidR3_GM_sf2_file', - '0380_GeneralUserGS_sf2_file', + '0380_FluidR3_GM_sf2_file', // bisl detuned + // '0380_GeneralUserGS_sf2_file', // laut '0380_JCLive_sf2_file', //'0380_SBLive_sf2', //'0380_SoundBlasterOld_sf2', - '0381_FluidR3_GM_sf2_file', + '0381_FluidR3_GM_sf2_file', // bisl detuned '0381_GeneralUserGS_sf2_file', - '0382_FluidR3_GM_sf2_file', + //'0382_FluidR3_GM_sf2_file', // kein synth bass '0382_GeneralUserGS_sf2_file', '0383_GeneralUserGS_sf2_file', '0384_GeneralUserGS_sf2_file', - '0386_GeneralUserGS_sf2_file', + //'0386_GeneralUserGS_sf2_file', // knackt '0387_GeneralUserGS_sf2_file', + + // Synth Bass 2: Bass '0390_Aspirin_sf2_file', - '0390_Chaos_sf2_file', + // '0390_Chaos_sf2_file', // same as last '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_FluidR3_GM_sf2_file', // lauuut + // '0391_GeneralUserGS_sf2_file', // missing //'0391_SoundBlasterOld_sf2', - '0392_FluidR3_GM_sf2_file', - '0392_GeneralUserGS_sf2_file', - '0393_GeneralUserGS_sf2_file', + '0392_FluidR3_GM_sf2_file', // lauut + //'0392_GeneralUserGS_sf2_file', // kein synth und -1oct + '0393_GeneralUserGS_sf2_file', // lauuuut + + // Violin: Strings '0400_Aspirin_sf2_file', '0400_Chaos_sf2_file', '0400_FluidR3_GM_sf2_file', @@ -453,333 +546,403 @@ export const instruments = [ '0400_JCLive_sf2_file', //'0400_SBLive_sf2', //'0400_SoundBlasterOld_sf2', - '0401_Aspirin_sf2_file', + '0401_Aspirin_sf2_file', // synth '0401_FluidR3_GM_sf2_file', '0401_GeneralUserGS_sf2_file', - '0402_GeneralUserGS_sf2_file', + '0402_GeneralUserGS_sf2_file', // pizzicato + + // Viola: Strings '0410_Aspirin_sf2_file', - '0410_Chaos_sf2_file', + // '0410_Chaos_sf2_file', // laut und sehr unstringy '0410_FluidR3_GM_sf2_file', '0410_GeneralUserGS_sf2_file', - '0410_JCLive_sf2_file', + '0410_JCLive_sf2_file', // <3 //'0410_SBLive_sf2', //'0410_SoundBlasterOld_sf2', '0411_FluidR3_GM_sf2_file', + + // Cello: Strings '0420_Aspirin_sf2_file', - '0420_Chaos_sf2_file', + // '0420_Chaos_sf2_file', // kein cello und laut '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', + '0421_GeneralUserGS_sf2_file', // pizzicato + + // Contrabass: Strings '0430_Aspirin_sf2_file', '0430_Chaos_sf2_file', - '0430_FluidR3_GM_sf2_file', + // '0430_FluidR3_GM_sf2_file', // missing notes '0430_GeneralUserGS_sf2_file', - '0430_JCLive_sf2_file', + //'0430_JCLive_sf2_file', // -1 oct und meh //'0430_SBLive_sf2', //'0430_SoundBlasterOld_sf2', - '0431_FluidR3_GM_sf2_file', + // '0431_FluidR3_GM_sf2_file', // missing notes + + // Tremolo Strings: Strings '0440_Aspirin_sf2_file', '0440_Chaos_sf2_file', - '0440_FluidR3_GM_sf2_file', + //'0440_FluidR3_GM_sf2_file', // huuuge '0440_GeneralUserGS_sf2_file', '0440_JCLive_sf2_file', //'0440_SBLive_sf2', //'0440_SoundBlasterOld_sf2', '0441_GeneralUserGS_sf2_file', '0442_GeneralUserGS_sf2_file', + + // Pizzicato Strings: Strings '0450_Aspirin_sf2_file', - '0450_Chaos_sf2_file', - '0450_FluidR3_GM_sf2_file', - '0450_GeneralUserGS_sf2_file', - '0450_JCLive_sf2_file', + '0450_Chaos_sf2_file', // same as last + '0450_FluidR3_GM_sf2_file', // chrono trigger flashback + '0450_GeneralUserGS_sf2_file', // -1 oct? + '0450_JCLive_sf2_file', // filter env //'0450_SBLive_sf2', //'0450_SoundBlasterOld_sf2', '0451_FluidR3_GM_sf2_file', + + // Orchestral Harp: Strings '0460_Aspirin_sf2_file', - '0460_Chaos_sf2_file', + // '0460_Chaos_sf2_file', // knackt '0460_FluidR3_GM_sf2_file', '0460_GeneralUserGS_sf2_file', '0460_JCLive_sf2_file', //'0460_SBLive_sf2', //'0460_SoundBlasterOld_sf2', '0461_FluidR3_GM_sf2_file', + + // Timpani: Strings '0470_Aspirin_sf2_file', '0470_Chaos_sf2_file', '0470_FluidR3_GM_sf2_file', '0470_GeneralUserGS_sf2_file', - '0470_JCLive_sf2_file', + // '0470_JCLive_sf2_file', // wrong pitches //'0470_SBLive_sf2', //'0470_SoundBlasterOld_sf2', '0471_FluidR3_GM_sf2_file', '0471_GeneralUserGS_sf2_file', + + // String Ensemble 1: Ensemble '0480_Aspirin_sf2_file', '0480_Chaos_sf2_file', - '0480_FluidR3_GM_sf2_file', + '0480_FluidR3_GM_sf2_file', // large '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', + + // these dont work.. + //'04810_GeneralUserGS_sf2_file', // missing notes + brass + //'04811_GeneralUserGS_sf2_file', // missing notes + brass + //'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_FluidR3_GM_sf2_file', // brass '0481_GeneralUserGS_sf2_file', - '0482_Aspirin_sf2_file', + '0482_Aspirin_sf2_file', // brass '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', + '0483_GeneralUserGS_sf2_file', // brass + // another block of buggyness: + //'0484_GeneralUserGS_sf2_file', // keys?! + knackt + //'0485_GeneralUserGS_sf2_file', // missing notes + //'0486_GeneralUserGS_sf2_file', + //'0487_GeneralUserGS_sf2_file', + //'0488_GeneralUserGS_sf2_file', + //'0489_GeneralUserGS_sf2_file', + + // String Ensemble 2: Ensemble '0490_Aspirin_sf2_file', '0490_Chaos_sf2_file', - '0490_FluidR3_GM_sf2_file', + '0490_FluidR3_GM_sf2_file', // large '0490_GeneralUserGS_sf2_file', '0490_JCLive_sf2_file', //'0490_SBLive_sf2', //'0490_SoundBlasterOld_sf2', '0491_GeneralUserGS_sf2_file', '0492_GeneralUserGS_sf2_file', + + // Synth Strings 1: Ensemble '0500_Aspirin_sf2_file', - '0500_Chaos_sf2_file', - '0500_FluidR3_GM_sf2_file', + // '0500_Chaos_sf2_file', // same as above + //'0500_FluidR3_GM_sf2_file', // detune + knack '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', + // '0501_GeneralUserGS_sf2_file', // crackles + // '0502_FluidR3_GM_sf2_file', // missing '0502_GeneralUserGS_sf2_file', - '0503_FluidR3_GM_sf2_file', - '0504_FluidR3_GM_sf2_file', + '0503_FluidR3_GM_sf2_file', // large + // '0504_FluidR3_GM_sf2_file', // missing '0505_FluidR3_GM_sf2_file', + + // Synth Strings 2: Ensemble '0510_Aspirin_sf2_file', '0510_Chaos_sf2_file', - '0510_FluidR3_GM_sf2_file', + // '0510_FluidR3_GM_sf2_file', // detune + crackle '0510_GeneralUserGS_sf2_file', - '0510_JCLive_sf2_file', - //'0510_SBLive_sf2', + //'0510_JCLive_sf2_file', // laarge and meh + //'0510_SBLive_sf2', // missing //'0510_SoundBlasterOld_sf2', - '0511_GeneralUserGS_sf2_file', + '0511_GeneralUserGS_sf2_file', // crackly //'0511_SoundBlasterOld_sf2', + + // Choir Aahs: Ensemble '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_Soul_Ahhs_sf2_file', // large //'0520_SoundBlasterOld_sf2', '0521_FluidR3_GM_sf2_file', - '0521_Soul_Ahhs_sf2_file', + '0521_Soul_Ahhs_sf2_file', // large //'0521_SoundBlasterOld_sf2', - '0522_Soul_Ahhs_sf2_file', + '0522_Soul_Ahhs_sf2_file', // large + + // Voice Oohs: Ensemble '0530_Aspirin_sf2_file', '0530_Chaos_sf2_file', '0530_FluidR3_GM_sf2_file', '0530_GeneralUserGS_sf2_file', - '0530_JCLive_sf2_file', + //'0530_JCLive_sf2_file', // same as above //'0530_SBLive_sf2', - '0530_Soul_Ahhs_sf2_file', + // '0530_Soul_Ahhs_sf2_file', // not ooh //'0530_SoundBlasterOld_sf2', '0531_FluidR3_GM_sf2_file', - '0531_GeneralUserGS_sf2_file', + // '0531_GeneralUserGS_sf2_file', // ends crackle '0531_JCLive_sf2_file', //'0531_SoundBlasterOld_sf2', + + // Synth Choir: Ensemble '0540_Aspirin_sf2_file', '0540_Chaos_sf2_file', '0540_FluidR3_GM_sf2_file', '0540_GeneralUserGS_sf2_file', - '0540_JCLive_sf2_file', + //'0540_JCLive_sf2_file', // large + crackles //'0540_SBLive_sf2', //'0540_SoundBlasterOld_sf2', '0541_FluidR3_GM_sf2_file', + + // Orchestra Hit: Ensemble '0550_Aspirin_sf2_file', '0550_Chaos_sf2_file', '0550_FluidR3_GM_sf2_file', '0550_GeneralUserGS_sf2_file', - '0550_JCLive_sf2_file', + //'0550_JCLive_sf2_file', // same as above //'0550_SBLive_sf2', //'0550_SoundBlasterOld_sf2', - '0551_Aspirin_sf2_file', + //'0551_Aspirin_sf2_file', // not an orch hit.. '0551_FluidR3_GM_sf2_file', + + // Trumpet: Brass '0560_Aspirin_sf2_file', '0560_Chaos_sf2_file', '0560_FluidR3_GM_sf2_file', - '0560_GeneralUserGS_sf2_file', + //'0560_GeneralUserGS_sf2_file', // -1 oct '0560_JCLive_sf2_file', //'0560_SBLive_sf2', //'0560_SoundBlasterOld_sf2', + + // Trombone: Brass '0570_Aspirin_sf2_file', '0570_Chaos_sf2_file', '0570_FluidR3_GM_sf2_file', '0570_GeneralUserGS_sf2_file', - '0570_JCLive_sf2_file', + //'0570_JCLive_sf2_file', // -1oct //'0570_SBLive_sf2', //'0570_SoundBlasterOld_sf2', '0571_GeneralUserGS_sf2_file', + + // Tuba: Brass '0580_Aspirin_sf2_file', '0580_Chaos_sf2_file', '0580_FluidR3_GM_sf2_file', '0580_GeneralUserGS_sf2_file', - '0580_JCLive_sf2_file', + //'0580_JCLive_sf2_file', // -1oct //'0580_SBLive_sf2', //'0580_SoundBlasterOld_sf2', - '0581_GeneralUserGS_sf2_file', + //'0581_GeneralUserGS_sf2_file', // missing + + // Muted Trumpet: Brass '0590_Aspirin_sf2_file', '0590_Chaos_sf2_file', '0590_FluidR3_GM_sf2_file', '0590_GeneralUserGS_sf2_file', - '0590_JCLive_sf2_file', + '0590_JCLive_sf2_file', // winner //'0590_SBLive_sf2', //'0590_SoundBlasterOld_sf2', - '0591_GeneralUserGS_sf2_file', + // '0591_GeneralUserGS_sf2_file', // missing + + // French Horn: Brass '0600_Aspirin_sf2_file', - '0600_Chaos_sf2_file', - '0600_FluidR3_GM_sf2_file', - '0600_GeneralUserGS_sf2_file', - '0600_JCLive_sf2_file', + //'0600_Chaos_sf2_file', // weird jumps + '0600_FluidR3_GM_sf2_file', // tiny crackles + '0600_GeneralUserGS_sf2_file', // tiny crackles + '0600_JCLive_sf2_file', // tiny crackles //'0600_SBLive_sf2', //'0600_SoundBlasterOld_sf2', '0601_FluidR3_GM_sf2_file', - '0601_GeneralUserGS_sf2_file', - '0602_GeneralUserGS_sf2_file', - '0603_GeneralUserGS_sf2_file', + //'0601_GeneralUserGS_sf2_file', // tiny crackles + // '0602_GeneralUserGS_sf2_file', // bad gain diffs + // '0603_GeneralUserGS_sf2_file', // tiny crackles + + // Brass Section: Brass '0610_Aspirin_sf2_file', '0610_Chaos_sf2_file', - '0610_FluidR3_GM_sf2_file', + '0610_FluidR3_GM_sf2_file', // large '0610_GeneralUserGS_sf2_file', '0610_JCLive_sf2_file', //'0610_SBLive_sf2', //'0610_SoundBlasterOld_sf2', - '0611_GeneralUserGS_sf2_file', + // '0611_GeneralUserGS_sf2_file', // missing sounds '0612_GeneralUserGS_sf2_file', - '0613_GeneralUserGS_sf2_file', - '0614_GeneralUserGS_sf2_file', - '0615_GeneralUserGS_sf2_file', + //'0613_GeneralUserGS_sf2_file', // -1 oct + // '0614_GeneralUserGS_sf2_file', // missing sounds + // '0615_GeneralUserGS_sf2_file', // missing sounds + + // Synth Brass 1: Brass '0620_Aspirin_sf2_file', - '0620_Chaos_sf2_file', + //'0620_Chaos_sf2_file', // weird gain diff '0620_FluidR3_GM_sf2_file', - '0620_GeneralUserGS_sf2_file', - '0620_JCLive_sf2_file', + //'0620_GeneralUserGS_sf2_file', // loooud + // '0620_JCLive_sf2_file', // weird gain diff //'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', + // '0621_GeneralUserGS_sf2_file', // detune + loooud + //'0622_FluidR3_GM_sf2_file', // loud.. + //'0622_GeneralUserGS_sf2_file', // loud + crackles + + // Synth Brass 2: Brass '0630_Aspirin_sf2_file', '0630_Chaos_sf2_file', '0630_FluidR3_GM_sf2_file', - '0630_GeneralUserGS_sf2_file', + //'0630_GeneralUserGS_sf2_file', // detune + looud '0630_JCLive_sf2_file', //'0630_SBLive_sf2', //'0630_SoundBlasterOld_sf2', - '0631_Aspirin_sf2_file', + // '0631_Aspirin_sf2_file', // looud + detune + gain diffs '0631_FluidR3_GM_sf2_file', - '0631_GeneralUserGS_sf2_file', + //'0631_GeneralUserGS_sf2_file', // crackles '0632_FluidR3_GM_sf2_file', - '0633_FluidR3_GM_sf2_file', + '0633_FluidR3_GM_sf2_file', // tiny crackles + + // Soprano Sax: Reed '0640_Aspirin_sf2_file', '0640_Chaos_sf2_file', '0640_FluidR3_GM_sf2_file', - '0640_GeneralUserGS_sf2_file', + // '0640_GeneralUserGS_sf2_file', // crackles '0640_JCLive_sf2_file', //'0640_SBLive_sf2', //'0640_SoundBlasterOld_sf2', '0641_FluidR3_GM_sf2_file', - '0650_Aspirin_sf2_file', + + // Alto Sax: Reed + //'0650_Aspirin_sf2_file', // this is not an alto sax '0650_Chaos_sf2_file', - '0650_FluidR3_GM_sf2_file', + '0650_FluidR3_GM_sf2_file', // sounds really stringy '0650_GeneralUserGS_sf2_file', '0650_JCLive_sf2_file', //'0650_SBLive_sf2', //'0650_SoundBlasterOld_sf2', '0651_Aspirin_sf2_file', - '0651_FluidR3_GM_sf2_file', + '0651_FluidR3_GM_sf2_file', // really stringy '0660_Aspirin_sf2_file', '0660_Chaos_sf2_file', - '0660_FluidR3_GM_sf2_file', + //'0660_FluidR3_GM_sf2_file', // weird pitches '0660_GeneralUserGS_sf2_file', '0660_JCLive_sf2_file', //'0660_SBLive_sf2', //'0660_SoundBlasterOld_sf2', - '0661_FluidR3_GM_sf2_file', - '0661_GeneralUserGS_sf2_file', + // '0661_FluidR3_GM_sf2_file', // weird pitches + // '0661_GeneralUserGS_sf2_file', // missing + + // Baritone Sax: Reed '0670_Aspirin_sf2_file', '0670_Chaos_sf2_file', - '0670_FluidR3_GM_sf2_file', + '0670_FluidR3_GM_sf2_file', // huge '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', + '0671_FluidR3_GM_sf2_file', // huge + + // Oboe: Reed + //'0680_Aspirin_sf2_file', // tiny crackles + '0680_Chaos_sf2_file', // tiny crackles + '0680_FluidR3_GM_sf2_file', // tiny crackles '0680_GeneralUserGS_sf2_file', '0680_JCLive_sf2_file', //'0680_SBLive_sf2', //'0680_SoundBlasterOld_sf2', - '0681_FluidR3_GM_sf2_file', + '0681_FluidR3_GM_sf2_file', // tiny crackles + + // English Horn: Reed '0690_Aspirin_sf2_file', - '0690_Chaos_sf2_file', + //'0690_Chaos_sf2_file', // detuned '0690_FluidR3_GM_sf2_file', - '0690_GeneralUserGS_sf2_file', + //'0690_GeneralUserGS_sf2_file', // +1 oct '0690_JCLive_sf2_file', //'0690_SBLive_sf2', //'0690_SoundBlasterOld_sf2', - '0691_FluidR3_GM_sf2_file', - '0700_Aspirin_sf2_file', - '0700_Chaos_sf2_file', + '0691_FluidR3_GM_sf2_file', // tiny crackles + + // Bassoon: Reed + //'0700_Aspirin_sf2_file', // detune + gain diffs + // '0700_Chaos_sf2_file', // detune + crackles '0700_FluidR3_GM_sf2_file', - '0700_GeneralUserGS_sf2_file', + '0700_GeneralUserGS_sf2_file', // tiny crackles '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', + '0701_FluidR3_GM_sf2_file', // tiny crackles + //'0701_GeneralUserGS_sf2_file', // missing + + // Clarinet: Reed + '0710_Aspirin_sf2_file', // tiny crackles + '0710_Chaos_sf2_file', // tiny crackles '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', + + // Piccolo: Pipe + '0720_Aspirin_sf2_file', // +1oct + // '0720_Chaos_sf2_file', // not a piccolo '0720_FluidR3_GM_sf2_file', - '0720_GeneralUserGS_sf2_file', + '0720_GeneralUserGS_sf2_file', // crackles '0720_JCLive_sf2_file', //'0720_SBLive_sf2', //'0720_SoundBlasterOld_sf2', '0721_FluidR3_GM_sf2_file', //'0721_SoundBlasterOld_sf2', + + // Flute: Pipe '0730_Aspirin_sf2_file', - '0730_Chaos_sf2_file', + //'0730_Chaos_sf2_file', // etune '0730_FluidR3_GM_sf2_file', '0730_GeneralUserGS_sf2_file', '0730_JCLive_sf2_file', //'0730_SBLive_sf2', //'0730_SoundBlasterOld_sf2', - '0731_Aspirin_sf2_file', + //'0731_Aspirin_sf2_file', // not a flute '0731_FluidR3_GM_sf2_file', //'0731_SoundBlasterOld_sf2', + + // Recorder: Pipe '0740_Aspirin_sf2_file', '0740_Chaos_sf2_file', '0740_FluidR3_GM_sf2_file', @@ -787,19 +950,23 @@ export const instruments = [ '0740_JCLive_sf2_file', //'0740_SBLive_sf2', //'0740_SoundBlasterOld_sf2', - '0741_GeneralUserGS_sf2_file', - '0750_Aspirin_sf2_file', + // '0741_GeneralUserGS_sf2_file', // missing + + // Pan Flute: Pipe + '0750_Aspirin_sf2_file', // staccato '0750_Chaos_sf2_file', '0750_FluidR3_GM_sf2_file', - '0750_GeneralUserGS_sf2_file', + '0750_GeneralUserGS_sf2_file', // crackles '0750_JCLive_sf2_file', //'0750_SBLive_sf2', //'0750_SoundBlasterOld_sf2', '0751_Aspirin_sf2_file', '0751_FluidR3_GM_sf2_file', - '0751_GeneralUserGS_sf2_file', + '0751_GeneralUserGS_sf2_file', // crackles //'0751_SoundBlasterOld_sf2', - '0760_Aspirin_sf2_file', + + // Blown bottle: Pipe + // '0760_Aspirin_sf2_file', // same as below w crackle '0760_Chaos_sf2_file', '0760_FluidR3_GM_sf2_file', '0760_GeneralUserGS_sf2_file', @@ -807,44 +974,54 @@ export const instruments = [ //'0760_SBLive_sf2', //'0760_SoundBlasterOld_sf2', '0761_FluidR3_GM_sf2_file', - '0761_GeneralUserGS_sf2_file', + // '0761_GeneralUserGS_sf2_file', // missing //'0761_SoundBlasterOld_sf2', - '0762_GeneralUserGS_sf2_file', - '0770_Aspirin_sf2_file', - '0770_Chaos_sf2_file', + // '0762_GeneralUserGS_sf2_file', // missing + + // Shakuhachi: Pipe + '0770_Aspirin_sf2_file', // staccato + //'0770_Chaos_sf2_file', // not shakuhachi '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', + // '0771_GeneralUserGS_sf2_file', // missing + // '0772_GeneralUserGS_sf2_file', // missing + + // Whistle: Pipe + '0780_Aspirin_sf2_file', // crackles + '0780_Chaos_sf2_file', // crackles '0780_FluidR3_GM_sf2_file', - '0780_GeneralUserGS_sf2_file', - '0780_JCLive_sf2_file', + //'0780_GeneralUserGS_sf2_file', // loud.. + '0780_JCLive_sf2_file', // crackles //'0780_SBLive_sf2', //'0780_SoundBlasterOld_sf2', - '0781_GeneralUserGS_sf2_file', - '0790_Aspirin_sf2_file', - '0790_Chaos_sf2_file', + // '0781_GeneralUserGS_sf2_file', // detune + crackles + + // Ocarina: Pipe + '0790_Aspirin_sf2_file', // tiny crackles + //'0790_Chaos_sf2_file', // same as above '0790_FluidR3_GM_sf2_file', '0790_GeneralUserGS_sf2_file', - '0790_JCLive_sf2_file', + '0790_JCLive_sf2_file', // crackles //'0790_SBLive_sf2', //'0790_SoundBlasterOld_sf2', - '0791_GeneralUserGS_sf2_file', + //'0791_GeneralUserGS_sf2_file', // missing + + // Lead 1 (square): Synth Lead '0800_Aspirin_sf2_file', '0800_Chaos_sf2_file', '0800_FluidR3_GM_sf2_file', - '0800_GeneralUserGS_sf2_file', - '0800_JCLive_sf2_file', + // '0800_GeneralUserGS_sf2_file', // detuned + // '0800_JCLive_sf2_file', // detuned //'0800_SBLive_sf2', //'0800_SoundBlasterOld_sf2', - '0801_FluidR3_GM_sf2_file', - '0801_GeneralUserGS_sf2_file', + //'0801_FluidR3_GM_sf2_file', // detune + // '0801_GeneralUserGS_sf2_file', // detune + + // Lead 2 (sawtooth): Synth Lead '0810_Aspirin_sf2_file', '0810_Chaos_sf2_file', '0810_FluidR3_GM_sf2_file', @@ -855,63 +1032,75 @@ export const instruments = [ '0811_Aspirin_sf2_file', '0811_GeneralUserGS_sf2_file', //'0811_SoundBlasterOld_sf2', + + // Lead 3 (calliope): Synth Lead '0820_Aspirin_sf2_file', '0820_Chaos_sf2_file', '0820_FluidR3_GM_sf2_file', '0820_GeneralUserGS_sf2_file', - '0820_JCLive_sf2_file', + '0820_JCLive_sf2_file', // +1 oct //'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', + // '0822_GeneralUserGS_sf2_file', // missing + //'0823_GeneralUserGS_sf2_file', // missing + + // Lead 4 (chiff): Synth Lead '0830_Aspirin_sf2_file', - '0830_Chaos_sf2_file', + // '0830_Chaos_sf2_file', // same as above '0830_FluidR3_GM_sf2_file', '0830_GeneralUserGS_sf2_file', - '0830_JCLive_sf2_file', + '0830_JCLive_sf2_file', // flute synth //'0830_SBLive_sf2', //'0830_SoundBlasterOld_sf2', '0831_FluidR3_GM_sf2_file', '0831_GeneralUserGS_sf2_file', //'0831_SoundBlasterOld_sf2', + + // Lead 5 (charang): Synth Lead '0840_Aspirin_sf2_file', '0840_Chaos_sf2_file', '0840_FluidR3_GM_sf2_file', '0840_GeneralUserGS_sf2_file', - '0840_JCLive_sf2_file', + '0840_JCLive_sf2_file', // detune? //'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_JCLive_sf2_file', // +1oct + detune //'0841_SoundBlasterOld_sf2', '0842_FluidR3_GM_sf2_file', + + // Lead 6 (voice): Synth Lead '0850_Aspirin_sf2_file', - '0850_Chaos_sf2_file', + // '0850_Chaos_sf2_file', // same as above '0850_FluidR3_GM_sf2_file', - '0850_GeneralUserGS_sf2_file', - '0850_JCLive_sf2_file', + // '0850_GeneralUserGS_sf2_file', // no voice + '0850_JCLive_sf2_file', // more a flute //'0850_SBLive_sf2', //'0850_SoundBlasterOld_sf2', '0851_FluidR3_GM_sf2_file', '0851_GeneralUserGS_sf2_file', '0851_JCLive_sf2_file', //'0851_SoundBlasterOld_sf2', + + // Lead 7 (fifths): Synth Lead '0860_Aspirin_sf2_file', '0860_Chaos_sf2_file', - '0860_FluidR3_GM_sf2_file', + // '0860_FluidR3_GM_sf2_file', // loud and not fitting '0860_GeneralUserGS_sf2_file', '0860_JCLive_sf2_file', //'0860_SBLive_sf2', //'0860_SoundBlasterOld_sf2', '0861_Aspirin_sf2_file', - '0861_FluidR3_GM_sf2_file', + // '0861_FluidR3_GM_sf2_file', // lout and not fitting //'0861_SoundBlasterOld_sf2', + + // Lead 8 (bass + lead): Synth Lead '0870_Aspirin_sf2_file', '0870_Chaos_sf2_file', '0870_FluidR3_GM_sf2_file', @@ -919,9 +1108,11 @@ export const instruments = [ '0870_JCLive_sf2_file', //'0870_SBLive_sf2', //'0870_SoundBlasterOld_sf2', - '0871_GeneralUserGS_sf2_file', - '0872_GeneralUserGS_sf2_file', - '0873_GeneralUserGS_sf2_file', + // '0871_GeneralUserGS_sf2_file', // loud + detune + //'0872_GeneralUserGS_sf2_file', // loud + //'0873_GeneralUserGS_sf2_file', // loud + + // Pad 1 (new age): Synth Pad '0880_Aspirin_sf2_file', '0880_Chaos_sf2_file', '0880_FluidR3_GM_sf2_file', @@ -933,8 +1124,9 @@ export const instruments = [ '0881_FluidR3_GM_sf2_file', '0881_GeneralUserGS_sf2_file', //'0881_SoundBlasterOld_sf2', - '0882_Aspirin_sf2_file', - '0882_FluidR3_GM_sf2_file', + '0882_Aspirin_sf2_file', // staccato + // '0882_FluidR3_GM_sf2_file', // missing + '0882_GeneralUserGS_sf2_file', '0883_GeneralUserGS_sf2_file', '0884_GeneralUserGS_sf2_file', @@ -943,6 +1135,7 @@ export const instruments = [ '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', diff --git a/website/src/repl/Footer.jsx b/website/src/repl/Footer.jsx index 14789234..eaa7ce33 100644 --- a/website/src/repl/Footer.jsx +++ b/website/src/repl/Footer.jsx @@ -251,7 +251,10 @@ function SoundsTab() { const trigRef = useRef(); // stop current sound on mouseup useEvent('mouseup', () => { - trigRef.current?.then((ref) => ref?.stop(getAudioContext().currentTime + 0.01)); + trigRef.current?.then((ref) => { + ref?.stop(getAudioContext().currentTime + 0.01); + trigRef.current = undefined; + }); }); return (
@@ -264,7 +267,7 @@ function SoundsTab() { {soundEntries.map(([name, { data, onTrigger }]) => ( { const ctx = getAudioContext(); const params = { From b59b26460dc2786911bd7dee690c91a8c28fac44 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 12 Mar 2023 20:48:29 +0100 Subject: [PATCH 13/24] soundfont list curation part 2 --- packages/soundfonts/list.mjs | 170 +++++++++++++++++++++++++---------- 1 file changed, 124 insertions(+), 46 deletions(-) diff --git a/packages/soundfonts/list.mjs b/packages/soundfonts/list.mjs index 6c162206..4f95b359 100644 --- a/packages/soundfonts/list.mjs +++ b/packages/soundfonts/list.mjs @@ -858,6 +858,8 @@ export const instruments = [ //'0650_SoundBlasterOld_sf2', '0651_Aspirin_sf2_file', '0651_FluidR3_GM_sf2_file', // really stringy + + // Tenor Sax: Reed '0660_Aspirin_sf2_file', '0660_Chaos_sf2_file', //'0660_FluidR3_GM_sf2_file', // weird pitches @@ -1126,51 +1128,57 @@ export const instruments = [ //'0881_SoundBlasterOld_sf2', '0882_Aspirin_sf2_file', // staccato // '0882_FluidR3_GM_sf2_file', // missing - '0882_GeneralUserGS_sf2_file', - '0883_GeneralUserGS_sf2_file', - '0884_GeneralUserGS_sf2_file', + //'0883_GeneralUserGS_sf2_file', // missing + // '0884_GeneralUserGS_sf2_file', // broken '0885_GeneralUserGS_sf2_file', - '0886_GeneralUserGS_sf2_file', + //'0886_GeneralUserGS_sf2_file', // not a pad '0887_GeneralUserGS_sf2_file', - '0888_GeneralUserGS_sf2_file', - '0889_GeneralUserGS_sf2_file', + //'0888_GeneralUserGS_sf2_file', // not a pad + //'0889_GeneralUserGS_sf2_file', // not a pad + // Pad 2 (warm): Synth Pad '0890_Aspirin_sf2_file', '0890_Chaos_sf2_file', '0890_FluidR3_GM_sf2_file', - '0890_GeneralUserGS_sf2_file', + '0890_GeneralUserGS_sf2_file', // 1mb large '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', + // '0891_GeneralUserGS_sf2_file', // noise + + // Pad 3 (polysynth): Synth Pad + //'0900_Aspirin_sf2_file', // same as belo '0900_Chaos_sf2_file', '0900_FluidR3_GM_sf2_file', '0900_GeneralUserGS_sf2_file', - '0900_JCLive_sf2_file', + '0900_JCLive_sf2_file', // a bit plucky for a pad //'0900_SBLive_sf2', //'0900_SoundBlasterOld_sf2', '0901_Aspirin_sf2_file', '0901_FluidR3_GM_sf2_file', '0901_GeneralUserGS_sf2_file', //'0901_SoundBlasterOld_sf2', + + // Pad 4 (choir): Synth Pad '0910_Aspirin_sf2_file', - '0910_Chaos_sf2_file', + //'0910_Chaos_sf2_file', // +1oct '0910_FluidR3_GM_sf2_file', '0910_GeneralUserGS_sf2_file', '0910_JCLive_sf2_file', //'0910_SBLive_sf2', //'0910_SoundBlasterOld_sf2', - '0911_Aspirin_sf2_file', + // '0911_Aspirin_sf2_file', // fluty, crackles '0911_GeneralUserGS_sf2_file', - '0911_JCLive_sf2_file', + '0911_JCLive_sf2_file', // the only choiry pad //'0911_SoundBlasterOld_sf2', + + // Pad 5 (bowed): Synth Pad '0920_Aspirin_sf2_file', - '0920_Chaos_sf2_file', - '0920_FluidR3_GM_sf2_file', + //'0920_Chaos_sf2_file', // same as above + //'0920_FluidR3_GM_sf2_file', // detuned? '0920_GeneralUserGS_sf2_file', '0920_JCLive_sf2_file', //'0920_SBLive_sf2', @@ -1178,18 +1186,22 @@ export const instruments = [ '0921_Aspirin_sf2_file', '0921_GeneralUserGS_sf2_file', //'0921_SoundBlasterOld_sf2', + + // Pad 6 (metallic): Synth Pad '0930_Aspirin_sf2_file', '0930_Chaos_sf2_file', - '0930_FluidR3_GM_sf2_file', + '0930_FluidR3_GM_sf2_file', // little crackles '0930_GeneralUserGS_sf2_file', - '0930_JCLive_sf2_file', + // '0930_JCLive_sf2_file', // buggy zones: guitar / synth //'0930_SBLive_sf2', //'0930_SoundBlasterOld_sf2', - '0931_Aspirin_sf2_file', + '0931_Aspirin_sf2_file', // sitar '0931_FluidR3_GM_sf2_file', - '0931_GeneralUserGS_sf2_file', + '0931_GeneralUserGS_sf2_file', // guitar //'0931_SoundBlasterOld_sf2', - '0940_Aspirin_sf2_file', + + // Pad 7 (halo): Synth Pad + // '0940_Aspirin_sf2_file', // same as below '0940_Chaos_sf2_file', '0940_FluidR3_GM_sf2_file', '0940_GeneralUserGS_sf2_file', @@ -1200,6 +1212,8 @@ export const instruments = [ '0941_FluidR3_GM_sf2_file', '0941_GeneralUserGS_sf2_file', '0941_JCLive_sf2_file', + + // Pad 8 (sweep): Synth Pad '0950_Aspirin_sf2_file', '0950_Chaos_sf2_file', '0950_FluidR3_GM_sf2_file', @@ -1209,58 +1223,68 @@ export const instruments = [ //'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', + + // FX 1 (rain): Synth Effects + //'0960_Aspirin_sf2_file', //mixed samples? + '0960_Chaos_sf2_file', // pad? + '0960_FluidR3_GM_sf2_file', // ??? + '0960_GeneralUserGS_sf2_file', // pad + // '0960_JCLive_sf2_file', // mixed samples? //'0960_SBLive_sf2', //'0960_SoundBlasterOld_sf2', '0961_Aspirin_sf2_file', '0961_FluidR3_GM_sf2_file', - '0961_GeneralUserGS_sf2_file', + // '0961_GeneralUserGS_sf2_file', // ?!?! //'0961_SoundBlasterOld_sf2', '0962_GeneralUserGS_sf2_file', + + // FX 2 (soundtrack): Synth Effects '0970_Aspirin_sf2_file', - '0970_Chaos_sf2_file', + //'0970_Chaos_sf2_file', // wrong pitch '0970_FluidR3_GM_sf2_file', - '0970_GeneralUserGS_sf2_file', - '0970_JCLive_sf2_file', + '0970_GeneralUserGS_sf2_file', // not looping.. + //'0970_JCLive_sf2_file', // wrong pitch //'0970_SBLive_sf2', //'0970_SoundBlasterOld_sf2', '0971_FluidR3_GM_sf2_file', '0971_GeneralUserGS_sf2_file', //'0971_SoundBlasterOld_sf2', + + // FX 3 (crystal): Synth Effects '0980_Aspirin_sf2_file', '0980_Chaos_sf2_file', - '0980_FluidR3_GM_sf2_file', + // '0980_FluidR3_GM_sf2_file', // some notes are weird '0980_GeneralUserGS_sf2_file', '0980_JCLive_sf2_file', //'0980_SBLive_sf2', //'0980_SoundBlasterOld_sf2', - '0981_Aspirin_sf2_file', - '0981_FluidR3_GM_sf2_file', + '0981_Aspirin_sf2_file', // strings + '0981_FluidR3_GM_sf2_file', // mallet '0981_GeneralUserGS_sf2_file', //'0981_SoundBlasterOld_sf2', '0982_GeneralUserGS_sf2_file', - '0983_GeneralUserGS_sf2_file', + '0983_GeneralUserGS_sf2_file', // guitar '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', + + // FX 4 (atmosphere): Synth Effects + '0990_Aspirin_sf2_file', // pad + '0990_Chaos_sf2_file', // pad + '0990_FluidR3_GM_sf2_file', // guitar + '0990_GeneralUserGS_sf2_file', // guitar + '0990_JCLive_sf2_file', // pad //'0990_SBLive_sf2', //'0990_SoundBlasterOld_sf2', - '0991_Aspirin_sf2_file', - '0991_FluidR3_GM_sf2_file', - '0991_GeneralUserGS_sf2_file', - '0991_JCLive_sf2_file', + '0991_Aspirin_sf2_file', // guitar + '0991_FluidR3_GM_sf2_file', // pad + '0991_GeneralUserGS_sf2_file', // pad + '0991_JCLive_sf2_file', // guitar //'0991_SoundBlasterOld_sf2', - '0992_FluidR3_GM_sf2_file', - '0992_JCLive_sf2_file', - '0993_JCLive_sf2_file', - '0994_JCLive_sf2_file', + '0992_FluidR3_GM_sf2_file', // pad + '0992_JCLive_sf2_file', // guitar + '0993_JCLive_sf2_file', // guitar + '0994_JCLive_sf2_file', // guitar + + // FX 5 (brightness): Synth Effects '1000_Aspirin_sf2_file', '1000_Chaos_sf2_file', '1000_FluidR3_GM_sf2_file', @@ -1276,6 +1300,8 @@ export const instruments = [ '1002_Aspirin_sf2_file', '1002_FluidR3_GM_sf2_file', '1002_GeneralUserGS_sf2_file', + + // FX 6 (goblins): Synth Effects '1010_Aspirin_sf2_file', '1010_Chaos_sf2_file', '1010_FluidR3_GM_sf2_file', @@ -1287,6 +1313,8 @@ export const instruments = [ '1011_FluidR3_GM_sf2_file', '1011_JCLive_sf2_file', '1012_Aspirin_sf2_file', + + // FX 7 (echoes): Synth Effects '1020_Aspirin_sf2_file', '1020_Chaos_sf2_file', '1020_FluidR3_GM_sf2_file', @@ -1300,6 +1328,8 @@ export const instruments = [ '1021_JCLive_sf2_file', //'1021_SoundBlasterOld_sf2', '1022_GeneralUserGS_sf2_file', + + // FX 8 (sci-fi): Synth Effects '1030_Aspirin_sf2_file', '1030_Chaos_sf2_file', '1030_FluidR3_GM_sf2_file', @@ -1312,6 +1342,8 @@ export const instruments = [ '1031_GeneralUserGS_sf2_file', //'1031_SoundBlasterOld_sf2', '1032_FluidR3_GM_sf2_file', + + // 'Sitar: Ethnic '1040_Aspirin_sf2_file', '1040_Chaos_sf2_file', '1040_FluidR3_GM_sf2_file', @@ -1321,6 +1353,8 @@ export const instruments = [ //'1040_SoundBlasterOld_sf2', '1041_FluidR3_GM_sf2_file', '1041_GeneralUserGS_sf2_file', + + // Banjo: Ethnic '1050_Aspirin_sf2_file', '1050_Chaos_sf2_file', '1050_FluidR3_GM_sf2_file', @@ -1329,6 +1363,8 @@ export const instruments = [ //'1050_SBLive_sf2', //'1050_SoundBlasterOld_sf2', '1051_GeneralUserGS_sf2_file', + + // Shamisen: Ethnic '1060_Aspirin_sf2_file', '1060_Chaos_sf2_file', '1060_FluidR3_GM_sf2_file', @@ -1339,6 +1375,8 @@ export const instruments = [ '1061_FluidR3_GM_sf2_file', '1061_GeneralUserGS_sf2_file', //'1061_SoundBlasterOld_sf2', + + // Koto: Ethnic '1070_Aspirin_sf2_file', '1070_Chaos_sf2_file', '1070_FluidR3_GM_sf2_file', @@ -1350,6 +1388,8 @@ export const instruments = [ '1071_GeneralUserGS_sf2_file', '1072_GeneralUserGS_sf2_file', '1073_GeneralUserGS_sf2_file', + + // Kalimba: Ethnic '1080_Aspirin_sf2_file', '1080_Chaos_sf2_file', '1080_FluidR3_GM_sf2_file', @@ -1358,6 +1398,8 @@ export const instruments = [ //'1080_SBLive_sf2', //'1080_SoundBlasterOld_sf2', //'1081_SoundBlasterOld_sf2', + + // Bagpipe: Ethnic '1090_Aspirin_sf2_file', '1090_Chaos_sf2_file', '1090_FluidR3_GM_sf2_file', @@ -1366,6 +1408,8 @@ export const instruments = [ //'1090_SBLive_sf2', //'1090_SoundBlasterOld_sf2', //'1091_SoundBlasterOld_sf2', + + // Fiddle: Ethnic '1100_Aspirin_sf2_file', '1100_Chaos_sf2_file', '1100_FluidR3_GM_sf2_file', @@ -1377,6 +1421,8 @@ export const instruments = [ '1101_FluidR3_GM_sf2_file', '1101_GeneralUserGS_sf2_file', '1102_GeneralUserGS_sf2_file', + + // Shanai: Ethnic '1110_Aspirin_sf2_file', '1110_Chaos_sf2_file', '1110_FluidR3_GM_sf2_file', @@ -1384,6 +1430,8 @@ export const instruments = [ '1110_JCLive_sf2_file', //'1110_SBLive_sf2', //'1110_SoundBlasterOld_sf2', + + // Tinkle Bell: Percussive '1120_Aspirin_sf2_file', '1120_Chaos_sf2_file', '1120_FluidR3_GM_sf2_file', @@ -1392,6 +1440,8 @@ export const instruments = [ //'1120_SBLive_sf2', //'1120_SoundBlasterOld_sf2', //'1121_SoundBlasterOld_sf2', + + // Agogo: Percussive '1130_Aspirin_sf2_file', '1130_Chaos_sf2_file', '1130_FluidR3_GM_sf2_file', @@ -1401,6 +1451,8 @@ export const instruments = [ //'1130_SoundBlasterOld_sf2', '1131_FluidR3_GM_sf2_file', //'1131_SoundBlasterOld_sf2', + + // Steel Drums: Percussive '1140_Aspirin_sf2_file', '1140_Chaos_sf2_file', '1140_FluidR3_GM_sf2_file', @@ -1409,6 +1461,8 @@ export const instruments = [ //'1140_SBLive_sf2', //'1140_SoundBlasterOld_sf2', '1141_FluidR3_GM_sf2_file', + + // Woodblock: Percussive '1150_Aspirin_sf2_file', '1150_Chaos_sf2_file', '1150_FluidR3_GM_sf2_file', @@ -1420,6 +1474,8 @@ export const instruments = [ '1151_GeneralUserGS_sf2_file', '1152_FluidR3_GM_sf2_file', '1152_GeneralUserGS_sf2_file', + + // Taiko Drum: Percussive '1160_Aspirin_sf2_file', '1160_Chaos_sf2_file', '1160_FluidR3_GM_sf2_file', @@ -1433,6 +1489,8 @@ export const instruments = [ '1162_FluidR3_GM_sf2_file', '1162_GeneralUserGS_sf2_file', '1163_FluidR3_GM_sf2_file', + + // Melodic Tom: Percussive '1170_Aspirin_sf2_file', '1170_Chaos_sf2_file', '1170_FluidR3_GM_sf2_file', @@ -1444,6 +1502,8 @@ export const instruments = [ '1171_GeneralUserGS_sf2_file', '1172_FluidR3_GM_sf2_file', '1173_FluidR3_GM_sf2_file', + + // Synth Drum: Percussive '1180_Aspirin_sf2_file', '1180_Chaos_sf2_file', '1180_FluidR3_GM_sf2_file', @@ -1454,6 +1514,8 @@ export const instruments = [ '1181_FluidR3_GM_sf2_file', '1181_GeneralUserGS_sf2_file', //'1181_SoundBlasterOld_sf2', + + // Reverse Cymbal: Percussive '1190_Aspirin_sf2_file', '1190_Chaos_sf2_file', '1190_FluidR3_GM_sf2_file', @@ -1465,6 +1527,8 @@ export const instruments = [ '1192_GeneralUserGS_sf2_file', '1193_GeneralUserGS_sf2_file', '1194_GeneralUserGS_sf2_file', + + // Guitar Fret Noise: Sound effects '1200_Aspirin_sf2_file', '1200_Chaos_sf2_file', '1200_FluidR3_GM_sf2_file', @@ -1475,6 +1539,8 @@ export const instruments = [ '1201_Aspirin_sf2_file', '1201_GeneralUserGS_sf2_file', '1202_GeneralUserGS_sf2_file', + + // Breath Noise: Sound effects '1210_Aspirin_sf2_file', '1210_Chaos_sf2_file', '1210_FluidR3_GM_sf2_file', @@ -1485,6 +1551,8 @@ export const instruments = [ '1211_Aspirin_sf2_file', '1211_GeneralUserGS_sf2_file', '1212_GeneralUserGS_sf2_file', + + // Seashore: Sound effects '1220_Aspirin_sf2_file', '1220_Chaos_sf2_file', '1220_FluidR3_GM_sf2_file', @@ -1503,6 +1571,8 @@ export const instruments = [ '1224_GeneralUserGS_sf2_file', '1225_GeneralUserGS_sf2_file', '1226_GeneralUserGS_sf2_file', + + // Bird Tweet: Sound effects '1230_Aspirin_sf2_file', '1230_Chaos_sf2_file', '1230_FluidR3_GM_sf2_file', @@ -1516,6 +1586,8 @@ export const instruments = [ '1232_GeneralUserGS_sf2_file', '1233_GeneralUserGS_sf2_file', '1234_GeneralUserGS_sf2_file', + + // Telephone Ring: Sound effects '1240_Aspirin_sf2_file', '1240_Chaos_sf2_file', '1240_FluidR3_GM_sf2_file', @@ -1531,6 +1603,8 @@ export const instruments = [ '1243_GeneralUserGS_sf2_file', '1244_Aspirin_sf2_file', '1244_GeneralUserGS_sf2_file', + + // Helicopter: Sound effects '1250_Aspirin_sf2_file', '1250_Chaos_sf2_file', '1250_FluidR3_GM_sf2_file', @@ -1557,6 +1631,8 @@ export const instruments = [ '1258_Aspirin_sf2_file', '1258_GeneralUserGS_sf2_file', '1259_GeneralUserGS_sf2_file', + + // Applause: Sound effects '1260_Aspirin_sf2_file', '1260_Chaos_sf2_file', '1260_FluidR3_GM_sf2_file', @@ -1574,6 +1650,8 @@ export const instruments = [ '1264_GeneralUserGS_sf2_file', '1265_Aspirin_sf2_file', '1265_GeneralUserGS_sf2_file', + + // Gunshot: Sound effects '1270_Aspirin_sf2_file', '1270_Chaos_sf2_file', '1270_FluidR3_GM_sf2_file', From 7b529a30f40ca547da2034c50c07e0a8cc97ae32 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Tue, 14 Mar 2023 22:54:12 +0100 Subject: [PATCH 14/24] style sounds tab --- packages/soundfonts/list.mjs | 2 +- website/src/repl/Footer.jsx | 48 +++++++++++++++++----------------- website/src/repl/Reference.jsx | 2 +- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/packages/soundfonts/list.mjs b/packages/soundfonts/list.mjs index 4f95b359..fa21c110 100644 --- a/packages/soundfonts/list.mjs +++ b/packages/soundfonts/list.mjs @@ -805,7 +805,7 @@ export const instruments = [ //'0610_SBLive_sf2', //'0610_SoundBlasterOld_sf2', // '0611_GeneralUserGS_sf2_file', // missing sounds - '0612_GeneralUserGS_sf2_file', + // '0612_GeneralUserGS_sf2_file', //'0613_GeneralUserGS_sf2_file', // -1 oct // '0614_GeneralUserGS_sf2_file', // missing sounds // '0615_GeneralUserGS_sf2_file', // missing sounds diff --git a/website/src/repl/Footer.jsx b/website/src/repl/Footer.jsx index eaa7ce33..187aca18 100644 --- a/website/src/repl/Footer.jsx +++ b/website/src/repl/Footer.jsx @@ -85,10 +85,7 @@ export function Footer({ context }) { )}
{activeFooter !== '' && ( -
+
{activeFooter === 'intro' && } {activeFooter === 'console' && } {activeFooter === 'sounds' && } @@ -174,7 +171,7 @@ function WelcomeTab() { function ConsoleTab({ log }) { return ( -
+
{`███████╗████████╗██████╗ ██╗   ██╗██████╗ ███████╗██╗     
 ██╔════╝╚══██╔══╝██╔══██╗██║   ██║██╔══██╗██╔════╝██║     
 ███████╗   ██║   ██████╔╝██║   ██║██║  ██║█████╗  ██║     
@@ -228,24 +225,24 @@ const getSamples = (samples) =>
 function SoundsTab() {
   const sounds = useStore(soundMap);
   const { soundsFilter } = useSettings();
-
   const soundEntries = useMemo(() => {
+    let filtered = Object.entries(sounds).filter(([key]) => !key.startsWith('_'));
     if (!sounds) {
       return [];
     }
     if (soundsFilter === 'user') {
-      return Object.entries(sounds).filter(([_, { data }]) => !data.prebake);
+      return filtered.filter(([key, { data }]) => !data.prebake);
     }
     if (soundsFilter === 'samples') {
-      return Object.entries(sounds).filter(([_, { data }]) => data.type === 'sample');
+      return filtered.filter(([_, { data }]) => data.type === 'sample');
     }
     if (soundsFilter === 'synths') {
-      return Object.entries(sounds).filter(([_, { data }]) => data.type === 'synth');
+      return filtered.filter(([_, { data }]) => data.type === 'synth');
     }
     if (soundsFilter === 'soundfonts') {
-      return Object.entries(sounds).filter(([_, { data }]) => data.type === 'soundfont');
+      return filtered.filter(([_, { data }]) => data.type === 'soundfont');
     }
-    return Object.entries(sounds);
+    return filtered;
   }, [sounds, soundsFilter]);
   // holds mutable ref to current triggered sound
   const trigRef = useRef();
@@ -257,13 +254,15 @@ function SoundsTab() {
     });
   });
   return (
-    
- settingsMap.setKey('soundsFilter', value)} - items={{ samples: 'Samples', synths: 'Synths', soundfonts: 'Soundfonts', user: 'Custom' }} - > -
+
+
+ settingsMap.setKey('soundsFilter', value)} + items={{ samples: 'Samples', synths: 'Synths', soundfonts: 'Soundfonts', user: 'Custom' }} + > +
+
{soundEntries.map(([name, { data, onTrigger }]) => ( +
{Object.entries(items).map(([key, label], i, arr) => ( ))}
diff --git a/website/src/repl/Reference.jsx b/website/src/repl/Reference.jsx index 13a38ef8..90130d9e 100644 --- a/website/src/repl/Reference.jsx +++ b/website/src/repl/Reference.jsx @@ -6,7 +6,7 @@ const visibleFunctions = jsdocJson.docs export function Reference() { return (
-
+
{visibleFunctions.map((entry, i) => ( {entry.name} {/* {entry.meta.filename} */} From 8a22c5627aaac233bd4d1994103b44428bc847e3 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 15 Mar 2023 22:42:03 +0100 Subject: [PATCH 15/24] fix: cut glitches due to envelope release trouble --- packages/webaudio/helpers.mjs | 9 ++++++--- packages/webaudio/sampler.mjs | 10 ++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/webaudio/helpers.mjs b/packages/webaudio/helpers.mjs index 1ed1e637..24ee03c8 100644 --- a/packages/webaudio/helpers.mjs +++ b/packages/webaudio/helpers.mjs @@ -27,12 +27,15 @@ export const getEnvelope = (attack, decay, sustain, release, velocity, begin) => return { node: gainNode, stop: (t) => { - gainNode.gain.setValueAtTime(sustain * velocity, t); + if (typeof gainNode.gain.cancelAndHoldAtTime === 'function') { + gainNode.gain.cancelAndHoldAtTime(t); + } else { + // firefox: this will glitch when the sustain has not been reached yet at the time of release + gainNode.gain.setValueAtTime(sustain * velocity, t); + } gainNode.gain.linearRampToValueAtTime(0, t + release); }, }; - // gainNode.gain.linearRampToValueAtTime(0, end + release); // release - // return gainNode; }; export const getADSR = (attack, decay, sustain, release, velocity, begin, end) => { diff --git a/packages/webaudio/sampler.mjs b/packages/webaudio/sampler.mjs index 4266455a..1f1325b7 100644 --- a/packages/webaudio/sampler.mjs +++ b/packages/webaudio/sampler.mjs @@ -223,9 +223,12 @@ export async function onTriggerSample(t, value, onended, bank) { }*/ const { node: envelope, stop: releaseEnvelope } = getEnvelope(attack, decay, sustain, release, 1, t); bufferSource.connect(envelope); + const out = ac.createGain(); // we need a separate gain for the cutgroups because firefox... + envelope.connect(out); bufferSource.onended = function () { bufferSource.disconnect(); envelope.disconnect(); + out.disconnect(); onended(); }; const stop = (endTime, playWholeBuffer = !clip) => { @@ -236,15 +239,14 @@ export async function onTriggerSample(t, value, onended, bank) { bufferSource.stop(releaseTime + release); releaseEnvelope(releaseTime); }; - const handle = { node: envelope, bufferSource, stop }; + const handle = { node: out, bufferSource, stop }; // cut groups - // TODO: sometimes, the cutting won't work for very fast triggering... - // it worked before :-/ if (cut !== undefined) { const prev = cutGroups[cut]; if (prev) { - prev.stop(time, false); + prev.node.gain.setValueAtTime(1, time); + prev.node.gain.linearRampToValueAtTime(0, time + 0.01); } cutGroups[cut] = handle; } From a33ce67dd4a3f5095eb32a4fb70bd999ed703661 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 15 Mar 2023 23:01:56 +0100 Subject: [PATCH 16/24] fix: endless preview --- website/src/repl/Footer.jsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/website/src/repl/Footer.jsx b/website/src/repl/Footer.jsx index 187aca18..2bce3e70 100644 --- a/website/src/repl/Footer.jsx +++ b/website/src/repl/Footer.jsx @@ -248,9 +248,10 @@ function SoundsTab() { const trigRef = useRef(); // stop current sound on mouseup useEvent('mouseup', () => { - trigRef.current?.then((ref) => { + const t = trigRef.current; + trigRef.current = undefined; + t?.then((ref) => { ref?.stop(getAudioContext().currentTime + 0.01); - trigRef.current = undefined; }); }); return ( From f788d347ec156e4a98bfb9e27f259dc7bfe4674a Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 15 Mar 2023 23:02:05 +0100 Subject: [PATCH 17/24] add envelope to soundfonts --- packages/soundfonts/fontloader.mjs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/soundfonts/fontloader.mjs b/packages/soundfonts/fontloader.mjs index 45fae951..5e102124 100644 --- a/packages/soundfonts/fontloader.mjs +++ b/packages/soundfonts/fontloader.mjs @@ -1,5 +1,5 @@ import { toMidi } from '@strudel.cycles/core'; -import { getAudioContext, registerSound } from '@strudel.cycles/webaudio'; +import { getAudioContext, registerSound, getEnvelope } from '@strudel.cycles/webaudio'; import { instruments } from './list.mjs'; let loadCache = {}; @@ -122,18 +122,22 @@ export function registerSoundfonts() { instrument, async (time, value, onended) => { const { note, n } = value; + const { attack = 0.001, decay = 0.001, sustain = 1, release = 0.001 } = value; const ctx = getAudioContext(); const bufferSource = await getFontBufferSource(instrument, note || n, ctx); bufferSource.start(time); - const stop = (time) => bufferSource.stop(time); - const g = new GainNode(ctx, { gain: 0.3 }); - bufferSource.connect(g); + const { node: envelope, stop: releaseEnvelope } = getEnvelope(attack, decay, sustain, release, 0.3, time); + bufferSource.connect(envelope); + const stop = (releaseTime) => { + bufferSource.stop(releaseTime + release); + releaseEnvelope(releaseTime); + }; bufferSource.onended = () => { bufferSource.disconnect(); - g.disconnect(); + envelope.disconnect(); onended(); }; - return { node: g, stop }; + return { node: envelope, stop }; }, { type: 'soundfont', prebake: true }, ); From a688061616968c88006cbbae0be02f19e87d52cf Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 16 Mar 2023 12:23:58 +0100 Subject: [PATCH 18/24] group soundfonts into readable names --- packages/soundfonts/fontloader.mjs | 11 +- packages/soundfonts/gm.mjs | 1787 ++++++++++++++++++++++++++++ packages/soundfonts/list.mjs | 15 +- 3 files changed, 1796 insertions(+), 17 deletions(-) create mode 100644 packages/soundfonts/gm.mjs diff --git a/packages/soundfonts/fontloader.mjs b/packages/soundfonts/fontloader.mjs index 5e102124..cda396fa 100644 --- a/packages/soundfonts/fontloader.mjs +++ b/packages/soundfonts/fontloader.mjs @@ -1,6 +1,6 @@ import { toMidi } from '@strudel.cycles/core'; import { getAudioContext, registerSound, getEnvelope } from '@strudel.cycles/webaudio'; -import { instruments } from './list.mjs'; +import gm from './gm.mjs'; let loadCache = {}; async function loadFont(name) { @@ -117,14 +117,15 @@ async function getBuffer(zone, audioContext) { } export function registerSoundfonts() { - instruments.forEach((instrument) => { + Object.entries(gm).forEach(([name, fonts]) => { registerSound( - instrument, + name, async (time, value, onended) => { - const { note, n } = value; + const { note = 'c3', n = 0 } = value; const { attack = 0.001, decay = 0.001, sustain = 1, release = 0.001 } = value; + const font = fonts[n % fonts.length]; const ctx = getAudioContext(); - const bufferSource = await getFontBufferSource(instrument, note || n, ctx); + const bufferSource = await getFontBufferSource(font, note, ctx); bufferSource.start(time); const { node: envelope, stop: releaseEnvelope } = getEnvelope(attack, decay, sustain, release, 0.3, time); bufferSource.connect(envelope); diff --git a/packages/soundfonts/gm.mjs b/packages/soundfonts/gm.mjs new file mode 100644 index 00000000..780ea69b --- /dev/null +++ b/packages/soundfonts/gm.mjs @@ -0,0 +1,1787 @@ +export default { + gm_piano: [ + //'gm_acoustic-piano': [ + // Acoustic Grand Piano: Piano + '0000_JCLive_sf2_file', + '0000_FluidR3_GM_sf2_file', + '0000_Aspirin_sf2_file', + '0000_Chaos_sf2_file', + '0000_GeneralUserGS_sf2_file', + //0000_SBLive_sf2 + //0000_SoundBlasterOld_sf2 + '0001_FluidR3_GM_sf2_file', + '0001_GeneralUserGS_sf2_file', + //], + //'gm_bright-acoustic-piano': [ + // Bright Acoustic Piano: Piano + '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', + //], + //'gm_electric-grand-piano': [ + // Electric Grand Piano: Piano + '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', + //], + //'gm_honky-tonk-piano': [ + // Honky-tonk Piano: Piano + '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 her + ], + gm_epiano1: [ + // Electric Piano 1: Piano + '0040_JCLive_sf2_file', + '0040_FluidR3_GM_sf2_file', + '0040_Aspirin_sf2_file', + '0040_Chaos_sf2_file', + '0040_GeneralUserGS_sf2_file', + //0040_SBLive_sf2 // ? + //0040_SoundBlasterOld_sf2 // ? + '0041_FluidR3_GM_sf2_file', + '0041_GeneralUserGS_sf2_file', + //0041_SoundBlasterOld_sf2 // ? + '0042_GeneralUserGS_sf2_file', + '0043_GeneralUserGS_sf2_file', + '0044_GeneralUserGS_sf2_file', + //0045_GeneralUserGS_sf2_file // ? + '0046_GeneralUserGS_sf2_file', + ], + gm_epiano2: [ + // Electric Piano 2: Piano + '0050_JCLive_sf2_file', + '0050_FluidR3_GM_sf2_file', + '0050_Aspirin_sf2_file', + '0050_Chaos_sf2_file', + // ? + '0050_GeneralUserGS_sf2_file', + // cont + //0050_SBLive_sf2 // ? + //0050_SoundBlasterOld_sf2 // ? + '0051_FluidR3_GM_sf2_file', + '0051_GeneralUserGS_sf2_file', + //0052_GeneralUserGS_sf2_file // ? + '0053_GeneralUserGS_sf2_file', + // normal piano... + '0054_GeneralUserGS_sf2_file', + ], + gm_harpsichord: [ + // Harpsichord: Piano + '0060_JCLive_sf2_file', + '0060_FluidR3_GM_sf2_file', + '0060_Aspirin_sf2_file', + '0060_Chaos_sf2_file', + '0060_GeneralUserGS_sf2_file', + //0060_SBLive_sf2 + //0060_SoundBlasterOld_sf2 + '0061_Aspirin_sf2_file', + '0061_GeneralUserGS_sf2_file', + //0061_SoundBlasterOld_sf2 + '0062_GeneralUserGS_sf2_file', + ], + gm_clavinet: [ + // Clavinet: Piano + '0070_JCLive_sf2_file', + '0070_FluidR3_GM_sf2_file', + '0070_Aspirin_sf2_file', + '0070_Chaos_sf2_file', + // 0070_GeneralUserGS_sf2_file // half broken + //0070_SBLive_sf2 + //0070_SoundBlasterOld_sf2 + // 0071_GeneralUserGS_sf2_file // half broke + ], + gm_celesta: [ + // Celesta: Chromatic Percussion + '0080_JCLive_sf2_file', + '0080_Aspirin_sf2_file', + '0080_Chaos_sf2_file', + '0080_FluidR3_GM_sf2_file', + '0080_GeneralUserGS_sf2_file', + //0080_SBLive_sf2 + //0080_SoundBlasterOld_sf2 + '0081_FluidR3_GM_sf2_file', + // 0081_GeneralUserGS_sf2_file // weird detuned + //0081_SoundBlasterOld_sf + ], + gm_glockenspiel: [ + // Glockenspiel: Chromatic Percussion + '0090_JCLive_sf2_file', + '0090_Aspirin_sf2_file', + '0090_Chaos_sf2_file', + '0090_FluidR3_GM_sf2_file', + '0090_GeneralUserGS_sf2_file', + //0090_SBLive_sf2 + //0090_SoundBlasterOld_sf2 + //0091_SoundBlasterOld_sf + ], + 'gm_music-box': [ + // Music Box: Chromatic Percussion + '0100_JCLive_sf2_file', + '0100_Aspirin_sf2_file', + '0100_Chaos_sf2_file', + '0100_FluidR3_GM_sf2_file', + '0100_GeneralUserGS_sf2_file', + //0100_SBLive_sf2 + //0100_SoundBlasterOld_sf2 + // 0101_GeneralUserGS_sf2_file // weird detuned + //0101_SoundBlasterOld_sf + ], + gm_vibraphone: [ + // Vibraphone: Chromatic Percussion + '0110_JCLive_sf2_file', + '0110_Aspirin_sf2_file', + '0110_Chaos_sf2_file', + '0110_FluidR3_GM_sf2_file', + '0110_GeneralUserGS_sf2_file', + //0110_SBLive_sf2 + //0110_SoundBlasterOld_sf2 + '0111_FluidR3_GM_sf2_file', + ], + gm_marimba: [ + // Marimba: Chromatic Percussion + '0120_JCLive_sf2_file', + '0120_Aspirin_sf2_file', + '0120_Chaos_sf2_file', + '0120_FluidR3_GM_sf2_file', + '0120_GeneralUserGS_sf2_file', + //0120_SBLive_sf2 + //0120_SoundBlasterOld_sf2 + '0121_FluidR3_GM_sf2_file', + '0121_GeneralUserGS_sf2_file', + ], + gm_xylophone: [ + // Xylophone: Chromatic Percussion + '0130_JCLive_sf2_file', + '0130_Aspirin_sf2_file', + '0130_Chaos_sf2_file', + '0130_FluidR3_GM_sf2_file', + '0130_GeneralUserGS_sf2_file', + //0130_SBLive_sf2 + //0130_SoundBlasterOld_sf2 + '0131_FluidR3_GM_sf2_file', + ], + 'gm_tubular-bells': [ + // Tubular Bells: Chromatic Percussion + '0140_JCLive_sf2_file', + '0140_Aspirin_sf2_file', + // 0140_Chaos_sf2_file // same as aspirin? + '0140_FluidR3_GM_sf2_file', + '0140_GeneralUserGS_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 // bugg + ], + gm_dulcimer: [ + // Dulcimer: Chromatic Percussion + '0150_Aspirin_sf2_file', + '0150_Chaos_sf2_file', + '0150_FluidR3_GM_sf2_file', + '0150_GeneralUserGS_sf2_file', + // 0150_JCLive_sf2_file // detuned??? + //0150_SBLive_sf2 + //0150_SoundBlasterOld_sf2 + '0151_FluidR3_GM_sf2_file', + ], + 'gm_drawbar-organ': [ + // Drawbar Organ: Organ + '0160_JCLive_sf2_file', + '0160_Aspirin_sf2_file', + '0160_Chaos_sf2_file', + '0160_FluidR3_GM_sf2_file', + '0160_GeneralUserGS_sf2_file', + //0160_SBLive_sf2 + //0160_SoundBlasterOld_sf2 + '0161_Aspirin_sf2_file', + '0161_FluidR3_GM_sf2_file', + //0161_SoundBlasterOld_sf + ], + 'gm_percussive-organ': [ + // Percussive Organ: Organ + '0170_JCLive_sf2_file', + '0170_Aspirin_sf2_file', + '0170_Chaos_sf2_file', + '0170_FluidR3_GM_sf2_file', + // 0170_GeneralUserGS_sf2_file // repitched + //0170_SBLive_sf2 + //0170_SoundBlasterOld_sf2 + '0171_FluidR3_GM_sf2_file', + // 0171_GeneralUserGS_sf2_file // repitched + '0172_FluidR3_GM_sf2_file', + ], + 'gm_rock-organ': [ + // Rock Organ: Organ + '0180_JCLive_sf2_file', + '0180_Aspirin_sf2_file', + '0180_Chaos_sf2_file', + '0180_FluidR3_GM_sf2_file', + '0180_GeneralUserGS_sf2_file', + //0180_SBLive_sf2 + //0180_SoundBlasterOld_sf2 + //0181_Aspirin_sf2_file // flute + //0181_GeneralUserGS_sf2_file // marimbalike + //0181_SoundBlasterOld_sf + ], + 'gm_church-organ': [ + // Church Organ: Organ + '0190_JCLive_sf2_file', + '0190_Aspirin_sf2_file', + '0190_Chaos_sf2_file', + '0190_FluidR3_GM_sf2_file', + '0190_GeneralUserGS_sf2_file', + //0190_SBLive_sf2 + //0190_SoundBlasterOld_sf2 + //0191_Aspirin_sf2_file // string?? + //0191_GeneralUserGS_sf2_file // weird organ + //0191_SoundBlasterOld_sf + ], + 'gm_reed-organ': [ + // Reed Organ: Organ + '0200_JCLive_sf2_file', + '0200_Aspirin_sf2_file', + '0200_Chaos_sf2_file', + '0200_FluidR3_GM_sf2_file', + '0200_GeneralUserGS_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 // buggy + //0210_Chaos_sf2_file // bugg + ], + gm_accordion: [ + // Accordion: Organ + '0210_JCLive_sf2_file', + '0210_FluidR3_GM_sf2_file', + '0210_GeneralUserGS_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', + ], + gm_harmonica: [ + // Harmonica: Organ + '0220_FluidR3_GM_sf2_file', + '0220_JCLive_sf2_file', + '0220_Aspirin_sf2_file', + '0220_Chaos_sf2_file', + '0220_GeneralUserGS_sf2_file', + //0220_SBLive_sf2 + //0220_SoundBlasterOld_sf2 + '0221_FluidR3_GM_sf2_file', + ], + gm_bandoneon: [ + // Tango Accordion: Organ + '0230_Aspirin_sf2_file', + '0230_JCLive_sf2_file', + '0230_Chaos_sf2_file', + '0230_FluidR3_GM_sf2_file', + '0230_GeneralUserGS_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', + ], + 'gm_acoustic-guitar-nylon': [ + // Acoustic Guitar (nylon): Guitar + '0240_JCLive_sf2_file', + '0240_Aspirin_sf2_file', + '0240_Chaos_sf2_file', + '0240_FluidR3_GM_sf2_file', + '0240_GeneralUserGS_sf2_file', + '0240_LK_Godin_Nylon_SF2_file', + //0240_SBLive_sf2 + //0240_SoundBlasterOld_sf2 + // 0241_GeneralUserGS_sf2_file // organ like + '0241_JCLive_sf2_file', + '0242_JCLive_sf2_file', + '0243_JCLive_sf2_file', + ], + 'gm_acoustic-guitar-steel': [ + // Acoustic Guitar (steel): Guitar + '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 // detuned + '0250_LK_AcousticSteel_SF2_file', + //0250_SBLive_sf2 + //0250_SoundBlasterOld_sf2 + //0251_Acoustic_Guitar_sf2_file // detuned? + // 0251_GeneralUserGS_sf2_file // broken: missing pitches + // 0252_Acoustic_Guitar_sf2_file // detuned.. + // 0252_GeneralUserGS_sf2_file // broken: missing pitches + '0253_Acoustic_Guitar_sf2_file', + '0253_GeneralUserGS_sf2_file', + '0254_Acoustic_Guitar_sf2_file', + '0254_GeneralUserGS_sf2_file', + //0255_GeneralUserGS_sf2_file // no guitar. + ], + 'gm_electric-guitar-jazz': [ + // Electric Guitar (jazz): Guitar + '0260_JCLive_sf2_file', + '0260_Aspirin_sf2_file', + '0260_Chaos_sf2_file', + '0260_FluidR3_GM_sf2_file', + '0260_GeneralUserGS_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', + ], + 'gm_electric-guitar-clean': [ + // Electric Guitar (clean): Guitar + '0270_Aspirin_sf2_file', + '0270_Chaos_sf2_file', + '0270_FluidR3_GM_sf2_file', + '0270_GeneralUserGS_sf2_file', + //0270_Gibson_Les_Paul_sf2_file // detuned + // 0270_JCLive_sf2_file // broken: missing notes + '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', + ], + 'gm_electric-guitar-muted': [ + // Electric Guitar (muted): Guitar + '0280_Aspirin_sf2_file', + '0280_Chaos_sf2_file', + // 0280_FluidR3_GM_sf2_file // broken: wrong notes + '0280_GeneralUserGS_sf2_file', + '0280_JCLive_sf2_file', + //0280_LesPaul_sf2 // missing + '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 // broken: missing notes + // 0283_GeneralUserGS_sf2_file // missin + ], + 'gm_overdriven-guitar': [ + // Overdriven Guitar: Guitar + '0290_FluidR3_GM_sf2_file', + '0290_Aspirin_sf2_file', + '0290_Chaos_sf2_file', + '0290_GeneralUserGS_sf2_file', + //0290_JCLive_sf2_file // detuned.... + //0290_LesPaul_sf2 // broken + '0290_LesPaul_sf2_file', + '0290_SBAWE32_sf2_file', + //0290_SBLive_sf2 + //0290_SoundBlasterOld_sf2 + // 0291_Aspirin_sf2_file // broken + // 0291_LesPaul_sf2 // broken + '0291_LesPaul_sf2_file', + '0291_SBAWE32_sf2_file', + //0291_SoundBlasterOld_sf2 + '0292_Aspirin_sf2_file', + // 0292_LesPaul_sf2 // broken + '0292_LesPaul_sf2_file', + ], + 'gm_distortion-guitar': [ + // Distortion Guitar: Guitar + '0300_FluidR3_GM_sf2_file', + '0300_Aspirin_sf2_file', + '0300_Chaos_sf2_file', + '0300_GeneralUserGS_sf2_file', + // 0300_JCLive_sf2_file // broken + // 0300_LesPaul_sf2 // broken + '0300_LesPaul_sf2_file', + //0300_SBAWE32_sf2_file // -2 octave + //0300_SBLive_sf2 + //0300_SoundBlasterOld_sf2 + // 0301_Aspirin_sf2_file // missing + //0301_FluidR3_GM_sf2_file // weird broken bell + // 0301_GeneralUserGS_sf2_file // broken + // 0301_JCLive_sf2_file // broken + // 0301_LesPaul_sf2 // missing + // 0301_LesPaul_sf2_file // + 1 oct? + '0302_Aspirin_sf2_file', + // 0302_GeneralUserGS_sf2_file // not a guitar.. + //0302_JCLive_sf2_file // broken... + // 0303_Aspirin_sf2_file // guitar harmonic?? + '0304_Aspirin_sf2_file', + ], + 'gm_guitar-harmonics': [ + // Guitar Harmonics: Guitar + '0310_Aspirin_sf2_file', + '0310_FluidR3_GM_sf2_file', + '0310_Chaos_sf2_file', + //0310_GeneralUserGS_sf2_file // weird.. + // 0310_JCLive_sf2_file // weird + //0310_LesPaul_sf2 // missing + //0310_LesPaul_sf2_file // wrong pitches + //0310_SBAWE32_sf2_file // wrong pitches + //0310_SBLive_sf2 + //0310_SoundBlasterOld_sf2 + //0311_FluidR3_GM_sf2_file // knackt + //0311_GeneralUserGS_sf2_file // wrong note + ], + 'gm_acoustic-bass': [ + // Acoustic Bass: Bass + '0320_JCLive_sf2_file', + '0320_FluidR3_GM_sf2_file', + '0320_Aspirin_sf2_file', + '0320_Chaos_sf2_file', + // 0320_GeneralUserGS_sf2_file // missing notes + //0320_SBLive_sf2 + //0320_SoundBlasterOld_sf2 + // 0321_GeneralUserGS_sf2_file // nice sound but missing notes + // 0322_GeneralUserGS_sf2_file // missing note + ], + 'gm_electric-bass-finger': [ + // Electric Bass (finger): Bass + '0330_JCLive_sf2_file', + '0330_FluidR3_GM_sf2_fible', + '0330_Aspirin_sf2_file', + //0330_Chaos_sf2_file // same as last + '0330_GeneralUserGS_sf2_file', + //0330_SBLive_sf2 + //0330_SoundBlasterOld_sf2 + //0331_GeneralUserGS_sf2_file // knackt + // 0332_GeneralUserGS_sf2_file // missin + ], + 'gm_electric-bass-pick': [ + // Electric Bass (pick): Bass + '0340_JCLive_sf2_file', + '0340_FluidR3_GM_sf2_file', + '0340_Aspirin_sf2_file', + //0340_Chaos_sf2_file // same as last + '0340_GeneralUserGS_sf2_file', + //0340_SBLive_sf2 + //0340_SoundBlasterOld_sf2 + '0341_Aspirin_sf2_file', + //0341_GeneralUserGS_sf2_file // knack + ], + 'gm_fretless-bass': [ + // Fretless Bass: Bass + '0350_Aspirin_sf2_file', + // 0350_Chaos_sf2_file // same as last + //0350_FluidR3_GM_sf2_file // knackt + //0350_GeneralUserGS_sf2_file // -1 oct + knackt + '0350_JCLive_sf2_file', + //0350_SBLive_sf2 + //0350_SoundBlasterOld_sf2 + //0351_GeneralUserGS_sf2_file // missin + ], + 'gm_slap-bass-1': [ + // Slap Bass 1: Bass + '0360_Aspirin_sf2_file', + '0360_JCLive_sf2_file', + '0360_FluidR3_GM_sf2_file', + '0360_Chaos_sf2_file', + //0360_GeneralUserGS_sf2_file // -1 oct + //0360_SBLive_sf2 + //0360_SoundBlasterOld_sf2 + //0361_GeneralUserGS_sf2_file // missin + ], + 'gm_slap-bass-2': [ + // Slap Bass 2: Bass + '0370_Aspirin_sf2_file', + // 0370_Chaos_sf2_file // same as last + '0370_FluidR3_GM_sf2_file', + '0370_GeneralUserGS_sf2_fil e', + '0370_JCLive_sf2_file', + //0370_SBLive_sf2 + //0370_SoundBlasterOld_sf2 + //0371_GeneralUserGS_sf2_file // missing + //0372_GeneralUserGS_sf2_file // detuned + //0385_GeneralUserGS_sf2_file // missin + ], + 'gm_synth-bass-1': [ + // Synth Bass 1: Bass + '0380_Aspirin_sf2_file', + '0380_Chaos_sf2_file', + '0380_FluidR3_GM_sf2_file', + // 0380_GeneralUserGS_sf2_file // laut + '0380_JCLive_sf2_file', + //0380_SBLive_sf2 + //0380_SoundBlasterOld_sf2 + '0381_FluidR3_GM_sf2_file', + '0381_GeneralUserGS_sf2_file', + //0382_FluidR3_GM_sf2_file // kein synth bass + '0382_GeneralUserGS_sf2_file', + '0383_GeneralUserGS_sf2_file', + '0384_GeneralUserGS_sf2_file', + //0386_GeneralUserGS_sf2_file // knackt + '0387_GeneralUserGS_sf2_file', + ], + 'gm_synth-bass-2': [ + // Synth Bass 2: Bass + '0390_Aspirin_sf2_file', + // 0390_Chaos_sf2_file // same as last + '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 // missing + //0391_SoundBlasterOld_sf2 + '0392_FluidR3_GM_sf2_file', + //0392_GeneralUserGS_sf2_file // kein synth und -1oct + '0393_GeneralUserGS_sf2_file', + ], + gm_violin: [ + // Violin: Strings + '0400_Aspirin_sf2_file', + '0400_Chaos_sf2_file', + '0400_JCLive_sf2_file', + '0400_FluidR3_GM_sf2_file', + '0400_GeneralUserGS_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', + ], + gm_viola: [ + // Viola: Strings + '0410_Aspirin_sf2_file', + // 0410_Chaos_sf2_file // laut und sehr unstringy + '0410_FluidR3_GM_sf2_file', + '0410_GeneralUserGS_sf2_file', + '0410_JCLive_sf2_file', + //0410_SBLive_sf2 + //0410_SoundBlasterOld_sf2 + '0411_FluidR3_GM_sf2_file', + ], + gm_cello: [ + // Cello: Strings + '0420_Aspirin_sf2_file', + // 0420_Chaos_sf2_file // kein cello und laut + '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', + ], + gm_contrabass: [ + // Contrabass: Strings + '0430_Aspirin_sf2_file', + '0430_Chaos_sf2_file', + // 0430_FluidR3_GM_sf2_file // missing notes + '0430_GeneralUserGS_sf2_file', + //0430_JCLive_sf2_file // -1 oct und meh + //0430_SBLive_sf2 + //0430_SoundBlasterOld_sf2 + // 0431_FluidR3_GM_sf2_file // missing note + ], + 'gm_tremolo-strings': [ + // Tremolo Strings: Strings + '0440_Aspirin_sf2_file', + '0440_Chaos_sf2_file', + //0440_FluidR3_GM_sf2_file // huuuge + '0440_GeneralUserGS_sf2_file', + '0440_JCLive_sf2_file', + //0440_SBLive_sf2 + //0440_SoundBlasterOld_sf2 + '0441_GeneralUserGS_sf2_file', + '0442_GeneralUserGS_sf2_file', + ], + 'gm_pizzicato-strings': [ + // Pizzicato Strings: Strings + '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', + ], + 'gm_orchestral-harp': [ + // Orchestral Harp: Strings + '0460_Aspirin_sf2_file', + // 0460_Chaos_sf2_file // knackt + '0460_FluidR3_GM_sf2_file', + '0460_GeneralUserGS_sf2_file', + '0460_JCLive_sf2_file', + //0460_SBLive_sf2 + //0460_SoundBlasterOld_sf2 + '0461_FluidR3_GM_sf2_file', + ], + gm_timpani: [ + // Timpani: Strings + '0470_Aspirin_sf2_file', + '0470_Chaos_sf2_file', + '0470_FluidR3_GM_sf2_file', + '0470_GeneralUserGS_sf2_file', + // 0470_JCLive_sf2_file // wrong pitches + //0470_SBLive_sf2 + //0470_SoundBlasterOld_sf2 + '0471_FluidR3_GM_sf2_file', + '0471_GeneralUserGS_sf2_file', + ], + 'gm_string-ensemble-1': [ + // String Ensemble 1: Ensemble + '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 + // these dont work.. + //04810_GeneralUserGS_sf2_file // missing notes + brass + //04811_GeneralUserGS_sf2_file // missing notes + brass + //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', + // another block of buggyness: + //0484_GeneralUserGS_sf2_file // keys?! + knackt + //0485_GeneralUserGS_sf2_file // missing notes + //0486_GeneralUserGS_sf2_file + //0487_GeneralUserGS_sf2_file + //0488_GeneralUserGS_sf2_file + //0489_GeneralUserGS_sf2_fil + ], + 'gm_string-ensemble-2': [ + // String Ensemble 2: Ensemble + '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', + ], + 'gm_synth-strings-1': [ + // Synth Strings 1: Ensemble + '0500_Aspirin_sf2_file', + // 0500_Chaos_sf2_file // same as above + //0500_FluidR3_GM_sf2_file // detune + knack + '0500_GeneralUserGS_sf2_file', + '0500_JCLive_sf2_file', + //0500_SBLive_sf2 + //0500_SoundBlasterOld_sf2 + '0501_FluidR3_GM_sf2_file', + // 0501_GeneralUserGS_sf2_file // crackles + // 0502_FluidR3_GM_sf2_file // missing + '0502_GeneralUserGS_sf2_file', + '0503_FluidR3_GM_sf2_file', + // 0504_FluidR3_GM_sf2_file // missing + '0505_FluidR3_GM_sf2_file', + ], + 'gm_synth-strings-2': [ + // Synth Strings 2: Ensemble + '0510_Aspirin_sf2_file', + '0510_Chaos_sf2_file', + // 0510_FluidR3_GM_sf2_file // detune + crackle + '0510_GeneralUserGS_sf2_file', + //0510_JCLive_sf2_file // laarge and meh + //0510_SBLive_sf2 // missing + //0510_SoundBlasterOld_sf2 + '0511_GeneralUserGS_sf2_file', + //0511_SoundBlasterOld_sf + ], + 'gm_choir-aahs': [ + // Choir Aahs: Ensemble + '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', + ], + 'gm_voice-oohs': [ + // Voice Oohs: Ensemble + '0530_Aspirin_sf2_file', + '0530_Chaos_sf2_file', + '0530_FluidR3_GM_sf2_file', + '0530_GeneralUserGS_sf2_file', + //0530_JCLive_sf2_file // same as above + //0530_SBLive_sf2 + // 0530_Soul_Ahhs_sf2_file // not ooh + //0530_SoundBlasterOld_sf2 + '0531_FluidR3_GM_sf2_file', + // 0531_GeneralUserGS_sf2_file // ends crackle + '0531_JCLive_sf2_file', + //0531_SoundBlasterOld_sf + ], + 'gm_synth-choir': [ + // Synth Choir: Ensemble + '0540_Aspirin_sf2_file', + '0540_Chaos_sf2_file', + '0540_FluidR3_GM_sf2_file', + '0540_GeneralUserGS_sf2_file', + //0540_JCLive_sf2_file // large + crackles + //0540_SBLive_sf2 + //0540_SoundBlasterOld_sf2 + '0541_FluidR3_GM_sf2_file', + ], + 'gm_orchestra-hit': [ + // Orchestra Hit: Ensemble + '0550_Aspirin_sf2_file', + '0550_Chaos_sf2_file', + '0550_FluidR3_GM_sf2_file', + '0550_GeneralUserGS_sf2_file', + //0550_JCLive_sf2_file // same as above + //0550_SBLive_sf2 + //0550_SoundBlasterOld_sf2 + //0551_Aspirin_sf2_file // not an orch hit.. + '0551_FluidR3_GM_sf2_file', + ], + gm_trumpet: [ + // Trumpet: Brass + '0560_FluidR3_GM_sf2_file', + '0560_JCLive_sf2_file', + '0560_Aspirin_sf2_file', + '0560_Chaos_sf2_file', + //0560_GeneralUserGS_sf2_file // -1 oct + //0560_SBLive_sf2 + //0560_SoundBlasterOld_sf + ], + gm_trombone: [ + // Trombone: Brass + '0570_Aspirin_sf2_file', + '0570_Chaos_sf2_file', + '0570_FluidR3_GM_sf2_file', + '0570_GeneralUserGS_sf2_file', + //0570_JCLive_sf2_file // -1oct + //0570_SBLive_sf2 + //0570_SoundBlasterOld_sf2 + '0571_GeneralUserGS_sf2_file', + ], + gm_tuba: [ + // Tuba: Brass + '0580_FluidR3_GM_sf2_file', + '0580_Aspirin_sf2_file', + '0580_Chaos_sf2_file', + '0580_GeneralUserGS_sf2_file', + //0580_JCLive_sf2_file // -1oct + //0580_SBLive_sf2 + //0580_SoundBlasterOld_sf2 + //0581_GeneralUserGS_sf2_file // missin + ], + 'gm_muted-trumpet': [ + // Muted Trumpet: Brass + '0590_JCLive_sf2_file', + '0590_Aspirin_sf2_file', + '0590_Chaos_sf2_file', + '0590_FluidR3_GM_sf2_file', + '0590_GeneralUserGS_sf2_file', + //0590_SBLive_sf2 + //0590_SoundBlasterOld_sf2 + // 0591_GeneralUserGS_sf2_file // missin + ], + 'gm_french-horn': [ + // French Horn: Brass + '0600_Aspirin_sf2_file', + //0600_Chaos_sf2_file // weird jumps + '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 // tiny crackles + // 0602_GeneralUserGS_sf2_file // bad gain diffs + // 0603_GeneralUserGS_sf2_file // tiny crackle + ], + 'gm_brass-section': [ + // Brass Section: Brass + '0610_JCLive_sf2_file', + '0610_Aspirin_sf2_file', + '0610_Chaos_sf2_file', + '0610_FluidR3_GM_sf2_file', + '0610_GeneralUserGS_sf2_file', + //0610_SBLive_sf2 + //0610_SoundBlasterOld_sf2 + // 0611_GeneralUserGS_sf2_file // missing sounds + // 0612_GeneralUserGS_sf2_file + //0613_GeneralUserGS_sf2_file // -1 oct + // 0614_GeneralUserGS_sf2_file // missing sounds + // 0615_GeneralUserGS_sf2_file // missing sound + ], + 'gm_synth-brass-1': [ + // Synth Brass 1: Brass + '0620_Aspirin_sf2_file', + //0620_Chaos_sf2_file // weird gain diff + '0620_FluidR3_GM_sf2_file', + //0620_GeneralUserGS_sf2_file // loooud + // 0620_JCLive_sf2_file // weird gain diff + //0620_SBLive_sf2 + //0620_SoundBlasterOld_sf2 + '0621_Aspirin_sf2_file', + '0621_FluidR3_GM_sf2_file', + // 0621_GeneralUserGS_sf2_file // detune + loooud + //0622_FluidR3_GM_sf2_file // loud.. + //0622_GeneralUserGS_sf2_file // loud + crackle + ], + 'gm_synth-brass-2': [ + // Synth Brass 2: Brass + '0630_Aspirin_sf2_file', + '0630_Chaos_sf2_file', + '0630_FluidR3_GM_sf2_file', + //0630_GeneralUserGS_sf2_file // detune + looud + '0630_JCLive_sf2_file', + //0630_SBLive_sf2 + //0630_SoundBlasterOld_sf2 + // 0631_Aspirin_sf2_file // looud + detune + gain diffs + '0631_FluidR3_GM_sf2_file', + //0631_GeneralUserGS_sf2_file // crackles + '0632_FluidR3_GM_sf2_file', + '0633_FluidR3_GM_sf2_file', + ], + 'gm_soprano-sax': [ + // Soprano Sax: Reed + '0640_JCLive_sf2_file', + '0640_Aspirin_sf2_file', + '0640_Chaos_sf2_file', + '0640_FluidR3_GM_sf2_file', + // 0640_GeneralUserGS_sf2_file // crackles + //0640_SBLive_sf2 + //0640_SoundBlasterOld_sf2 + '0641_FluidR3_GM_sf2_file', + ], + 'gm_alto-sax': [ + // Alto Sax: Reed + //0650_Aspirin_sf2_file // this is not an alto sax + '0650_JCLive_sf2_file', + '0650_Chaos_sf2_file', + '0650_FluidR3_GM_sf2_file', + '0650_GeneralUserGS_sf2_file', + //0650_SBLive_sf2 + //0650_SoundBlasterOld_sf2 + '0651_Aspirin_sf2_file', + '0651_FluidR3_GM_sf2_file', + ], + 'gm_tenor-sax': [ + // Tenor Sax: Reed + '0660_JCLive_sf2_file', + '0660_Aspirin_sf2_file', + '0660_Chaos_sf2_file', + //0660_FluidR3_GM_sf2_file // weird pitches + '0660_GeneralUserGS_sf2_file', + //0660_SBLive_sf2 + //0660_SoundBlasterOld_sf2 + // 0661_FluidR3_GM_sf2_file // weird pitches + // 0661_GeneralUserGS_sf2_file // missin + ], + 'gm_baritone-sax': [ + // Baritone Sax: Reed + '0670_JCLive_sf2_file', + '0670_Aspirin_sf2_file', + '0670_Chaos_sf2_file', + '0670_FluidR3_GM_sf2_file', + '0670_GeneralUserGS_sf2_file', + //0670_SBLive_sf2 + //0670_SoundBlasterOld_sf2 + '0671_FluidR3_GM_sf2_file', + ], + gm_oboe: [ + // Oboe: Reed + //0680_Aspirin_sf2_file // tiny crackles + '0680_JCLive_sf2_file', + '0680_Chaos_sf2_file', + '0680_FluidR3_GM_sf2_file', + '0680_GeneralUserGS_sf2_file', + //0680_SBLive_sf2 + //0680_SoundBlasterOld_sf2 + '0681_FluidR3_GM_sf2_file', + ], + 'gm_english-horn': [ + // English Horn: Reed + '0690_JCLive_sf2_file', + '0690_Aspirin_sf2_file', + //0690_Chaos_sf2_file // detuned + '0690_FluidR3_GM_sf2_file', + //0690_GeneralUserGS_sf2_file // +1 oct + //0690_SBLive_sf2 + //0690_SoundBlasterOld_sf2 + '0691_FluidR3_GM_sf2_file', + ], + gm_bassoon: [ + // Bassoon: Reed + '0700_JCLive_sf2_file', + //0700_Aspirin_sf2_file // detune + gain diffs + // 0700_Chaos_sf2_file // detune + crackles + '0700_FluidR3_GM_sf2_file', + '0700_GeneralUserGS_sf2_file', + //0700_SBLive_sf2 + //0700_SoundBlasterOld_sf2 + '0701_FluidR3_GM_sf2_file', + //0701_GeneralUserGS_sf2_file // missin + ], + gm_clarinet: [ + // Clarinet: Reed + '0710_JCLive_sf2_file', + '0710_Aspirin_sf2_file', + '0710_Chaos_sf2_file', + '0710_FluidR3_GM_sf2_file', + '0710_GeneralUserGS_sf2_file', + //0710_SBLive_sf2 + //0710_SoundBlasterOld_sf2 + '0711_FluidR3_GM_sf2_file', + ], + gm_piccolo: [ + // Piccolo: Pipe + '0720_JCLive_sf2_file', + '0720_Aspirin_sf2_file', + // 0720_Chaos_sf2_file // not a piccolo + '0720_FluidR3_GM_sf2_file', + '0720_GeneralUserGS_sf2_file', + //0720_SBLive_sf2 + //0720_SoundBlasterOld_sf2 + '0721_FluidR3_GM_sf2_file', + //0721_SoundBlasterOld_sf + ], + gm_flute: [ + // Flute: Pipe + '0730_JCLive_sf2_file', + '0730_Aspirin_sf2_file', + //0730_Chaos_sf2_file // etune + '0730_FluidR3_GM_sf2_file', + '0730_GeneralUserGS_sf2_file', + //0730_SBLive_sf2 + //0730_SoundBlasterOld_sf2 + //0731_Aspirin_sf2_file // not a flute + '0731_FluidR3_GM_sf2_file', + //0731_SoundBlasterOld_sf + ], + gm_recorder: [ + // Recorder: Pipe + '0740_JCLive_sf2_file', + '0740_Aspirin_sf2_file', + '0740_Chaos_sf2_file', + '0740_FluidR3_GM_sf2_file', + '0740_GeneralUserGS_sf2_file', + //0740_SBLive_sf2 + //0740_SoundBlasterOld_sf2 + // 0741_GeneralUserGS_sf2_file // missin + ], + 'gm_pan-flute': [ + // Pan Flute: Pipe + '0750_JCLive_sf2_file', + '0750_FluidR3_GM_sf2_file', + '0750_Aspirin_sf2_file', + '0750_Chaos_sf2_file', + '0750_GeneralUserGS_sf2_file', + //0750_SBLive_sf2 + //0750_SoundBlasterOld_sf2 + '0751_Aspirin_sf2_file', + '0751_FluidR3_GM_sf2_file', + '0751_GeneralUserGS_sf2_file', + //0751_SoundBlasterOld_sf + ], + 'gm_blown-bottle': [ + // Blown bottle: Pipe + '0760_FluidR3_GM_sf2_file', + '0760_JCLive_sf2_file', + // 0760_Aspirin_sf2_file // same as below w crackle + '0760_Chaos_sf2_file', + '0760_GeneralUserGS_sf2_file', + //0760_SBLive_sf2 + //0760_SoundBlasterOld_sf2 + '0761_FluidR3_GM_sf2_file', + // 0761_GeneralUserGS_sf2_file // missing + //0761_SoundBlasterOld_sf2 + // 0762_GeneralUserGS_sf2_file // missin + ], + gm_shakuhachi: [ + // Shakuhachi: Pipe + '0770_JCLive_sf2_file', + '0771_FluidR3_GM_sf2_file', + '0770_Aspirin_sf2_file', + //0770_Chaos_sf2_file // not shakuhachi + '0770_FluidR3_GM_sf2_file', + '0770_GeneralUserGS_sf2_file', + //0770_SBLive_sf2 + //0770_SoundBlasterOld_sf2 + // 0771_GeneralUserGS_sf2_file // missing + // 0772_GeneralUserGS_sf2_file // missin + ], + gm_whistle: [ + // Whistle: Pipe + '0780_FluidR3_GM_sf2_file', + '0780_JCLive_sf2_file', + '0780_Aspirin_sf2_file', + '0780_Chaos_sf2_file', + //0780_GeneralUserGS_sf2_file // loud.. + //0780_SBLive_sf2 + //0780_SoundBlasterOld_sf2 + // 0781_GeneralUserGS_sf2_file // detune + crackle + ], + gm_ocarina: [ + // Ocarina: Pipe + '0790_FluidR3_GM_sf2_file', + '0790_JCLive_sf2_file', + '0790_Aspirin_sf2_file', + //0790_Chaos_sf2_file // same as above + '0790_GeneralUserGS_sf2_file', + //0790_SBLive_sf2 + //0790_SoundBlasterOld_sf2 + //0791_GeneralUserGS_sf2_file // missin + ], + 'gm_lead-1-square': [ + // Lead 1 (square): Synth Lead + '0800_Aspirin_sf2_file', + '0800_Chaos_sf2_file', + '0800_FluidR3_GM_sf2_file', + // 0800_GeneralUserGS_sf2_file // detuned + // 0800_JCLive_sf2_file // detuned + //0800_SBLive_sf2 + //0800_SoundBlasterOld_sf2 + //0801_FluidR3_GM_sf2_file // detune + // 0801_GeneralUserGS_sf2_file // detun + ], + 'gm_lead-2-sawtooth': [ + // Lead 2 (sawtooth): Synth Lead + '0810_JCLive_sf2_file', + '0810_Aspirin_sf2_file', + '0810_Chaos_sf2_file', + '0810_FluidR3_GM_sf2_file', + '0810_GeneralUserGS_sf2_file', + //0810_SBLive_sf2 + //0810_SoundBlasterOld_sf2 + '0811_Aspirin_sf2_file', + '0811_GeneralUserGS_sf2_file', + //0811_SoundBlasterOld_sf + ], + 'gm_lead-3-calliope': [ + // Lead 3 (calliope): Synth Lead + '0820_JCLive_sf2_file', + '0820_Aspirin_sf2_file', + '0820_Chaos_sf2_file', + '0820_FluidR3_GM_sf2_file', + '0820_GeneralUserGS_sf2_file', + //0820_SBLive_sf2 + //0820_SoundBlasterOld_sf2 + '0821_FluidR3_GM_sf2_file', + '0821_GeneralUserGS_sf2_file', + //0821_SoundBlasterOld_sf2 + // 0822_GeneralUserGS_sf2_file // missing + //0823_GeneralUserGS_sf2_file // missin + ], + 'gm_lead-4-chiff': [ + // Lead 4 (chiff): Synth Lead + '0830_JCLive_sf2_file', + '0830_Aspirin_sf2_file', + // 0830_Chaos_sf2_file // same as above + '0830_FluidR3_GM_sf2_file', + '0830_GeneralUserGS_sf2_file', + //0830_SBLive_sf2 + //0830_SoundBlasterOld_sf2 + '0831_FluidR3_GM_sf2_file', + '0831_GeneralUserGS_sf2_file', + //0831_SoundBlasterOld_sf + ], + 'gm_lead-5-charang': [ + // Lead 5 (charang): Synth Lead + '0840_JCLive_sf2_file', + '0840_FluidR3_GM_sf2_file', + '0840_Aspirin_sf2_file', + '0840_Chaos_sf2_file', + '0840_GeneralUserGS_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 // +1oct + detune + //0841_SoundBlasterOld_sf2 + '0842_FluidR3_GM_sf2_file', + ], + 'gm_lead-6-voice': [ + // Lead 6 (voice): Synth Lead + '0850_JCLive_sf2_file', + '0850_Aspirin_sf2_file', + // 0850_Chaos_sf2_file // same as above + '0850_FluidR3_GM_sf2_file', + // 0850_GeneralUserGS_sf2_file // no voice + //0850_SBLive_sf2 + //0850_SoundBlasterOld_sf2 + '0851_FluidR3_GM_sf2_file', + '0851_GeneralUserGS_sf2_file', + '0851_JCLive_sf2_file', + //0851_SoundBlasterOld_sf + ], + 'gm_lead-7-fifths': [ + // Lead 7 (fifths): Synth Lead + '0860_JCLive_sf2_file', + '0860_Aspirin_sf2_file', + '0860_Chaos_sf2_file', + // 0860_FluidR3_GM_sf2_file // loud and not fitting + '0860_GeneralUserGS_sf2_file', + //0860_SBLive_sf2 + //0860_SoundBlasterOld_sf2 + '0861_Aspirin_sf2_file', + // 0861_FluidR3_GM_sf2_file // lout and not fitting + //0861_SoundBlasterOld_sf + ], + 'gm_lead-8-bass-lead': [ + // Lead 8 (bass + lead): Synth Lead + '0870_JCLive_sf2_file', + '0870_Aspirin_sf2_file', + '0870_Chaos_sf2_file', + '0870_FluidR3_GM_sf2_file', + '0870_GeneralUserGS_sf2_file', + //0870_SBLive_sf2 + //0870_SoundBlasterOld_sf2 + // 0871_GeneralUserGS_sf2_file // loud + detune + //0872_GeneralUserGS_sf2_file // loud + //0873_GeneralUserGS_sf2_file // lou + ], + 'gm_pad-new-age': [ + // Pad 1 (new age): Synth Pad + '0880_JCLive_sf2_file', + '0880_Aspirin_sf2_file', + '0880_Chaos_sf2_file', + '0880_FluidR3_GM_sf2_file', + '0880_GeneralUserGS_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 // missing + '0882_GeneralUserGS_sf2_file', + //0883_GeneralUserGS_sf2_file // missing + // 0884_GeneralUserGS_sf2_file // broken + '0885_GeneralUserGS_sf2_file', + //0886_GeneralUserGS_sf2_file // not a pad + '0887_GeneralUserGS_sf2_file', + //0888_GeneralUserGS_sf2_file // not a pad + //0889_GeneralUserGS_sf2_file // not a pa + ], + 'gm_pad-warm': [ + // Pad 2 (warm): Synth Pad + '0890_JCLive_sf2_file', + '0890_Aspirin_sf2_file', + '0890_Chaos_sf2_file', + '0890_FluidR3_GM_sf2_file', + '0890_GeneralUserGS_sf2_file', + //0890_SBLive_sf2 + //0890_SoundBlasterOld_sf2 + '0891_Aspirin_sf2_file', + '0891_FluidR3_GM_sf2_file', + // 0891_GeneralUserGS_sf2_file // nois + ], + 'gm_pad-poly': [ + // Pad 3 (polysynth): Synth Pad + //0900_Aspirin_sf2_file // same as belo + '0900_JCLive_sf2_file', + '0900_Chaos_sf2_file', + '0900_FluidR3_GM_sf2_file', + '0900_GeneralUserGS_sf2_file', + //0900_SBLive_sf2 + //0900_SoundBlasterOld_sf2 + '0901_Aspirin_sf2_file', + '0901_FluidR3_GM_sf2_file', + '0901_GeneralUserGS_sf2_file', + //0901_SoundBlasterOld_sf + ], + 'gm_pad-choir': [ + // Pad 4 (choir): Synth Pad + '0910_JCLive_sf2_file', + '0910_Aspirin_sf2_file', + //0910_Chaos_sf2_file // +1oct + '0910_FluidR3_GM_sf2_file', + '0910_GeneralUserGS_sf2_file', + //0910_SBLive_sf2 + //0910_SoundBlasterOld_sf2 + // 0911_Aspirin_sf2_file // fluty crackles + '0911_GeneralUserGS_sf2_file', + '0911_JCLive_sf2_file', + //0911_SoundBlasterOld_sf + ], + 'gm_pad-bowed': [ + // Pad 5 (bowed): Synth Pad + '0920_JCLive_sf2_file', + '0920_Aspirin_sf2_file', + //0920_Chaos_sf2_file // same as above + //0920_FluidR3_GM_sf2_file // detuned? + '0920_GeneralUserGS_sf2_file', + //0920_SBLive_sf2 + //0920_SoundBlasterOld_sf2 + '0921_Aspirin_sf2_file', + '0921_GeneralUserGS_sf2_file', + //0921_SoundBlasterOld_sf + ], + 'gm_pad-metallic': [ + // Pad 6 (metallic): Synth Pad + '0930_Aspirin_sf2_file', + '0930_Chaos_sf2_file', + '0930_FluidR3_GM_sf2_file', + '0930_GeneralUserGS_sf2_file', + // 0930_JCLive_sf2_file // buggy zones: guitar / synth + //0930_SBLive_sf2 + //0930_SoundBlasterOld_sf2 + '0931_Aspirin_sf2_file', + '0931_FluidR3_GM_sf2_file', + '0931_GeneralUserGS_sf2_file', + //0931_SoundBlasterOld_sf + ], + 'gm_pad-halo': [ + // Pad 7 (halo): Synth Pad + // 0940_Aspirin_sf2_file // same as below + '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', + ], + 'gm_pad-sweep': [ + // Pad 8 (sweep): Synth Pad + '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', + ], + 'gm_fx-rain': [ + // FX 1 (rain): Synth Effects + //0960_Aspirin_sf2_file //mixed samples? + '0960_FluidR3_GM_sf2_file', + '0960_Chaos_sf2_file', + '0960_GeneralUserGS_sf2_file', + // 0960_JCLive_sf2_file // mixed samples? + //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', + ], + 'gm_fx-soundtrack': [ + // FX 2 (soundtrack): Synth Effects + '0970_FluidR3_GM_sf2_file', + '0970_Aspirin_sf2_file', + //0970_Chaos_sf2_file // wrong pitch + '0970_GeneralUserGS_sf2_file', + //0970_JCLive_sf2_file // wrong pitch + //0970_SBLive_sf2 + //0970_SoundBlasterOld_sf2 + '0971_FluidR3_GM_sf2_file', + '0971_GeneralUserGS_sf2_file', + //0971_SoundBlasterOld_sf + ], + 'gm_fx-crystal': [ + // FX 3 (crystal): Synth Effects + '0980_Aspirin_sf2_file', + '0980_JCLive_sf2_file', + '0980_Chaos_sf2_file', + // 0980_FluidR3_GM_sf2_file // some notes are weird + '0980_GeneralUserGS_sf2_file', + '0981_FluidR3_GM_sf2_file', + //0980_SBLive_sf2 + //0980_SoundBlasterOld_sf2 + '0981_Aspirin_sf2_file', + '0981_GeneralUserGS_sf2_file', + //0981_SoundBlasterOld_sf2 + '0982_GeneralUserGS_sf2_file', + '0983_GeneralUserGS_sf2_file', + '0984_GeneralUserGS_sf2_file', + ], + 'gm_fx-atmosphere': [ + // FX 4 (atmosphere): Synth Effects + '0990_JCLive_sf2_file', + '0990_Aspirin_sf2_file', + '0990_Chaos_sf2_file', + '0990_FluidR3_GM_sf2_file', + '0990_GeneralUserGS_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', + ], + 'gm_fx-brightness': [ + // FX 5 (brightness): Synth Effects + '1000_JCLive_sf2_file', + '1000_Aspirin_sf2_file', + '1000_Chaos_sf2_file', + '1000_FluidR3_GM_sf2_file', + '1000_GeneralUserGS_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', + ], + 'gm_fx-goblins': [ + // FX 6 (goblins): Synth Effects + '1010_FluidR3_GM_sf2_file', + '1010_JCLive_sf2_file', + '1010_Aspirin_sf2_file', + '1010_Chaos_sf2_file', + '1010_GeneralUserGS_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', + ], + 'gm_fx-echoes': [ + // FX 7 (echoes): Synth Effects + '1020_FluidR3_GM_sf2_file', + '1020_JCLive_sf2_file', + '1020_Aspirin_sf2_file', + '1020_Chaos_sf2_file', + '1020_GeneralUserGS_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', + ], + 'gm_fx-sci-fi': [ + // FX 8 (sci-fi): Synth Effects + '1030_FluidR3_GM_sf2_file', + '1030_Aspirin_sf2_file', + '1030_Chaos_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', + ], + gm_sitar: [ + // Sitar: Ethnic + '1040_Aspirin_sf2_file', + '1040_FluidR3_GM_sf2_file', + '1040_JCLive_sf2_file', + '1040_Chaos_sf2_file', + '1040_GeneralUserGS_sf2_file', + //1040_SBLive_sf2 + //1040_SoundBlasterOld_sf2 + '1041_FluidR3_GM_sf2_file', + '1041_GeneralUserGS_sf2_file', + ], + gm_banjo: [ + // Banjo: Ethnic + '1050_FluidR3_GM_sf2_file', + '1050_JCLive_sf2_file', + '1050_Aspirin_sf2_file', + '1050_Chaos_sf2_file', + '1050_GeneralUserGS_sf2_file', + //1050_SBLive_sf2 + //1050_SoundBlasterOld_sf2 + '1051_GeneralUserGS_sf2_file', + ], + gm_shamisen: [ + // Shamisen: Ethnic + '1060_JCLive_sf2_file', + '1060_FluidR3_GM_sf2_file', + '1060_Aspirin_sf2_file', + '1060_Chaos_sf2_file', + '1060_GeneralUserGS_sf2_file', + //1060_SBLive_sf2 + //1060_SoundBlasterOld_sf2 + '1061_FluidR3_GM_sf2_file', + '1061_GeneralUserGS_sf2_file', + //1061_SoundBlasterOld_sf + ], + gm_koto: [ + // Koto: Ethnic + '1070_FluidR3_GM_sf2_file', + '1070_JCLive_sf2_file', + '1070_Aspirin_sf2_file', + '1070_Chaos_sf2_file', + '1070_GeneralUserGS_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', + ], + gm_kalimba: [ + // Kalimba: Ethnic + '1080_JCLive_sf2_file', + '1080_FluidR3_GM_sf2_file', + '1080_Aspirin_sf2_file', + '1080_Chaos_sf2_file', + '1080_GeneralUserGS_sf2_file', + //1080_SBLive_sf2 + //1080_SoundBlasterOld_sf2 + //1081_SoundBlasterOld_sf + ], + gm_bagpipe: [ + // Bagpipe: Ethnic + '1090_Aspirin_sf2_file', + // '1090_Chaos_sf2_file', // broken pitches + // '1090_GeneralUserGS_sf2_file', // broken pitches + // '1090_FluidR3_GM_sf2_file', // broken pitches ? + // '1090_JCLive_sf2_file', // broken pitches ? + //1090_SBLive_sf2 + //1090_SoundBlasterOld_sf2 + //1091_SoundBlasterOld_sf + ], + gm_fiddle: [ + // Fiddle: Ethnic + '1100_JCLive_sf2_file', + '1100_Aspirin_sf2_file', + '1100_Chaos_sf2_file', + '1100_FluidR3_GM_sf2_file', + '1100_GeneralUserGS_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', + ], + gm_shanai: [ + // Shanai: Ethnic + '1110_Aspirin_sf2_file', + '1110_FluidR3_GM_sf2_file', + '1110_JCLive_sf2_file', + '1110_Chaos_sf2_file', + '1110_GeneralUserGS_sf2_file', + //1110_SBLive_sf2 + //1110_SoundBlasterOld_sf + ], + 'gm_tinkle-bell': [ + // Tinkle Bell: Percussive + '1120_Aspirin_sf2_file', + // '1120_Chaos_sf2_file', // same as above + // '1120_GeneralUserGS_sf2_file', // sounds exactly as Aspirin + // '1120_FluidR3_GM_sf2_file', // +1oct + // '1120_JCLive_sf2_file', // +1oct + //1120_SBLive_sf2 + //1120_SoundBlasterOld_sf2 + //1121_SoundBlasterOld_sf + ], + gm_agogo: [ + // Agogo: Percussive + '1130_JCLive_sf2_file', + '1130_Aspirin_sf2_file', + '1130_Chaos_sf2_file', + '1130_FluidR3_GM_sf2_file', + '1130_GeneralUserGS_sf2_file', + //1130_SBLive_sf2 + //1130_SoundBlasterOld_sf2 + '1131_FluidR3_GM_sf2_file', + //1131_SoundBlasterOld_sf + ], + 'gm_steel-drums': [ + // Steel Drums: Percussive + '1140_FluidR3_GM_sf2_file', + '1140_Aspirin_sf2_file', + '1140_JCLive_sf2_file', + '1140_Chaos_sf2_file', + '1140_GeneralUserGS_sf2_file', + //1140_SBLive_sf2 + //1140_SoundBlasterOld_sf2 + '1141_FluidR3_GM_sf2_file', + ], + gm_woodblock: [ + // Woodblock: Percussive + '1150_JCLive_sf2_file', + '1150_Aspirin_sf2_file', + '1150_Chaos_sf2_file', + '1150_FluidR3_GM_sf2_file', + '1150_GeneralUserGS_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', + ], + 'gm_taiko-drum': [ + // Taiko Drum: Percussive + '1160_JCLive_sf2_file', + '1160_FluidR3_GM_sf2_file', + '1160_Aspirin_sf2_file', + '1160_Chaos_sf2_file', + '1160_GeneralUserGS_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', + ], + 'gm_melodic-tom': [ + // Melodic Tom: Percussive + '1170_JCLive_sf2_file', + '1170_Aspirin_sf2_file', + '1170_Chaos_sf2_file', + '1170_FluidR3_GM_sf2_file', + '1170_GeneralUserGS_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', + ], + 'gm_synth-drum': [ + // Synth Drum: Percussive + '1180_JCLive_sf2_file', + '1180_Aspirin_sf2_file', + '1180_Chaos_sf2_file', + '1180_FluidR3_GM_sf2_file', + '1180_GeneralUserGS_sf2_file', + //1180_SBLive_sf2 + //1180_SoundBlasterOld_sf2 + '1181_FluidR3_GM_sf2_file', + '1181_GeneralUserGS_sf2_file', + //1181_SoundBlasterOld_sf + ], + 'gm_reverse-cymbal': [ + // Reverse Cymbal: Percussive + '1190_JCLive_sf2_file', + '1190_Aspirin_sf2_file', + '1190_Chaos_sf2_file', + '1190_FluidR3_GM_sf2_file', + '1190_GeneralUserGS_sf2_file', + //1190_SBLive_sf2 + //1190_SoundBlasterOld_sf2 + '1191_GeneralUserGS_sf2_file', + '1192_GeneralUserGS_sf2_file', + '1193_GeneralUserGS_sf2_file', + '1194_GeneralUserGS_sf2_file', + ], + 'gm_guitar-fret-noise': [ + // Guitar Fret Noise: Sound effects + '1200_JCLive_sf2_file', + '1200_Aspirin_sf2_file', + '1200_Chaos_sf2_file', + '1200_FluidR3_GM_sf2_file', + '1200_GeneralUserGS_sf2_file', + //1200_SBLive_sf2 + //1200_SoundBlasterOld_sf2 + '1201_Aspirin_sf2_file', + '1201_GeneralUserGS_sf2_file', + '1202_GeneralUserGS_sf2_file', + ], + 'gm_breath-noise': [ + // Breath Noise: Sound effects + '1210_FluidR3_GM_sf2_file', + '1210_JCLive_sf2_file', + '1210_Aspirin_sf2_file', + '1210_Chaos_sf2_file', + '1210_GeneralUserGS_sf2_file', + //1210_SBLive_sf2 + //1210_SoundBlasterOld_sf2 + '1211_Aspirin_sf2_file', + '1211_GeneralUserGS_sf2_file', + '1212_GeneralUserGS_sf2_file', + ], + gm_seashore: [ + // Seashore: Sound effects + '1220_JCLive_sf2_file', + '1220_Aspirin_sf2_file', + '1220_Chaos_sf2_file', + '1220_FluidR3_GM_sf2_file', + '1220_GeneralUserGS_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', + ], + 'gm_bird-tweet': [ + // Bird Tweet: Sound effects + '1230_FluidR3_GM_sf2_file', + '1230_JCLive_sf2_file', + '1230_Aspirin_sf2_file', + // '1230_Chaos_sf2_file', + '1230_GeneralUserGS_sf2_file', + //1230_SBLive_sf2 + //1230_SoundBlasterOld_sf2 + //'1231_Aspirin_sf2_file', + '1231_GeneralUserGS_sf2_file', // dog + // '1232_Aspirin_sf2_file',// ? + '1232_GeneralUserGS_sf2_file', // horse + // '1233_GeneralUserGS_sf2_file', // + '1234_GeneralUserGS_sf2_file', // scratch + ], + gm_telephone: [ + // Telephone Ring: Sound effects + '1240_JCLive_sf2_file', + '1240_Aspirin_sf2_file', + '1240_Chaos_sf2_file', + '1240_FluidR3_GM_sf2_file', + // '1240_GeneralUserGS_sf2_file', + //1240_SBLive_sf2 + //1240_SoundBlasterOld_sf2 + '1241_Aspirin_sf2_file', // door? + //'1241_GeneralUserGS_sf2_file', + // '1242_Aspirin_sf2_file', // ? + '1242_GeneralUserGS_sf2_file', // door + '1243_Aspirin_sf2_file', // scratch + '1243_GeneralUserGS_sf2_file', // door close? + '1244_Aspirin_sf2_file', // bells + '1244_GeneralUserGS_sf2_file', // bells + ], + gm_helicopter: [ + // Helicopter: Sound effects + '1250_JCLive_sf2_file', + '1250_Aspirin_sf2_file', + // '1250_Chaos_sf2_file', // same as above + '1250_FluidR3_GM_sf2_file', + '1250_GeneralUserGS_sf2_file', + //1250_SBLive_sf2 + //1250_SoundBlasterOld_sf2 + // '1251_Aspirin_sf2_file', // slooow + '1251_FluidR3_GM_sf2_file', // guitar + '1251_GeneralUserGS_sf2_file', // engine start with loop at end.. + '1252_Aspirin_sf2_file', // alien + '1252_FluidR3_GM_sf2_file', // seashore + '1252_GeneralUserGS_sf2_file', // carbreak + // '1253_Aspirin_sf2_file', // plane + '1253_GeneralUserGS_sf2_file', // racing car + // '1254_Aspirin_sf2_file', + '1254_GeneralUserGS_sf2_file', // breaking + // '1255_Aspirin_sf2_file', + '1255_GeneralUserGS_sf2_file', // siren + // '1256_Aspirin_sf2_file', + '1256_GeneralUserGS_sf2_file', // hmm + // '1257_Aspirin_sf2_file', + '1257_GeneralUserGS_sf2_file', // noise + // '1258_Aspirin_sf2_file', + '1258_GeneralUserGS_sf2_file', // metallic noise + '1259_GeneralUserGS_sf2_file', // watery nosie + ], + gm_applause: [ + // Applause: Sound effects + '1260_JCLive_sf2_file', + '1260_Aspirin_sf2_file', + '1260_Chaos_sf2_file', + '1260_FluidR3_GM_sf2_file', + '1260_GeneralUserGS_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', + ], + gm_gunshot: [ + // Gunshot: Sound effects + '1270_JCLive_sf2_file', + '1270_Aspirin_sf2_file', + '1270_Chaos_sf2_file', + '1270_FluidR3_GM_sf2_file', + '1270_GeneralUserGS_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', + '', + ], +}; diff --git a/packages/soundfonts/list.mjs b/packages/soundfonts/list.mjs index fa21c110..853e2fb3 100644 --- a/packages/soundfonts/list.mjs +++ b/packages/soundfonts/list.mjs @@ -1,4 +1,7 @@ +// this list is not used anymore.. + export const instruments = [ + // Acoustic Grand Piano: Piano '0000_JCLive_sf2_file', '0000_Aspirin_sf2_file', @@ -10,10 +13,6 @@ export const instruments = [ '0001_FluidR3_GM_sf2_file', '0001_GeneralUserGS_sf2_file', - // ?? - '0002_GeneralUserGS_sf2_file', // strring - '0003_GeneralUserGS_sf2_file', // vibraphone like - // Bright Acoustic Piano: Piano '0010_Aspirin_sf2_file', '0010_Chaos_sf2_file', @@ -25,7 +24,6 @@ export const instruments = [ '0011_Aspirin_sf2_file', '0011_FluidR3_GM_sf2_file', '0011_GeneralUserGS_sf2_file', - '0012_GeneralUserGS_sf2_file', // string?? // Electric Grand Piano: Piano @@ -66,8 +64,6 @@ export const instruments = [ '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', // ? @@ -232,8 +228,6 @@ export const instruments = [ '0180_JCLive_sf2_file', //'0180_SBLive_sf2', //'0180_SoundBlasterOld_sf2', - - // ??? //'0181_Aspirin_sf2_file', // flute //'0181_GeneralUserGS_sf2_file', // marimbalike //'0181_SoundBlasterOld_sf2', @@ -415,7 +409,6 @@ export const instruments = [ //'0300_SBLive_sf2', //'0300_SoundBlasterOld_sf2', // '0301_Aspirin_sf2_file', // missing - //'0301_FluidR3_GM_sf2_file', // weird broken bell // '0301_GeneralUserGS_sf2_file', // broken // '0301_JCLive_sf2_file', // broken @@ -632,7 +625,6 @@ export const instruments = [ '0480_JCLive_sf2_file', //'0480_SBLive_sf2', //'0480_SoundBlasterOld_sf2', - // these dont work.. //'04810_GeneralUserGS_sf2_file', // missing notes + brass //'04811_GeneralUserGS_sf2_file', // missing notes + brass @@ -642,7 +634,6 @@ export const instruments = [ //'04815_GeneralUserGS_sf2_file', //'04816_GeneralUserGS_sf2_file', //'04817_GeneralUserGS_sf2_file', - '0481_Aspirin_sf2_file', '0481_FluidR3_GM_sf2_file', // brass '0481_GeneralUserGS_sf2_file', From b5d3aa81f99be6dea437bef405be1e089ee5afd2 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 16 Mar 2023 12:25:08 +0100 Subject: [PATCH 19/24] format --- packages/soundfonts/list.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/soundfonts/list.mjs b/packages/soundfonts/list.mjs index 853e2fb3..116eecf9 100644 --- a/packages/soundfonts/list.mjs +++ b/packages/soundfonts/list.mjs @@ -1,7 +1,6 @@ // this list is not used anymore.. export const instruments = [ - // Acoustic Grand Piano: Piano '0000_JCLive_sf2_file', '0000_Aspirin_sf2_file', From 15681262defc1dc3bea40f9ad9dea2b78598ba4f Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 16 Mar 2023 15:19:38 +0100 Subject: [PATCH 20/24] use only _ for easier copying via double click --- packages/soundfonts/gm.mjs | 190 ++++++++++++++++++------------------- 1 file changed, 95 insertions(+), 95 deletions(-) diff --git a/packages/soundfonts/gm.mjs b/packages/soundfonts/gm.mjs index 780ea69b..c0e57dcb 100644 --- a/packages/soundfonts/gm.mjs +++ b/packages/soundfonts/gm.mjs @@ -1,6 +1,6 @@ export default { gm_piano: [ - //'gm_acoustic-piano': [ + //'gm_acoustic_piano': [ // Acoustic Grand Piano: Piano '0000_JCLive_sf2_file', '0000_FluidR3_GM_sf2_file', @@ -12,7 +12,7 @@ export default { '0001_FluidR3_GM_sf2_file', '0001_GeneralUserGS_sf2_file', //], - //'gm_bright-acoustic-piano': [ + //'gm_bright_acoustic_piano': [ // Bright Acoustic Piano: Piano '0010_Aspirin_sf2_file', '0010_Chaos_sf2_file', @@ -26,7 +26,7 @@ export default { '0011_GeneralUserGS_sf2_file', '0012_GeneralUserGS_sf2_file', //], - //'gm_electric-grand-piano': [ + //'gm_electric_grand_piano': [ // Electric Grand Piano: Piano '0020_Aspirin_sf2_file', '0020_Chaos_sf2_file', @@ -40,8 +40,8 @@ export default { // ? '0022_Aspirin_sf2_file', //], - //'gm_honky-tonk-piano': [ - // Honky-tonk Piano: Piano + //'gm_honky_tonk_piano': [ + // Honky_tonk Piano: Piano '0030_Aspirin_sf2_file', '0030_Chaos_sf2_file', '0030_FluidR3_GM_sf2_file', @@ -139,7 +139,7 @@ export default { //0090_SoundBlasterOld_sf2 //0091_SoundBlasterOld_sf ], - 'gm_music-box': [ + gm_music_box: [ // Music Box: Chromatic Percussion '0100_JCLive_sf2_file', '0100_Aspirin_sf2_file', @@ -185,7 +185,7 @@ export default { //0130_SoundBlasterOld_sf2 '0131_FluidR3_GM_sf2_file', ], - 'gm_tubular-bells': [ + gm_tubular_bells: [ // Tubular Bells: Chromatic Percussion '0140_JCLive_sf2_file', '0140_Aspirin_sf2_file', @@ -210,7 +210,7 @@ export default { //0150_SoundBlasterOld_sf2 '0151_FluidR3_GM_sf2_file', ], - 'gm_drawbar-organ': [ + gm_drawbar_organ: [ // Drawbar Organ: Organ '0160_JCLive_sf2_file', '0160_Aspirin_sf2_file', @@ -223,7 +223,7 @@ export default { '0161_FluidR3_GM_sf2_file', //0161_SoundBlasterOld_sf ], - 'gm_percussive-organ': [ + gm_percussive_organ: [ // Percussive Organ: Organ '0170_JCLive_sf2_file', '0170_Aspirin_sf2_file', @@ -236,7 +236,7 @@ export default { // 0171_GeneralUserGS_sf2_file // repitched '0172_FluidR3_GM_sf2_file', ], - 'gm_rock-organ': [ + gm_rock_organ: [ // Rock Organ: Organ '0180_JCLive_sf2_file', '0180_Aspirin_sf2_file', @@ -249,7 +249,7 @@ export default { //0181_GeneralUserGS_sf2_file // marimbalike //0181_SoundBlasterOld_sf ], - 'gm_church-organ': [ + gm_church_organ: [ // Church Organ: Organ '0190_JCLive_sf2_file', '0190_Aspirin_sf2_file', @@ -262,7 +262,7 @@ export default { //0191_GeneralUserGS_sf2_file // weird organ //0191_SoundBlasterOld_sf ], - 'gm_reed-organ': [ + gm_reed_organ: [ // Reed Organ: Organ '0200_JCLive_sf2_file', '0200_Aspirin_sf2_file', @@ -318,7 +318,7 @@ export default { '0232_FluidR3_GM_sf2_file', '0233_FluidR3_GM_sf2_file', ], - 'gm_acoustic-guitar-nylon': [ + gm_acoustic_guitar_nylon: [ // Acoustic Guitar (nylon): Guitar '0240_JCLive_sf2_file', '0240_Aspirin_sf2_file', @@ -333,7 +333,7 @@ export default { '0242_JCLive_sf2_file', '0243_JCLive_sf2_file', ], - 'gm_acoustic-guitar-steel': [ + gm_acoustic_guitar_steel: [ // Acoustic Guitar (steel): Guitar '0253_Acoustic_Guitar_sf2_file', '0250_Aspirin_sf2_file', @@ -354,7 +354,7 @@ export default { '0254_GeneralUserGS_sf2_file', //0255_GeneralUserGS_sf2_file // no guitar. ], - 'gm_electric-guitar-jazz': [ + gm_electric_guitar_jazz: [ // Electric Guitar (jazz): Guitar '0260_JCLive_sf2_file', '0260_Aspirin_sf2_file', @@ -369,7 +369,7 @@ export default { '0261_Stratocaster_sf2_file', '0262_Stratocaster_sf2_file', ], - 'gm_electric-guitar-clean': [ + gm_electric_guitar_clean: [ // Electric Guitar (clean): Guitar '0270_Aspirin_sf2_file', '0270_Chaos_sf2_file', @@ -385,7 +385,7 @@ export default { '0271_Stratocaster_sf2_file', '0272_Stratocaster_sf2_file', ], - 'gm_electric-guitar-muted': [ + gm_electric_guitar_muted: [ // Electric Guitar (muted): Guitar '0280_Aspirin_sf2_file', '0280_Chaos_sf2_file', @@ -404,7 +404,7 @@ export default { // 0282_GeneralUserGS_sf2_file // broken: missing notes // 0283_GeneralUserGS_sf2_file // missin ], - 'gm_overdriven-guitar': [ + gm_overdriven_guitar: [ // Overdriven Guitar: Guitar '0290_FluidR3_GM_sf2_file', '0290_Aspirin_sf2_file', @@ -425,7 +425,7 @@ export default { // 0292_LesPaul_sf2 // broken '0292_LesPaul_sf2_file', ], - 'gm_distortion-guitar': [ + gm_distortion_guitar: [ // Distortion Guitar: Guitar '0300_FluidR3_GM_sf2_file', '0300_Aspirin_sf2_file', @@ -434,7 +434,7 @@ export default { // 0300_JCLive_sf2_file // broken // 0300_LesPaul_sf2 // broken '0300_LesPaul_sf2_file', - //0300_SBAWE32_sf2_file // -2 octave + //0300_SBAWE32_sf2_file // _2 octave //0300_SBLive_sf2 //0300_SoundBlasterOld_sf2 // 0301_Aspirin_sf2_file // missing @@ -449,7 +449,7 @@ export default { // 0303_Aspirin_sf2_file // guitar harmonic?? '0304_Aspirin_sf2_file', ], - 'gm_guitar-harmonics': [ + gm_guitar_harmonics: [ // Guitar Harmonics: Guitar '0310_Aspirin_sf2_file', '0310_FluidR3_GM_sf2_file', @@ -464,7 +464,7 @@ export default { //0311_FluidR3_GM_sf2_file // knackt //0311_GeneralUserGS_sf2_file // wrong note ], - 'gm_acoustic-bass': [ + gm_acoustic_bass: [ // Acoustic Bass: Bass '0320_JCLive_sf2_file', '0320_FluidR3_GM_sf2_file', @@ -476,7 +476,7 @@ export default { // 0321_GeneralUserGS_sf2_file // nice sound but missing notes // 0322_GeneralUserGS_sf2_file // missing note ], - 'gm_electric-bass-finger': [ + gm_electric_bass_finger: [ // Electric Bass (finger): Bass '0330_JCLive_sf2_file', '0330_FluidR3_GM_sf2_fible', @@ -488,7 +488,7 @@ export default { //0331_GeneralUserGS_sf2_file // knackt // 0332_GeneralUserGS_sf2_file // missin ], - 'gm_electric-bass-pick': [ + gm_electric_bass_pick: [ // Electric Bass (pick): Bass '0340_JCLive_sf2_file', '0340_FluidR3_GM_sf2_file', @@ -500,29 +500,29 @@ export default { '0341_Aspirin_sf2_file', //0341_GeneralUserGS_sf2_file // knack ], - 'gm_fretless-bass': [ + gm_fretless_bass: [ // Fretless Bass: Bass '0350_Aspirin_sf2_file', // 0350_Chaos_sf2_file // same as last //0350_FluidR3_GM_sf2_file // knackt - //0350_GeneralUserGS_sf2_file // -1 oct + knackt + //0350_GeneralUserGS_sf2_file // _1 oct + knackt '0350_JCLive_sf2_file', //0350_SBLive_sf2 //0350_SoundBlasterOld_sf2 //0351_GeneralUserGS_sf2_file // missin ], - 'gm_slap-bass-1': [ + gm_slap_bass_1: [ // Slap Bass 1: Bass '0360_Aspirin_sf2_file', '0360_JCLive_sf2_file', '0360_FluidR3_GM_sf2_file', '0360_Chaos_sf2_file', - //0360_GeneralUserGS_sf2_file // -1 oct + //0360_GeneralUserGS_sf2_file // _1 oct //0360_SBLive_sf2 //0360_SoundBlasterOld_sf2 //0361_GeneralUserGS_sf2_file // missin ], - 'gm_slap-bass-2': [ + gm_slap_bass_2: [ // Slap Bass 2: Bass '0370_Aspirin_sf2_file', // 0370_Chaos_sf2_file // same as last @@ -535,7 +535,7 @@ export default { //0372_GeneralUserGS_sf2_file // detuned //0385_GeneralUserGS_sf2_file // missin ], - 'gm_synth-bass-1': [ + gm_synth_bass_1: [ // Synth Bass 1: Bass '0380_Aspirin_sf2_file', '0380_Chaos_sf2_file', @@ -553,7 +553,7 @@ export default { //0386_GeneralUserGS_sf2_file // knackt '0387_GeneralUserGS_sf2_file', ], - 'gm_synth-bass-2': [ + gm_synth_bass_2: [ // Synth Bass 2: Bass '0390_Aspirin_sf2_file', // 0390_Chaos_sf2_file // same as last @@ -566,7 +566,7 @@ export default { // 0391_GeneralUserGS_sf2_file // missing //0391_SoundBlasterOld_sf2 '0392_FluidR3_GM_sf2_file', - //0392_GeneralUserGS_sf2_file // kein synth und -1oct + //0392_GeneralUserGS_sf2_file // kein synth und _1oct '0393_GeneralUserGS_sf2_file', ], gm_violin: [ @@ -612,12 +612,12 @@ export default { '0430_Chaos_sf2_file', // 0430_FluidR3_GM_sf2_file // missing notes '0430_GeneralUserGS_sf2_file', - //0430_JCLive_sf2_file // -1 oct und meh + //0430_JCLive_sf2_file // _1 oct und meh //0430_SBLive_sf2 //0430_SoundBlasterOld_sf2 // 0431_FluidR3_GM_sf2_file // missing note ], - 'gm_tremolo-strings': [ + gm_tremolo_strings: [ // Tremolo Strings: Strings '0440_Aspirin_sf2_file', '0440_Chaos_sf2_file', @@ -629,7 +629,7 @@ export default { '0441_GeneralUserGS_sf2_file', '0442_GeneralUserGS_sf2_file', ], - 'gm_pizzicato-strings': [ + gm_pizzicato_strings: [ // Pizzicato Strings: Strings '0450_Aspirin_sf2_file', '0450_Chaos_sf2_file', @@ -640,7 +640,7 @@ export default { //0450_SoundBlasterOld_sf2 '0451_FluidR3_GM_sf2_file', ], - 'gm_orchestral-harp': [ + gm_orchestral_harp: [ // Orchestral Harp: Strings '0460_Aspirin_sf2_file', // 0460_Chaos_sf2_file // knackt @@ -663,7 +663,7 @@ export default { '0471_FluidR3_GM_sf2_file', '0471_GeneralUserGS_sf2_file', ], - 'gm_string-ensemble-1': [ + gm_string_ensemble_1: [ // String Ensemble 1: Ensemble '0480_Aspirin_sf2_file', '0480_Chaos_sf2_file', @@ -695,7 +695,7 @@ export default { //0488_GeneralUserGS_sf2_file //0489_GeneralUserGS_sf2_fil ], - 'gm_string-ensemble-2': [ + gm_string_ensemble_2: [ // String Ensemble 2: Ensemble '0490_Aspirin_sf2_file', '0490_Chaos_sf2_file', @@ -707,7 +707,7 @@ export default { '0491_GeneralUserGS_sf2_file', '0492_GeneralUserGS_sf2_file', ], - 'gm_synth-strings-1': [ + gm_synth_strings_1: [ // Synth Strings 1: Ensemble '0500_Aspirin_sf2_file', // 0500_Chaos_sf2_file // same as above @@ -724,7 +724,7 @@ export default { // 0504_FluidR3_GM_sf2_file // missing '0505_FluidR3_GM_sf2_file', ], - 'gm_synth-strings-2': [ + gm_synth_strings_2: [ // Synth Strings 2: Ensemble '0510_Aspirin_sf2_file', '0510_Chaos_sf2_file', @@ -736,7 +736,7 @@ export default { '0511_GeneralUserGS_sf2_file', //0511_SoundBlasterOld_sf ], - 'gm_choir-aahs': [ + gm_choir_aahs: [ // Choir Aahs: Ensemble '0520_Aspirin_sf2_file', '0520_Chaos_sf2_file', @@ -751,7 +751,7 @@ export default { //0521_SoundBlasterOld_sf2 '0522_Soul_Ahhs_sf2_file', ], - 'gm_voice-oohs': [ + gm_voice_oohs: [ // Voice Oohs: Ensemble '0530_Aspirin_sf2_file', '0530_Chaos_sf2_file', @@ -766,7 +766,7 @@ export default { '0531_JCLive_sf2_file', //0531_SoundBlasterOld_sf ], - 'gm_synth-choir': [ + gm_synth_choir: [ // Synth Choir: Ensemble '0540_Aspirin_sf2_file', '0540_Chaos_sf2_file', @@ -777,7 +777,7 @@ export default { //0540_SoundBlasterOld_sf2 '0541_FluidR3_GM_sf2_file', ], - 'gm_orchestra-hit': [ + gm_orchestra_hit: [ // Orchestra Hit: Ensemble '0550_Aspirin_sf2_file', '0550_Chaos_sf2_file', @@ -795,7 +795,7 @@ export default { '0560_JCLive_sf2_file', '0560_Aspirin_sf2_file', '0560_Chaos_sf2_file', - //0560_GeneralUserGS_sf2_file // -1 oct + //0560_GeneralUserGS_sf2_file // _1 oct //0560_SBLive_sf2 //0560_SoundBlasterOld_sf ], @@ -805,7 +805,7 @@ export default { '0570_Chaos_sf2_file', '0570_FluidR3_GM_sf2_file', '0570_GeneralUserGS_sf2_file', - //0570_JCLive_sf2_file // -1oct + //0570_JCLive_sf2_file // _1oct //0570_SBLive_sf2 //0570_SoundBlasterOld_sf2 '0571_GeneralUserGS_sf2_file', @@ -816,12 +816,12 @@ export default { '0580_Aspirin_sf2_file', '0580_Chaos_sf2_file', '0580_GeneralUserGS_sf2_file', - //0580_JCLive_sf2_file // -1oct + //0580_JCLive_sf2_file // _1oct //0580_SBLive_sf2 //0580_SoundBlasterOld_sf2 //0581_GeneralUserGS_sf2_file // missin ], - 'gm_muted-trumpet': [ + gm_muted_trumpet: [ // Muted Trumpet: Brass '0590_JCLive_sf2_file', '0590_Aspirin_sf2_file', @@ -832,7 +832,7 @@ export default { //0590_SoundBlasterOld_sf2 // 0591_GeneralUserGS_sf2_file // missin ], - 'gm_french-horn': [ + gm_french_horn: [ // French Horn: Brass '0600_Aspirin_sf2_file', //0600_Chaos_sf2_file // weird jumps @@ -846,7 +846,7 @@ export default { // 0602_GeneralUserGS_sf2_file // bad gain diffs // 0603_GeneralUserGS_sf2_file // tiny crackle ], - 'gm_brass-section': [ + gm_brass_section: [ // Brass Section: Brass '0610_JCLive_sf2_file', '0610_Aspirin_sf2_file', @@ -857,11 +857,11 @@ export default { //0610_SoundBlasterOld_sf2 // 0611_GeneralUserGS_sf2_file // missing sounds // 0612_GeneralUserGS_sf2_file - //0613_GeneralUserGS_sf2_file // -1 oct + //0613_GeneralUserGS_sf2_file // _1 oct // 0614_GeneralUserGS_sf2_file // missing sounds // 0615_GeneralUserGS_sf2_file // missing sound ], - 'gm_synth-brass-1': [ + gm_synth_brass_1: [ // Synth Brass 1: Brass '0620_Aspirin_sf2_file', //0620_Chaos_sf2_file // weird gain diff @@ -876,7 +876,7 @@ export default { //0622_FluidR3_GM_sf2_file // loud.. //0622_GeneralUserGS_sf2_file // loud + crackle ], - 'gm_synth-brass-2': [ + gm_synth_brass_2: [ // Synth Brass 2: Brass '0630_Aspirin_sf2_file', '0630_Chaos_sf2_file', @@ -891,7 +891,7 @@ export default { '0632_FluidR3_GM_sf2_file', '0633_FluidR3_GM_sf2_file', ], - 'gm_soprano-sax': [ + gm_soprano_sax: [ // Soprano Sax: Reed '0640_JCLive_sf2_file', '0640_Aspirin_sf2_file', @@ -902,7 +902,7 @@ export default { //0640_SoundBlasterOld_sf2 '0641_FluidR3_GM_sf2_file', ], - 'gm_alto-sax': [ + gm_alto_sax: [ // Alto Sax: Reed //0650_Aspirin_sf2_file // this is not an alto sax '0650_JCLive_sf2_file', @@ -914,7 +914,7 @@ export default { '0651_Aspirin_sf2_file', '0651_FluidR3_GM_sf2_file', ], - 'gm_tenor-sax': [ + gm_tenor_sax: [ // Tenor Sax: Reed '0660_JCLive_sf2_file', '0660_Aspirin_sf2_file', @@ -926,7 +926,7 @@ export default { // 0661_FluidR3_GM_sf2_file // weird pitches // 0661_GeneralUserGS_sf2_file // missin ], - 'gm_baritone-sax': [ + gm_baritone_sax: [ // Baritone Sax: Reed '0670_JCLive_sf2_file', '0670_Aspirin_sf2_file', @@ -948,7 +948,7 @@ export default { //0680_SoundBlasterOld_sf2 '0681_FluidR3_GM_sf2_file', ], - 'gm_english-horn': [ + gm_english_horn: [ // English Horn: Reed '0690_JCLive_sf2_file', '0690_Aspirin_sf2_file', @@ -1018,7 +1018,7 @@ export default { //0740_SoundBlasterOld_sf2 // 0741_GeneralUserGS_sf2_file // missin ], - 'gm_pan-flute': [ + gm_pan_flute: [ // Pan Flute: Pipe '0750_JCLive_sf2_file', '0750_FluidR3_GM_sf2_file', @@ -1032,7 +1032,7 @@ export default { '0751_GeneralUserGS_sf2_file', //0751_SoundBlasterOld_sf ], - 'gm_blown-bottle': [ + gm_blown_bottle: [ // Blown bottle: Pipe '0760_FluidR3_GM_sf2_file', '0760_JCLive_sf2_file', @@ -1081,7 +1081,7 @@ export default { //0790_SoundBlasterOld_sf2 //0791_GeneralUserGS_sf2_file // missin ], - 'gm_lead-1-square': [ + gm_lead_1_square: [ // Lead 1 (square): Synth Lead '0800_Aspirin_sf2_file', '0800_Chaos_sf2_file', @@ -1093,7 +1093,7 @@ export default { //0801_FluidR3_GM_sf2_file // detune // 0801_GeneralUserGS_sf2_file // detun ], - 'gm_lead-2-sawtooth': [ + gm_lead_2_sawtooth: [ // Lead 2 (sawtooth): Synth Lead '0810_JCLive_sf2_file', '0810_Aspirin_sf2_file', @@ -1106,7 +1106,7 @@ export default { '0811_GeneralUserGS_sf2_file', //0811_SoundBlasterOld_sf ], - 'gm_lead-3-calliope': [ + gm_lead_3_calliope: [ // Lead 3 (calliope): Synth Lead '0820_JCLive_sf2_file', '0820_Aspirin_sf2_file', @@ -1121,7 +1121,7 @@ export default { // 0822_GeneralUserGS_sf2_file // missing //0823_GeneralUserGS_sf2_file // missin ], - 'gm_lead-4-chiff': [ + gm_lead_4_chiff: [ // Lead 4 (chiff): Synth Lead '0830_JCLive_sf2_file', '0830_Aspirin_sf2_file', @@ -1134,7 +1134,7 @@ export default { '0831_GeneralUserGS_sf2_file', //0831_SoundBlasterOld_sf ], - 'gm_lead-5-charang': [ + gm_lead_5_charang: [ // Lead 5 (charang): Synth Lead '0840_JCLive_sf2_file', '0840_FluidR3_GM_sf2_file', @@ -1151,7 +1151,7 @@ export default { //0841_SoundBlasterOld_sf2 '0842_FluidR3_GM_sf2_file', ], - 'gm_lead-6-voice': [ + gm_lead_6_voice: [ // Lead 6 (voice): Synth Lead '0850_JCLive_sf2_file', '0850_Aspirin_sf2_file', @@ -1165,7 +1165,7 @@ export default { '0851_JCLive_sf2_file', //0851_SoundBlasterOld_sf ], - 'gm_lead-7-fifths': [ + gm_lead_7_fifths: [ // Lead 7 (fifths): Synth Lead '0860_JCLive_sf2_file', '0860_Aspirin_sf2_file', @@ -1178,7 +1178,7 @@ export default { // 0861_FluidR3_GM_sf2_file // lout and not fitting //0861_SoundBlasterOld_sf ], - 'gm_lead-8-bass-lead': [ + gm_lead_8_bass_lead: [ // Lead 8 (bass + lead): Synth Lead '0870_JCLive_sf2_file', '0870_Aspirin_sf2_file', @@ -1191,7 +1191,7 @@ export default { //0872_GeneralUserGS_sf2_file // loud //0873_GeneralUserGS_sf2_file // lou ], - 'gm_pad-new-age': [ + gm_pad_new_age: [ // Pad 1 (new age): Synth Pad '0880_JCLive_sf2_file', '0880_Aspirin_sf2_file', @@ -1215,7 +1215,7 @@ export default { //0888_GeneralUserGS_sf2_file // not a pad //0889_GeneralUserGS_sf2_file // not a pa ], - 'gm_pad-warm': [ + gm_pad_warm: [ // Pad 2 (warm): Synth Pad '0890_JCLive_sf2_file', '0890_Aspirin_sf2_file', @@ -1228,7 +1228,7 @@ export default { '0891_FluidR3_GM_sf2_file', // 0891_GeneralUserGS_sf2_file // nois ], - 'gm_pad-poly': [ + gm_pad_poly: [ // Pad 3 (polysynth): Synth Pad //0900_Aspirin_sf2_file // same as belo '0900_JCLive_sf2_file', @@ -1242,12 +1242,12 @@ export default { '0901_GeneralUserGS_sf2_file', //0901_SoundBlasterOld_sf ], - 'gm_pad-choir': [ + gm_pad_choir: [ // Pad 4 (choir): Synth Pad + '0910_FluidR3_GM_sf2_file', '0910_JCLive_sf2_file', '0910_Aspirin_sf2_file', //0910_Chaos_sf2_file // +1oct - '0910_FluidR3_GM_sf2_file', '0910_GeneralUserGS_sf2_file', //0910_SBLive_sf2 //0910_SoundBlasterOld_sf2 @@ -1256,7 +1256,7 @@ export default { '0911_JCLive_sf2_file', //0911_SoundBlasterOld_sf ], - 'gm_pad-bowed': [ + gm_pad_bowed: [ // Pad 5 (bowed): Synth Pad '0920_JCLive_sf2_file', '0920_Aspirin_sf2_file', @@ -1269,7 +1269,7 @@ export default { '0921_GeneralUserGS_sf2_file', //0921_SoundBlasterOld_sf ], - 'gm_pad-metallic': [ + gm_pad_metallic: [ // Pad 6 (metallic): Synth Pad '0930_Aspirin_sf2_file', '0930_Chaos_sf2_file', @@ -1283,7 +1283,7 @@ export default { '0931_GeneralUserGS_sf2_file', //0931_SoundBlasterOld_sf ], - 'gm_pad-halo': [ + gm_pad_halo: [ // Pad 7 (halo): Synth Pad // 0940_Aspirin_sf2_file // same as below '0940_Chaos_sf2_file', @@ -1297,7 +1297,7 @@ export default { '0941_GeneralUserGS_sf2_file', '0941_JCLive_sf2_file', ], - 'gm_pad-sweep': [ + gm_pad_sweep: [ // Pad 8 (sweep): Synth Pad '0950_Aspirin_sf2_file', '0950_Chaos_sf2_file', @@ -1309,7 +1309,7 @@ export default { '0951_FluidR3_GM_sf2_file', '0951_GeneralUserGS_sf2_file', ], - 'gm_fx-rain': [ + gm_fx_rain: [ // FX 1 (rain): Synth Effects //0960_Aspirin_sf2_file //mixed samples? '0960_FluidR3_GM_sf2_file', @@ -1324,7 +1324,7 @@ export default { //0961_SoundBlasterOld_sf2 '0962_GeneralUserGS_sf2_file', ], - 'gm_fx-soundtrack': [ + gm_fx_soundtrack: [ // FX 2 (soundtrack): Synth Effects '0970_FluidR3_GM_sf2_file', '0970_Aspirin_sf2_file', @@ -1337,7 +1337,7 @@ export default { '0971_GeneralUserGS_sf2_file', //0971_SoundBlasterOld_sf ], - 'gm_fx-crystal': [ + gm_fx_crystal: [ // FX 3 (crystal): Synth Effects '0980_Aspirin_sf2_file', '0980_JCLive_sf2_file', @@ -1354,7 +1354,7 @@ export default { '0983_GeneralUserGS_sf2_file', '0984_GeneralUserGS_sf2_file', ], - 'gm_fx-atmosphere': [ + gm_fx_atmosphere: [ // FX 4 (atmosphere): Synth Effects '0990_JCLive_sf2_file', '0990_Aspirin_sf2_file', @@ -1373,7 +1373,7 @@ export default { '0993_JCLive_sf2_file', '0994_JCLive_sf2_file', ], - 'gm_fx-brightness': [ + gm_fx_brightness: [ // FX 5 (brightness): Synth Effects '1000_JCLive_sf2_file', '1000_Aspirin_sf2_file', @@ -1391,7 +1391,7 @@ export default { '1002_FluidR3_GM_sf2_file', '1002_GeneralUserGS_sf2_file', ], - 'gm_fx-goblins': [ + gm_fx_goblins: [ // FX 6 (goblins): Synth Effects '1010_FluidR3_GM_sf2_file', '1010_JCLive_sf2_file', @@ -1405,7 +1405,7 @@ export default { '1011_JCLive_sf2_file', '1012_Aspirin_sf2_file', ], - 'gm_fx-echoes': [ + gm_fx_echoes: [ // FX 7 (echoes): Synth Effects '1020_FluidR3_GM_sf2_file', '1020_JCLive_sf2_file', @@ -1421,8 +1421,8 @@ export default { //1021_SoundBlasterOld_sf2 '1022_GeneralUserGS_sf2_file', ], - 'gm_fx-sci-fi': [ - // FX 8 (sci-fi): Synth Effects + gm_fx_sci_fi: [ + // FX 8 (sci_fi): Synth Effects '1030_FluidR3_GM_sf2_file', '1030_Aspirin_sf2_file', '1030_Chaos_sf2_file', @@ -1532,7 +1532,7 @@ export default { //1110_SBLive_sf2 //1110_SoundBlasterOld_sf ], - 'gm_tinkle-bell': [ + gm_tinkle_bell: [ // Tinkle Bell: Percussive '1120_Aspirin_sf2_file', // '1120_Chaos_sf2_file', // same as above @@ -1555,7 +1555,7 @@ export default { '1131_FluidR3_GM_sf2_file', //1131_SoundBlasterOld_sf ], - 'gm_steel-drums': [ + gm_steel_drums: [ // Steel Drums: Percussive '1140_FluidR3_GM_sf2_file', '1140_Aspirin_sf2_file', @@ -1580,7 +1580,7 @@ export default { '1152_FluidR3_GM_sf2_file', '1152_GeneralUserGS_sf2_file', ], - 'gm_taiko-drum': [ + gm_taiko_drum: [ // Taiko Drum: Percussive '1160_JCLive_sf2_file', '1160_FluidR3_GM_sf2_file', @@ -1596,7 +1596,7 @@ export default { '1162_GeneralUserGS_sf2_file', '1163_FluidR3_GM_sf2_file', ], - 'gm_melodic-tom': [ + gm_melodic_tom: [ // Melodic Tom: Percussive '1170_JCLive_sf2_file', '1170_Aspirin_sf2_file', @@ -1610,7 +1610,7 @@ export default { '1172_FluidR3_GM_sf2_file', '1173_FluidR3_GM_sf2_file', ], - 'gm_synth-drum': [ + gm_synth_drum: [ // Synth Drum: Percussive '1180_JCLive_sf2_file', '1180_Aspirin_sf2_file', @@ -1623,7 +1623,7 @@ export default { '1181_GeneralUserGS_sf2_file', //1181_SoundBlasterOld_sf ], - 'gm_reverse-cymbal': [ + gm_reverse_cymbal: [ // Reverse Cymbal: Percussive '1190_JCLive_sf2_file', '1190_Aspirin_sf2_file', @@ -1637,7 +1637,7 @@ export default { '1193_GeneralUserGS_sf2_file', '1194_GeneralUserGS_sf2_file', ], - 'gm_guitar-fret-noise': [ + gm_guitar_fret_noise: [ // Guitar Fret Noise: Sound effects '1200_JCLive_sf2_file', '1200_Aspirin_sf2_file', @@ -1650,7 +1650,7 @@ export default { '1201_GeneralUserGS_sf2_file', '1202_GeneralUserGS_sf2_file', ], - 'gm_breath-noise': [ + gm_breath_noise: [ // Breath Noise: Sound effects '1210_FluidR3_GM_sf2_file', '1210_JCLive_sf2_file', @@ -1684,7 +1684,7 @@ export default { '1225_GeneralUserGS_sf2_file', '1226_GeneralUserGS_sf2_file', ], - 'gm_bird-tweet': [ + gm_bird_tweet: [ // Bird Tweet: Sound effects '1230_FluidR3_GM_sf2_file', '1230_JCLive_sf2_file', From e63a5d10c8191d9a2f5ae5bf2a911219f85d6218 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 16 Mar 2023 15:21:16 +0100 Subject: [PATCH 21/24] regroup sounds - extra tab for drum-machines - combine synths and soundfonts --- packages/soundfonts/fontloader.mjs | 2 +- packages/webaudio/sampler.mjs | 3 +- website/src/repl/Footer.jsx | 48 ++++++++---------------------- website/src/repl/prebake.mjs | 7 +++-- 4 files changed, 21 insertions(+), 39 deletions(-) diff --git a/packages/soundfonts/fontloader.mjs b/packages/soundfonts/fontloader.mjs index cda396fa..c28dfb2f 100644 --- a/packages/soundfonts/fontloader.mjs +++ b/packages/soundfonts/fontloader.mjs @@ -140,7 +140,7 @@ export function registerSoundfonts() { }; return { node: envelope, stop }; }, - { type: 'soundfont', prebake: true }, + { type: 'soundfont', prebake: true, fonts }, ); }); } diff --git a/packages/webaudio/sampler.mjs b/packages/webaudio/sampler.mjs index 1f1325b7..48c45e11 100644 --- a/packages/webaudio/sampler.mjs +++ b/packages/webaudio/sampler.mjs @@ -129,7 +129,7 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '', option throw new Error(`error loading "${sampleMap}"`); }); } - const { prebake } = options; + const { prebake, tag } = options; Object.entries(sampleMap).forEach(([key, value]) => { if (typeof value === 'string') { value = [value]; @@ -155,6 +155,7 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '', option samples: value, baseUrl, prebake, + tag, }); }); }; diff --git a/website/src/repl/Footer.jsx b/website/src/repl/Footer.jsx index 2bce3e70..56950ef4 100644 --- a/website/src/repl/Footer.jsx +++ b/website/src/repl/Footer.jsx @@ -191,34 +191,6 @@ function ConsoleTab({ log }) { ); } -/* -function groupBy(obj = {}, getter) { - const grouped = Object.entries(obj).reduce((acc, [key, value]) => { - const propValue = getter(value, key); - if (!acc.has(propValue)) { - acc.set(propValue, new Map()); - } - acc.get(propValue).set(key, value); - return acc; - }, new Map()); - return grouped; -} - const grouped = useMemo(() => { - if (!sounds) { - return {}; - } - return groupBy(sounds, (s) => - s.data.type === 'sample' ? 'Samples from ' + s.data?.baseUrl : 'Type ' + s.data.type, - ); -}, [sounds]); - - {Array.from(grouped).map(([category, sounds]) => ( - -

{category}:

-
- ))} -*/ - const getSamples = (samples) => Array.isArray(samples) ? samples.length : typeof samples === 'object' ? Object.values(samples).length : 1; @@ -233,14 +205,14 @@ function SoundsTab() { if (soundsFilter === 'user') { return filtered.filter(([key, { data }]) => !data.prebake); } + if (soundsFilter === 'drums') { + return filtered.filter(([_, { data }]) => data.type === 'sample' && data.tag === 'drum-machines'); + } if (soundsFilter === 'samples') { - return filtered.filter(([_, { data }]) => data.type === 'sample'); + return filtered.filter(([_, { data }]) => data.type === 'sample' && data.tag !== 'drum-machines'); } if (soundsFilter === 'synths') { - return filtered.filter(([_, { data }]) => data.type === 'synth'); - } - if (soundsFilter === 'soundfonts') { - return filtered.filter(([_, { data }]) => data.type === 'soundfont'); + return filtered.filter(([_, { data }]) => ['synth', 'soundfont'].includes(data.type)); } return filtered; }, [sounds, soundsFilter]); @@ -260,14 +232,19 @@ function SoundsTab() { settingsMap.setKey('soundsFilter', value)} - items={{ samples: 'Samples', synths: 'Synths', soundfonts: 'Soundfonts', user: 'Custom' }} + items={{ + samples: 'samples', + drums: 'drum-machines', + synths: 'Synths', + user: 'User', + }} >
{soundEntries.map(([name, { data, onTrigger }]) => ( { const ctx = getAudioContext(); const params = { @@ -287,6 +264,7 @@ function SoundsTab() { {' '} {name} {data?.type === 'sample' ? `(${getSamples(data.samples)})` : ''} + {data?.type === 'soundfont' ? `(${data.fonts.length})` : ''} ))} {!soundEntries.length ? 'No custom sounds loaded in this pattern (yet).' : ''} diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index 04ec66a7..b7b848d0 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -13,8 +13,11 @@ export async function prebake() { // https://api.github.com/repositories/126427031/contents/ // LICENSE: CC0 general-purpose samples(`./vcsl.json`, 'github:sgossner/VCSL/master/', { prebake: true }), - samples(`./tidal-drum-machines.json`, 'github:ritchse/tidal-drum-machines/main/machines/', { prebake: true }), - samples(`./EmuSP12.json`, `./EmuSP12/`, { prebake: true }), + samples(`./tidal-drum-machines.json`, 'github:ritchse/tidal-drum-machines/main/machines/', { + prebake: true, + tag: 'drum-machines', + }), + samples(`./EmuSP12.json`, `./EmuSP12/`, { prebake: true, tag: 'drum-machines' }), // samples('github:tidalcycles/Dirt-Samples/master'), ]); } From aad721890addc5235533e6a44df81ac57a87f0da Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 16 Mar 2023 15:48:59 +0100 Subject: [PATCH 22/24] pass duration to source callback --- packages/webaudio/webaudio.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 8b694e93..c75bde0b 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -167,7 +167,7 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => { // get source AudioNode let sourceNode; if (source) { - sourceNode = source(t, hap.value); + sourceNode = source(t, hap.value, hapDuration); } else if (getSound(s)) { const { onTrigger } = getSound(s); const soundHandle = await onTrigger(t, hap.value, onended); From 9f9fe529e409cc8eaf4e298d52f04762cceba7cf Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 16 Mar 2023 15:49:08 +0100 Subject: [PATCH 23/24] fix only tune that uses soundfonts --- website/src/repl/tunes.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/repl/tunes.mjs b/website/src/repl/tunes.mjs index 554fe43c..9a564609 100644 --- a/website/src/repl/tunes.mjs +++ b/website/src/repl/tunes.mjs @@ -566,7 +566,7 @@ samples({ "C^7 Am7 Dm7 G7".slow(2).voicings('lefthand') .stack("0@6 [<1 2> <2 0> 1]@2".scale('C5 major')) .note().slow(4) - .s('0040_FluidR3_GM_sf2_file') + .s("gm_epiano1:1") .color('steelblue') .stack( "<-7 ~@2 [~@2 -7] -9 ~@2 [~@2 -9] -10!2 ~ [~@2 -10] -5 ~ [-3 -2 -10]@2>*2".scale('C3 major') From 58ed51b49c07d2a4e3b6c875d4c391562cad1aa4 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 16 Mar 2023 15:49:56 +0100 Subject: [PATCH 24/24] snapshot --- test/__snapshots__/tunes.test.mjs.snap | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/__snapshots__/tunes.test.mjs.snap b/test/__snapshots__/tunes.test.mjs.snap index 0675938f..261255f0 100644 --- a/test/__snapshots__/tunes.test.mjs.snap +++ b/test/__snapshots__/tunes.test.mjs.snap @@ -8193,11 +8193,11 @@ exports[`renders tunes > tune: orbit 1`] = ` exports[`renders tunes > tune: outroMusic 1`] = ` [ - "[ (0/1 → 1/1) ⇝ 3/1 | note:E3 s:0040_FluidR3_GM_sf2_file attack:0.05 decay:0.1 sustain:0.7 cutoff:1111.7252990603447 gain:0.3 ]", - "[ (0/1 → 1/1) ⇝ 3/1 | note:G3 s:0040_FluidR3_GM_sf2_file attack:0.05 decay:0.1 sustain:0.7 cutoff:1111.7252990603447 gain:0.3 ]", - "[ (0/1 → 1/1) ⇝ 3/1 | note:B3 s:0040_FluidR3_GM_sf2_file attack:0.05 decay:0.1 sustain:0.7 cutoff:1111.7252990603447 gain:0.3 ]", - "[ (0/1 → 1/1) ⇝ 3/1 | note:D4 s:0040_FluidR3_GM_sf2_file attack:0.05 decay:0.1 sustain:0.7 cutoff:1111.7252990603447 gain:0.3 ]", - "[ (0/1 → 1/1) ⇝ 9/2 | note:C5 s:0040_FluidR3_GM_sf2_file attack:0.05 decay:0.1 sustain:0.7 cutoff:1111.7252990603447 gain:0.3 ]", + "[ (0/1 → 1/1) ⇝ 3/1 | note:E3 s:gm_epiano1 n:1 attack:0.05 decay:0.1 sustain:0.7 cutoff:1111.7252990603447 gain:0.3 ]", + "[ (0/1 → 1/1) ⇝ 3/1 | note:G3 s:gm_epiano1 n:1 attack:0.05 decay:0.1 sustain:0.7 cutoff:1111.7252990603447 gain:0.3 ]", + "[ (0/1 → 1/1) ⇝ 3/1 | note:B3 s:gm_epiano1 n:1 attack:0.05 decay:0.1 sustain:0.7 cutoff:1111.7252990603447 gain:0.3 ]", + "[ (0/1 → 1/1) ⇝ 3/1 | note:D4 s:gm_epiano1 n:1 attack:0.05 decay:0.1 sustain:0.7 cutoff:1111.7252990603447 gain:0.3 ]", + "[ (0/1 → 1/1) ⇝ 9/2 | note:C5 s:gm_epiano1 n:1 attack:0.05 decay:0.1 sustain:0.7 cutoff:1111.7252990603447 gain:0.3 ]", "[ 0/1 → 3/4 | note:C2 s:sawtooth attack:0.05 decay:0.1 sustain:0.7 cutoff:864.536878321087 gain:0.3 ]", "[ 0/1 → 3/4 | s:bd speed:0.9107561463868479 n:3 ]", "[ (3/4 → 1/1) ⇝ 3/2 | s:sd speed:0.9931522866332672 n:3 ]",