[PD] send~ receive~ throw~ catch~ inlet~ outlet~ latency

José de Abreu abreubacelar at gmail.com
Tue Oct 29 23:53:28 CET 2019


Hello all, I have a question.

If i create a [s~ ] and [r~ ] inside a clone abstraction, and control
everyone by messages once (the first will send to the next and so on, it
could be set up by a loadbang in the start, taking the cloned id number in
account), it will be guaranteed that Pd will process the first clone before
the second and so on?

there is an "invisible" inlet~ and outlet~ forcing order from one clone to
the next?

Em Ter, 29 de out de 2019 12:25, Henri Augusto Bisognini <
msndohenri at hotmail.com> escreveu:

> Maybe that text could be in the documentation :)
>
> ------------------------------
> *De:* Pd-list <pd-list-bounces at lists.iem.at> em nome de Simon Iten <
> itensimon at gmail.com>
> *Enviado:* terça-feira, 29 de outubro de 2019 06:20
> *Cc:* Pd-list <pd-list at lists.iem.at>
> *Assunto:* Re: [PD] send~ receive~ throw~ catch~ inlet~ outlet~ latency
>
> Johannes, thank you so much for your in depth answer! i hope this will
> also serve well for others (hence my verbose mail subject)
>
> appreciated!!
>
> On Tue, Oct 29, 2019, 10:15 IOhannes m zmoelnig <zmoelnig at iem.at> wrote:
>
> On 28.10.19 23:50, Simon Iten wrote:
> > hi there,
> >
> > can somebody clear up something for me regarding tilde “wireless”
> objects and subpatches?
> >
> > the G05.execution.order example mentions possible 64-sample delays in
> send~ receive~ and throw~ catch~
> >
>
>
> first let's make clear what is causing latency.
> e.g. consider three signal objects that are chained up "A->B->C".
> when turning DSP "on", those objects will start calculating samples
> based on their input.
> every 1.45ms ("each DSP tick") all 3 objects will need to calculate 64
> samples.
>
> if "A" does its calculations before "B" and "B" before "C", then the 3
> objects will do their calculations with zero latency. that is: if all
> objects just pass their input samples to their output, and at the
> beginning of the DSP tick the "A" objects gets a single sample value of
> 1 (with all other samples before and after being 0), then it will read
> this pulse and pass it on to "B" which will read the pulse and pass it
> on the "C" which in turn will pass it to its output. once all the
> calculations are done, the pulse has passed through all objects.
>
> conversely, what happens if "C" does its calculation before "B" and "B"
> before "A"? we still feed the pulse to "A", but since "C" is being
> executed first, its input has all zeros which it passes to the final
> output, then "B" will read all zeros, passing them to its output, and
> finally "A" will pass the pulse to its output.
> all DSP calculations are now done, and at the output we get silence (but
> there's a pulse lingering between "A" and "B")
> in the next DSP tick, "C" will first read its input (which is the output
> that "B" 'just' (in the last DSP-tick) created, that is: zeros) and pass
> it on; then "B" will pass its input (which is the output that "A" just
> created: a pulse) and pass it on.
> all DSP calculations are now done, and at the output we get silence (but
> now the pulse is pulse lingering between "B" and "C").
> in the next DSP tick, "C" will again read its input (which is the output
> that "B" just created: a pulse).
> once all DSP calculations are done, the output (of "C") will be a pulse.
>
> comparing this to the 1st A, 2nd B, 3rd C calculation above, we see that
> the output is late by 2 DSP ticks, which is 2 blocks (each 64 samples,
> usually).
>
>
>
> obviously it is better to do the calculations in the correct order,
> because it allows you to achieve zero latency in a whole chain of objects.
> So Pd tries hard to do exactly that: if two objects are connected with a
> signal connection, the source object will always be processed before the
> sink object.
> this is done by the Pd-scheduler that sorts the DSP graph (as a directed
> acyclic graph that expresses the inter-object dependencies) whenever you
> turn DSP "on"
>
> incidentally, this also works for meta-objects ("abstractions" or
> "sub-patches"): if you connect two abstractions with signal connections
> ("X->Y"), then the *entire* source abstraction (*all* signal objects
> within "X") will be processed before the entire sink abstraction (*all*
> signal objects withing "Y").
>
>
> now what's different with implicit connections ([s~], [r~],...)?
> simply put: the Pd-scheduler (that does the sorting of the DSP
> calculations) does not know that a [s~ foo] object is connected to a
> [receive~ foo].
> these two objects are connected via their own logic, but the
> Pd-scheduler doesn't know anything about their inner logic and just
> looks at their explicit connections to determine which object needs to
> be evaluated first.
>
> depending on the patch, there are three possibilities:
> 1) somehow the [r~ foo] is connected explicitely to [s~ foo], typically
> if you are doing feedback.
> in this case, the [r~] must be processed before the [s~], so the [s~]
> didn't have the chance yet to generate the new sample block, leaving
> [r~] with the last sample block - introducing a delay of one block.
>
> 2) somehow the [s~ foo] is connected explicitely to [r~ foo]. this is a
> bit harder to acchieve, since [s~] has no outlet and [r~] to inlet.
> however, if we put both into abstractions/subpatches with iolet~s, then
> we can connect these iolets. since the entire source abstraction is
> processed before the entire sink abstraction, any [s~] in the source
> abstraction will also be processed before any [r~] in the sink abstraction.
> whenever [r~] does it's thing, [s~] will already have produced a new
> block of samples, so [r~] will get the fresh stuff and no delay occurs.
>
> 3) the [s~] and [r~] are not connected at all (e.g. "[adc~ 1]->[s~ foo]
>   [r~ foo]->[dac~ 1]")
> in this case, Pd doesn't know whether it should first process the [s~]
> or the [r~] and will pick one "randomly". depending on which it picked,
> you will get a block delay or not.
> this is the "fan out" for signals.
>
>
> > i don’t fully get the strategy to avoid them.
> > do i have to put them into a subpatch and connect inlets~ and outlets~
>
> yes.
> the *only* safe way to guarantee a certain order of execution for signal
> objects is by making their dependencies explicit.
> the only way to make dependencies explicit is to use signal connections
> (which involves inlet~ and outlet~ when it comes to subpatches)
>
> > (somewhat defeating the purpose of the s~ and r~ objects)
>
> only somewhat.
> there are multiple purposes of [s~] and [r~] objects.
> avoiding explicit connections is the worst use.
>
> > also, inlet~ and outlet~ never add latency, right?
>
> jein.
>
> they don't add latency by themselves, as they are only crutches to make
> explicit connections between windows.
>
> but if your subpatch runs on a higher blocksize (e.g. 1024 instead of
> the default 64, using [block~ 1024]) then the [inlet~]/[outlet~] objects
> are the place were the actual re-blocking happens.
>
> gmasdrt
> IOhannes
>
> _______________________________________________
> Pd-list at lists.iem.at mailing list
> UNSUBSCRIBE and account-management ->
> https://lists.puredata.info/listinfo/pd-list
>
> _______________________________________________
> Pd-list at lists.iem.at mailing list
> UNSUBSCRIBE and account-management ->
> https://lists.puredata.info/listinfo/pd-list
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puredata.info/pipermail/pd-list/attachments/20191029/615908f2/attachment-0001.html>


More information about the Pd-list mailing list