Math equation formula to spark patch. (Envelope Graph)

Hi, I need a lil bit of help here.
So I was messing around with Desmos trying to learn a bunch of formula to create different soundwave and somehow ended up trying to make an envelope.
It is an ADSR envelope, but I Intentionally left the decay out.
I want to create a patch that has similar function to this, but I don’t know how to translate it in patch. Especially to create the restriction in spark. And also the colon : part (i don’t know how to call it in english. is it like a compare/ratio or something?).
This is the graph:
[click play animation to each variables to see how each variable behaves/reacts to each other.]

I think it’s going to be a pretty handy tool in our arsenal.
I know that we have keyframe patch, but it can’t process shader generic signal, while this will hopefully can.

this is how the patch would look like:
the graph:

In desmos:

  • Input = x
  • Y max = ys
  • Attack = xa
  • Sustain = xs
  • Release = xr
  • Output = y

Can someone help me? lets just start with the restriction and the colon thingy or whatever it is called in english math. Thanksss :smiley:

The set notation is just defining the range for x. Maybe you could do something similar with “To Range” where you’d define the individual function ranges and then add them together?

Yeah. I know. I’m just still struggling to process it in my head to figure out what’s missing. cuz i tried the to range to set the restriction but when i test it with just a simple loop animation, the output number is just wrong.

So I’m stuck here:

Inside the ASR Patch:

This is the project file: ASR Envelope.arprojpkg (27.1 KB)
This is the patch only: ASR Envelope.arp (10.9 KB)

I have no idea how/where to go from here :sweat:

1 Like

Hey Adi,

I took the task at hand and it made my saturday interesting.

The colon denotes the Range of Y.
We could simplify this as y = { f(x) : g(x) }
Which would translate to clamping values of y between f(x) and g(x) where x is our input.

There is no need for to/from range patch as we have to work within the range given to use as f(x) and g(x), hence we do not want to define the range again. But yes that should be restricted between f(x) and g(x).

So I started working with the patch shared by you, by replacing the to range patches with Clamp patches. I couldn’t stop here so i decided to actually see if my interpretation of colon above was right.
Hence i decided to visualise this in spark.
I designed a base coordinate system and defined an origin in the center of the screen.

Then i print all three curves one by one using SDF line, here is the output.

Now i started drawing the curves.

Here are all 3 curves together.

It’s not very much optimised, but here is the project file attached.

Plotting clamped ranges_Draft02.arexport (476.0 KB)


Wow. Great work! thanks for sharing!
I’ll take a look at project file and try to absorb and make sense of how it works.
I mean, it definitely works based on the video, but idk if it’s actually doing what i want to achieve.

What I was trying to do is to make the X input from the ASR patch to throws out a Y output that follows the set of range in the patch. In audio processing, the X is time, and Y is the volume of a sound.
So this patch purpose was actually to modify the value/volume/intensity of a Y value by an A, S, R value in some X time progressively/continuously. Not necessarily to draw the graph, but hey, you did it! It’s actually super useful as a visual feedback. So Thanks!

Okay enough talking before actually seeing the project, I’ll be back to report it!
Once again, what a marvelous work Navi, I really appreciate it. Thanks!!

This is how it suppose to work:

1 Like

