Controlled decelertion of LFO signals around given values

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Controlled decelertion of LFO signals around given values

daniel-mayer
Hi,

I’ve got the following demand concerning an LFO oscillating between bounds a and b. Let's say I want to define an arbitrary number of points within the interval:

a < x0 < x1 < … < xN < b

Now I want to slow down the defined LFO movement around those intermediate points. Of course I’d also like to control the amount of deceleration. I imagine implementing such with segmented waveshaping (a more clumsy workaround would be mimicking e.g. with an Env and sine segments).

But I also suppose people have already developed solutions for such a scenario, do you know about something out there ?

Greetings

Daniel

-------------------------
http://daniel-mayer.at
-------------------------

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|

Re: Controlled decelertion of LFO signals around given values

shiihs
daniel-mayer wrote

> I’ve got the following demand concerning an LFO oscillating between bounds
> a and b. Let's say I want to define an arbitrary number of points within
> the interval:
>
> a < x0 < x1 < … < xN < b
>
> Now I want to slow down the defined LFO movement around those intermediate
> points. Of course I’d also like to control the amount of deceleration. I
> imagine implementing such with segmented waveshaping (a more clumsy
> workaround would be mimicking e.g. with an Env and sine segments).

Sorry, I'm a bit confused. Just to be clear: are a, x0,...,xN, b moments in
time where you try to momentarily slow down the LFO? but the word "bounds"
suggests perhaps it's something about amplitudes?

Do I understand correctly you are looking for some kind of easing/tweening
code?

I did experiment with composable tweening (in a different context, but the
ideas can be transplanted to the current context I think) in python last
summer (see e.g.
https://github.com/shimpe/pyvectortween/blob/master/examples/example_sequential.py
).

The idea there was to specify number animations with user specifiable
tweening, and compose several of those number animations together into
bigger sequential number animations. Such composed sequential animation can
be used as if it were a single number animation, but it has the effect of
running all the animations it's composed of in sequence (including all
intermediate tweening).

If no one else has a better/ready-made solution, I think the same mechanism
should be usable to accomplish what you are trying to achieve.




--
Sent from: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/SuperCollider-Users-New-Use-this-f2676391.html

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|

Re: Controlled decelertion of LFO signals around given values

daniel-mayer
Hi Stefaan,

thanks for your feedback and input. Indeed this is comparable, but I'd stay within one dimension


Sorry, I'm a bit confused. Just to be clear: are a, x0,...,xN, b moments in
time where you try to momentarily slow down the LFO? but the word "bounds"
suggests perhaps it's something about amplitudes? 

Right, amplitudes, they should also be possibly dynamic.


Meanwhile I've written the segmented waveshaping solution and it works very well in my use case. Maybe some of you want to test it ?
My application was a control purpose, but the thing can be used for synthesis as well.

To get it working you'd have to have miSCellaneous_lib installed, it's based on the SmoothClipX pseudo ugens.
The number of segments is fixed and to ensure correct multichannel expansion, some of the inputs must be ref'd.

Args:

in: source for segmented waveshaping
compareRef: bounds, assumed to be ordered, otherwise useless results. can be ugens too
amountRef: smoothing amount, like with SmoothClipX
curveRef: segments can -- in addition to sine smooth amount -- be exponentially shaped 

///////////////////////////////////////////////////////

// miSCellaneous must be installed
// save under Extensions in a .sc file and recompile SC

GreaterThanIndex : UGen {

*ar { |in, compareRef|
^this.multiNew(in, compareRef)
}

*kr { |in, compareRef|
^this.multiNew(in, compareRef)
}

*new1 { |in, compareRef|
^(compareRef.value.collect { |x| in >= x }).sum
}
}

