From a525de2522d442e0ca005cd083c738ff3ae0d39e Mon Sep 17 00:00:00 2001 From: Jonathan Borne Date: Sun, 4 Aug 2019 17:37:03 +0000 Subject: [PATCH 01/11] Adding holdAndJoin in signals.lib: A function that holds its input value when receiving a :off: trigger. When receiving a :on: trigger, the function waits for the input value to join the held value. Once the input joins the ouput value, the function is bypassed. --- signals.lib | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/signals.lib b/signals.lib index 9a8c7586..05b1ae66 100644 --- a/signals.lib +++ b/signals.lib @@ -154,6 +154,108 @@ polySmooth(g,s,d) = smooth(s*((g==(g@d)) | (g == 0))); //------------------------------------------------------------------- smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); +//-----------------------`(si.)holdAndJoin`-------------------------------- +// A function that holds its output +// signal when a 'off' trigger is sent to it. +// When a 'on' trigger is received +// the function waits until the input signal +// joins the held value. Once the input +// value joins the output value the function is bypassed. +// +// When working with multi-timbral synthesizers, some parameters +// might be shared between different synth voices (filter cutoff, resonance, ...). +// It is common that such a parameter will +// be controlled by a physical potentiometer sending Midi CC. +// Depending on which synthesizer voice has the focus, the user might set +// the potentiometer to different positions. +// When switching back to a voice, the parameters values +// might jump because the potentiometers physical positions +// do not match the parameters values anymore. +// +// Wrong jump example: +// Focus on voice 1: setting cutoff to 200 Hz via midi CC 54 +// Focus on voice 2: setting cutoff to 1000 Hz via midi CC 54 +// Focus on voice 1: setting cutoff -> value jumps abruptly to 1000 Hz. +// +// On the above example we would prefer to: +// - Hold the parameter value when we lose focus on voice 1. +// - When focus goes back to voice1, wait +// for the potentiometer position to +// join the parameter value to regain control. +// +// Wrong Jump, Illustration: +// +// ``` +// (At time 0, the focus is on the synthesizer voice 1.) +// 127 ^ +// | /\ ! . ! +// | /\ / \!______________! /\ +// |/ \ / !. . . ! / \ / +// | \/ ! . . . . ! /\ / \ / +// | ! . . ..!/ \/ \/ +// 0 +-----------!--------------!-------------------------------> t +// Input CC !<--- hold --->! Input CC regain control +// sets ! param value ! of param value but +// the param ! until we ! jumps abruptly from the held value +// value ! acquire focus! to the CC value +// ! ! +// v ^ +// focus lost focus +// acquired +// ``` +// +// holdAndjoin, illustration: +// +// ``` +// (At time 0, the focus is on voice 1.) +// +// 127 ^ +// | /\ ! . ! /\ +// | /\ / \!______________!_______________/ \ /\ +// |/ \ / !. . . ! .! \ / \ +// | \/ ! . . . . ! .. ... .. . ! \/ +// | ! . . ..!. .. .. . ! +// 0 +-----------!--------------!---------------!----------------> t +// Input CC !<--- hold --->!<--- wait ---> ! Input CC +// sets ! param value ! until input CC! regain control +// the param ! until we ! joins the ! of param value +// value ! acquire focus! param value ! +// ! ! ! +// v ^ +// focus lost focus +// acquired +// Ascii : +// / : parameter value +// . : Midi CC value +// ``` +// +// #### Usage +// +// ``` +// hslider(...),g : holdAndJoin : _ +// ``` +// +// #### Usage Example +// +// ``` +// x = hslider("x[midi:ctrl 30]", 0, 0, 127, 1); +// focus = (checkbox("focus_lost") + 1) % 2; +// process = x, focus : holdAndJoin : hbargraph("y", 0, 127); +// ``` +// +// Where: +// +// * `x`: the input signal +// * `g`: the hold signal (0 for hold, 1 for bypass) +//------------------------------------------------------------------- +holdAndJoin(x,g) = (joined_h : _, h), x : select2((g == 1) & (_)) +with { + joined_h = (_, _ :> (joined, joined) :> _, _) ~ ((h, h) :> _, _); + joined = \(c).((g == 1) & (x == c)) , (g == 0) : ba.on_and_off; + h(j) = x : ba.sAndH((g == 1) & (j == 1)); +}; + + //-----------------------------`(si.)bsmooth`------------------------------ // Block smooth linear interpolation during a block of samples. // From 1bd595d27641d7526c7539e467d44f47e55aac08 Mon Sep 17 00:00:00 2001 From: Jonathan Borne Date: Sun, 15 Sep 2019 19:03:27 +0000 Subject: [PATCH 02/11] Modified HoldAndJoin documentation example: variables names --- signals.lib | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/signals.lib b/signals.lib index 05b1ae66..221042a2 100644 --- a/signals.lib +++ b/signals.lib @@ -160,7 +160,7 @@ smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); // When a 'on' trigger is received // the function waits until the input signal // joins the held value. Once the input -// value joins the output value the function is bypassed. +// value joins the held value the function is bypassed. // // When working with multi-timbral synthesizers, some parameters // might be shared between different synth voices (filter cutoff, resonance, ...). @@ -238,15 +238,15 @@ smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); // #### Usage Example // // ``` -// x = hslider("x[midi:ctrl 30]", 0, 0, 127, 1); -// focus = (checkbox("focus_lost") + 1) % 2; -// process = x, focus : holdAndJoin : hbargraph("y", 0, 127); +// in = hslider("in", 0, 0, 127, 1); +// b = checkbox("Hold/Join"); +// process = in, b : holdAndJoin : hbargraph("out", 0, 127); // ``` // // Where: // -// * `x`: the input signal -// * `g`: the hold signal (0 for hold, 1 for bypass) +// * `in`: the input signal +// * `b`: the hold signal (0 for hold, 1 for Join) //------------------------------------------------------------------- holdAndJoin(x,g) = (joined_h : _, h), x : select2((g == 1) & (_)) with { From 1f3f536c21dc06b7c16496f33e1d70a169b5f942 Mon Sep 17 00:00:00 2001 From: Jonathan Borne Date: Sun, 15 Sep 2019 21:12:19 +0000 Subject: [PATCH 03/11] Cleaned HoldAndJoin: explicitely named function inputs, removed useless duplication of joined, clarified documentation --- signals.lib | 72 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/signals.lib b/signals.lib index 221042a2..cc3b3c97 100644 --- a/signals.lib +++ b/signals.lib @@ -154,27 +154,37 @@ polySmooth(g,s,d) = smooth(s*((g==(g@d)) | (g == 0))); //------------------------------------------------------------------- smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); -//-----------------------`(si.)holdAndJoin`-------------------------------- -// A function that holds its output -// signal when a 'off' trigger is sent to it. -// When a 'on' trigger is received -// the function waits until the input signal -// joins the held value. Once the input -// value joins the held value the function is bypassed. -// -// When working with multi-timbral synthesizers, some parameters -// might be shared between different synth voices (filter cutoff, resonance, ...). -// It is common that such a parameter will -// be controlled by a physical potentiometer sending Midi CC. -// Depending on which synthesizer voice has the focus, the user might set -// the potentiometer to different positions. -// When switching back to a voice, the parameters values -// might jump because the potentiometers physical positions -// do not match the parameters values anymore. +//-----------------------`(si.)holdOrJoin`-------------------------------- +// +// This function takes a signal "i" as input and a boolean +// value representing the state of the function (hold or join). +// Suppose we start in join mode, the function outputs its +// input signal. +// When the function goes into "hold" state for the first time +// it samples, holds and output the input signal value "i0". +// +// When going back into join mode, +// the function outputs "i0" until the input signal +// joins "i0" (i==i0). +// The function then outputs "i" again. +// +// If we go into hold state again and +// "i" hasn't joined "i0" the function keeps outputting "i0" +// +// This function solves the particular use case of controlling +// Multitimbral synthesizer parameters via midi controllers. +// As an example: +// Filter cutoff potentiometer might be +// shared between the multiples voices of the synth. +// Depending on which synthesizer voice has the focus, +// the user might move the potentiometer to different positions. +// When switching between voices, the parameter value +// might jump because the potentiometer physical position +// do not match the parameter value anymore. // // Wrong jump example: -// Focus on voice 1: setting cutoff to 200 Hz via midi CC 54 -// Focus on voice 2: setting cutoff to 1000 Hz via midi CC 54 +// Focus on voice 1: setting cutoff to 200 Hz +// Focus on voice 2: setting cutoff to 1000 Hz // Focus on voice 1: setting cutoff -> value jumps abruptly to 1000 Hz. // // On the above example we would prefer to: @@ -204,7 +214,7 @@ smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); // acquired // ``` // -// holdAndjoin, illustration: +// holdOrjoin, illustration: // // ``` // (At time 0, the focus is on voice 1.) @@ -232,7 +242,7 @@ smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); // #### Usage // // ``` -// hslider(...),g : holdAndJoin : _ +// hslider(...),g : holdOrJoin : _ // ``` // // #### Usage Example @@ -240,22 +250,26 @@ smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); // ``` // in = hslider("in", 0, 0, 127, 1); // b = checkbox("Hold/Join"); -// process = in, b : holdAndJoin : hbargraph("out", 0, 127); +// process = in, b : holdOrJoin : hbargraph("out", 0, 127); // ``` // // Where: // -// * `in`: the input signal -// * `b`: the hold signal (0 for hold, 1 for Join) +// * `i`: the input signal +// * `b`: the function state (0 for hold, 1 for join) //------------------------------------------------------------------- -holdAndJoin(x,g) = (joined_h : _, h), x : select2((g == 1) & (_)) +holdOrJoin(i, b) = (joined_h(i, b) <: _, holder(i)), i : select2((b == 1) & (_)) with { - joined_h = (_, _ :> (joined, joined) :> _, _) ~ ((h, h) :> _, _); - joined = \(c).((g == 1) & (x == c)) , (g == 0) : ba.on_and_off; - h(j) = x : ba.sAndH((g == 1) & (j == 1)); + // Ensure we do not sample a new value if the old value hasn't + // been joined. + joined_h(i,b) = joined(i,b) ~ holder(i) + with { + joined(i,b,h) = ((b == 1) & (i == h)) , (b == 0) : ba.on_and_off; + }; + // sample if in hold mode AND previous sampled value was joined + holder(i,j) = i : ba.sAndH((b == 1) & (j == 1)); }; - //-----------------------------`(si.)bsmooth`------------------------------ // Block smooth linear interpolation during a block of samples. // From 93ae780ec9739711817b19dd13d92e4756dba9d6 Mon Sep 17 00:00:00 2001 From: Jonathan Borne Date: Sun, 15 Sep 2019 21:38:17 +0000 Subject: [PATCH 04/11] Minor fixes --- signals.lib | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/signals.lib b/signals.lib index cc3b3c97..fc872892 100644 --- a/signals.lib +++ b/signals.lib @@ -157,25 +157,27 @@ smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); //-----------------------`(si.)holdOrJoin`-------------------------------- // // This function takes a signal "i" as input and a boolean -// value representing the state of the function (hold or join). -// Suppose we start in join mode, the function outputs its +// value representing the state of the function (0 = hold, 1 = join). +// Suppose we start in "join" state, the function simply outputs its // input signal. // When the function goes into "hold" state for the first time -// it samples, holds and output the input signal value "i0". +// it samples, holds and output the input sampled value "s0". // -// When going back into join mode, -// the function outputs "i0" until the input signal -// joins "i0" (i==i0). -// The function then outputs "i" again. +// When going back into "join" state, +// the function outputs "s0" until the input signal +// joins "s0". // -// If we go into hold state again and -// "i" hasn't joined "i0" the function keeps outputting "i0" +// As soon as the input signal "i" joins the +// value "s0" the function switch its output to "i". +// +// Rem: If we go into "hold" state again and +// "i" hasn't joined "s0" the function keeps outputting "s0". // // This function solves the particular use case of controlling // Multitimbral synthesizer parameters via midi controllers. // As an example: // Filter cutoff potentiometer might be -// shared between the multiples voices of the synth. +// shared between the multiples voices of a synth. // Depending on which synthesizer voice has the focus, // the user might move the potentiometer to different positions. // When switching between voices, the parameter value From 583629248abf100abc382ac3e9045bc7423f4831 Mon Sep 17 00:00:00 2001 From: Jonathan Borne Date: Mon, 16 Sep 2019 21:04:47 +0000 Subject: [PATCH 05/11] Updated holdOrJoin documentation --- signals.lib | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/signals.lib b/signals.lib index fc872892..0d0ed3dc 100644 --- a/signals.lib +++ b/signals.lib @@ -156,23 +156,16 @@ smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); //-----------------------`(si.)holdOrJoin`-------------------------------- // -// This function takes a signal "i" as input and a boolean -// value representing the state of the function (0 = hold, 1 = join). -// Suppose we start in "join" state, the function simply outputs its -// input signal. -// When the function goes into "hold" state for the first time -// it samples, holds and output the input sampled value "s0". -// -// When going back into "join" state, -// the function outputs "s0" until the input signal -// joins "s0". -// -// As soon as the input signal "i" joins the -// value "s0" the function switch its output to "i". -// -// Rem: If we go into "hold" state again and -// "i" hasn't joined "s0" the function keeps outputting "s0". -// +// The simplest way to understand this function is to compare it to +// the sample and hold function from the basic library (ba.sAndH) +// sAndH has two states: +// - In state 1 it holds a value sampled from its input, +// - In state 2 it releases the value and becomes a pass through. +// holdOrJoin is basically a sample and hold with a join property: +// - In one state it holds a value sampled from its input +// - In the other, it release the value and becomes a pass through +// but only after the input joined the held value... +// // This function solves the particular use case of controlling // Multitimbral synthesizer parameters via midi controllers. // As an example: @@ -260,16 +253,17 @@ smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); // * `i`: the input signal // * `b`: the function state (0 for hold, 1 for join) //------------------------------------------------------------------- -holdOrJoin(i, b) = (joined_h(i, b) <: _, holder(i)), i : select2((b == 1) & (_)) +holdOrJoin(i, b) = joined_h(i, b) , i : select2((b == 1) & (_)) with { // Ensure we do not sample a new value if the old value hasn't // been joined. - joined_h(i,b) = joined(i,b) ~ holder(i) + joined_h(i,b) = joined(i,b) ~ holder(i) with { - joined(i,b,h) = ((b == 1) & (i == h)) , (b == 0) : ba.on_and_off; + joined(i,b,h,thru) = + ((b == 1) & (i == h)) , (b == 0) : ba.on_and_off, thru; }; // sample if in hold mode AND previous sampled value was joined - holder(i,j) = i : ba.sAndH((b == 1) & (j == 1)); + holder(i,j) = i : ba.sAndH((b == 1) & (j == 1)) <: _,_; }; //-----------------------------`(si.)bsmooth`------------------------------ From 817463d74328aa34b075da5dfbb3614fc91c8073 Mon Sep 17 00:00:00 2001 From: Jonathan Borne Date: Mon, 16 Sep 2019 21:24:52 +0000 Subject: [PATCH 06/11] Updated holdOrJoin --- signals.lib | 68 ----------------------------------------------------- 1 file changed, 68 deletions(-) diff --git a/signals.lib b/signals.lib index 0d0ed3dc..fedf6bea 100644 --- a/signals.lib +++ b/signals.lib @@ -166,74 +166,6 @@ smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); // - In the other, it release the value and becomes a pass through // but only after the input joined the held value... // -// This function solves the particular use case of controlling -// Multitimbral synthesizer parameters via midi controllers. -// As an example: -// Filter cutoff potentiometer might be -// shared between the multiples voices of a synth. -// Depending on which synthesizer voice has the focus, -// the user might move the potentiometer to different positions. -// When switching between voices, the parameter value -// might jump because the potentiometer physical position -// do not match the parameter value anymore. -// -// Wrong jump example: -// Focus on voice 1: setting cutoff to 200 Hz -// Focus on voice 2: setting cutoff to 1000 Hz -// Focus on voice 1: setting cutoff -> value jumps abruptly to 1000 Hz. -// -// On the above example we would prefer to: -// - Hold the parameter value when we lose focus on voice 1. -// - When focus goes back to voice1, wait -// for the potentiometer position to -// join the parameter value to regain control. -// -// Wrong Jump, Illustration: -// -// ``` -// (At time 0, the focus is on the synthesizer voice 1.) -// 127 ^ -// | /\ ! . ! -// | /\ / \!______________! /\ -// |/ \ / !. . . ! / \ / -// | \/ ! . . . . ! /\ / \ / -// | ! . . ..!/ \/ \/ -// 0 +-----------!--------------!-------------------------------> t -// Input CC !<--- hold --->! Input CC regain control -// sets ! param value ! of param value but -// the param ! until we ! jumps abruptly from the held value -// value ! acquire focus! to the CC value -// ! ! -// v ^ -// focus lost focus -// acquired -// ``` -// -// holdOrjoin, illustration: -// -// ``` -// (At time 0, the focus is on voice 1.) -// -// 127 ^ -// | /\ ! . ! /\ -// | /\ / \!______________!_______________/ \ /\ -// |/ \ / !. . . ! .! \ / \ -// | \/ ! . . . . ! .. ... .. . ! \/ -// | ! . . ..!. .. .. . ! -// 0 +-----------!--------------!---------------!----------------> t -// Input CC !<--- hold --->!<--- wait ---> ! Input CC -// sets ! param value ! until input CC! regain control -// the param ! until we ! joins the ! of param value -// value ! acquire focus! param value ! -// ! ! ! -// v ^ -// focus lost focus -// acquired -// Ascii : -// / : parameter value -// . : Midi CC value -// ``` -// // #### Usage // // ``` From 89fcda14593d392d2427a6c231fa5949796d4e15 Mon Sep 17 00:00:00 2001 From: Jonathan Borne Date: Mon, 16 Sep 2019 21:36:22 +0000 Subject: [PATCH 07/11] Updated holdOrJoin: renamed to releaseAfterJoin, removed diagrams and usecase text (unnecessary complexity --- signals.lib | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/signals.lib b/signals.lib index fedf6bea..d411e135 100644 --- a/signals.lib +++ b/signals.lib @@ -154,7 +154,7 @@ polySmooth(g,s,d) = smooth(s*((g==(g@d)) | (g == 0))); //------------------------------------------------------------------- smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); -//-----------------------`(si.)holdOrJoin`-------------------------------- +//-----------------------`(si.)releaseAfterJoin`-------------------------------- // // The simplest way to understand this function is to compare it to // the sample and hold function from the basic library (ba.sAndH) @@ -169,15 +169,15 @@ smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); // #### Usage // // ``` -// hslider(...),g : holdOrJoin : _ +// hslider(...),g : releaseAfterJoin : _ // ``` // // #### Usage Example // // ``` // in = hslider("in", 0, 0, 127, 1); -// b = checkbox("Hold/Join"); -// process = in, b : holdOrJoin : hbargraph("out", 0, 127); +// b = checkbox("Hold/Release"); +// process = in, b : releaseAfterJoin : hbargraph("out", 0, 127); // ``` // // Where: @@ -185,7 +185,7 @@ smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); // * `i`: the input signal // * `b`: the function state (0 for hold, 1 for join) //------------------------------------------------------------------- -holdOrJoin(i, b) = joined_h(i, b) , i : select2((b == 1) & (_)) +releaseAfterJoin(i, b) = joined_h(i, b) , i : select2((b == 1) & (_)) with { // Ensure we do not sample a new value if the old value hasn't // been joined. From 613ac88389ee0b56687db7fad6197be19233b6f0 Mon Sep 17 00:00:00 2001 From: Jonathan Borne Date: Mon, 16 Sep 2019 21:38:54 +0000 Subject: [PATCH 08/11] Updated releaseAfterJoin doc: minor fix --- signals.lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/signals.lib b/signals.lib index d411e135..b2b8bb53 100644 --- a/signals.lib +++ b/signals.lib @@ -161,7 +161,7 @@ smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); // sAndH has two states: // - In state 1 it holds a value sampled from its input, // - In state 2 it releases the value and becomes a pass through. -// holdOrJoin is basically a sample and hold with a join property: +// releaseAfterJoin is basically a sample and hold with a join property: // - In one state it holds a value sampled from its input // - In the other, it release the value and becomes a pass through // but only after the input joined the held value... From 005f768723b22b1127427794b614afbea4aae0f7 Mon Sep 17 00:00:00 2001 From: Jonathan Borne Date: Mon, 16 Sep 2019 22:13:06 +0000 Subject: [PATCH 09/11] updated releaseAfterJoin: clearer example, changed the parameters order to match sAndH --- signals.lib | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/signals.lib b/signals.lib index b2b8bb53..7a577248 100644 --- a/signals.lib +++ b/signals.lib @@ -175,17 +175,19 @@ smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); // #### Usage Example // // ``` -// in = hslider("in", 0, 0, 127, 1); -// b = checkbox("Hold/Release"); -// process = in, b : releaseAfterJoin : hbargraph("out", 0, 127); +// in = hslider("input", 0, 0, 127, 1); +// b = (checkbox("Release/Hold")+1) %2;// Start from release state +// out_sAndH = ba.sAndH(b,in); +// out_releaseAfterJoin = releaseAfterJoin(b,in); +// process = (out_sAndH : hbargraph("sAndH output", 0, 127)), (out_releaseAfterJoin : hbargraph("releaseAfterJoin output", 0, 127)) ; // ``` // // Where: // -// * `i`: the input signal -// * `b`: the function state (0 for hold, 1 for join) +// * `in`: the input signal +// * `b`: the function state (hold, release) //------------------------------------------------------------------- -releaseAfterJoin(i, b) = joined_h(i, b) , i : select2((b == 1) & (_)) +releaseAfterJoin(b, i) = joined_h(i, b) , i : select2((b == 1) & (_)) with { // Ensure we do not sample a new value if the old value hasn't // been joined. From 175b0db58e01d1e7fab60295485bbe81af9676a6 Mon Sep 17 00:00:00 2001 From: Jonathan Borne Date: Mon, 16 Sep 2019 22:40:54 +0000 Subject: [PATCH 10/11] Fixed markdown syntax in releaseAfterJoin documentation --- signals.lib | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/signals.lib b/signals.lib index 7a577248..fbc943e4 100644 --- a/signals.lib +++ b/signals.lib @@ -155,21 +155,23 @@ polySmooth(g,s,d) = smooth(s*((g==(g@d)) | (g == 0))); smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); //-----------------------`(si.)releaseAfterJoin`-------------------------------- +// The simplest way to understand `releaseAfterJoin` is to compare it to +// `ba.sAndH` (sample and hold). +// `sAndH` has two states: // -// The simplest way to understand this function is to compare it to -// the sample and hold function from the basic library (ba.sAndH) -// sAndH has two states: -// - In state 1 it holds a value sampled from its input, -// - In state 2 it releases the value and becomes a pass through. -// releaseAfterJoin is basically a sample and hold with a join property: -// - In one state it holds a value sampled from its input -// - In the other, it release the value and becomes a pass through -// but only after the input joined the held value... +// * State 0: holds a value sampled from its input, +// * State 1: releases the value and becomes a pass through. +// +// `releaseAfterJoin` is basically a `sAndH` with a join property: +// +// * State 0: holds a value sampled from its input +// * State 1: releases the value and becomes a pass through +// **BUT** only after the input joined the held value... // // #### Usage // // ``` -// hslider(...),g : releaseAfterJoin : _ +// _ : releaseAfterJoin(b) : _ // ``` // // #### Usage Example From 5ccaad33164eb0ec48b4018b29a0154ab070d1b3 Mon Sep 17 00:00:00 2001 From: Jonathan Borne Date: Tue, 17 Sep 2019 11:47:57 +0000 Subject: [PATCH 11/11] Updated releaseAfterJoin: parameters order, put older inside with --- signals.lib | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/signals.lib b/signals.lib index fbc943e4..434ec0a7 100644 --- a/signals.lib +++ b/signals.lib @@ -189,17 +189,17 @@ smoothAndH(t,s) = smooth(s*t) : ba.sAndH(t); // * `in`: the input signal // * `b`: the function state (hold, release) //------------------------------------------------------------------- -releaseAfterJoin(b, i) = joined_h(i, b) , i : select2((b == 1) & (_)) +releaseAfterJoin(b, i) = joined_h(b, i) , i : select2((b == 1) & (_)) with { // Ensure we do not sample a new value if the old value hasn't // been joined. - joined_h(i,b) = joined(i,b) ~ holder(i) + joined_h(b,i) = joined(b,i) ~ holder(i) with { - joined(i,b,h,thru) = + joined(b,i,h,thru) = ((b == 1) & (i == h)) , (b == 0) : ba.on_and_off, thru; + // sample if in hold mode AND previous sampled value was joined + holder(i,j) = i : ba.sAndH((b == 1) & (j == 1)) <: _,_; }; - // sample if in hold mode AND previous sampled value was joined - holder(i,j) = i : ba.sAndH((b == 1) & (j == 1)) <: _,_; }; //-----------------------------`(si.)bsmooth`------------------------------