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~
i don’t fully get the strategy to avoid them. do i have to put them into a subpatch and connect inlets~ and outlets~ (somewhat defeating the purpose of the s~ and r~ objects)
also, inlet~ and outlet~ never add latency, right?
thanks for insights and i am sure this has been covered before but i cannot find it on the list...
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:
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.
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.
[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
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@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:
- 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.
- 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.
- 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@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list
Maybe that text could be in the documentation :)
De: Pd-list pd-list-bounces@lists.iem.at em nome de Simon Iten itensimon@gmail.com Enviado: terça-feira, 29 de outubro de 2019 06:20 Cc: Pd-list pd-list@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@iem.atmailto:zmoelnig@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:
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.
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.
[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@lists.iem.atmailto:Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list
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@hotmail.com> escreveu:
Maybe that text could be in the documentation :)
*De:* Pd-list pd-list-bounces@lists.iem.at em nome de Simon Iten < itensimon@gmail.com> *Enviado:* terça-feira, 29 de outubro de 2019 06:20 *Cc:* Pd-list pd-list@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@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:
- 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.
- 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.
- 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@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list
On Tue, 2019-10-29 at 10:13 +0100, IOhannes m zmoelnig wrote:
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)
So, the non-signal iolets do _not_ influence order of execution for signal objects?
Roman
No, they don't. They are not part of the DSP graph.
Gesendet: Mittwoch, 06. November 2019 um 14:17 Uhr Von: "Roman Haefeli" reduzent@gmail.com An: pd-list@lists.iem.at Betreff: Re: [PD] send~ receive~ throw~ catch~ inlet~ outlet~ latency
On Tue, 2019-10-29 at 10:13 +0100, IOhannes m zmoelnig wrote:
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)
So, the non-signal iolets do _not_ influence order of execution for signal objects?
Roman _______________________________________________ Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list