mirror of
https://codeberg.org/uzu/strudel
synced 2026-07-17 16:16:09 -04:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d198910a86 | |||
| 8ce6a881e6 | |||
| 7bc8576a68 | |||
| bbe95b3995 | |||
| 2dc921e375 | |||
| 3d13955c41 | |||
| ae9638c353 | |||
| 97cd3a5946 | |||
| ca3452bf52 | |||
| 7f528870b7 | |||
| 60e5682829 | |||
| d605fbbde8 | |||
| 21e6d81d34 | |||
| 85e79d9932 | |||
| 71dfbeea88 | |||
| ffcab7bf6c | |||
| c3f6a1d6ba | |||
| eb96d3ad63 | |||
| 06e10cd693 | |||
| 35bfd8b3ff | |||
| c2720a5738 | |||
| cd48e67675 | |||
| 7cff2050c8 | |||
| e6e96c8603 | |||
| d4b3a3b972 | |||
| fd2ff255e5 | |||
| 5903070c02 | |||
| e92865cecb | |||
| a5c4fd5bc1 | |||
| 5caaf423ff |
+1061
-123
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/codemirror",
|
||||
"version": "1.2.6",
|
||||
"version": "1.2.7",
|
||||
"description": "Codemirror Extensions for Strudel",
|
||||
"main": "index.mjs",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/core",
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.6",
|
||||
"description": "Port of Tidal Cycles to JavaScript",
|
||||
"main": "index.mjs",
|
||||
"type": "module",
|
||||
@@ -31,6 +31,7 @@
|
||||
},
|
||||
"homepage": "https://strudel.cc",
|
||||
"dependencies": {
|
||||
"@kabelsalat/web": "^0.4.1",
|
||||
"fraction.js": "^5.2.1"
|
||||
},
|
||||
"gitHead": "0e26d4e741500f5bae35b023608f062a794905c2",
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
} from './util.mjs';
|
||||
import drawLine from './drawLine.mjs';
|
||||
import { errorLogger, logger } from './logger.mjs';
|
||||
import { strudelScope } from './evaluate.mjs';
|
||||
|
||||
let stringParser;
|
||||
|
||||
@@ -1683,7 +1684,9 @@ export function register(name, func, patternify = true, preserveSteps = false, j
|
||||
|
||||
// toplevel functions get curried as well as patternified
|
||||
// because pfunc uses spread args, we need to state the arity explicitly!
|
||||
return curry(pfunc, null, arity);
|
||||
const curried = curry(pfunc, null, arity);
|
||||
strudelScope[name] = curried;
|
||||
return curried;
|
||||
}
|
||||
|
||||
// Like register, but defaults to stepJoin
|
||||
@@ -3774,3 +3777,83 @@ Pattern.prototype.FX = function (...effects) {
|
||||
return { ...v, FX: currFX.concat(vEff) };
|
||||
}).appLeft(parray(effects));
|
||||
};
|
||||
|
||||
const _asArrayPattern = (pats) => {
|
||||
const pack = (...xs) => xs;
|
||||
let acc = pure(curry(pack, null, pats.length));
|
||||
for (const p of pats) acc = acc.appLeft(p);
|
||||
return acc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Produces a [Kabelsalat](https://kabel.salat.dev/) modular sound engine.
|
||||
* This can be used as either an effect (by including `audioin()` at the beginning
|
||||
* of your kabel expression) or as a sound source (via any expression which doesn't
|
||||
* start with `audioin()`).
|
||||
*
|
||||
* Some helpers you have available to you:
|
||||
* * Strudel mini notation works fine in K(..) via "" or ``
|
||||
* * More complex Strudel expressions (like "0 1 2".fast(4) or irand(24)) can be
|
||||
* written by wrapping them in `S(..)` inside your Kabel code
|
||||
* * We expose Strudel's note frequency under `sFreq` and Strudel's gate
|
||||
* information under `sGate`
|
||||
* * You can use more complex multi-line expressions (like `let x = a; let y = b; x.lpf(y);`)
|
||||
* by wrapping them inside a function in K (see example).
|
||||
*
|
||||
* @name K
|
||||
* @param {KabelsalatExpression | Function} expr Kabelsalat graph definition
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
*
|
||||
* @example
|
||||
* note("A c e".fast(4)).transpose("<0 2 4 6 8>")
|
||||
* .scale("F:minor").transpose("12")
|
||||
* .s("saw")
|
||||
* .K(
|
||||
* // audioin().mul(sGate.adsr(0.001, 0.3, 0, 0.2)) // as effect
|
||||
* saw(saw(sFreq / "2!3 16").mul(8).add(sFreq).lag("0!3 0.1")).mul(0.3) // as source
|
||||
* .mul(sGate.adsr(0, 0.15, 0.5, "0.1!3 1"))
|
||||
* .lpf(sGate.adsr(0, 0.2, 0.3, 0.2).mul(1).add(0))
|
||||
* .add(x => x.delay(S("0.3 0.2".fast(2))).mul(0.7))
|
||||
* .add(x => x.delay("0.03 [0.08 0.01] 0.01 0.013").mul(0.77)).mul(0.7)
|
||||
* .add(x => x.delay(.13).mul(0.7))
|
||||
* .out()
|
||||
* )
|
||||
*
|
||||
* @example
|
||||
* n("<0 1 <2 3 2 4>>*16")
|
||||
* .scale("G#2:minor").sometimes(x => x.transpose("12 | 24"))
|
||||
* .K(() => {
|
||||
* const att = S(rand.range(0, 0.05))
|
||||
* const dec = S(rand.range(0.05, 0.2))
|
||||
* let f = n(sFreq);
|
||||
* const mod = sine(f).mul("0.1 | 0.2 | 0.3")
|
||||
* .add("[[1.5 1] | 1 | 2 | 4 | [6 4@3]]*2")
|
||||
* saw(f.mul(mod))
|
||||
* .mul(sGate.ad(att, dec))
|
||||
* .add(x => x.delay(0.4).mul(0.3))
|
||||
* .out()
|
||||
* }).fxr(1).room(0.3)
|
||||
*/
|
||||
/**
|
||||
* Creates a worklet effect. Typically derived by writing K(...) in the REPL which will parse
|
||||
* Kabelsalat code.
|
||||
*
|
||||
* @name worklet
|
||||
* @param {string} src Source code of the worklet update function
|
||||
* @param {...number | ...Pattern} inputs Worklet inputs
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @noAutocomplete
|
||||
*/
|
||||
Pattern.prototype.worklet = function (src, ...inputs) {
|
||||
inputs = inputs.map(reify);
|
||||
return this.outerBind((v) => {
|
||||
return _asArrayPattern(inputs).withValue((vInput) => {
|
||||
const currInputs = v.workletInputs ?? [];
|
||||
return { ...v, workletSrc: src, workletInputs: currInputs.concat(vInput) };
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const worklet = (...args) => pure({}).worklet(...args);
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
import { evalScope } from './evaluate.mjs';
|
||||
import { register, Pattern, isPattern, silence, stack } from './pattern.mjs';
|
||||
import { reset_state } from './impure.mjs';
|
||||
import { SalatRepl } from '@kabelsalat/web';
|
||||
|
||||
export function repl({
|
||||
defaultOutput,
|
||||
@@ -30,6 +31,7 @@ export function repl({
|
||||
id,
|
||||
mondo = false,
|
||||
}) {
|
||||
const kabel = new SalatRepl({ localScope: true });
|
||||
const state = {
|
||||
schedulerError: undefined,
|
||||
evalError: undefined,
|
||||
@@ -87,6 +89,11 @@ export function repl({
|
||||
return silence;
|
||||
};
|
||||
|
||||
const compileKabel = (code) => {
|
||||
const node = kabel.evaluate(code);
|
||||
return node.compile({ log: false });
|
||||
};
|
||||
|
||||
// helper to get a patternified pure value out
|
||||
function unpure(pat) {
|
||||
if (pat._Pattern) {
|
||||
@@ -208,6 +215,7 @@ export function repl({
|
||||
setcps: setCps,
|
||||
setCpm,
|
||||
setcpm: setCpm,
|
||||
compileKabel,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/csound",
|
||||
"version": "1.2.6",
|
||||
"version": "1.2.7",
|
||||
"description": "csound bindings for strudel",
|
||||
"main": "index.mjs",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/draw",
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.6",
|
||||
"description": "Helpers for drawing with Strudel",
|
||||
"main": "index.mjs",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/embed",
|
||||
"version": "1.1.1",
|
||||
"version": "1.1.2",
|
||||
"description": "Embeddable Web Component to load a Strudel REPL into an iframe",
|
||||
"main": "embed.js",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/gamepad",
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.6",
|
||||
"description": "Gamepad Inputs for strudel",
|
||||
"main": "index.mjs",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/hydra",
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.6",
|
||||
"description": "Hydra integration for strudel",
|
||||
"main": "hydra.mjs",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/midi",
|
||||
"version": "1.2.6",
|
||||
"version": "1.2.7",
|
||||
"description": "Midi API for strudel",
|
||||
"main": "index.mjs",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/mini",
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.6",
|
||||
"description": "Mini notation for strudel",
|
||||
"main": "index.mjs",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mondolang",
|
||||
"version": "1.1.1",
|
||||
"version": "1.1.2",
|
||||
"description": "a language for functional composition that translates to js",
|
||||
"main": "mondo.mjs",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/mondo",
|
||||
"version": "1.1.5",
|
||||
"version": "1.1.6",
|
||||
"description": "mondo notation for strudel",
|
||||
"main": "mondough.mjs",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/motion",
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.6",
|
||||
"description": "DeviceMotion API for strudel",
|
||||
"main": "index.mjs",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/mqtt",
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.6",
|
||||
"description": "MQTT API for strudel",
|
||||
"main": "mqtt.mjs",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/osc",
|
||||
"version": "1.3.0",
|
||||
"version": "1.3.1",
|
||||
"description": "OSC messaging for strudel",
|
||||
"main": "osc.mjs",
|
||||
"bin": "./server.js",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/reference",
|
||||
"version": "1.2.1",
|
||||
"version": "1.2.2",
|
||||
"description": "Headless reference of all strudel functions",
|
||||
"main": "index.mjs",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/repl",
|
||||
"version": "1.2.7",
|
||||
"version": "1.2.8",
|
||||
"description": "Strudel REPL as a Web Component",
|
||||
"module": "index.mjs",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/sampler",
|
||||
"version": "0.2.3",
|
||||
"version": "0.2.4",
|
||||
"description": "",
|
||||
"keywords": [
|
||||
"tidalcycles",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/serial",
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.6",
|
||||
"description": "Webserial API for strudel",
|
||||
"main": "serial.mjs",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/soundfonts",
|
||||
"version": "1.2.6",
|
||||
"version": "1.2.7",
|
||||
"description": "Soundsfont support for strudel",
|
||||
"main": "index.mjs",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -154,9 +154,8 @@ export function getCompressor(ac, threshold, ratio, knee, attack, release) {
|
||||
attack: attack ?? 0.005,
|
||||
release: release ?? 0.05,
|
||||
};
|
||||
const now = ac.currentTime;
|
||||
Object.entries(options).forEach(([key, value]) => {
|
||||
node[key].setValueAtTime(value, now);
|
||||
node[key].value = value;
|
||||
});
|
||||
return node;
|
||||
}
|
||||
@@ -242,9 +241,8 @@ export function createFilter(context, start, end, params, cps, cycle) {
|
||||
const factory = () => context.createBiquadFilter();
|
||||
filter = getNodeFromPool('filter', factory);
|
||||
filter.type = type;
|
||||
const now = context.currentTime;
|
||||
Object.entries({ Q: q, frequency }).forEach(([key, value]) => {
|
||||
filter[key].setValueAtTime(value, now);
|
||||
filter[key].value = value;
|
||||
});
|
||||
frequencyParam = filter.frequency;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "superdough",
|
||||
"version": "1.2.6",
|
||||
"version": "1.2.7",
|
||||
"description": "simple web audio synth and sampler intended for live coding. inspired by superdirt and webdirt.",
|
||||
"main": "index.mjs",
|
||||
"type": "module",
|
||||
@@ -36,6 +36,7 @@
|
||||
"vite-plugin-bundle-audioworklet": "workspace:*"
|
||||
},
|
||||
"dependencies": {
|
||||
"@kabelsalat/lib": "^0.4.1",
|
||||
"nanostores": "^0.11.3"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
gainNode,
|
||||
getCompressor,
|
||||
getDistortion,
|
||||
getFrequencyFromValue,
|
||||
getLfo,
|
||||
getWorklet,
|
||||
releaseAudioNode,
|
||||
@@ -408,9 +409,9 @@ function mapChannelNumbers(channels) {
|
||||
}
|
||||
|
||||
class Chain {
|
||||
constructor(head) {
|
||||
this.audioNodes = [head];
|
||||
this.tails = [head];
|
||||
constructor() {
|
||||
this.audioNodes = [];
|
||||
this.tails = [];
|
||||
}
|
||||
connect(...nodes) {
|
||||
nodes.forEach((node) => {
|
||||
@@ -539,6 +540,8 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
||||
value.s = s;
|
||||
}
|
||||
|
||||
const chain = new Chain(); // connection manager which tracks audio nodes for releasing
|
||||
|
||||
// get source AudioNode
|
||||
let sourceNode;
|
||||
if (source) {
|
||||
@@ -579,7 +582,8 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
||||
return;
|
||||
}
|
||||
|
||||
const chain = new Chain(sourceNode); // connection manager which tracks audio nodes for releasing
|
||||
chain.connect(sourceNode);
|
||||
|
||||
FX = [...FX, value]; // run through the FX chain and then run through all FX outside of it as well
|
||||
for (let [idx, fx] of Object.entries(FX)) {
|
||||
const key = idx == FX.length - 1 ? 'main' : idx;
|
||||
@@ -597,7 +601,6 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
||||
delayfeedback = getDefaultValue('delayfeedback'),
|
||||
delaysync = getDefaultValue('delaysync'),
|
||||
delaytime,
|
||||
stretch = getDefaultValue('stretch'),
|
||||
i = getDefaultValue('i'),
|
||||
} = fx;
|
||||
gain = applyGainCurve(nanFallback(gain, 1));
|
||||
@@ -608,8 +611,21 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
|
||||
gain *= velocity; // velocity currently only multiplies with gain. it might do other things in the future
|
||||
delaytime = delaytime ?? cycleToSeconds(delaysync, cps);
|
||||
|
||||
if (stretch !== undefined) {
|
||||
const phaseVocoder = getWorklet(ac, 'phase-vocoder-processor', { pitchFactor: stretch });
|
||||
// Kabelsalat
|
||||
if (fx.workletSrc !== undefined) {
|
||||
const workletNode = getWorklet(ac, 'generic-processor', {}, { outputChannelCount: [2] });
|
||||
chain.connect(workletNode);
|
||||
const workletSrc = fx.workletSrc
|
||||
.replace(/\bpat\[(\d+)\]/g, (_, i) => fx.workletInputs[i])
|
||||
.replaceAll('sFreq', getFrequencyFromValue(value))
|
||||
.replaceAll('sGate', `cc('strudel-gate-${chainID}')`);
|
||||
/* global compileKabel */
|
||||
const { src, ugens, registers } = compileKabel(workletSrc);
|
||||
workletNode.port.postMessage({ src, schema: { ugens, registers }, start: t, gateEnd: end, end: endWithRelease });
|
||||
}
|
||||
|
||||
if (fx.stretch !== undefined) {
|
||||
const phaseVocoder = getWorklet(ac, 'phase-vocoder-processor', { pitchFactor: fx.stretch });
|
||||
chain.connect(phaseVocoder);
|
||||
fxNodes['stretch'] = [phaseVocoder];
|
||||
}
|
||||
|
||||
@@ -178,11 +178,10 @@ export function registerSynthSounds() {
|
||||
};
|
||||
const factory = () => new AudioWorkletNode(ac, 'supersaw-oscillator', { outputChannelCount: [2] });
|
||||
const o = getNodeFromPool('supersaw', factory);
|
||||
const now = ac.currentTime;
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
const param = o.parameters.get(key);
|
||||
const target = value !== undefined ? value : param.defaultValue;
|
||||
param.setValueAtTime(target, now);
|
||||
param.value = target;
|
||||
});
|
||||
o.port.postMessage({ type: 'initialize' });
|
||||
const gainAdjustment = 1 / Math.sqrt(voices);
|
||||
|
||||
@@ -244,11 +244,10 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) {
|
||||
};
|
||||
const factory = () => new AudioWorkletNode(ac, 'wavetable-oscillator-processor', { outputChannelCount: [2] });
|
||||
const source = getNodeFromPool('wavetable', factory);
|
||||
const now = ac.currentTime;
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
const param = source.parameters.get(key);
|
||||
const target = value !== undefined ? value : param.defaultValue;
|
||||
param.setValueAtTime(target, now);
|
||||
param.value = target;
|
||||
});
|
||||
source.port.postMessage({ type: 'initialize', payload });
|
||||
if (ac.currentTime > t) {
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
import OLAProcessor from './ola-processor';
|
||||
import FFT from './fft.js';
|
||||
import { getDistortionAlgorithm } from './helpers.mjs';
|
||||
import * as ugens from '@kabelsalat/lib/src/ugens.js';
|
||||
|
||||
const UGENS = new Map(Object.entries(ugens));
|
||||
|
||||
const blockSize = 128;
|
||||
const PI = Math.PI;
|
||||
@@ -1479,3 +1482,81 @@ class TransientProcessor extends AudioWorkletProcessor {
|
||||
}
|
||||
|
||||
registerProcessor('transient-processor', TransientProcessor);
|
||||
|
||||
class GenericProcessor extends AudioWorkletProcessor {
|
||||
constructor() {
|
||||
super();
|
||||
this.playPos = 0;
|
||||
const channels = 16;
|
||||
this.outputs = new Array(channels).fill(0);
|
||||
this.sources = new Array(channels).fill(0);
|
||||
this.gateEnded = false;
|
||||
this.started = false;
|
||||
this.port.onmessage = (event) => {
|
||||
let {
|
||||
src,
|
||||
schema: { ugens, registers },
|
||||
start,
|
||||
gateEnd,
|
||||
end,
|
||||
} = event.data;
|
||||
this.start = start;
|
||||
this.gateEnd = gateEnd;
|
||||
this.end = end;
|
||||
this.registers = new Array(registers).fill(0);
|
||||
this.src = `o.fill(0); // reset outputs\n${src}`;
|
||||
this.nodes = [];
|
||||
for (let i = 0; i < ugens.length; i++) {
|
||||
const ugen = ugens[i];
|
||||
const nodeClass = UGENS.get(ugen.type);
|
||||
const node = new nodeClass(i, ugen, sampleRate);
|
||||
if (node.type === 'cc' && ugen.inputs?.[0]?.includes('strudel-gate')) {
|
||||
node.setValue(1);
|
||||
this.gateNode = node;
|
||||
}
|
||||
this.nodes[i] = node;
|
||||
}
|
||||
this.genSample = new Function(
|
||||
'time',
|
||||
'nodes',
|
||||
'input',
|
||||
'r', // registers
|
||||
'o', // outputs
|
||||
's', // sources
|
||||
this.src,
|
||||
);
|
||||
};
|
||||
}
|
||||
process(inputs, outputs) {
|
||||
const input = inputs[0]?.[0];
|
||||
if (currentTime >= this.end) {
|
||||
return false;
|
||||
} else if (this.genSample === undefined || currentTime < this.start) {
|
||||
// pending
|
||||
return true;
|
||||
}
|
||||
this.started = true;
|
||||
if (!this.gateEnded && currentTime > this.gateEnd) {
|
||||
this.gateNode?.setValue(0);
|
||||
this.gateEnded = true;
|
||||
}
|
||||
const output = outputs[0];
|
||||
const outL = output[0];
|
||||
const outR = output[1];
|
||||
for (let n = 0; n < blockSize; n++) {
|
||||
this.genSample(this.playPos, this.nodes, input ? input[n] : 0, this.registers, this.outputs, this.sources);
|
||||
const left = this.outputs[0];
|
||||
const right = this.outputs[1];
|
||||
// Spread to stereo if possible; else mixdown to mono
|
||||
if (outR) {
|
||||
outL[n] = left;
|
||||
outR[n] = right;
|
||||
} else {
|
||||
outL[n] = 0.5 * (left + right);
|
||||
}
|
||||
this.playPos += 1 / sampleRate;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
registerProcessor('generic-processor', GenericProcessor);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "supradough",
|
||||
"version": "1.2.4",
|
||||
"version": "1.2.5",
|
||||
"description": "platform agnostic synth and sampler intended for live coding. a reimplementation of superdough.",
|
||||
"main": "index.mjs",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/tonal",
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.6",
|
||||
"description": "Tonal functions for strudel",
|
||||
"main": "index.mjs",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/transpiler",
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.6",
|
||||
"description": "Transpiler for strudel user code. Converts syntactically correct but semantically meaningless JS into evaluatable strudel code.",
|
||||
"main": "index.mjs",
|
||||
"type": "module",
|
||||
|
||||
@@ -26,6 +26,20 @@ describe('transpiler', () => {
|
||||
it('adds await to bare samples call', () => {
|
||||
expect(transpiler("samples('xxx');", simple).output).toEqual("await samples('xxx');");
|
||||
});
|
||||
it('handles mini strings in K(...)', () => {
|
||||
expect(transpiler('K("bd sd")', simple).output).toEqual("worklet('pat[0]', m('bd sd', 2));");
|
||||
});
|
||||
it('treats K(...) as kabelsalat', () => {
|
||||
expect(transpiler('K(1+2)', simple).output).toEqual("worklet('1 + 2');");
|
||||
});
|
||||
it('automatically calls functions in K(...)', () => {
|
||||
expect(transpiler('K(() => { return 1 + 2 })', simple).output).toEqual(
|
||||
"worklet('(() => {\\n return 1 + 2\\n})()');",
|
||||
);
|
||||
});
|
||||
it('handles strudel S(...) inside kabelsalat K(...)', () => {
|
||||
expect(transpiler('K(S("bd".fast(4)))', simple).output).toEqual("worklet('pat[0]', m('bd', 4).fast(4));");
|
||||
});
|
||||
/* it('parses dynamic imports', () => {
|
||||
expect(
|
||||
transpiler("const { default: foo } = await import('https://bar.com/foo.js');", {
|
||||
|
||||
@@ -119,7 +119,64 @@ export function transpiler(input, options = {}) {
|
||||
return this.replace(labelToP(node));
|
||||
}
|
||||
},
|
||||
leave(node, parent, prop, index) {},
|
||||
|
||||
leave(node, parent, prop, index) {
|
||||
if (!isKabelCall(node)) return;
|
||||
|
||||
let [expr, ...rest] = node.arguments;
|
||||
if (!expr) throw new Error('K(...) requires an expression');
|
||||
|
||||
if (shouldCallKabelExpression(expr)) {
|
||||
expr = {
|
||||
type: 'CallExpression',
|
||||
callee: expr,
|
||||
arguments: [],
|
||||
optional: false,
|
||||
};
|
||||
}
|
||||
|
||||
const { template, patternExprs } = extractPatternPlaceholders(expr);
|
||||
if (patternExprs.length) {
|
||||
const workletArgs = [{ type: 'Literal', value: template }, ...patternExprs, ...rest];
|
||||
|
||||
let callee = node.callee;
|
||||
if (callee.type === 'ChainExpression') callee = callee.expression;
|
||||
if (callee.type === 'MemberExpression') {
|
||||
return this.replace({
|
||||
type: 'CallExpression',
|
||||
callee: workletMemberAst(callee.object),
|
||||
arguments: workletArgs,
|
||||
optional: false,
|
||||
});
|
||||
}
|
||||
return this.replace({
|
||||
type: 'CallExpression',
|
||||
callee: { type: 'Identifier', name: 'worklet' },
|
||||
arguments: workletArgs,
|
||||
optional: false,
|
||||
});
|
||||
}
|
||||
|
||||
const kabelSrc = genExprSource(expr);
|
||||
const workletArgs = [{ type: 'Literal', value: kabelSrc }, ...rest];
|
||||
|
||||
let callee = node.callee;
|
||||
if (callee.type === 'ChainExpression') callee = callee.expression;
|
||||
if (callee.type === 'MemberExpression') {
|
||||
return this.replace({
|
||||
type: 'CallExpression',
|
||||
callee: workletMemberAst(callee.object),
|
||||
arguments: workletArgs,
|
||||
optional: false,
|
||||
});
|
||||
}
|
||||
return this.replace({
|
||||
type: 'CallExpression',
|
||||
callee: { type: 'Identifier', name: 'worklet' },
|
||||
arguments: workletArgs,
|
||||
optional: false,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
let { body } = ast;
|
||||
@@ -155,6 +212,166 @@ export function transpiler(input, options = {}) {
|
||||
return { output, miniLocations, widgets };
|
||||
}
|
||||
|
||||
function isKabelCall(node) {
|
||||
if (node.type !== 'CallExpression') return false;
|
||||
let callee = node.callee;
|
||||
if (callee.type === 'ChainExpression') callee = callee.expression;
|
||||
if (callee.type === 'MemberExpression') return !callee.computed && callee.property?.name === 'K';
|
||||
return callee.type === 'Identifier' && callee.name === 'K';
|
||||
}
|
||||
|
||||
function shouldCallKabelExpression(expr) {
|
||||
if (expr.type !== 'ArrowFunctionExpression' && expr.type !== 'FunctionExpression') {
|
||||
return false;
|
||||
}
|
||||
if (expr.params.length) {
|
||||
return false;
|
||||
}
|
||||
return expr.body?.type === 'BlockStatement';
|
||||
}
|
||||
|
||||
function genExprSource(expr) {
|
||||
return escodegen.generate(expr, { format: { semicolons: false } });
|
||||
}
|
||||
|
||||
function extractPatternPlaceholders(expr) {
|
||||
const templateExpr = cloneNode(expr);
|
||||
const parents = new Map();
|
||||
const targets = [];
|
||||
|
||||
walk(templateExpr, {
|
||||
enter(node, parent, prop, index) {
|
||||
parents.set(node, { parent, prop, index });
|
||||
const patternExpr = getStrudelPatternExpr(node);
|
||||
if (patternExpr) {
|
||||
targets.push({ node, patternExpr });
|
||||
this.skip();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (!targets.length) {
|
||||
return { template: genExprSource(templateExpr), patternExprs: [] };
|
||||
}
|
||||
|
||||
targets.sort((a, b) => getPatternNodeOrder(a.node) - getPatternNodeOrder(b.node));
|
||||
|
||||
const patternExprs = targets.map(({ patternExpr }) => cloneNode(patternExpr));
|
||||
|
||||
let currentExpr = templateExpr;
|
||||
targets.forEach(({ node }, index) => {
|
||||
currentExpr = replaceNode(node, placeholderAst(index), parents, currentExpr);
|
||||
});
|
||||
|
||||
const template = genExprSource(currentExpr);
|
||||
return { template, patternExprs };
|
||||
}
|
||||
|
||||
function getStrudelPatternExpr(node) {
|
||||
if (isStrudelPatternWrap(node)) {
|
||||
const arg = node.arguments?.[0];
|
||||
if (!arg) {
|
||||
throw new Error('S(...) requires an argument');
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
if (isMiniCall(node)) {
|
||||
return node;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function isStrudelPatternWrap(node) {
|
||||
if (node.type !== 'CallExpression') {
|
||||
return false;
|
||||
}
|
||||
const callee = node.callee;
|
||||
if (callee.type === 'Identifier') {
|
||||
return callee.name === 'S';
|
||||
}
|
||||
if (callee.type === 'MemberExpression' && !callee.computed) {
|
||||
return callee.property?.name === 'S';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getMinilangName() {
|
||||
const minilang = languages.get('minilang');
|
||||
return minilang?.name || 'm';
|
||||
}
|
||||
|
||||
// Used to identify transpiled `m(...)` calls for proper conversion
|
||||
// to, say, kabelsalat placeholders
|
||||
function isMiniCall(node) {
|
||||
if (node.type !== 'CallExpression') {
|
||||
return false;
|
||||
}
|
||||
const callee = node.callee;
|
||||
if (callee.type !== 'Identifier') {
|
||||
return false;
|
||||
}
|
||||
if (callee.name !== getMinilangName()) {
|
||||
return false;
|
||||
}
|
||||
const firstArg = node.arguments?.[0];
|
||||
return firstArg?.type === 'Literal' && typeof firstArg.value === 'string';
|
||||
}
|
||||
|
||||
// If `start` is available, we use it. If it's already been transpiled
|
||||
// to `m(...)`, use the provided offset
|
||||
function getPatternNodeOrder(node) {
|
||||
if (typeof node.start === 'number') {
|
||||
return node.start;
|
||||
}
|
||||
if (isMiniCall(node)) {
|
||||
const offsetArg = node.arguments?.[1];
|
||||
if (offsetArg?.type === 'Literal' && typeof offsetArg.value === 'number') {
|
||||
return offsetArg.value;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function placeholderAst(index) {
|
||||
return {
|
||||
type: 'MemberExpression',
|
||||
object: { type: 'Identifier', name: 'pat' },
|
||||
property: { type: 'Literal', value: index },
|
||||
computed: true,
|
||||
optional: false,
|
||||
};
|
||||
}
|
||||
|
||||
function replaceNode(node, replacement, parents, currentRoot) {
|
||||
const info = parents.get(node);
|
||||
if (!info || !info.parent) {
|
||||
return replacement;
|
||||
}
|
||||
|
||||
const { parent, prop, index } = info;
|
||||
if (Array.isArray(parent[prop])) {
|
||||
parent[prop][index] = replacement;
|
||||
} else {
|
||||
parent[prop] = replacement;
|
||||
}
|
||||
parents.set(replacement, { parent, prop, index });
|
||||
return currentRoot;
|
||||
}
|
||||
|
||||
function cloneNode(node) {
|
||||
return JSON.parse(JSON.stringify(node));
|
||||
}
|
||||
|
||||
function workletMemberAst(objectExpr) {
|
||||
return {
|
||||
type: 'MemberExpression',
|
||||
object: objectExpr,
|
||||
property: { type: 'Identifier', name: 'worklet' },
|
||||
computed: false,
|
||||
optional: false,
|
||||
};
|
||||
}
|
||||
|
||||
function isStringWithDoubleQuotes(node, locations, code) {
|
||||
if (node.type !== 'Literal') {
|
||||
return false;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "vite-plugin-bundle-audioworklet",
|
||||
"main": "./vite-plugin-bundle-audioworklet.js",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"description": "",
|
||||
"keywords": [
|
||||
"vite",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/web",
|
||||
"version": "1.2.6",
|
||||
"version": "1.2.7",
|
||||
"description": "Easy to setup, opiniated bundle of Strudel for the browser.",
|
||||
"module": "web.mjs",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/webaudio",
|
||||
"version": "1.2.6",
|
||||
"version": "1.2.7",
|
||||
"description": "Web Audio helpers for Strudel",
|
||||
"main": "index.mjs",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/xen",
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.6",
|
||||
"description": "Xenharmonic API for strudel",
|
||||
"main": "index.mjs",
|
||||
"type": "module",
|
||||
|
||||
Generated
+28
-2
@@ -41,7 +41,7 @@ importers:
|
||||
version: 2.2.7
|
||||
'@vitest/coverage-v8':
|
||||
specifier: 3.0.4
|
||||
version: 3.0.4(vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(@vitest/ui@3.0.4)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.37.0)(yaml@2.7.0))
|
||||
version: 3.0.4(vitest@3.0.4)
|
||||
'@vitest/ui':
|
||||
specifier: ^3.0.4
|
||||
version: 3.0.4(vitest@3.0.4)
|
||||
@@ -234,6 +234,9 @@ importers:
|
||||
|
||||
packages/core:
|
||||
dependencies:
|
||||
'@kabelsalat/web':
|
||||
specifier: ^0.4.1
|
||||
version: 0.4.1
|
||||
fraction.js:
|
||||
specifier: ^5.2.1
|
||||
version: 5.2.1
|
||||
@@ -518,6 +521,9 @@ importers:
|
||||
|
||||
packages/superdough:
|
||||
dependencies:
|
||||
'@kabelsalat/lib':
|
||||
specifier: ^0.4.1
|
||||
version: 0.4.1
|
||||
nanostores:
|
||||
specifier: ^0.11.3
|
||||
version: 0.11.3
|
||||
@@ -1969,6 +1975,15 @@ packages:
|
||||
resolution: {integrity: sha512-yYxMVH7Dqw6nO0d5NIV8OQWnitU8k6vXH8NtgqAfIa/IUqRMxRv/NUJJ08VEKbAakwxlgBl5PJdrU0dMPStsnw==}
|
||||
engines: {node: '>=v12.0.0'}
|
||||
|
||||
'@kabelsalat/core@0.4.0':
|
||||
resolution: {integrity: sha512-5zV8nh8HffW8aexObXs5pE0xgL0jb1cHc3o8UN6AvK0mBt87fjZvW65E4rMslHyq+OuCscoBJW7B3MbYfWrwMQ==}
|
||||
|
||||
'@kabelsalat/lib@0.4.1':
|
||||
resolution: {integrity: sha512-gBCjrZKD9huTKNJuBC6BXM4PMQSg8otL8A/vp8j98P9v6yWTX1TuyaqdLg/1PrIAMV4hlWoav9ZD3YMFlrvouw==}
|
||||
|
||||
'@kabelsalat/web@0.4.1':
|
||||
resolution: {integrity: sha512-ASkFhePJLx3GjadYOueI7sHKXBbRPk/a1pfslFeQNI9gU7yZq/KrnkmOmLrgrtixAsy7gyi1vWqkmRRvH3Ki6w==}
|
||||
|
||||
'@lerna/create@8.1.9':
|
||||
resolution: {integrity: sha512-DPnl5lPX4v49eVxEbJnAizrpMdMTBz1qykZrAbBul9rfgk531v8oAt+Pm6O/rpAleRombNM7FJb5rYGzBJatOQ==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
@@ -9261,6 +9276,17 @@ snapshots:
|
||||
dependencies:
|
||||
lodash: 4.17.21
|
||||
|
||||
'@kabelsalat/core@0.4.0': {}
|
||||
|
||||
'@kabelsalat/lib@0.4.1':
|
||||
dependencies:
|
||||
'@kabelsalat/core': 0.4.0
|
||||
|
||||
'@kabelsalat/web@0.4.1':
|
||||
dependencies:
|
||||
'@kabelsalat/core': 0.4.0
|
||||
'@kabelsalat/lib': 0.4.1
|
||||
|
||||
'@lerna/create@8.1.9(encoding@0.1.13)(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@npmcli/arborist': 7.5.4
|
||||
@@ -10554,7 +10580,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@vitest/coverage-v8@3.0.4(vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(@vitest/ui@3.0.4)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.37.0)(yaml@2.7.0))':
|
||||
'@vitest/coverage-v8@3.0.4(vitest@3.0.4)':
|
||||
dependencies:
|
||||
'@ampproject/remapping': 2.3.0
|
||||
'@bcoe/v8-coverage': 1.0.2
|
||||
|
||||
@@ -611,6 +611,132 @@ exports[`runs examples > example "FX" example index 1 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "K" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/12 | note:Bb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.03] ]",
|
||||
"[ 1/12 → 1/6 | note:C4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.03] ]",
|
||||
"[ 1/6 → 1/4 | note:F4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.03] ]",
|
||||
"[ 1/4 → 1/3 | note:Bb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.2 0.08] ]",
|
||||
"[ (1/3 → 3/8) ⇝ 5/12 | note:C4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.2 0.08] ]",
|
||||
"[ 1/3 ⇜ (3/8 → 5/12) | note:C4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.2 0.01] ]",
|
||||
"[ 5/12 → 1/2 | note:F4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.2 0.01] ]",
|
||||
"[ 1/2 → 7/12 | note:Bb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.01] ]",
|
||||
"[ 7/12 → 2/3 | note:C4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.01] ]",
|
||||
"[ 2/3 → 3/4 | note:F4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.01] ]",
|
||||
"[ 3/4 → 5/6 | note:Bb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[16 0.1 1 0.2 0.013] ]",
|
||||
"[ 5/6 → 11/12 | note:C4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[16 0.1 1 0.2 0.013] ]",
|
||||
"[ 11/12 → 1/1 | note:F4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[16 0.1 1 0.2 0.013] ]",
|
||||
"[ 1/1 → 13/12 | note:C5 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.03] ]",
|
||||
"[ 13/12 → 7/6 | note:Eb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.03] ]",
|
||||
"[ 7/6 → 5/4 | note:G4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.03] ]",
|
||||
"[ 5/4 → 4/3 | note:C5 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.2 0.08] ]",
|
||||
"[ (4/3 → 11/8) ⇝ 17/12 | note:Eb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.2 0.08] ]",
|
||||
"[ 4/3 ⇜ (11/8 → 17/12) | note:Eb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.2 0.01] ]",
|
||||
"[ 17/12 → 3/2 | note:G4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.2 0.01] ]",
|
||||
"[ 3/2 → 19/12 | note:C5 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.01] ]",
|
||||
"[ 19/12 → 5/3 | note:Eb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.01] ]",
|
||||
"[ 5/3 → 7/4 | note:G4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.01] ]",
|
||||
"[ 7/4 → 11/6 | note:C5 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[16 0.1 1 0.2 0.013] ]",
|
||||
"[ 11/6 → 23/12 | note:Eb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[16 0.1 1 0.2 0.013] ]",
|
||||
"[ 23/12 → 2/1 | note:G4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[16 0.1 1 0.2 0.013] ]",
|
||||
"[ 2/1 → 25/12 | note:Db4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.03] ]",
|
||||
"[ 25/12 → 13/6 | note:F4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.03] ]",
|
||||
"[ 13/6 → 9/4 | note:Ab4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.03] ]",
|
||||
"[ 9/4 → 7/3 | note:Db4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.2 0.08] ]",
|
||||
"[ (7/3 → 19/8) ⇝ 29/12 | note:F4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.2 0.08] ]",
|
||||
"[ 7/3 ⇜ (19/8 → 29/12) | note:F4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.2 0.01] ]",
|
||||
"[ 29/12 → 5/2 | note:Ab4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.2 0.01] ]",
|
||||
"[ 5/2 → 31/12 | note:Db4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.01] ]",
|
||||
"[ 31/12 → 8/3 | note:F4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.01] ]",
|
||||
"[ 8/3 → 11/4 | note:Ab4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.01] ]",
|
||||
"[ 11/4 → 17/6 | note:Db4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[16 0.1 1 0.2 0.013] ]",
|
||||
"[ 17/6 → 35/12 | note:F4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[16 0.1 1 0.2 0.013] ]",
|
||||
"[ 35/12 → 3/1 | note:Ab4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[16 0.1 1 0.2 0.013] ]",
|
||||
"[ 3/1 → 37/12 | note:Eb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.03] ]",
|
||||
"[ 37/12 → 19/6 | note:G4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.03] ]",
|
||||
"[ 19/6 → 13/4 | note:Bb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.03] ]",
|
||||
"[ 13/4 → 10/3 | note:Eb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.2 0.08] ]",
|
||||
"[ (10/3 → 27/8) ⇝ 41/12 | note:G4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.2 0.08] ]",
|
||||
"[ 10/3 ⇜ (27/8 → 41/12) | note:G4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.2 0.01] ]",
|
||||
"[ 41/12 → 7/2 | note:Bb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.2 0.01] ]",
|
||||
"[ 7/2 → 43/12 | note:Eb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.01] ]",
|
||||
"[ 43/12 → 11/3 | note:G4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.01] ]",
|
||||
"[ 11/3 → 15/4 | note:Bb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[2 0 0.1 0.3 0.01] ]",
|
||||
"[ 15/4 → 23/6 | note:Eb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[16 0.1 1 0.2 0.013] ]",
|
||||
"[ 23/6 → 47/12 | note:G4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[16 0.1 1 0.2 0.013] ]",
|
||||
"[ 47/12 → 4/1 | note:Bb4 s:saw workletSrc:saw(saw(sFreq / pat[0]).mul(8).add(sFreq).lag(pat[1])).mul(0.3).mul(sGate.adsr(0 0.15 0.5 pat[2])).lpf(sGate.adsr(0 0.2 0.3 0.2).mul(1).add(0)).add(x => x.delay(pat[3]).mul(0.7)).add(x => x.delay(pat[4]).mul(0.77)).mul(0.7).add(x => x.delay(0.13).mul(0.7)).out() workletInputs:[16 0.1 1 0.2 0.013] ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "K" example index 1 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/16 | note:G#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0 0.05 0.1 1.5] FXrelease:1 room:0.3 ]",
|
||||
"[ 1/16 → 1/8 | note:A#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0 0.05 0.1 1.5] FXrelease:1 room:0.3 ]",
|
||||
"[ 1/8 → 3/16 | note:B2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0 0.05 0.1 1.5] FXrelease:1 room:0.3 ]",
|
||||
"[ 3/16 → 1/4 | note:G#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0 0.05 0.1 1.5] FXrelease:1 room:0.3 ]",
|
||||
"[ 1/4 → 5/16 | note:A#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0 0.05 0.1 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 5/16 → 3/8 | note:C#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0 0.05 0.1 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 3/8 → 7/16 | note:G#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0 0.05 0.1 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 7/16 → 1/2 | note:A#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0 0.05 0.1 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 1/2 → 9/16 | note:B3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0 0.05 0.1 2] FXrelease:1 room:0.3 ]",
|
||||
"[ 9/16 → 5/8 | note:G#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0 0.05 0.1 2] FXrelease:1 room:0.3 ]",
|
||||
"[ 5/8 → 11/16 | note:A#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0 0.05 0.1 2] FXrelease:1 room:0.3 ]",
|
||||
"[ 11/16 → 3/4 | note:D#4 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0 0.05 0.1 2] FXrelease:1 room:0.3 ]",
|
||||
"[ 3/4 → 13/16 | note:G#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0 0.05 0.1 2] FXrelease:1 room:0.3 ]",
|
||||
"[ 13/16 → 7/8 | note:A#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0 0.05 0.1 2] FXrelease:1 room:0.3 ]",
|
||||
"[ 7/8 → 15/16 | note:B3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0 0.05 0.1 2] FXrelease:1 room:0.3 ]",
|
||||
"[ 15/16 → 1/1 | note:G#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0 0.05 0.1 2] FXrelease:1 room:0.3 ]",
|
||||
"[ 1/1 → 17/16 | note:A#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.025977108255028726 0.12793132476508617 0.2 6] FXrelease:1 room:0.3 ]",
|
||||
"[ 17/16 → 9/8 | note:C#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.025977108255028726 0.12793132476508617 0.2 6] FXrelease:1 room:0.3 ]",
|
||||
"[ 9/8 → 19/16 | note:G#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.025977108255028726 0.12793132476508617 0.2 4] FXrelease:1 room:0.3 ]",
|
||||
"[ 19/16 → 5/4 | note:A#4 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.025977108255028726 0.12793132476508617 0.2 4] FXrelease:1 room:0.3 ]",
|
||||
"[ 5/4 → 21/16 | note:B2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.025977108255028726 0.12793132476508617 0.2 4] FXrelease:1 room:0.3 ]",
|
||||
"[ 21/16 → 11/8 | note:G#4 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.025977108255028726 0.12793132476508617 0.2 4] FXrelease:1 room:0.3 ]",
|
||||
"[ 11/8 → 23/16 | note:A#4 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.025977108255028726 0.12793132476508617 0.2 4] FXrelease:1 room:0.3 ]",
|
||||
"[ 23/16 → 3/2 | note:D#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.025977108255028726 0.12793132476508617 0.2 4] FXrelease:1 room:0.3 ]",
|
||||
"[ 3/2 → 25/16 | note:G#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.025977108255028726 0.12793132476508617 0.2 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 25/16 → 13/8 | note:A#4 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.025977108255028726 0.12793132476508617 0.2 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 13/8 → 27/16 | note:B4 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.025977108255028726 0.12793132476508617 0.2 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 27/16 → 7/4 | note:G#4 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.025977108255028726 0.12793132476508617 0.2 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 7/4 → 29/16 | note:A#4 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.025977108255028726 0.12793132476508617 0.2 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 29/16 → 15/8 | note:C#5 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.025977108255028726 0.12793132476508617 0.2 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 15/8 → 31/16 | note:G#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.025977108255028726 0.12793132476508617 0.2 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 31/16 → 2/1 | note:A#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.025977108255028726 0.12793132476508617 0.2 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 2/1 → 33/16 | note:B2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.047976355999708176 0.19392906799912457 0.3 1.5] FXrelease:1 room:0.3 ]",
|
||||
"[ 33/16 → 17/8 | note:G#4 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.047976355999708176 0.19392906799912457 0.3 1.5] FXrelease:1 room:0.3 ]",
|
||||
"[ 17/8 → 35/16 | note:A#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.047976355999708176 0.19392906799912457 0.3 1.5] FXrelease:1 room:0.3 ]",
|
||||
"[ 35/16 → 9/4 | note:D#5 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.047976355999708176 0.19392906799912457 0.3 1.5] FXrelease:1 room:0.3 ]",
|
||||
"[ 9/4 → 37/16 | note:G#4 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.047976355999708176 0.19392906799912457 0.3 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 37/16 → 19/8 | note:A#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.047976355999708176 0.19392906799912457 0.3 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 19/8 → 39/16 | note:B2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.047976355999708176 0.19392906799912457 0.3 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 39/16 → 5/2 | note:G#4 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.047976355999708176 0.19392906799912457 0.3 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 5/2 → 41/16 | note:A#4 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.047976355999708176 0.19392906799912457 0.3 1.5] FXrelease:1 room:0.3 ]",
|
||||
"[ 41/16 → 21/8 | note:C#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.047976355999708176 0.19392906799912457 0.3 1.5] FXrelease:1 room:0.3 ]",
|
||||
"[ 21/8 → 43/16 | note:G#4 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.047976355999708176 0.19392906799912457 0.3 1.5] FXrelease:1 room:0.3 ]",
|
||||
"[ 43/16 → 11/4 | note:A#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.047976355999708176 0.19392906799912457 0.3 1.5] FXrelease:1 room:0.3 ]",
|
||||
"[ 11/4 → 45/16 | note:B2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.047976355999708176 0.19392906799912457 0.3 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 45/16 → 23/8 | note:G#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.047976355999708176 0.19392906799912457 0.3 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 23/8 → 47/16 | note:A#4 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.047976355999708176 0.19392906799912457 0.3 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 47/16 → 3/1 | note:D#5 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.047976355999708176 0.19392906799912457 0.3 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 3/1 → 49/16 | note:G#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.010864455532282592 0.08259336659684778 0.1 2] FXrelease:1 room:0.3 ]",
|
||||
"[ 49/16 → 25/8 | note:A#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.010864455532282592 0.08259336659684778 0.1 2] FXrelease:1 room:0.3 ]",
|
||||
"[ 25/8 → 51/16 | note:B3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.010864455532282592 0.08259336659684778 0.1 2] FXrelease:1 room:0.3 ]",
|
||||
"[ 51/16 → 13/4 | note:G#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.010864455532282592 0.08259336659684778 0.1 2] FXrelease:1 room:0.3 ]",
|
||||
"[ 13/4 → 53/16 | note:A#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.010864455532282592 0.08259336659684778 0.1 2] FXrelease:1 room:0.3 ]",
|
||||
"[ 53/16 → 27/8 | note:C#4 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.010864455532282592 0.08259336659684778 0.1 2] FXrelease:1 room:0.3 ]",
|
||||
"[ 27/8 → 55/16 | note:G#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.010864455532282592 0.08259336659684778 0.1 2] FXrelease:1 room:0.3 ]",
|
||||
"[ 55/16 → 7/2 | note:A#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.010864455532282592 0.08259336659684778 0.1 2] FXrelease:1 room:0.3 ]",
|
||||
"[ 7/2 → 57/16 | note:B3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.010864455532282592 0.08259336659684778 0.1 1.5] FXrelease:1 room:0.3 ]",
|
||||
"[ 57/16 → 29/8 | note:G#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.010864455532282592 0.08259336659684778 0.1 1.5] FXrelease:1 room:0.3 ]",
|
||||
"[ 29/8 → 59/16 | note:A#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.010864455532282592 0.08259336659684778 0.1 1.5] FXrelease:1 room:0.3 ]",
|
||||
"[ 59/16 → 15/4 | note:D#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.010864455532282592 0.08259336659684778 0.1 1.5] FXrelease:1 room:0.3 ]",
|
||||
"[ 15/4 → 61/16 | note:G#2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.010864455532282592 0.08259336659684778 0.1 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 61/16 → 31/8 | note:A#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.010864455532282592 0.08259336659684778 0.1 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 31/8 → 63/16 | note:B2 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.010864455532282592 0.08259336659684778 0.1 1] FXrelease:1 room:0.3 ]",
|
||||
"[ 63/16 → 4/1 | note:G#3 workletSrc:(() => {\\n const att = pat[0];\\n const dec = pat[1];\\n let f = n(sFreq);\\n const mod = sine(f).mul(pat[2]).add(pat[3]);\\n saw(f.mul(mod)).mul(sGate.ad(att dec)).add(x => x.delay(0.4).mul(0.3)).out()\\n})() workletInputs:[0.010864455532282592 0.08259336659684778 0.1 1] FXrelease:1 room:0.3 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "accelerate" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 2/1 | s:sax accelerate:0 ]",
|
||||
|
||||
@@ -1,14 +1,30 @@
|
||||
fetch('https://codeberg.org/api/v1/repos/uzu/strudel/pulls?state=closed&page=1')
|
||||
.then((res) => res.json())
|
||||
.then((pulls) => {
|
||||
const r = pulls
|
||||
.filter((pull) => pull.merged)
|
||||
.sort((a, b) => new Date(b.closed_at) - new Date(a.closed_at))
|
||||
.map((pull) => `${pull.closed_at} ${pull.title} by ${pull.user.login || '?'} in: [#${pull.number}](${pull.url}) `)
|
||||
.join('\n');
|
||||
console.log(r);
|
||||
});
|
||||
// this script loads all merged PRs within the given page range
|
||||
// it can be used to update the CHANGELOG.md file in a semi-automated way
|
||||
// the problem: codeberg doesn't support loading merged PRs, so we have to filter them in memory
|
||||
// luckily, we can sort after "recentupdate", which means we can do incremental changelog generation
|
||||
// todo: support setting a "last_updated" date, so the script would automatically check how far it has to go
|
||||
|
||||
/*
|
||||
async function main() {
|
||||
let pageStart = 1;
|
||||
let pageEnd = 1;
|
||||
let prs = [];
|
||||
for (let p = pageStart; p <= pageEnd; p++) {
|
||||
console.log(`load page ${p}/${pageEnd}`);
|
||||
const res = await fetch(
|
||||
`https://codeberg.org/api/v1/repos/uzu/strudel/pulls?state=closed&sort=recentupdate&page=${p}`,
|
||||
);
|
||||
const pulls = await res.json();
|
||||
const merged = pulls.filter((pull) => pull.merged);
|
||||
prs = prs.concat(merged);
|
||||
}
|
||||
const output = prs
|
||||
.sort((a, b) => new Date(b.closed_at) - new Date(a.closed_at))
|
||||
.map(
|
||||
(pull) => `- ${pull.closed_at} ${pull.title} by @${pull.user.login || '?'} in: [#${pull.number}](${pull.url}) `,
|
||||
)
|
||||
.join('\n');
|
||||
console.log('-------------');
|
||||
console.log(output);
|
||||
}
|
||||
|
||||
*/
|
||||
main();
|
||||
|
||||
@@ -53,6 +53,7 @@ Available tags are:
|
||||
- `@url`: web page(s) related to the music (git repository, Soundcloud link, etc.)
|
||||
- `@genre`: music genre(s) (pop, jazz, etc.)
|
||||
- `@album`: music album name
|
||||
- `@tag`: custom tag
|
||||
|
||||
Note to tool authors: _Never_ trust that a song has filled those fields with syntactically correct values; make sure your software is robust enough it doesn't break if it encounters bad values
|
||||
|
||||
@@ -92,3 +93,21 @@ If a tag doesn't accept a list, it can take multi-line values:
|
||||
the sofa in the living room.
|
||||
*/
|
||||
```
|
||||
|
||||
# Searching meta-data in the online repl
|
||||
|
||||
Meta-data can be used in the search field of the patterns tab in the online repl.
|
||||
|
||||
For example to search for all patterns by a specific author use the search term
|
||||
|
||||
```
|
||||
by: Ada L
|
||||
```
|
||||
|
||||
or search for patterns with a specific genre like
|
||||
|
||||
```
|
||||
genre: unicorns
|
||||
```
|
||||
|
||||
Hint: If no meta-data property is provided in the search all patterns with a `@title`, `@by` or `@tag` matching the search term will be shown.
|
||||
|
||||
Reference in New Issue
Block a user