Compare commits

..

11 Commits

Author SHA1 Message Date
alex 9dc19fb9bf Merge branch 'main' into busparts 2025-10-30 21:37:48 +00:00
alex 4a158db9d2 Revert "state twiddles wip"
This reverts commit 55839e7ee8.
2025-10-30 21:28:58 +00:00
alex 55839e7ee8 state twiddles wip 2025-10-26 21:14:11 +00:00
alex 9aaa9bee6b fixes + tidying 2025-10-24 20:51:12 +01:00
alex 1834d689ef fixes + tidying 2025-10-24 20:48:35 +01:00
Alex McLean 77a7a148f0 wip 2025-10-23 21:26:27 +01:00
Alex McLean 52931e879d nearly there 2025-10-23 16:18:47 +01:00
Alex McLean d5c9be1c30 add _processParts() 2025-10-23 15:14:22 +01:00
Alex McLean 2b30ab3008 Merge branch 'main' of ssh://codeberg.org/uzu/strudel into busparts 2025-10-23 14:59:07 +01:00
Alex McLean 13cbeb3f67 wip 2025-10-23 14:58:57 +01:00
alex 352d8659ec wip 2025-10-23 14:02:41 +01:00
9 changed files with 247 additions and 315 deletions
+4 -2
View File
@@ -10,7 +10,7 @@ function getExports(code) {
let ast;
try {
ast = parse(code, {
ecmaVersion: 'latest',
ecmaVersion: 11,
sourceType: 'module',
});
} catch (err) {
@@ -49,7 +49,9 @@ function getExports(code) {
}
function isDocumented(name, docs) {
return docs.find((d) => d.name === name || d.synonyms?.includes(name));
return docs.find(
(d) => d.name === name || d.tags?.find((t) => t.title === 'synonyms' && t.value.split(', ').includes(name)),
);
}
async function getUndocumented(path, docs) {
+9
View File
@@ -72,6 +72,15 @@ export function registerControl(names, ...aliases) {
return bag;
}
// Constructs a superdirt effect bus control
const bus = register('bus', function (busid, control_name, busval, pat) {
return pat[control_name]('c' + busid).withValue((val) => {
const newval = { ...val };
newval['^' + control_name] = [busid, busval];
return newval;
});
});
/**
* Select a sound / sample by name. When using mininotation, you can also optionally supply 'n' and 'gain' parameters
* separated by ':'.
+2 -3
View File
@@ -58,11 +58,10 @@ export class Cyclist {
// query the pattern for events
const haps = this.pattern.queryArc(begin, end, { _cps: this.cps, cyclist: 'cyclist' });
haps.forEach((hap) => {
if (hap.hasOnset()) {
if (hap.hasOnset() || hap.context.processParts) {
const targetTime =
(hap.whole.begin - this.num_cycles_at_cps_change) / this.cps + this.seconds_at_cps_change + latency;
(hap.part.begin - this.num_cycles_at_cps_change) / this.cps + this.seconds_at_cps_change + latency;
const duration = hap.duration / this.cps;
// the following line is dumb and only here for backwards compatibility
// see https://codeberg.org/uzu/strudel/pulls/1004
+5 -1
View File
@@ -16,7 +16,7 @@ export class Hap {
then the whole will be returned as None, in which case the given
value will have been sampled from the point halfway between the
start and end of the 'part' timespan.
The context is to store a list of source code locations causing the event.
The context is to store metadata, including a list of source code locations causing the event.
The word 'Event' is more or less a reserved word in javascript, hence this
class is named called 'Hap'.
@@ -161,6 +161,10 @@ export class Hap {
return new Hap(this.whole, this.part, this.value, context);
}
withContext(f) {
return new Hap(this.whole, this.part, this.value, f(this.context));
}
ensureObjectValue() {
/* if (isNote(hap.value)) {
// supports primitive hap values that look like notes
+5 -2
View File
@@ -62,7 +62,12 @@ export class Pattern {
this.__steps = steps === undefined ? undefined : Fraction(steps);
}
_processParts() {
return this.withHap((hap) => hap.withContext((c) => ({ ...c, processParts: true })));
}
setSteps(steps) {
// TODO shouldn't this be pure and return a new pattern?
this._steps = steps;
return this;
}
@@ -3289,7 +3294,6 @@ export const striate = register('striate', function (n, pat) {
/**
* Makes the sample fit the given number of cycles by changing the speed.
* @name loopAt
* @synonyms loopat
* @memberof Pattern
* @returns Pattern
* @example
@@ -3422,7 +3426,6 @@ export const fit = register('fit', (pat) =>
* given by a global clock and this function will be
* deprecated/removed.
* @name loopAtCps
* @synonyms loopatcps
* @memberof Pattern
* @returns Pattern
* @example
+7 -37
View File
@@ -10,27 +10,11 @@ import Fraction from './fraction.mjs';
import { id, keyAlias, getCurrentKeyboardState } from './util.mjs';
/**
* A `signal` consisting of a constant value. Similar to `pure`, except that function
* creates a pattern with one event per cycle, whereas this pattern doesn't have an intrinsic
* structure.
*
* @param {*} value The constant value of the resulting pattern
* @returns Pattern
*/
export function steady(value) {
// A continuous value
return new Pattern((state) => [new Hap(undefined, state.span, value)]);
}
/**
* Creates a "signal", an unstructured pattern consisting of a single value that changes
* over time.
*
*
* @param {*} func
* @returns Pattern
*/
export const signal = (func) => {
const query = (state) => [new Hap(undefined, state.span, func(state.span.begin))];
return new Pattern(query);
@@ -39,7 +23,7 @@ export const signal = (func) => {
/**
* A sawtooth signal between 0 and 1.
*
* @type {Pattern}
* @return {Pattern}
* @example
* note("<c3 [eb3,g3] g2 [g3,bb3]>*8")
* .clip(saw.slow(2))
@@ -173,7 +157,6 @@ export const time = signal(id);
/**
* The mouse's x position value ranges from 0 to 1.
* @name mousex
* @synonyms mouseX
* @return {Pattern}
* @example
* n(mousex.segment(4).range(0,7)).scale("C:minor")
@@ -183,7 +166,6 @@ export const time = signal(id);
/**
* The mouse's y position value ranges from 0 to 1.
* @name mousey
* @synonyms mouseY
* @return {Pattern}
* @example
* n(mousey.segment(4).range(0,7)).scale("C:minor")
@@ -233,6 +215,10 @@ const timeToRandsPrime = (seed, n) => {
const timeToRands = (t, n) => timeToRandsPrime(timeToIntSeed(t), n);
/**
*
*/
/**
* A discrete pattern of numbers from 0 to n-1
* @example
@@ -403,22 +389,16 @@ export const chooseInWith = (pat, xs) => {
/**
* Chooses randomly from the given list of elements.
* @synonyms chooseOut
* @param {...any} xs values / patterns to choose from.
* @returns {Pattern} - a continuous pattern.
* @example
* note("c2 g2!2 d2 f1").s(choose("sine", "triangle", "bd:6"))
*/
export const choose = (...xs) => chooseWith(rand, xs);
export const chooseOut = choose;
/**
* As with {choose}, but the structure comes from the chosen values, rather
* than the pattern you're using to choose with.
* @param {...any} xs
* @returns
*/
// todo: doc
export const chooseIn = (...xs) => chooseInWith(rand, xs);
export const chooseOut = choose;
/**
* Chooses from the given list of values (or patterns of values), according
@@ -516,7 +496,6 @@ function _perlin(t) {
const v = interp(t - ta)(timeToRand(ta))(timeToRand(tb));
return v;
}
export const perlinWith = (tpat) => {
return tpat.fmap(_perlin);
};
@@ -562,15 +541,6 @@ export const perlin = perlinWith(time.fmap((v) => Number(v)));
*/
export const berlin = berlinWith(time.fmap((v) => Number(v)));
/**
* Removes events from a pattern given a signal of numbers and a cutoff
* value for interpreting that pattern as true or false.
* @param {number} withPat - A numeric pattern for comparing the main pattern
* against. Values higher than the cutoff will let events through and lower
* values will remove events from the main pattern
* @param {number} cutoff - The threshold value to use when interpreting the
* `withPat`
*/
export const degradeByWith = register(
'degradeByWith',
(withPat, x, pat) => pat.fmap((a) => (_) => a).appLeft(withPat.filterValues((v) => v > x)),
+35 -7
View File
@@ -52,6 +52,7 @@ export function parseControlsFromHap(hap, cps) {
controls.unit === 'c' && controls.speed != null && (controls.speed = controls.speed / cps);
const channels = controls.channels;
channels != undefined && (controls.channels = JSON.stringify(channels));
return controls;
}
@@ -63,16 +64,42 @@ export async function oscTrigger(hap, currentTime, cps = 1, targetTime) {
const keyvals = Object.entries(controls).flat();
const ts = collator.calculateTimestamp(currentTime, targetTime) * 1000;
const msg = { address: '/dirt/play', args: keyvals, timestamp: ts };
if ('oschost' in hap.value) {
msg['host'] = hap.value['oschost'];
}
if ('oscport' in hap.value) {
msg['port'] = hap.value['oscport'];
}
ws.send(JSON.stringify(msg));
}
export async function superdirtTrigger(hap, currentTime, cps = 1, targetTime) {
const ws = await connect();
const controls = parseControlsFromHap(hap, cps);
const ts = collator.calculateTimestamp(currentTime, targetTime) * 1000;
let oschost = '127.0.0.1';
let oscport = 57120;
let bushost = oschost;
let busport = 57110;
for (const [k, v] of Object.entries(controls)) {
if (k.startsWith('^')) {
const bus_idval = v;
const msg = JSON.stringify({
oschost: bushost,
oscport: busport,
address: '/c_set',
args: bus_idval,
timestamp: ts,
});
// console.log('bus message', msg);
ws.send(msg);
// So they aren't sent with trigger messages
delete controls[k];
}
}
if (hap.hasOnset()) {
const keyvals = Object.entries(controls).flat();
ws.send(JSON.stringify({ oschost, oscport, address: '/dirt/play', args: keyvals, timestamp: ts }));
}
}
/**
*
* Sends each hap as an OSC message, which can be picked up by SuperCollider or any other OSC-enabled software.
@@ -83,3 +110,4 @@ export async function oscTrigger(hap, currentTime, cps = 1, targetTime) {
* @returns Pattern
*/
export const osc = register('osc', (pat) => pat.onTrigger(oscTrigger));
export const superdirt = register('superdirt', (pat) => pat._processParts().onTrigger(superdirtTrigger));
+9 -13
View File
@@ -12,18 +12,13 @@ import { WebSocketServer } from 'ws';
import osc from 'osc';
const WS_PORT = 8080; // WebSocket server port
const OSC_REMOTE_IP = '127.0.0.1';
const OSC_REMOTE_PORT = 57120;
const udpPort = new osc.UDPPort({
localAddress: '0.0.0.0',
localPort: 0,
remoteAddress: OSC_REMOTE_IP,
remotePort: OSC_REMOTE_PORT,
});
udpPort.open();
console.log(`[Sending OSC] ${OSC_REMOTE_IP}:${OSC_REMOTE_PORT}`);
udpPort.on('error', (e) => {
console.log('Error: ', e);
@@ -36,23 +31,24 @@ wss.on('connection', (ws) => {
console.log('New WebSocket connection');
ws.on('message', (message) => {
let osc_host = '127.0.0.1';
let osc_port = 57120;
let oschost = '127.0.0.1';
let oscport = 57120;
try {
const data = JSON.parse(message);
if ('host' in data) {
osc_host = data['host'];
if ('oschost' in data) {
oschost = data['oschost'];
delete data['oschost'];
}
if ('port' in data) {
osc_port = data['port'];
if ('oscport' in data) {
oscport = data['oscport'];
delete data['oscport'];
}
let msg = { address: data['address'], args: data['args'] };
if ('timestamp' in data) {
msg = { timeTag: osc.timeTag(0, data['timestamp']), packets: [msg] };
}
udpPort.send(msg, osc_host, osc_port);
udpPort.send(msg, oschost, oscport);
} catch (err) {
console.error('Error parsing message:', err);
}
+171 -250
View File
@@ -32,12 +32,7 @@
"/packages/codemirror/keybindings.mjs": [
"keybindings"
],
"/packages/codemirror/themes/theme-helper.mjs": [
"createTheme"
],
"/packages/codemirror/themes/strudel-theme.mjs": [
"settings"
],
"/packages/codemirror/themes/strudel-theme.mjs": [],
"/packages/codemirror/themes/bluescreen.mjs": [
"settings"
],
@@ -53,103 +48,7 @@
"/packages/codemirror/themes/algoboy.mjs": [
"settings"
],
"/packages/codemirror/themes/CutiePi.mjs": [
"settings"
],
"/packages/codemirror/themes/sonic-pink.mjs": [
"settings"
],
"/packages/codemirror/themes/red-text.mjs": [
"settings"
],
"/packages/codemirror/themes/green-text.mjs": [
"settings"
],
"/packages/codemirror/themes/archBtw.mjs": [
"settings"
],
"/packages/codemirror/themes/fruitDaw.mjs": [
"settings"
],
"/packages/codemirror/themes/bluescreenlight.mjs": [
"settings"
],
"/packages/codemirror/themes/androidstudio.mjs": [
"settings"
],
"/packages/codemirror/themes/atomone.mjs": [
"settings"
],
"/packages/codemirror/themes/aura.mjs": [
"settings"
],
"/packages/codemirror/themes/darcula.mjs": [
"settings"
],
"/packages/codemirror/themes/dracula.mjs": [
"settings"
],
"/packages/codemirror/themes/duotoneDark.mjs": [
"settings"
],
"/packages/codemirror/themes/eclipse.mjs": [
"settings"
],
"/packages/codemirror/themes/githubDark.mjs": [
"settings"
],
"/packages/codemirror/themes/githubLight.mjs": [
"settings"
],
"/packages/codemirror/themes/gruvboxDark.mjs": [
"settings"
],
"/packages/codemirror/themes/gruvboxLight.mjs": [
"settings"
],
"/packages/codemirror/themes/materialDark.mjs": [
"settings"
],
"/packages/codemirror/themes/materialLight.mjs": [
"settings"
],
"/packages/codemirror/themes/nord.mjs": [
"settings"
],
"/packages/codemirror/themes/monokai.mjs": [
"settings"
],
"/packages/codemirror/themes/solarizedDark.mjs": [
"settings"
],
"/packages/codemirror/themes/solarizedLight.mjs": [
"settings"
],
"/packages/codemirror/themes/sublime.mjs": [
"settings"
],
"/packages/codemirror/themes/tokyoNight.mjs": [
"settings"
],
"/packages/codemirror/themes/tokioNightStorm.mjs": [
"settings"
],
"/packages/codemirror/themes/tokyoNightDay.mjs": [
"settings"
],
"/packages/codemirror/themes/vscodeDark.mjs": [
"settings"
],
"/packages/codemirror/themes/vscodeLight.mjs": [
"settings"
],
"/packages/codemirror/themes/xcodeLight.mjs": [
"settings"
],
"/packages/codemirror/themes/bbedit.mjs": [
"settings"
],
"/packages/codemirror/themes/noctisLilac.mjs": [
"/packages/codemirror/themes/terminal.mjs": [
"settings"
],
"/packages/codemirror/themes.mjs": [
@@ -162,12 +61,7 @@
"activateTheme"
],
"/packages/codemirror/slider.mjs": [
"sliderValues",
"SliderWidget",
"setSliderWidgets",
"updateSliderWidgets",
"sliderPlugin",
"sliderWithID"
"acorn parse error: SyntaxError: undefined"
],
"/packages/codemirror/widget.mjs": [
"addWidget",
@@ -184,59 +78,6 @@
"StrudelMirror"
],
"/packages/codemirror/index.mjs": [],
"/packages/core/logger.mjs": [
"logKey",
"errorLogger",
"logger"
],
"/packages/core/util.mjs": [
"isNoteWithOctave",
"isNote",
"tokenizeNote",
"noteToMidi",
"midiToFreq",
"freqToMidi",
"valueToMidi",
"getEventOffsetMs",
"_mod",
"averageArray",
"nanFallback",
"getSoundIndex",
"getPlayableNoteValue",
"getFrequency",
"rotate",
"pipe",
"compose",
"flatten",
"id",
"constant",
"listRange",
"curry",
"parseNumeral",
"mapArgs",
"numeralArgs",
"parseFractional",
"fractionalArgs",
"splitAt",
"zipWith",
"pairs",
"clamp",
"sol2note",
"uniq",
"uniqsort",
"uniqsortr",
"unicodeToBase64",
"base64ToUnicode",
"code2hash",
"hash2code",
"objectMap",
"cycleToSeconds",
"ClockCollator",
"getPerformanceTimeSeconds",
"keyAlias",
"getCurrentKeyboardState",
"stringifyValues"
],
"/packages/core/fraction.mjs": [
"gcd",
"lcm"
@@ -250,6 +91,45 @@
"/packages/core/state.mjs": [
"State"
],
"/packages/core/logger.mjs": [
"logKey",
"logger"
],
"/packages/core/util.mjs": [
"isNoteWithOctave",
"isNote",
"tokenizeNote",
"noteToMidi",
"midiToFreq",
"freqToMidi",
"valueToMidi",
"_mod",
"nanFallback",
"getSoundIndex",
"getPlayableNoteValue",
"getFrequency",
"rotate",
"pipe",
"compose",
"flatten",
"constant",
"listRange",
"curry",
"parseNumeral",
"mapArgs",
"numeralArgs",
"parseFractional",
"fractionalArgs",
"splitAt",
"zipWith",
"clamp",
"sol2note",
"unicodeToBase64",
"base64ToUnicode",
"code2hash",
"hash2code",
"objectMap"
],
"/packages/core/value.mjs": [
"unionWithObj",
"valued",
@@ -258,8 +138,10 @@
],
"/packages/core/drawLine.mjs": [],
"/packages/core/pattern.mjs": [
"calculateSteps",
"setStringParser",
"polyrhythm",
"pr",
"pm",
"nothing",
"isPattern",
"reify",
@@ -267,12 +149,8 @@
"stackRight",
"stackCentre",
"stackBy",
"bind",
"innerBind",
"outerBind",
"squeezeBind",
"stepBind",
"polyBind",
"fastcat",
"_polymeterListSteps",
"set",
"keep",
"keepif",
@@ -296,51 +174,96 @@
"func",
"compressSpan",
"compressspan",
"fastgap",
"focusSpan",
"focusspan",
"density",
"sparsity",
"zoomArc",
"zoomarc",
"inv",
"juxby",
"echowith",
"stutWith",
"stutwith",
"iterback",
"slowchunk",
"slowChunk",
"chunkback",
"fastchunk",
"bypass",
"hsla",
"hsl",
"_retime",
"_slices",
"_fitslice",
"_match",
"_polymeterListSteps",
"shrinklist",
"s_cat",
"s_alt",
"s_polymeter",
"s_taper",
"s_taperlist",
"s_add",
"s_sub",
"s_expand",
"s_extend",
"s_contract",
"s_tour",
"s_zip",
"steps",
"_morph"
"loopat",
"loopatcps"
],
"/packages/core/controls.mjs": [
"createParam",
"isControlName",
"registerControl",
"sound",
"src",
"att",
"fmi",
"fmrelease",
"fmvelocity",
"analyze",
"fft",
"dec",
"sus",
"rel",
"hold",
"duck",
"bandf",
"bp",
"bandq",
"loopb",
"loope",
"ch",
"phaserrate",
"phasr",
"ph",
"phs",
"phc",
"phd",
"phasdp",
"cutoff",
"ctf",
"lp",
"lpe",
"hpe",
"bpe",
"lpa",
"hpa",
"bpa",
"lpd",
"hpd",
"bpd",
"lps",
"hps",
"bps",
"lpr",
"hpr",
"bpr",
"fanchor",
"vibrato",
"v",
"vmod",
"hcutoff",
"hp",
"hresonance",
"resonance",
"delayfb",
"dfb",
"delayt",
"dt",
"lock",
"det",
"fadeTime",
"fadeOutTime",
"fadeInTime",
"patt",
"pdec",
"psustain",
"psus",
"prel",
"gate",
"gat",
"activeLabel",
@@ -368,13 +291,26 @@
"offset",
"octaves",
"mode",
"rlp",
"rdim",
"rfade",
"ir",
"size",
"sz",
"rsize",
"dist",
"compressorKnee",
"compressorRatio",
"compressorAttack",
"compressorRelease",
"waveloss",
"density",
"expression",
"sustainpedal",
"tremolodepth",
"tremdp",
"tremolorate",
"tremr",
"fshift",
"fshiftnote",
"fshiftphase",
@@ -400,15 +336,27 @@
"binshift",
"hbrick",
"lbrick",
"midichan",
"control",
"ccn",
"ccv",
"polyTouch",
"midibend",
"miditouch",
"ctlNum",
"frameRate",
"frames",
"hours",
"midicmd",
"minutes",
"progNum",
"seconds",
"songPtr",
"uid",
"val",
"cps",
"legato",
"dur",
"zrand",
"curve",
"deltaSlide",
@@ -420,40 +368,44 @@
"zmod",
"zcrush",
"zdelay",
"tremolo",
"zzfx",
"colour",
"createParams",
"ad",
"ds",
"ar",
"midimap",
"ctlNum",
"polyTouch",
"getControlName"
"ar"
],
"/packages/core/euclid.mjs": [
"bjork",
"e",
"euclidrot"
],
"/packages/core/zyklus.mjs": [],
"/packages/core/signal.mjs": [
"randrun",
"steady",
"signal",
"isaw",
"isaw2",
"saw2",
"sine2",
"cosine2",
"square2",
"tri2",
"time",
"_brandBy",
"_irand",
"pickSqueeze",
"pickmodSqueeze",
"__chooseWith",
"chooseIn",
"chooseOut",
"randcat",
"wrandcat",
"perlinWith",
"berlinWith",
"degradeByWith",
"_keyDown"
"degradeByWith"
],
"/packages/core/pick.mjs": [],
"/packages/core/speak.mjs": [
"speak"
],
"/packages/core/evaluate.mjs": [
"strudelScope",
"evalScope",
"evaluate"
],
@@ -488,18 +440,13 @@
"isTauri"
],
"/packages/desktopbridge/midibridge.mjs": [],
"/packages/desktopbridge/oscbridge.mjs": [
"oscTriggerTauri"
],
"/packages/desktopbridge/oscbridge.mjs": [],
"/packages/desktopbridge/index.mjs": [],
"/packages/draw/draw.mjs": [
"getDrawContext",
"cleanupDraw",
"Framer",
"Drawer",
"getComputedPropertyValue",
"getTheme",
"setTheme"
"Drawer"
],
"/packages/draw/animate.mjs": [
"x",
@@ -520,19 +467,16 @@
"convertHexToNumber"
],
"/packages/draw/pianoroll.mjs": [
"__pianoroll",
"getDrawOptions",
"getPunchcardPainter",
"drawPianoroll"
],
"/packages/draw/spiral.mjs": [],
"/packages/draw/pitchwheel.mjs": [],
"/packages/draw/index.mjs": [],
"/packages/midi/midi.mjs": [
"WebMidi",
"enableWebMidi",
"midicontrolMap",
"midisoundMap"
"midin"
],
"/packages/midi/index.mjs": [],
"/packages/mini/krill-parser.js": [],
@@ -552,11 +496,12 @@
"/packages/repl/prebake.mjs": [
"prebake"
],
"/packages/repl/repl-component.mjs": [],
"/packages/repl/repl-component.mjs": [
"acorn parse error: SyntaxError: undefined"
],
"/packages/repl/index.mjs": [],
"/packages/soundfonts/gm.mjs": [],
"/packages/soundfonts/fontloader.mjs": [
"setSoundfontUrl",
"getFontBufferSource",
"getFontPitch",
"registerSoundfonts"
@@ -577,7 +522,6 @@
"vowelFormant"
],
"/packages/superdough/logger.mjs": [
"errorLogger",
"logger",
"setLogger"
],
@@ -590,19 +534,10 @@
"valueToMidi",
"nanFallback",
"_mod",
"getSoundIndex",
"cycleToSeconds",
"secondsToCycle"
],
"/packages/superdough/noise.mjs": [
"getNoiseBuffer",
"getNoiseOscillator",
"getNoiseMix"
"getSoundIndex"
],
"/packages/superdough/helpers.mjs": [
"noises",
"gainNode",
"getWorklet",
"getParamADSR",
"getCompressor",
"getADSRValues",
@@ -615,8 +550,6 @@
],
"/packages/superdough/sampler.mjs": [
"getCachedBuffer",
"getSampleInfo",
"getSampleBuffer",
"getSampleBufferSource",
"loadBuffer",
"reverseBuffer",
@@ -626,32 +559,18 @@
"onTriggerSample"
],
"/packages/superdough/superdough.mjs": [
"DEFAULT_MAX_POLYPHONY",
"setMaxPolyphony",
"setMultiChannelOrbits",
"soundMap",
"registerSound",
"applyGainCurve",
"setGainCurve",
"getSound",
"getAudioDevices",
"setDefault",
"resetDefaults",
"setDefaultValue",
"getDefaultValue",
"setDefaultValues",
"resetDefaultValues",
"setVersionDefaults",
"resetLoadedSounds",
"setDefaultAudioContext",
"getAudioContext",
"getAudioContextCurrentTime",
"getWorklet",
"initAudio",
"initAudioOnFirstClick",
"initializeAudioOutput",
"connectToDestination",
"panic",
"getLfo",
"analysers",
"analysersData",
"getAnalyserById",
@@ -660,13 +579,17 @@
"superdough",
"superdoughTrigger"
],
"/packages/superdough/noise.mjs": [
"getNoiseOscillator",
"getNoiseMix"
],
"/packages/superdough/synth.mjs": [
"registerSynthSounds",
"waveformN",
"getOscillator"
],
"/packages/superdough/zzfx_fork.mjs": [
"buildSamples"
"acorn parse error: SyntaxError: undefined"
],
"/packages/superdough/zzfx.mjs": [
"getZZFX",
@@ -717,7 +640,6 @@
],
"/packages/transpiler/transpiler.mjs": [
"registerWidgetType",
"registerLanguage",
"transpiler",
"getWidgetID"
],
@@ -732,7 +654,6 @@
"drawTimeScope",
"drawFrequencyScope"
],
"/packages/webaudio/spectrum.mjs": [],
"/packages/webaudio/index.mjs": [],
"/packages/xen/xen.mjs": [
"edo",