ADR Function - Graphical with Dials
Hi,
Im stuck on a simple ADR Envelope using the function object. So i've decided to post here for some help.
I ran a few searches online to see if i could find some help with controlling the function obj with dials for the Attack, Decay and Release.
The only link I could find detailing something similar was this interesting article:
http://designingsound.org/2013/04/29/generating-complexity-in-max/
However on analysing the patch it is too complex for me to break down as a beginner with MaxMSP.
I have set out using my own patch. I have 6 dials each for the X & Y positions of the breakpoint for each segment - ADR.
The problems i'm encountering are:
1. How to initialise 5 breakpoints on patch load set to a standard ADR shape and limit the breakpoint numbers to 5nr.
2. Set the first breakpoint to only be co-ordinates 0,0
3. For some reason the Y co-ordinate in the paklist for the Attack controls the X value and
the X co-ordinate for the decay section controls the attacks Height?
If somebody could help me with a pointers it would be a massive help.
Patch below:
Thanks in advance,
D
Hi,
I made a little progress and used a loadbang to fire up a generic ADSR envelope shape on patch load.
I'm still stuck on adjusting the other breakpoints Reading the help file for function kind of explains how the list works if its is a 3 number list so I'm guessing thats the issue with operation, how do i define each breakpoint so I can manipulate them?
Looking at the help i can see that using a symbol might be the answer but i have absolutely no clue how to do this, the help file doesnt demonstrate it and I cant find any examples on a search.
Any help would be appreciated.
File attached.
Thanks,
David
The [function] points are numbered from left to right, starting with 0, so the first point you want to move is number 1. Moving is similar to creating points, just with the point number in front.
A list "150 800" means "create a point at X 150 and Y 800"
A list "1 150 800" means "move point 1 to X 150 and Y 800"
—
See attached patcher.
Click on "Reset" and the [coll] clears the [function] and generates 5 new points. After that (bang out of uzi), the dials are set to default values by the [trigger] above them. Attack is self-explaining, it sets the x/y values of point 1. Decay sets the x value of point 2 (length of decay). Sustain sets the y values of points 2 and 3 to keep the sustain line horizontal. Finally, Release sets the x value of point 3 (length of release).
This was the simple part. But [function] is not friendly to external operation. If you don't control the x ranges, you can easily destroy the curve. The simple way is to set the ranges of the dials manually to avoid overlaps. This is of course not always possible. But if a moving x value should stop at it's neighbour of even push the neighbour in a controlled manner, and the dials should reflect these actions (what they really should do), the whole thing becomes complicated.
If appropriate, I would rather make a nice looking [function], disallow 'adding points' and 'changing sustain' and let the user modify the curve manually in the display. With this method it also easier to make curves, not just lines (set the function mode to 'Curve' and alt-drag over a line). Just provide a reset function that draws a new curve.
the problem with custom envelopes is usually that you run into chaos with the time/value pairs.
unfortunately they are not linear, because A, D, and R describe time, while S is a magnitude value.
so when you started your first envelope patch by writing a bunch of time/value pairs into a pack object in order to send it to line~, you are already lost. ;)
Thanks for the help guys - really appreciated!!
I checked the patch and this is what im wanting.
I understand what you are saying with the x-ranges - is it possible to limit the x-ranges on breakpoints? so it doesnt screw the curve up ? I'm trying to emulate the envelope of my Elektron Digitakt it's quite simple and has no curves - what you have made is pretty much spot on, adding the x-range limit would be icing on the cake! :)
I've limited the dial min and max range - works a treat :) thanks!
Peter to better understand Max MSP i'm trying to figure out how this runs can you let me know if i'm on the right lines?
Loadbang to uzi - fires 6 triggers/bangs on patch start - 5 of these going to the default ADSR shape (150, 800,300, 500, 800)
the 6th trigger is collected however confused with the route symbol and T L object? Trigger and List? What is the purpose of the symbol?
I'm guessing prepend is used to prepend a unique number to each ADR as an identifier for each breakpoint?
thanks,
David
When [uzi 6] gets banged, the right output sends numbers 1-6 to [coll], which in turn sends out lines 1-6 as stored inside the coll (Note: 'Save data in patcher' is activated in the coll's inspector).
If you connect a [print] object to the [coll] output, you see what the coll is sending. The first line, stored as the word clear, comes out as 'symbol clear'. That's the reason for the [route symbol] object. No magic there. It simply sends a list that begins with the word 'symbol' to the first outlet, where it appears as the remaining single word 'clear'. The other 5 coll lines don't match this routing, they go to the last route output. The word 'clear' is the first to reach [function], point creation follows. The [t l] (or [trigger l]) objects just collect data. A [t l] lets almost everything through (int, float, list), so it is quite handy to organize the cabling visually.
After uzi has spit out all it's numbers, it sends a bang from the middle outlet. This triggers the [t ... ...] containing your default values to set the dials and the point positions in [function]. Since these values are set after [function] got initialized, the breakpoints match the dials and all [pak] objects are correctly loaded. This way the circuit is ready to use after patcher load or after clicking 'Reset'.
Your question about [prepend]:
You are right. [prepend 1] sets number 1 before the incoming number pair and therefore tells point number 1 to move. Be aware that a point number is not bound to a specific breakpoint. Numbering goes strictly from left to right, starting with 0. In other words: the point order is always as you see it in the [function] display.
Thanks peter that better explains it - i've tried adding a print object on the outputs of a lot of objects including coll but my max console isnt displaying anything, i added a bang to the loadbang to fire it up to test as well but no luck.
Never heard about that. Without readouts you can hardly work in Max.
Works on the triggers and prepends etc. but not on coll or route symbol.
Maybe you are on the wrong outputs?
At [coll], print the leftmost output.
[route] sends depending on the input, cable all outputs to a [print].
hi peter,
came back to this - still unable to print coll. i set up another message that prints fine but i would really like to see how coll outputs to get a greater understanding of the patch.

This coll does not do anything, it is empty. My fault.
I forgot to set "Store data with patcher" in the inspector.
Lock the patcher, doubleclick the coll and copy/paste
the following lines into the empty window:
1, clear;
2, 0 0;
3, 150 800;
4, 300 500;
5, 800 500;
6, 1000 0;
After closing the coll window, unlock the patcher, activate the coll and activate "Store data with patcher" in the inspector.
The uzi sends numbers 1-6 and coll reacts by sending it's 6 lines to the function. First line is a 'clear' command, the others are the 5 xy coordinates to set 5 default points.
(I replaced the patcher in the post above, it works now.)
thanks peter much appreciated! :D