Dear list,
i have a question regarding timing in Pd:
I understand that messages to tilde objects just get passed to the DSP tree within DSP blocks.
How about the reverse?
Found out that snapshot~ is returning the last sample of the last block during which it got banged. This is fine, since it is the sample value most closely to the output of the result.
Now when i use the following setup:
[bang~] | | [t b b] | | | | [timer]
i get a minimum logical time of 1.45 msec (aquivalent to 64samples at 44.1 kHz) even when i use a blocksize of [block~ 32]. That makes me assume that the "sampling period" for an external process (such as an audio clock, represented by bang~) is limited to 64 samples.
What is also interesting, is that i get the double value of 2.9 msec for blocksizes above 64, for example 65 and above. There are no adc~ or dac~ objects or any subpatches in this setup.
So, with predefined timing objects (such as [del]), the resolution of the logical time in [timer] can be as low as a fraction of a millisecond, while non-deterministic events get sampled every 64 DSP ticks (or probably integer mutiples).
All still confusing somehow, looking forwards to any answers!
regards, Peter
Hallo, Peter Plessas hat gesagt: // Peter Plessas wrote:
i have a question regarding timing in Pd:
I understand that messages to tilde objects just get passed to the DSP tree within DSP blocks.
How about the reverse?
Found out that snapshot~ is returning the last sample of the last block during which it got banged. This is fine, since it is the sample value most closely to the output of the result.
Now when i use the following setup:
[bang~] | | [t b b] | | | | [timer]
i get a minimum logical time of 1.45 msec (aquivalent to 64samples at 44.1 kHz) even when i use a blocksize of [block~ 32].
I think, bang~ should bang after each block, so with [block~ 32] it should bang every 32 samples. But it seems to have a lower limit of 64 samples. Don't know why.
In general, Pd has like to times: One is the time realm of clock-delayed messages, i.e. everything that originates in a clock objects like metro, delay, pipe, qlist, etc. Clock delayed messages have sub-sample accuracy. This is achieved by "tagging" each normal message with a time tag, similar to the old time tagged triggers in t3_lib. The tags for clocks are invisible, though.
To convert dsp signals to clock-delayed messages you must use [vsnapshot~], but [snapshot~]. It will give you the value of a sample even when bang'ed somewhere in the middle of a block.
Note that you cannot use this value to modify other samples during the same block! Because when the message comes out of [vsnapshot~], this block has already been calculated. So you can only start to use the value to modify the next block's content.
Frank
Hi all,
Frank Barknecht wrote:
Hallo, Peter Plessas hat gesagt: // Peter Plessas wrote:
i have a question regarding timing in Pd:
I understand that messages to tilde objects just get passed to the DSP tree within DSP blocks.
How about the reverse?
Found out that snapshot~ is returning the last sample of the last block during which it got banged. This is fine, since it is the sample value most closely to the output of the result.
Now when i use the following setup:
[bang~] | | [t b b] | | | | [timer]
i get a minimum logical time of 1.45 msec (aquivalent to 64samples at 44.1 kHz) even when i use a blocksize of [block~ 32].
I think, bang~ should bang after each block, so with [block~ 32] it should bang every 32 samples. But it seems to have a lower limit of 64 samples. Don't know why.
thanks for the reply, Frank.
That's what made me curious. Since the duration of a DSP-block does not belong to the realm of clock-delayed messages (pd can't know of the exact duration of the DSP block, assume f.e. an external audio clock with jitter) those values may have to be "sampled" by the messaging system. This sampling would then appear at a minimum rate of 64 samps. So bang~ only makes sense for blocksizes greater than 32 samples, right? Phew, does that make sense? Still trying to completely understand that.
In general, Pd has like to times: One is the time realm of clock-delayed messages, i.e. everything that originates in a clock objects like metro, delay, pipe, qlist, etc. Clock delayed messages have sub-sample accuracy. This is achieved by "tagging" each normal message with a time tag, similar to the old time tagged triggers in t3_lib. The tags for clocks are invisible, though.
Timing is a very interesting topic in pd (and with computers in general). When i try to measure the [realtime] of a [metro 4] object, i get: print: 11.351 print: 0.122 print: 0.11 print: 11.402 print: 0.088 print: 0.119 print: 11.374
I think you get the same values. Can it be true that there is a deviation of 7ms now and then? More interesting: Why is it not only now-and-then, but every fourth sample? So there must be some phase shift which accumulates in the operation of [realtime]. On averaging those values, one gets a value close to 4ms though. Does anyone know about the real-life resolution of [realtime]?
cheers, Peter
On Sun, 2009-01-11 at 12:26 +0100, Peter Plessas wrote:
Timing is a very interesting topic in pd (and with computers in general). When i try to measure the [realtime] of a [metro 4] object, i get: print: 11.351 print: 0.122 print: 0.11 print: 11.402 print: 0.088 print: 0.119 print: 11.374
I think you get the same values. Can it be true that there is a deviation of 7ms now and then? More interesting: Why is it not only now-and-then, but every fourth sample? So there must be some phase shift which accumulates in the operation of [realtime]. On averaging those values, one gets a value close to 4ms though. Does anyone know about the real-life resolution of [realtime]?
those time steps seem to be related to the audio driver. you seem to run pd on jack with a latency of 23ms / 512 frames per buffer @ 44.1kHz. when i use 2048 per buffer at 44.1kHz, i get 92 ms latency and the numbers look like this:
print: 0.048 print: 0.047 print: 0.033 print: 0.049 print: 0.05 print: 45.916 print: 0.04 print: 0.05 print: 0.051 print: 0.052 print: 0.035 print: 0.05 print: 0.064 print: 0.052 print: 0.032 print: 0.046 print: 0.048 print: 45.825 print: 0.033 print: 0.047
so, here every 12th number is significantly bigger than 0 and also here, this number is approximately the half of the latency. this behaviour seems to be typical for jack. when i run pd in windows in virtualbox, i get more random looking numbers.
i guess, if you want really accurate realtime values, you would have to go for the least possible latency, since it seems, that time of execution of pd is completely dependent on the audio driver. and even if this would cause drop-outs, the results of [realtime] wouldn't be affected in a way, that the overall measured time is still valid. if you use [timer], which measures logical time, and you get drop-outs, all dropped out time is not part of the measurement and you will get wrong (too small) values as a result.
i never understood, why [timer] is giving different values from the ones that you expected, when connected to a [bang~] inside a re-blocked subpatch. would be cool to have that either explained or declared as a bug.
roman
Telefonate ohne weitere Kosten vom PC zum PC: http://messenger.yahoo.de
Thanks Roman,
(see for comments below)
Roman Haefeli wrote:
On Sun, 2009-01-11 at 12:26 +0100, Peter Plessas wrote:
Timing is a very interesting topic in pd (and with computers in general). When i try to measure the [realtime] of a [metro 4] object, i get: print: 11.351 print: 0.122 print: 0.11 print: 11.402 print: 0.088 print: 0.119 print: 11.374
I think you get the same values. Can it be true that there is a deviation of 7ms now and then? More interesting: Why is it not only now-and-then, but every fourth sample? So there must be some phase shift which accumulates in the operation of [realtime]. On averaging those values, one gets a value close to 4ms though. Does anyone know about the real-life resolution of [realtime]?
those time steps seem to be related to the audio driver. you seem to run pd on jack with a latency of 23ms / 512 frames per buffer @ 44.1kHz. when i use 2048 per buffer at 44.1kHz, i get 92 ms latency and the numbers look like this:
I did this test with -audiobuf 50 running OSS. You are right, the values differ greatly on the kind of audio driver i am using, f.e. with alsa and -audiobuf 50 i get: print: 0.1 print: 4.928 print: 4.991 print: 4.951 print: 4.994 print: 0.098 print: 4.931 print: 4.994 print: 4.949
while using alsa and -audiobuf 100 the result is slightly different as well. And all this while DSP processing is even turned off.
i guess, if you want really accurate realtime values, you would have to go for the least possible latency, since it seems, that time of execution of pd is completely dependent on the audio driver. and even if this would cause drop-outs, the results of [realtime] wouldn't be affected in a way, that the overall measured time is still valid. if you use [timer], which measures logical time, and you get drop-outs, all dropped out time is not part of the measurement and you will get wrong (too small) values as a result.
So realtime is dependent on the audio clock? I always thought that it took the cputime/OS time... I understand that logical time in timer is the internal "perfect" representation of pd's time.
i never understood, why [timer] is giving different values from the ones that you expected, when connected to a [bang~] inside a re-blocked subpatch. would be cool to have that either explained or declared as a bug.
Yes, that one is still unclear to me.
regards, Peter
On Sun, 2009-01-11 at 13:42 +0100, Peter Plessas wrote:
I did this test with -audiobuf 50 running OSS. You are right, the values differ greatly on the kind of audio driver i am using, f.e. with alsa and -audiobuf 50 i get: print: 0.1 print: 4.928 print: 4.991 print: 4.951 print: 4.994 print: 0.098 print: 4.931 print: 4.994 print: 4.949
interesting....
So realtime is dependent on the audio clock? I always thought that it took the cputime/OS time...
i still think, that [realtime] is _not_ dependent on the audio clock (without having read the code). the issue here is the moment, at which the time from OS clock is polled. from what i understand, the pd process is driven by the audio driver, respectively by its clock, so the time, when the 'bang' to [realtime] is executed, is dependent on the implementation of the audio driver. even when not having drop-outs, you wouldn't know exactly, when [realtime] polls the system clock. this could be somewhere between now (0ms) and chosen latency. that is why you get the jitter, when measuring with [realtime].
i once could make use of this two different time measurement methods to tune the jack-server running with the dummy driver to the correct samplingrate.
roman
Telefonate ohne weitere Kosten vom PC zum PC: http://messenger.yahoo.de
Hi Peter/Roman/Frank, hi list,
Thanks for the lively discussion and your insightful contributions.
Peter Plessas wrote:
So realtime is dependent on the audio clock? I always thought that it took the cputime/OS time...
[realtime] takes the system time as measured by the OS.
(For clarity, I would not call it "CPU time", since that "is the amount of time a computer program uses in processing central processing unit (CPU) instructions, as opposed for example to waiting for input/output operations" (Wikipedia), as measured by [cputime] in Pd in order to derive the current CPU load in Pd's load meter, for example.)
For example, when you reset the clock using the Unix 'date' command during an ongoing [realtime] measurement, that change will affect the measurement's result.
So in my understanding, [realtime] does _not_ depend on the audio clock (or audio driver); it gives accurate values also for measurements of [metro 2], etc. It's the actual timing of [metro] which gets messed up. Or am I getting your question wrong here?
I understand that logical time in timer is the internal "perfect" representation of pd's time.
That's my understanding as well. [timer] represents the ideal "score" derived from all timed objects ([del], [metro], etc.). It's what Pd 'aims for'.
i never understood, why [timer] is giving different values from the ones that you expected, when connected to a [bang~] inside a re-blocked subpatch. would be cool to have that either explained or declared as a bug.
Sorry, Roman - could you clarify which blocksizes you are talking about? What Peter and I have observed is that block sizes < 64 give the same [timer] results as a block size of 64, so there seems to be a lower limit. I am not sure though whether you are you talking about the same phenomenon?
best, flo.H
On Sun, 2009-01-11 at 18:34 +0000, Florian Hollerweger wrote:
i never understood, why [timer] is giving different values from the ones that you expected, when connected to a [bang~] inside a re-blocked subpatch. would be cool to have that either explained or declared as a bug.
Sorry, Roman - could you clarify which blocksizes you are talking about? What Peter and I have observed is that block sizes < 64 give the same [timer] results as a block size of 64, so there seems to be a lower limit. I am not sure though whether you are you talking about the same phenomenon?
yo, this is what i was talking about. in a subpatch with a lower blocksize than 64, [bang~] still outputs a bang only every 64 samples.
roman
___________________________________________________________ Der frühe Vogel fängt den Wurm. Hier gelangen Sie zum neuen Yahoo! Mail: http://mail.yahoo.de
Hallo, Peter Plessas hat gesagt: // Peter Plessas wrote:
That's what made me curious. Since the duration of a DSP-block does not belong to the realm of clock-delayed messages
Actually it does belong to the same realm AFAIK: Pd's clock is computed using the audio card as a reference. "Subsample accuracy" just means, that events can be scheduled between samples as well.
But the time, when they should be scheduled, is still calculated from the audio card. In the end [metro] will have the same jitter as the audio card.
Maybe an example makes this clearer: Lets assume you have a digital watch that only shows hours and minutes, but no seconds. So it has a sample rate of 1/60 Hz.
Now you want to boil an egg for breakfast. You like your eggs if they have been boiled for three and a half minutes. So you drop your egg into the water when the watch is changing minutes. After three minutes you start interpolating: You have to take the egg out of the water halfway in between the ticks that come every minute. (If your watch has a lot of jitter, you egg will be wrong, too.)
That's the same "sub-sample accuracy" Pd uses to schedule events that should happpen in the middle of a block or between two samples.
For the nasty details check out Miller's book http://crca.ucsd.edu/~msp/techniques/latest/book-html/node43.html where he explains the various possible techniques to use for interpolating between two ticks.
Also see http://crca.ucsd.edu/~msp/techniques/latest/book-html/node52.html for how it's implemented in Pd and everything else in that chapter, too.
(pd can't know of the exact duration of the DSP block, assume f.e. an external audio clock with jitter) those values may have to be "sampled" by the messaging system. This sampling would then appear at a minimum rate of 64 samps. So bang~ only makes sense for blocksizes greater than 32 samples, right? Phew, does that make sense? Still trying to completely understand that.
I don't understand what this has to do with [bang~]?
Does anyone know about the real-life resolution of [realtime]?
I think this depends on how accurate your operation systems realtime clock is. On Linux, you can maybe check: /proc/sys/dev/hpet/max-user-freq rsp. /proc/sys/dev/rtc/max-user-freq for the max allowed polling frequency or so. But I'm no expert on this.
Frank
Hi again,
Frank(ly), there is still something unclear to me. Please see below.
Frank Barknecht wrote:
In general, Pd has like to times: One is the time realm of clock-delayed messages, i.e. everything that originates in a clock objects like metro, delay, pipe, qlist, etc. Clock delayed messages have sub-sample accuracy. This is achieved by "tagging" each normal message with a time tag, similar to the old time tagged triggers in t3_lib. The tags for clocks are invisible, though.
I understand you mean "Pd has two times", the first one being the sub-samply accuracy of clock-delayed objects like [delay]. (I exclude metro from this group since it has the hard-coded limit of integer msec values). What would be the other "timing" then?
Thanks! have a nice one,
PP
On Sun, 2009-01-11 at 14:05 +0100, Peter Plessas wrote:
Hi again,
Frank(ly), there is still something unclear to me. Please see below.
Frank Barknecht wrote:
In general, Pd has like to times: One is the time realm of clock-delayed messages, i.e. everything that originates in a clock objects like metro, delay, pipe, qlist, etc. Clock delayed messages have sub-sample accuracy. This is achieved by "tagging" each normal message with a time tag, similar to the old time tagged triggers in t3_lib. The tags for clocks are invisible, though.
I understand you mean "Pd has two times", the first one being the sub-samply accuracy of clock-delayed objects like [delay]. (I exclude metro from this group since it has the hard-coded limit of integer msec values).
this is not true. [metro] also works with non-integer time intervals, though it has a hardcoded lower limit of 1ms (i guess, that is some kind of stack overflow protection).
What would be the other "timing" then?
while not being 100% sure, what frank meant with the other timing domain, i guess, he meant all the messages, that are not initiated by [metro]/[delay]/[pipe] and co. this would be messages from:
all those messages lack the extra timing information and thus are executed only at block boundaries.
for the same reasons explained in the previous mail about [realtime], all those object classes seem to suffer from a big (bigger than 1 block) and audio driver/settings dependent jitter as well. you don't exactly know, when those messages arrive in pd.
roman
Telefonate ohne weitere Kosten vom PC zum PC: http://messenger.yahoo.de
Thanks for the discussion Roman,
see below
Roman Haefeli wrote:
while not being 100% sure, what frank meant with the other timing domain, i guess, he meant all the messages, that are not initiated by [metro]/[delay]/[pipe] and co. this would be messages from:
- the guis and clicks on message boxes
- networking objects [netreceive]/[tcpreceive] etc.
- [hid] / [comport] / [arduino] / [wiimote]
- [cltin] / [notein] / [midiin] etc.
- probably more
all those messages lack the extra timing information and thus are executed only at block boundaries.
I managed to find something that contradicts here: A Gui-bang to a [t b b] to a [timer] in a subpatch with a [block~ 8192] object. Clicking the bang very fast with my mouse gives smaller than blocksize message intervals: print: 127.71 print: 116.1 print: 116.1 print: 127.71 print: 116.1 print: 127.71 print: 104.49 print: 92.8798 print: 104.49 print: 81.2698 print: 104.49 print: 116.1 usw.
Hmmm, still searching. Thanks for all the good pointers!
regards, PP
Peter Plessas wrote:
Thanks for the discussion Roman,
see below
Roman Haefeli wrote:
while not being 100% sure, what frank meant with the other timing domain, i guess, he meant all the messages, that are not initiated by [metro]/[delay]/[pipe] and co. this would be messages from:
- the guis and clicks on message boxes
- networking objects [netreceive]/[tcpreceive] etc.
- [hid] / [comport] / [arduino] / [wiimote]
- [cltin] / [notein] / [midiin] etc.
- probably more
all those messages lack the extra timing information and thus are executed only at block boundaries.
That's the adc~/dac~ block boundaries, so...
I managed to find something that contradicts here: A Gui-bang to a [t b b] to a [timer] in a subpatch with a [block~ 8192]
...that's why.
object. Clicking the bang very fast with my mouse gives smaller than blocksize message intervals: print: 127.71 print: 116.1 print: 116.1 print: 127.71 print: 116.1 print: 127.71 print: 104.49 print: 92.8798 print: 104.49 print: 81.2698 print: 104.49 print: 116.1
note the quantisation!
127.7 ms = 88 blocks exactly 116.1 ms = 80 blocks exactly 104.5 ms = 72 blocks exactly 92.88 ms = 64 blocks exactly
at 44100Hz with 64 samples per block
so i'm guessing your audio driver has a block size of 512 samples (8 * 64), which Pd fills with its 64 sample blocks quicker than you can click twice => massive jitter of "logical time" vs "real time".
usw.
Hmmm, still searching. Thanks for all the good pointers!
regards, PP
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Claude Heiland-Allen wrote:
Peter Plessas wrote:
Thanks for the discussion Roman,
see below
Roman Haefeli wrote:
while not being 100% sure, what frank meant with the other timing domain, i guess, he meant all the messages, that are not initiated by [metro]/[delay]/[pipe] and co. this would be messages from:
- the guis and clicks on message boxes
- networking objects [netreceive]/[tcpreceive] etc.
- [hid] / [comport] / [arduino] / [wiimote]
- [cltin] / [notein] / [midiin] etc.
- probably more
all those messages lack the extra timing information and thus are executed only at block boundaries.
That's the adc~/dac~ block boundaries, so...
Wow Claude, that explains it. Wonderful indeed. So the logical timing of externally triggered objects, those who don't show a predetermined behavior like a [del 0.3] is dependent on the adc/dac block boundaries.
Thanks for calculating the [timer] output into multiples of eight blocks for me!
cheers, Peter
Dear Roman, Frank, List
Roman Haefeli wrote:
while not being 100% sure, what frank meant with the other timing domain, i guess, he meant all the messages, that are not initiated by [metro]/[delay]/[pipe] and co. this would be messages from:
- the guis and clicks on message boxes
- networking objects [netreceive]/[tcpreceive] etc.
- [hid] / [comport] / [arduino] / [wiimote]
- [cltin] / [notein] / [midiin] etc.
- probably more
all those messages lack the extra timing information and thus are executed only at block boundaries.
I'm just interested, how would you argue that the logical timing of the following is sub-adc/dac-block (which it is)?
[t b b]
|
|
|
|
[t b b] [random 100]
| |
| [/ 100]
| /
| /
| /
[delay]
|
[t b b]
| |
[timer]
|
[print]
Clearly we all agree that [del] follows Pd's time tagged execution. So this time tag must be set with respect to the whole logical tree, including the new value given by the [random] object, right?
cheers,
Peter
Hallo, Peter Plessas hat gesagt: // Peter Plessas wrote:
I understand you mean "Pd has two times", the first one being the sub-samply accuracy of clock-delayed objects like [delay]. (I exclude metro from this group since it has the hard-coded limit of integer msec values).
[metro] has a hardcoded lower limit, but it is not limited to integer values, it works fine with real floats like 133.3333
What would be the other "timing" then?
The other are messages that don't originate in a clock (and still another kind are messages from the outside world.) Clicking on a GUI object for example does not generate a clock-delayed message.
Frank
i get a minimum logical time of 1.45 msec (aquivalent to 64samples at 44.1 kHz) even when i use a blocksize of [block~ 32].
I think, bang~ should bang after each block, so with [block~ 32] it should bang every 32 samples. But it seems to have a lower limit of 64 samples. Don't know why.
iirc, bang~ uses pd's timer callbacks, which are only executed once every dsp tick, i.e. each 64 samples. while pd has a notion of `logical time', timers for the interval of 64 samples are executed at the same time. if the same timer callback is scheduled twice during this interval, it is only executed once ...
tim