jevstrudel.git / packages / dough / dough.mjs

dough.mjs Copyright (C) 2022 Strudel contributors - see https://codeberg.org/uzu/strudel/src/branch/main/packages/osc/osc.mjs This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/.

7import { register, noteToMidi } from '@strudel/core';
8import { Dough, doughsamples } from 'dough-synth';
9import { getAudioContext, ensureMinimalOutput } from '@strudel/webaudio';
10import wasm from 'dough-synth/dough.wasm?url';
11import workletCode from 'dough-synth/dough.js?raw';
13Object.assign(globalThis, { doughsamples });
14
15let D;

initializes dough ahead of time. you don't need to use this, but if you do, you can await it, so dough is ready before the pattern starts.

@name initDough @tags external_io @memberof Pattern @example await initDough() $: chord("<Dm9 Dm11 Dm7>").offset("<-1 0 1 0>").voicing() .phaser(3).fm(1.4).fmh(1.01) .dough()

29export function initDough() {
30  if (!D || D.audioContext !== getAudioContext()) {
31    D = new Dough({
32      wasm,
33      workletCode,
34      audioContext: getAudioContext(),
35    });
36  }
37  return D.ready;
38}
40export async function doughTrigger(hap, _currentTime, cps = 1, targetTime) {
41  const offset = D.context_offset?.[0];
42  if (!offset) {
43    return; // not ready
44  }
45  hap.ensureObjectValue();
46  const event = {
47    dough: 'play',
48    ...hap.value,
49    time: targetTime - offset,
50    duration: hap.duration / cps,
51  };
52  if (typeof event.note === 'string') {
53    event.note = noteToMidi(event.note);
54  }
55  D.evaluate(event);
56}

Uses dough as the audio engine. more info at https://dough.strudel.cc

@name dough @tags external_io @memberof Pattern @returns Pattern @example $: chord("<Dm9 Dm11 Dm7>").offset("<-1 0 1 0>").voicing() .phaser(3).fm(1.4).fmh(1.01) .dough()

71export const dough = register('dough', (pat) => {
72  initDough();
73  ensureMinimalOutput();
74  return pat.onTrigger(doughTrigger);
75});