So I’ve been playing around with it a lil bit but it seems like it doesn’t really work like what I created in desmos.
The stages are suppose to be progressive. What I mean by that is that everything is meant to be a one continuous system, like the xr, should not be able to be smaller than the xs, and xs should not be able to be smaller than xa. with that said, then this should not be happening:
image (the magenta line end point should always greater or equal the length of the blue. while the start point should always at the end point of blue line. if the sustain is0, then the magenta start point should also greater or equal the attack (green) line end point.

1 Like

Aah ! The sound waves looks so interesting.

We can restricts the inputs like xr > xs >xa

I understood why this is happening, i have to change the offsets for curve-2 and curve-3.
The offsets are causing an error they might have been calculated more than once as i am increasing the number of curves.
Hopefully this can be fixed.

I will report back with a fix.

Yup! You are absolutely right.
By the way, you don’t have to make it too complicated by visualizing it using multiple sdf tho, cuz in envelope, it’s suppose to be working with this Input:

  • 1 main patch with only 1 main input (x value or for example time) whether it is triggered as one shot, or constant, or continuous or looped or mirror looped.
  • 4 parameter (1 attack length, 1 sustain length, 1 release length, and the Ymax).

The Y origin or Y start or (Y0) should be 0 by default
(except if you want to provide another input to set the start value for the Y).

And for the output should only be:

  • 1 main output which is the Y end (Y1) or the Y value at the xr end point.

The reason of why you shouldn’t make it too complicated using sdf line is simply because so people can try to experiment with this patch even with shader generic signal, for example a Luminance value, or Hue, or RGBA (not as a whole but as individual unpacked channel. which then could be packed again).
Another reason is simply because this envelope should be an alternative of the keyframe patch to create a ramp up, hold, and ramp down that works with any data type like mentioned in the previous reason.

Once again, thank you for your super valuable contribution here. This type of Interaction/passing ideas/collaboration is quite literally the reason why I love this community and especially this forum.
So glad to have you here @Navi !!

1 Like

Thank you for the detailed explanation of the envelope.
I have been trying to accomplish a very different output haha, no doubt i am loving our interaction on this.

Well, i think now the interpretation of our : (colon) should be changed from earlier.

According to the new interpretation of y = { f(x) : g(x) }
g(x) should represent the range of function y for all the values from domain function f(x).
f(x) → Domain
g(x) → Range

So our envelop should become something like this, let me know your thoughts on it.

ASR Envelope.arp (18.4 KB)

It’s almost correct. the problem right now is that when the x input reaches 1, the Y immediately jumps up to the Y max, where it suppose to ramps up in linear fashion. But the ramps down or the fade out is already correct. it gradually decreasing from Y max to origin in this case 0.

as we can see in this image, the input is 1 but the output jumps up to 2 which is caused by the if else patch.

also another problem is that because in this patch is using logic patches (greater than, less or equal, and, if than else), it makes this patch is not available for shader generic signal.

as we can see in the image, it throws out an error when i try to plug in Camlum (camera texture luminosity value).

This is the problem that I was trying to figure out since 2 days ago… We can use step and mix patch to replace the numerical logic, to shader logic, but even then i don’t know how to implement the colon part which is progressive from xa to then xs and reach Y max and then decline to the end point of the xr.
I know it’s such a niche problem and such a specific problem, and that’s exactly why i’m trying to figure it out. that’s the charm of this patch. because it’s functionality is specific to accomplish this particular task. I hope you can get a picture of what my vision of this patch. But the more I think and give some trial and error, the more I think it might be not possible. I know we’re so close to the answer

1 Like

Pardon me, the previous had a small error in the value of Y1.
I changed it but the changes weren’t saved to shared patch.

I also made some changes to the way we are defining our input.

Although i still have to interpret your previous message fully, as i trying to visualise it in my head.
Please see if this update does any better.

For the second problem, Yes it’s going to be an issue for shader generic input using this approach unless we figure out a new angle on this.

Edit : Adding the plain visualisation

patch-Update.arexport (49.6 KB)

1 Like

Man, this is a great thread! I was a bit lost on how to define the segments initially. I’m happy to see you both made progress on it.

I am late to the party, but maybe this patch will be a useful counterpart. From what I remember, it’s similar to the plotting function used in the book of shaders. It can be used to visualize curves.

POP_Plotter.arexport (66.0 KB)

As far as plotting multiple segments in certain ranges, I think you can use some stepped values to isolate a segment, then multiply that by the curve you want to isolate.

To combine segments, you can just add the results together

Edit: Square waves might be better than step diffs Inigo Quilez :: fractals, computer graphics, mathematics, shaders, demoscene and more


Wow, this is super useful.

Thanks for sharing :slight_smile:

1 Like

Sorry for late response, I’ve been struggling with something irl.
Just downloaded the patch and play around with it a lil bit, and I think that is it man! Well done.
I’m still trying to figure out how to translate the logic part by replacing it with patches that could accept shader generic signal. Great job!

Oh sick, that pop plotter will definitely a handy tool to debug. Thanks!
And yeah, I think that multiple segments method would work. I haven’t tried it tho, so I still have to play around with it a lil bit more.