SmoothMultiShapeS : UGen {

*ar { |in, compareRef, amountRef, curveRef, delta = 0.00001|
^this.multiNew(\audio, in, compareRef, amountRef, curveRef, delta)
}

*kr { |in, compareRef, amountRef, curveRef, delta = 0.00001|
^this.multiNew(\control, in, compareRef, amountRef, curveRef, delta)
}

*new1 { |rate, in, compareRef, amountRef, curveRef, delta = 0.00001|
var selector = this.methodSelectorForRate(rate),
compare = compareRef.(), amount = amountRef.(), curve = curveRef.(),
smoothClips, index;

smoothClips = (compare.size - 1).collect { |i|
var mid, sig;
mid = compare[i] + compare[i+1] * DC.perform(selector, 0.5);

sig = SmoothClipS.perform(selector, in, compare[i], compare[i+1], amount[i], delta);
curveRef.notNil.if {
(sig < mid).if(
sig.lincurve(compare[i], mid, -1, 1, curve[i]).linlin(-1, 1, compare[i], mid),
sig.lincurve(mid, compare[i+1], -1, 1, curve[i].neg).linlin(-1, 1, mid, compare[i+1]) )
}{
sig
}
};

index = max(0, GreaterThanIndex.perform(selector, in, compareRef) - 1);
^Select.perform(selector, index, smoothClips)
}
}

///////////////////////////////////////////////////////


See attached plot or



(
{ [
// segmented waveshaping, segments are half linear + half sine smoothened
Line.ar(-1, 1, 0.1, doneAction: 2),
`[-1, -0.7, 0, 0.6, 1],
`(0.5!4)
),
// full sine smoothing
Line.ar(-1, 1, 0.1),
`[-1, -0.7, 0, 0.6, 1],
`(1!4)
),
// additional exponential curvature
Line.ar(-1, 1, 0.1),
`[-1, -0.7, 0, 0.6, 1],
`(1!4),
`(5!4)
),
// no sine smoothing -> linear mapping
Line.ar(-1, 1, 0.1),
`[-1, -0.7, 0, 0.6, 1],
`(0!4)
),
// only exponential curvature
Line.ar(-1, 1, 0.1),
`[-1, -0.7, 0, 0.6, 1],
`(0!4),
`(5!4)
)
] }.plot(0.1)
)


// audio example with multichannel expansion
// higher curve values (MouseY) lead to a kind of smoothened bit crusher effect

(
{
SinOsc.ar([50, 51]),
`[-1, MouseX.kr(-0.7, -0.2), 0,  MouseX.kr(0.1, 0.9), 1],
`(1!4),
`(MouseY.kr(0, 10)!4),
) * 0.2
}.scope
)


As everything (except the number of segments, but even here one could be flexible below a max) can be controlled dynamically I suppose nice synthesis applications can be possible. I'll add with the next miSCellaneous update.

Greetings

Daniel

----------------------------------------------------
http://daniel-mayer.at/software_en.htm
----------------------------------------------------


Reply | Threaded
Open this post in threaded view
|

Re: Controlled decelertion of LFO signals around given values

daniel-mayer

Am 13.02.2018 um 22:10 schrieb [hidden email]:

>
> sig.lincurve(compare[i], mid, -1, 1, curve[i]).linlin(-1, 1, compare[i], mid),
> sig.lincurve(mid, compare[i+1], -1, 1, curve[i].neg).linlin(-1, 1, mid, compare[i+1]) )



... oops, leftover from an unnecessary complication, this should do


                                        sig.lincurve(compare[i], mid, compare[i], mid, curve[i]),
                                        sig.lincurve(mid, compare[i+1], mid, compare[i+1], curve[i].neg)


The lincurve mapping only has to run in parallel if a curveRef arg is passed, otherwise it's omitted anyway.
BTW negative curvature values shift the breakpoints to the middle of the segments, e.g. compare

(
{ [
        // only exponential curvature
        SmoothMultiShapeS.ar(
                Line.ar(-1, 1, 0.1),
                `[-1, -0.7, 0, 0.6, 1],
                `(0!4),
                `(5!4)
        ),
        SmoothMultiShapeS.ar(
                Line.ar(-1, 1, 0.1),
                `[-1, -0.7, 0, 0.6, 1],
                `(0!4),
                `(-5!4)
        )

] }.plot(0.1)
)


Regards

Daniel

----------------------------------------------------
http://daniel-mayer.at/software_en.htm
----------------------------------------------------


_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/