Preventing Slide~ from descending until it has ascended to a value

DanBennett's icon

I've been trying to work out how to engineer something like this, but haven't got very far.

I'd like to create an envelope (simple attack, sustain, release) that can also go up to audio spectrum rates, and where I can control the curve of the line.
To go into the audio spectrum without glitchiness it'll need to be signal input. Also I want to ensure that the attack segment completes before the release is allowed to kick in.

The way I thought of doing it is using slide~ to turn an incoming "gate" signal (either 1 or 0) into a ramp/curve. This is fine so far as it goes, but if the incoming gate signal goes back to 0 before slide reaches 1, then slide begins its descent regardless.

Any ideas on something I could put between the gate signal and the slide input such that once the gate input leaves 0, it is not allowed to fall back down to 0 again until the slide~ output has reached 1?
If the slide output reaches 1 and the gate input is still at 1 it should then hold at 1 until the gate input falls
ie
I've tried a few things with the bitwise operators but I can't figure out anything that works.

Roman Thilenius's icon

change second argument to 9999999 until you want it to get back to 250?

DanBennett's icon

Not a bad idea as a workaround to try.

I guess, on thinking about it and refining the question, what I think I'd need to get this (and other things I'm interested in) working is a signal rate flip-flop switch.
Ie When it receives a 1 (or passes a certain threshold) it goes to (and holds at) 1 until it receives a 0 (or goes below a certain threshold) it outputs (and holds at) 0.

Easy to do at message rate, but I can't see how to do it in signal objects.
I'd be surprised if an object didn't exist somewhere - am I just not looking hard enough.

pdelges's icon

Sound like a schmitt trigger. thresh~ can do that.

p

DanBennett's icon

Ah thanks again Looks like thresh~ would do that.

But I just realised I was on wrong track. I'm being a bit muddled about this.
Each mistake gets me closer though.

So
I've realised that using a change~ on the output of the envelope I can pick out when it's rising (1), falling(-1) or steady (0)
if I put that output through

So I could combine that output with the gate input and some binary logic to get the desired input to the env.
I just can't work out the binary logic operation to get the result I want!

Truth table looks like this:

Change < 1____Gate In__ desired result
0 _____________ 0 ________1
0 _____________ 1 ________1
1 _____________ 0 ________1
1 _____________ 1 ________0

Any ideas what object or combination of objects will get me from the first two columns to the third?

DanBennett's icon

I swear I just needed to write the problem down!

in case anyone else wants to do the same thing:
I think if I invert the gate using ==0, I can then use AND on inverted gate & [change~ into

Peter McCulloch's icon

*~ and ==~ 0 will also produce that truth table. (*~ works well as a logical and)

Peter McCulloch's icon

Also, you may want to see this thread: https://cycling74.com/forums/tapestart-emulation regarding the timing of slide~. You'll find that it's WAY off for large values.

DanBennett's icon

Thanks - I've always wondered whether there were there any performance benefits in using &&~ over *~ for this function (or vice versa)?
I imagine quite small if so anyway - simble bitwise operations are meat and potatoes for computers.

Good to know about the timing peculiarities with slide~ also.
I've since realised that deltaclip~ will work better than slide~ since I don't want retriggers during the release period to take as long to travel, say, 0.5 to 1 as an attack from 0 would. So in practice, I actually want to control rate rather than period of slew. I'll sort curve control by putting a pow~ on the output.

This is all scribbled on the back of an envelope (no pun intended) at the moment but when I actually get a chance to sit in front of a pc with MAX on it, I'll build and post for anyone who's interested.