jevstrudel.git / packages / repl / prebake.mjs
1import { noteToMidi, valueToMidi, Pattern, evalScope } from '@strudel/core';
2import { aliasBank, registerSynthSounds, registerZZFXSounds, samples } from '@strudel/webaudio';
3import * as core from '@strudel/core';
4
5export async function prebake() {
6  const modulesLoading = evalScope(
7    // import('@strudel/core'),
8    core,
9    import('@strudel/draw'),
10    import('@strudel/mini'),
11    import('@strudel/edo'),
12    import('@strudel/tonal'),
13    import('@strudel/webaudio'),
14    import('@strudel/codemirror'),
15    import('@strudel/hydra'),
16    import('@strudel/soundfonts'),
17    import('@strudel/midi'),
18    // import('@strudel/xen'),
19    // import('@strudel/serial'),
20    // import('@strudel/csound'),
21    // import('@strudel/osc'),
22  );
23  // load samples
24  const ds = 'https://raw.githubusercontent.com/felixroos/dough-samples/main';
25
26  // TODO: move this onto the strudel repo
27  const ts = 'https://raw.githubusercontent.com/todepond/samples/main';
28
29  const tc = 'https://raw.githubusercontent.com/tidalcycles/uzu-drumkit/main';
30
31  await Promise.all([
32    modulesLoading,
33    registerSynthSounds(),
34    registerZZFXSounds(),
35    //registerSoundfonts(),
36    // need dynamic import here, because importing @strudel/soundfonts fails on server:
37    // => getting "window is not defined", as soon as "@strudel/soundfonts" is imported statically
38    // seems to be a problem with soundfont2
39    import('@strudel/soundfonts').then(({ registerSoundfonts }) => registerSoundfonts()),
40    samples(`${ds}/tidal-drum-machines.json`),
41    samples(`${ds}/piano.json`),
42    samples(`${ds}/Dirt-Samples.json`),
43    samples(`${ds}/vcsl.json`),
44    samples(`${ds}/mridangam.json`),
45    samples(`${tc}/strudel.json`),
46  ]);
47
48  aliasBank(`${ts}/tidal-drum-machines-alias.json`);
49}
50
51const maxPan = noteToMidi('C8');
52const panwidth = (pan, width) => pan * width + (1 - width) / 2;
53
54Pattern.prototype.piano = function () {
55  return this.fmap((v) => ({ ...v, clip: v.clip ?? 1 })) // set clip if not already set..
56    .s('piano')
57    .release(0.1)
58    .fmap((value) => {
59      const midi = valueToMidi(value);
60      // pan by pitch
61      const pan = panwidth(Math.min(Math.round(midi) / maxPan, 1), 0.5);
62      return { ...value, pan: (value.pan || 1) * pan };
63    });
64};