diff --git a/dev/src/dsp-definitions/07-param-layers.ts b/dev/src/dsp-definitions/07-param-layers.ts index aefb2f3..de8e905 100644 --- a/dev/src/dsp-definitions/07-param-layers.ts +++ b/dev/src/dsp-definitions/07-param-layers.ts @@ -3,23 +3,26 @@ import type { DspDefinition } from "../types"; const dsp = ` import("stdfaust.lib"); +isFirstTick = ba.time == 0; +sAndHWithDefault(default, trig, x) = ba.sAndH(isFirstTick | trig, select2(isFirstTick, x, default)); + changed(x) = x != x'; layerIsAwake(l,x,t) = return with { - layerChange = l : changed; - startPos = x : ba.sAndH(layerChange); - nudged = abs(x - startPos) > t; - return = layerChange,nudged : ba.on_and_off : _ == 0; + layerChange = l : changed; + startPos = x : ba.sAndH(layerChange); + nudged = abs(x - startPos) > t; + return = layerChange,nudged : ba.on_and_off : _ == 0; }; -layerValue(l,i,x) = return with { - return = x : ba.sAndH((l == i) & layerIsAwake(l,knob,0.1)); +layerValue(l,i,t,x) = return with { + return = x : sAndHWithDefault(0.5, (l == i) & layerIsAwake(l,knob,t)); }; layer = hslider("layer", 0.0, 0.0, 2.0, 1.0); knob = hslider("knob", 0.0, 0.0, 1.0, 0.001); -layerOutput(i) = layerValue(layer,i,knob): hbargraph("value %i", 0.0, 1.0); +layerOutput(i) = layerValue(layer,i,0.1,knob): hbargraph("value %i", 0.0, 1.0); process = par(i, 3, layerOutput(i)); `; diff --git a/dev/src/dsp-definitions/31-echoloop-live.ts b/dev/src/dsp-definitions/31-echoloop-live.ts index 11c9090..5be7b15 100644 --- a/dev/src/dsp-definitions/31-echoloop-live.ts +++ b/dev/src/dsp-definitions/31-echoloop-live.ts @@ -1,28 +1,97 @@ import type { DspDefinition } from "../types"; +// L -> send -> sum ---> L +// ^ +// delay(main) +// R ------------+---- delay(offset) -> R + +// foo[OWL:A], bar[OWL:B] + const dsp = ` import("stdfaust.lib"); -loop_delay_time = hslider("delay time", 500.0, 0.0, 1000.0, 0.1) * 0.001 * ma.SR; -loop_delay = de.delay(ma.SR, loop_delay_time); -fb_loop = loop_delay; +// +// param layers +// + +changed(x) = x != x'; -right_channel_delay_time = hslider("right channel delay time", 250.0, 0.0, 1000.0, 0.1) * 0.001 * ma.SR; -right_channel_delay = de.delay(ma.SR, right_channel_delay_time); +sAndHWithDefault(default, trig, x) = return with { + isFirstTick = ba.time == 0; + sample = select2(isFirstTick, x, default); + return = ba.sAndH(isFirstTick | trig, sample); +}; + +layerIsAwake(l,x,t) = return with { + layerChange = l : changed; + startPos = x : ba.sAndH(layerChange); + nudged = abs(x - startPos) > t; + return = layerChange,nudged : ba.on_and_off : _ == 0; +}; + +layerValue(d,l,i,t,x) = return with { + return = x : sAndHWithDefault(d, (l == i) & layerIsAwake(l,x,t)); +}; + +// +// bitcrusher +// + +bitcrusher(nbits,x) = return with { + // floor(x) = x : int; + scaler = float(2^nbits - 1); + return = floor(x * scaler) / scaler; +}; -dry_volume = hslider("dry", 1.0, 0.0, 1.0, 0.01); -dry(x) = x * dry_volume; +// +// params +// -wet_volume = hslider("wet", 0.5, 0.0, 1.0, 0.01); -wet(x) = x * wet_volume; +dry_volume_param = hslider("dry", 1.0, 0.0, 1.0, 0.01); +wet_volume_param = hslider("wet", 0.5, 0.0, 1.0, 0.01); -feedback = hslider("feedback", 0.5, 0.0, 1.0, 0.01); +button_alt = checkbox("alt[OWL:B1]"); +button_snapshot = button("snapshot[OWL:B2]"); -dsp(l, r) = (l + r * feedback), (r : right_channel_delay); +time_param = hslider("time[OWL:A]", 500.0, 0.0, 1000.0, 0.1); +feedback_param = hslider("feedback[OWL:B]", 0.5, 0.0, 1.0, 0.01); + +// +// param layers +// + +delay_left_time = time_param : layerValue(500.0, button_alt, 0, 10.0) * 0.001 * ma.SR; +delay_right_time = time_param : layerValue(250.0, button_alt, 1, 10.0) * 0.001 * ma.SR; + +delay_left = de.delay(ma.SR, delay_left_time); +delay_right = de.delay(ma.SR, delay_right_time); + +feedback_amount = feedback_param : layerValue(0.5, button_alt, 0, 0.05); +bitcrush_amount = feedback_param : layerValue(1.0, button_alt, 1, 0.05); + +// +// dsp +// + +feedback_path(x) = (x * feedback_amount) : delay_left : bitcrusher(bitcrush_amount * 16.0); +dsp(l, r) = (l + (r : feedback_path)), (r : delay_right); + +// +// simulated feedback loop +// + +feedback_loop = _; + +// +// routing +// loop(dsp, fb, l) = (l, fb : dsp), fb; lr(l, r) = r, l; -alchemist(dsp, x) = x : loop(dsp) ~ fb_loop : !,_,_ : lr; +alchemist(dsp, x) = x : loop(dsp) ~ feedback_loop : !,_,_ : lr; + +dry(x) = x * dry_volume_param; +wet(x) = x * wet_volume_param; echoloop(dsp, l, r) = out with {