[PD] [env~] issues

Jonathan Wilkes jancsika at yahoo.com
Wed Dec 17 22:53:31 CET 2014

Hi Raphaël,
The problem is not very intuitive to solve.
It's difficult enough to understand the flow in a patch that only uses signal objects.  And it's more difficult to understand the flow in a patch that uses control objects.  That's because you can no longer just assume that each object will compute its inputs before sending output-- you must instead read all the right-to-left triggering to know where the data will go.  (Plus you must understanding what triggers the object chain traversal in the first place.)
But it's even more difficult to understand a patch that mixes the two. And on top of _that_ you have a [delay] in the object chain, which has its own timing outside of the normal firing of control events.  That normal firing of events in a chain of control objects happens in zero logical time.  Oh, and the value you're providing for your delay time is zero.
That isn't trivial to understand, much less come up with as a solution in the situation of [env~].
One way to approach this is to think what happens to the following patch if you turned on audio for a single block and then turn it off again:[env~]|[bang]|[delay 1000]|[print delayed]
[env~]|[bang]|[print normal]
The [print normal] object will obviously print before the delayed one, right?  It does, but let's look at a part of how Pd schedules this stuff.  It's something like this:* fire the messages from each [env~], based on the order in which were created.  Let's assume the first one you created is the one connected to the [delay 1000].  Here's what happens:1) message goes from [env~] to [bang] to [delay 1000]. The [delay 1000] schedules a bang to output 1000ms later.  This next part is the key: Pd will _not_ check to see whether 1000ms has passed until it has processed step #2 below.  Also important is that Pd will _immediately_ proceed to step #2 below-- it doesn't wait 1000ms before doing so.  You probably already knew that part, but many programming languages do in fact have mechanisms which let you just sit there waiting before computing the next logical part of the program.2) message goes from [env~] to [bang] to [print normal].  We get an immediate printout to the console.3) 1000ms passes, and [delay 1000] finally sends to [print delay].  We get the second printout to the console.
Now here's the (lack of) magic: if you edit your patch and replace [delay 1000] with [delay 0], the same exact process happens in the same exact order.  The only difference is that Pd waits 0ms before doing step #3 instead of 1000ms.  But you're still guaranteeing the same order, and the program is still following all the same steps.  (In other words, [del 0] doesn't trigger any special code that I know of-- it really does schedule a delay, which just happens to be 0ms.)
Finally, notice that the console printout stays the same even if you switch steps #1 and #2.  In other words, the [delay] ensures that you get the printout order you want, _regardless_ of the order in which you created the [env~] objects.
Also, notice that this trick doesn't scale very well.  If you had a patch full of [del 0] to force ordering in the way you do above, you're almost guaranteeing that there will be bugs.
Anyway, I hope everything I wrote above is correct!  These things are definitely difficult to explain and understand.

     On Wednesday, December 17, 2014 2:10 PM, Raphaël Ilias <phae.ilias at gmail.com> wrote:

oh, but that is just trivial:

messages and signals are always calculated one after each other (first
all messages; once they are done, signals are processed).

so an even easier way would be to use a latch ([f]) and [bang~]+[del 0]
to do the calculation in msg-domain.
[bang~] will output a bang before each signal block (or after; it really
will trigger a bang before the *next* signal block).
unfortunately, this bang can happen before or after the events sent out
by [env~], so we need to make sure to get an event *after* all [env~]s
have triggered.
the simplest way to achieve this is by using an additional [delay 0],
which will schedule an event at the same logical time NOW but after all
events already scheduled for NOW (e.g. those from [env~]).

see attached patch. (in the attached patch i wasn't able to trigger an
undesired behaviour without the [delay 0]; however i haven't tried hard
and i'm pretty sure that you *can*; thus you should use [del 0])

thanks !
yes, with [delay 0] it ensures to get the good result (same block)...
(also tried to get an undesired behaviour without [del 0], but didn't succeed !)

i already used [delay 0] sometimes, but i don't see where it's role is documented

i already knew [bang~] but with this object my doubt was always : "i know that it will happen *every* block during message-domain computation, but *when* in that block ? relatively to other "not-triggerred" objects like [env~]..."

well, maybe i'm going too far with this... since you gave me a working solution :-)

however, also sent this to the pd-list because i wonder if i'm the only one to feel that this issue isn't very intuitive to solve...



Pd-list at lists.iem.at mailing list
UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puredata.info/pipermail/pd-list/attachments/20141217/dd476a14/attachment-0001.html>

More information about the Pd-list mailing list