mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-11 13:48:34 +00:00
Merge pull request #1245 from TodePond/lu/add-drum-suffixes
Add bank aliasing and case insensitivity
This commit is contained in:
commit
3d37478577
@ -11,3 +11,5 @@ pnpm-lock.yaml
|
|||||||
pnpm-workspace.yaml
|
pnpm-workspace.yaml
|
||||||
**/dev-dist
|
**/dev-dist
|
||||||
website/.astro
|
website/.astro
|
||||||
|
!tidal-drum-machines.json
|
||||||
|
!tidal-drum-machines-alias.json
|
||||||
|
|||||||
@ -94,3 +94,15 @@ or
|
|||||||
The `.editor` property on the `strudel-editor` web component gives you the instance of [StrudelMirror](https://github.com/tidalcycles/strudel/blob/a46bd9b36ea7d31c9f1d3fca484297c7da86893f/packages/codemirror/codemirror.mjs#L124) that runs the REPL.
|
The `.editor` property on the `strudel-editor` web component gives you the instance of [StrudelMirror](https://github.com/tidalcycles/strudel/blob/a46bd9b36ea7d31c9f1d3fca484297c7da86893f/packages/codemirror/codemirror.mjs#L124) that runs the REPL.
|
||||||
|
|
||||||
For example, you could use `setCode` to change the code from the outside, `start` / `stop` to toggle playback or `evaluate` to evaluate the code.
|
For example, you could use `setCode` to change the code from the outside, `start` / `stop` to toggle playback or `evaluate` to evaluate the code.
|
||||||
|
|
||||||
|
## Development: How to Test
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd packages/repl
|
||||||
|
pnpm build
|
||||||
|
cd ../.. # back to root folder
|
||||||
|
# edit ./examples/buildless/web-component-no-iframe.html
|
||||||
|
# use <script src="/packages/repl/dist/index.js"></script>
|
||||||
|
pnpx serve # from root folder
|
||||||
|
# go to http://localhost:3000/examples/buildless/web-component-no-iframe
|
||||||
|
```
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { noteToMidi, valueToMidi, Pattern, evalScope } from '@strudel/core';
|
import { noteToMidi, valueToMidi, Pattern, evalScope } from '@strudel/core';
|
||||||
import { registerSynthSounds, registerZZFXSounds, samples } from '@strudel/webaudio';
|
import { aliasBank, registerSynthSounds, registerZZFXSounds, samples } from '@strudel/webaudio';
|
||||||
import * as core from '@strudel/core';
|
import * as core from '@strudel/core';
|
||||||
|
|
||||||
export async function prebake() {
|
export async function prebake() {
|
||||||
@ -21,6 +21,9 @@ export async function prebake() {
|
|||||||
);
|
);
|
||||||
// load samples
|
// load samples
|
||||||
const ds = 'https://raw.githubusercontent.com/felixroos/dough-samples/main/';
|
const ds = 'https://raw.githubusercontent.com/felixroos/dough-samples/main/';
|
||||||
|
|
||||||
|
// TODO: move this onto the strudel repo
|
||||||
|
const ts = 'https://raw.githubusercontent.com/todepond/samples/main/';
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
modulesLoading,
|
modulesLoading,
|
||||||
registerSynthSounds(),
|
registerSynthSounds(),
|
||||||
@ -36,6 +39,8 @@ export async function prebake() {
|
|||||||
samples(`${ds}/EmuSP12.json`),
|
samples(`${ds}/EmuSP12.json`),
|
||||||
samples(`${ds}/vcsl.json`),
|
samples(`${ds}/vcsl.json`),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
aliasBank(`${ts}/tidal-drum-machines-alias.json`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxPan = noteToMidi('C8');
|
const maxPan = noteToMidi('C8');
|
||||||
|
|||||||
@ -17,11 +17,72 @@ import { loadBuffer } from './sampler.mjs';
|
|||||||
export const soundMap = map();
|
export const soundMap = map();
|
||||||
|
|
||||||
export function registerSound(key, onTrigger, data = {}) {
|
export function registerSound(key, onTrigger, data = {}) {
|
||||||
soundMap.setKey(key, { onTrigger, data });
|
soundMap.setKey(key.toLowerCase(), { onTrigger, data });
|
||||||
|
}
|
||||||
|
|
||||||
|
function aliasBankMap(aliasMap) {
|
||||||
|
// Make all bank keys lower case for case insensitivity
|
||||||
|
for (const key in aliasMap) {
|
||||||
|
aliasMap[key.toLowerCase()] = aliasMap[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look through every sound...
|
||||||
|
const soundDictionary = soundMap.get();
|
||||||
|
for (const key in soundDictionary) {
|
||||||
|
// Check if the sound is part of a bank...
|
||||||
|
const [bank, suffix] = key.split('_');
|
||||||
|
if (!suffix) continue;
|
||||||
|
|
||||||
|
// Check if the bank is aliased...
|
||||||
|
const aliasValue = aliasMap[bank];
|
||||||
|
if (aliasValue) {
|
||||||
|
if (typeof aliasValue === 'string') {
|
||||||
|
// Alias a single alias
|
||||||
|
soundDictionary[`${aliasValue}_${suffix}`.toLowerCase()] = soundDictionary[key];
|
||||||
|
} else if (Array.isArray(aliasValue)) {
|
||||||
|
// Alias multiple aliases
|
||||||
|
for (const alias of aliasValue) {
|
||||||
|
soundDictionary[`${alias}_${suffix}`.toLowerCase()] = soundDictionary[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the sound map!
|
||||||
|
// We need to destructure here to trigger the update
|
||||||
|
soundMap.set({ ...soundDictionary });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function aliasBankPath(path) {
|
||||||
|
const response = await fetch(path);
|
||||||
|
const aliasMap = await response.json();
|
||||||
|
aliasBankMap(aliasMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an alias for a bank of sounds.
|
||||||
|
* Optionally accepts a single argument map of bank aliases.
|
||||||
|
* Optionally accepts a single argument string of a path to a JSON file containing bank aliases.
|
||||||
|
* @param {string} bank - The bank to alias
|
||||||
|
* @param {string} alias - The alias to use for the bank
|
||||||
|
*/
|
||||||
|
export async function aliasBank(...args) {
|
||||||
|
switch (args.length) {
|
||||||
|
case 1:
|
||||||
|
if (typeof args[0] === 'string') {
|
||||||
|
return aliasBankPath(args[0]);
|
||||||
|
} else {
|
||||||
|
return aliasBankMap(args[0]);
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
return aliasBankMap({ [args[0]]: args[1] });
|
||||||
|
default:
|
||||||
|
throw new Error('aliasMap expects 1 or 2 arguments, received ' + args.length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getSound(s) {
|
export function getSound(s) {
|
||||||
return soundMap.get()[s];
|
return soundMap.get()[s.toLowerCase()];
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultDefaultValues = {
|
const defaultDefaultValues = {
|
||||||
|
|||||||
68
website/public/tidal-drum-machines-alias.json
Normal file
68
website/public/tidal-drum-machines-alias.json
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"AJKPercusyn": "Percysyn",
|
||||||
|
"AkaiLinn": "Linn",
|
||||||
|
"AkaiMPC60": "MPC60",
|
||||||
|
"AkaiXR10": "XR10",
|
||||||
|
"AlesisHR16": "HR16",
|
||||||
|
"AlesisSR16": "SR16",
|
||||||
|
"BossDR110": "DR110",
|
||||||
|
"BossDR220": "DR220",
|
||||||
|
"BossDR55": "DR55",
|
||||||
|
"BossDR550": "DR550",
|
||||||
|
"CasioRZ1": "RZ1",
|
||||||
|
"CasioSK1": "SK1",
|
||||||
|
"CasioVL1": "VL1",
|
||||||
|
"DoepferMS404": "MS404",
|
||||||
|
"EmuDrumulator": "Drumulator",
|
||||||
|
"EmuSP12": "SP12",
|
||||||
|
"KorgDDM110": "DDM110",
|
||||||
|
"KorgKPR77": "KPR77",
|
||||||
|
"KorgKR55": "KR55",
|
||||||
|
"KorgKRZ": "KRZ",
|
||||||
|
"KorgM1": "M1",
|
||||||
|
"KorgMinipops": "Minipops",
|
||||||
|
"KorgPoly800": "Poly800",
|
||||||
|
"KorgT3": "T3",
|
||||||
|
"Linn9000": "9000",
|
||||||
|
"LinnLM1": "LM1",
|
||||||
|
"LinnLM2": "LM2",
|
||||||
|
"MoogConcertMateMG1": "ConcertMateMG1",
|
||||||
|
"OberheimDMX": "DMX",
|
||||||
|
"RhodesPolaris": "Polaris",
|
||||||
|
"RhythmAce": "Ace",
|
||||||
|
"RolandCompurhythm1000": "Compurhythm1000",
|
||||||
|
"RolandCompurhythm78": "Compurhythm78",
|
||||||
|
"RolandCompurhythm8000": "Compurhythm8000",
|
||||||
|
"RolandD110": "D110",
|
||||||
|
"RolandD70": "D70",
|
||||||
|
"RolandDDR30": "DDR30",
|
||||||
|
"RolandJD990": "JD990",
|
||||||
|
"RolandMC202": "MC202",
|
||||||
|
"RolandMC303": "MC303",
|
||||||
|
"RolandMT32": "MT32",
|
||||||
|
"RolandR8": "R8",
|
||||||
|
"RolandS50": "S50",
|
||||||
|
"RolandSH09": "SH09",
|
||||||
|
"RolandSystem100": "System100",
|
||||||
|
"RolandTR505": "TR505",
|
||||||
|
"RolandTR606": "TR606",
|
||||||
|
"RolandTR626": "TR626",
|
||||||
|
"RolandTR707": "TR707",
|
||||||
|
"RolandTR727": "TR727",
|
||||||
|
"RolandTR808": "TR808",
|
||||||
|
"RolandTR909": "TR909",
|
||||||
|
"SakataDPM48": "DPM48",
|
||||||
|
"SequentialCircuitsDrumtracks": "CircuitsDrumtracks",
|
||||||
|
"SequentialCircuitsTom": "CircuitsTom",
|
||||||
|
"SimmonsSDS400": "SDS400",
|
||||||
|
"SimmonsSDS5": "SDS5",
|
||||||
|
"SoundmastersR88": "R88",
|
||||||
|
"UnivoxMicroRhythmer12": "MicroRhythmer12",
|
||||||
|
"ViscoSpaceDrum": "SpaceDrum",
|
||||||
|
"XdrumLM8953": "LM8953",
|
||||||
|
"YamahaRM50": "RM50",
|
||||||
|
"YamahaRX21": "RX21",
|
||||||
|
"YamahaRX5": "RX5",
|
||||||
|
"YamahaRY30": "RY30",
|
||||||
|
"YamahaTG33": "TG33"
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import { Pattern, noteToMidi, valueToMidi } from '@strudel/core';
|
import { Pattern, noteToMidi, valueToMidi } from '@strudel/core';
|
||||||
import { registerSynthSounds, registerZZFXSounds, samples } from '@strudel/webaudio';
|
import { aliasBank, registerSynthSounds, registerZZFXSounds, samples } from '@strudel/webaudio';
|
||||||
import { registerSamplesFromDB } from './idbutils.mjs';
|
import { registerSamplesFromDB } from './idbutils.mjs';
|
||||||
import './piano.mjs';
|
import './piano.mjs';
|
||||||
import './files.mjs';
|
import './files.mjs';
|
||||||
@ -121,6 +121,8 @@ export async function prebake() {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
aliasBank(`${baseNoTrailing}/tidal-drum-machines-alias.json`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxPan = noteToMidi('C8');
|
const maxPan = noteToMidi('C8');
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user