Frank Barknecht wrote: I think, it's comport's fault: [metro] generates clock-delayed messages. These are like messages tagged with a time-stamp referring to Pd's internal clock. However an object needs to actually use the time-stamps and "look at the clock" to see what time it is. Objects like [vline~] or [delay] do this, but comport doesn't.
Well that's interesting! How does one access these timestamps? I thought a bang has no associated info. Or are you referring to a [metro~]?
Martin
Hallo, martin.peach@sympatico.ca hat gesagt: // martin.peach@sympatico.ca wrote:
Frank Barknecht wrote: I think, it's comport's fault: [metro] generates clock-delayed messages. These are like messages tagged with a time-stamp referring to Pd's internal clock. However an object needs to actually use the time-stamps and "look at the clock" to see what time it is. Objects like [vline~] or [delay] do this, but comport doesn't.
(Actually I may be wrong here: Maybe comport doesn't need to do anything about this, as it's not a dsp-object. But read on.)
Well that's interesting! How does one access these timestamps? I thought a bang has no associated info.
Well, there are no "real" timestamps attached to a bang-message. But Pd has a clock running (actually many, sync'd to the main scheduler clock), and objects that want to know the current time a message arrives, need to look at the clock.
vsnapshot~ for example (d_ctl.c) seems to do it like this: In its dsp-perform routine, which is called every sample block, it stores the current time with "x->x_time = clock_getlogicaltime();" Then in the bang-routine, vsnapshot~ uses "int indx = clock_gettimesince(x->x_time) * x->x_sampspermsec;" to calculate the correct index into the incoming sample block from the difference between the time stored previously and the current time. This is what I meant with "looking at the clock".
Objects like [delay] or [metro] produce these clock-delayed messages. They register their clocks with Pd's main scheduler using clock_new(...) and then order the scheduler to generate the clock-delayed messages like the metro-bangs using clock_delay(). The actual output of [delay], [metro] etc. then is initiated by the scheduler which calls the registered clock methods: delay_tick(), metro_tick(),...
However I must admit, I'm not sure how this relates to comport and if comport should also register its port-writing-method with a clock and let the scheduler "tick" the clock and initiate the writing and if that could get rid of the jitter you mentioned.
At least "normal" objects like [float] don't do any funky clock-stuff and still don't disturb the correct timing of clock-delayed messages.
Frank Barknecht _ ______footils.org_ __goto10.org__
Frank Barknecht wrote:
Hallo,
Objects like [delay] or [metro] produce these clock-delayed messages. They register their clocks with Pd's main scheduler using clock_new(...) and then order the scheduler to generate the clock-delayed messages like the metro-bangs using clock_delay(). The actual output of [delay], [metro] etc. then is initiated by the scheduler which calls the registered clock methods: delay_tick(), metro_tick(),...
However I must admit, I'm not sure how this relates to comport and if comport should also register its port-writing-method with a clock and let the scheduler "tick" the clock and initiate the writing and if that could get rid of the jitter you mentioned.
no, this won't work.
[metro] is arbitrarily accurate within pd-land: here we deal with "logical" time, where the execution of a message (and everything it triggers directly) is happening in zero-time by definition.
in the world outside, there is no "logical" time, there is only the "real" time, where the execution of messages takes some cpu-cycles and thus real time.
messages are dealt with during dsp-cycles (in fact, dsp-cycles are dealt with in between msg-cycles; this is why a message-overload can lead to click, when one dsp-cycle has to be dropped).
in "real" time messages are executed in bursts, but for each message in the burst the "logical" time will be correctly set.
this is all fine as long as you don't have to deal with the world outside: the only place where this is handled somehow correctly is with audio: pd writes the samples (who live in "logical" time land) into a buffer; the soundcard reads this buffer in sync with the "real" time. as long as the 2 time references are roughly in synch everything goes well; when they get badly out of synch (drift>buffersize), you will get audio-dropouts.
when dealing with other world outside interfaces (e.g. parallel/serial port), there might be no such mechanism: whenever some data is sent to the port (regardless of the "logical" time) it is visible "on the other side in "real" time; this might appear in bursts and have a jitter. the only way to overcome this is to create a buffer that synchs the two time references.
a simple way to do this is to just overdrive the port a little bit, so that your operating system's port buffer is always filled.
At least "normal" objects like [float] don't do any funky clock-stuff and still don't disturb the correct timing of clock-delayed messages.
because they do not interface with the world outside.
mf.asr IOhannes
On 08/05/2007, at 9.19, IOhannes m zmoelnig wrote:
because they do not interface with the world outside.
I feel that i don't interface with "the world" inside. I would
greatly appreciate if someone would translate the scope of this
discussion into noobish.
I sense that it's not that hard to grasp the scope once getting the
'aahh' experience. Like when you look at a map (of the world, you
thought) but can't find out what part you are looking at and think
"this is a fictive map" until some kind soul points and says "that
bit is water, the other is land". (I've tried that, it very
embarrassing but then thats ruled out...)
Or just ignore this email.
Best, Steffen
Steffen wrote:
On 08/05/2007, at 9.19, IOhannes m zmoelnig wrote:
because they do not interface with the world outside.
I feel that i don't interface with "the world" inside. I would
greatly appreciate if someone would translate the scope of this
discussion into noobish.
sorry if i confused anybody. unfortunately i am not very good at explaining things in simple words; anyone else wants togive it a try?
mfga.dr IOhannes
Hallo, IOhannes m zmoelnig hat gesagt: // IOhannes m zmoelnig wrote:
unfortunately i am not very good at explaining things in simple words; anyone else wants togive it a try?
Pd is nirvana, comport is the harsh reality.
Frank Barknecht _ ______footils.org_ __goto10.org__
On Tue, 2007-05-08 at 13:12 +0200, Steffen wrote:
On 08/05/2007, at 9.19, IOhannes m zmoelnig wrote:
because they do not interface with the world outside.
I feel that i don't interface with "the world" inside. I would
greatly appreciate if someone would translate the scope of this
discussion into noobish.I sense that it's not that hard to grasp the scope once getting the
'aahh' experience. Like when you look at a map (of the world, you
thought) but can't find out what part you are looking at and think
"this is a fictive map" until some kind soul points and says "that
bit is water, the other is land". (I've tried that, it very
embarrassing but then thats ruled out...)Or just ignore this email.
i think, i understood, what IOhannes explained, though i am not a coder. but this is more an issue of concepts than of code itself, i think. before i give it another try to explain, i would like to know, what exactly you did not understand. could you elaborate that a bit more (if that's possible for you, of course)? i mean, is it the difference between logical time and real time ?
roman
Telefonate ohne weitere Kosten vom PC zum PC: http://messenger.yahoo.de
On 08/05/2007, at 14.36, Roman Haefeli wrote:
i think, i understood, what IOhannes explained,
I'm sorry i wasn't cleat about what i didn't understand. By "this
discussion" i mean to refer not only to IOhannes mail but the whole
thread.
"Confusion Is Sex", they say. So i guess it's not necessarily a bad
thing.
but this is more an issue of concepts than of code itself, i think.
I think so too. Hence my map example.
is it the difference between logical time and real time ?
No not really. And Marius gave a good shot explaining that.
Marius also ends out with some explanation of the 'block' concept. I
think that what i don't really get.
I understand that decreasing the block size will possible requirer
more computation/logical time then there is real time enough to
complete. And therefore that the information in a block is available
to the program to process. Which also means that after that block has
been processes the information is not longer available. Is that true?
What is a block, what's in it, what properties does it have. Is a
block a sample or is a block made out of a number (being the block
size) of samples? And also Jamie's question: what does the 'v' stand
for?
I suspect there is some digital music fundamentals that I'm lacking.
Thanks for your patients, all of you.
what happens in a block cycle?
first all dsp computation is done, then all new messaging is handled:
usually 64 samples of digital (audio) signal are blocked together. so lets say you have a line~ object that received a message [0, 1 10( before the new block started. so that is executed beginning with the first sample of the block cycle. lets say the line~ is directly connected to an [dac~] object. so there is a buffer of 64 samples and the first of these samples is filled with 0. then (still dsp computations...) the next value of line is calculated, which will be dependend on the sample rate settings (let's say 44.1k) so 1 sample is 1/44.1 ms, which will give the next rampvalue of 0.00227 (you will reach "1" after 441 samples). in this way 64 samples are written to the buffer. 0, 0.00454, 0.00680... during all these calculations no new messages are handled. [v messages have a slightly different behaviour here] finally (that is varying depending on the sound card driver and operating system you are using) this buffer goes to the soundcard. THEN: after all that dsp stuff is done, the messaging process is turned on. interface events (even if they are received and saved during dsp computation) will only have effect for the beginning of the next block. the whole messaging process will set a lot of new values that will interact with the next dsp computations. for example our line object might receive new values...
does this all make sense? smaller blocksizes give you the possibility to handle messages in even shorter time intervals, bigger blocksizes may help to declick for example when you write to arrays. [for some objects blocksize is even more important (fft~, tabsend~).]
marius.
Steffen wrote:
I understand that decreasing the block size will possible requirer
more computation/logical time then there is real time enough to
complete. And therefore that the information in a block is available
to the program to process. Which also means that after that block has
been processes the information is not longer available. Is that true?
What is a block, what's in it, what properties does it have. Is a
block a sample or is a block made out of a number (being the block
size) of samples? And also Jamie's question: what does the 'v' stand
for?I suspect there is some digital music fundamentals that I'm lacking.
Thanks for your patients, all of you.
PD-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Hallo, marius schebella hat gesagt: // marius schebella wrote:
does this all make sense? smaller blocksizes give you the possibility to handle messages in even shorter time intervals, bigger blocksizes may help to declick for example when you write to arrays. [for some objects blocksize is even more important (fft~, tabsend~).]
I think, it may be easier to explain this from a practical point of view. I'll give it a shot:
What does this mean? All messages *inside* of Pd are handled with (almost) complete accuracy. If you have a bang going through a [del 0.3] and going through [del 0.299] then you can be sure that Pd triggers the 0.299-bang 0.001 msec before the 0.3-bang, regardless of what your blocksize or so is. It would be terrible and lead to lots of nasty errors if you couldn't rely on Pd to schedule events in that fashion.
It would be a complete waste of ressources to update the GUI or poll GUI elements for changes every sample or every 1/44100 seconds. So currently events coming from the GUI are only read once every 64 samples. This interval also is independent from the blocksize! You can check this with attached patch by setting the blocksize to some really big value like 23 seconds and bang the [random 8]: You don't have to wait 23 seconds to get the result. Also with the [timer] object in that patch you can see the quantization of GUI messages to 64 samples.
As you've explained so well, DSP signals in Pd are calculated in blocks of several samples in one go. Normally 64 samples are one such block, but even with a blocksize of only 1 sample it would be tricky to convert messages to signals correctly, because even one sample takes a certain time (1/SR seconds) to compute.
Generally DSP objects calculate a complete block and cannot react to messages in between that time. The messages themselves are scheduled correctly (Axiom 1) it's just that most DSP objects don't listen for messages during their computation time.
Some DSP objects however actually can react quicker than a block: [vline~] and [vsnapshot~] are the prime examples. They use a little trick to do so: While they still calculate a full block in advance like everyone~ else, they "know" beforehand when messages are scheduled to reach them possibly in the middle of such a block and they calculate their sample block with these "future" messages in mind.
This is possible for messages, that are scheduled to be send at some future point in time. For example a [metro] generates this kind of message: When a [metro 500] bangs, it also instructs Pd to bang again after 500ms. [vline~] then can ask Pd: "Are there any messages scheduled for me during the next block?" and because Pd knows about that scheduled [metro]-bang, it can tell [vline~]: "Yes, there is one bang waiting for you 0.526 msec into the next block. Please take this into account!"
The normal [line~] object doesn't ask Pd about such scheduled messages and as such is faster to compute. If you just need to declick some value from a slider, then you can just use [line~] instead of [vline~] because slider events don't happen faster than 64 samples anyway. But if you build a drum machine that is driven by [metro] , you should really use [vline~] to get a drumset, that is not only good enough for acousmatic music, but also good enough for Jazz, as Eric Lyon once put it.
Frank Barknecht _ ______footils.org_ __goto10.org__
On Tue, 2007-05-08 at 18:37 +0200, Steffen wrote:
Marius also ends out with some explanation of the 'block' concept. I
think that what i don't really get.I understand that decreasing the block size will possible requirer
more computation/logical time then there is real time enough to
complete.
what do you mean by computational time? logical time and the time, the cpu needs to compute something are not the same.
And therefore that the information in a block is available
to the program to process. Which also means that after that block has
been processes the information is not longer available. Is that true?
i am afraid, i couldn't fully follow. i'll try to explain it in my own words and hope that i don't tell too much rubbish, cause this is only what i assume, how things are:
a block is a number of numbers, in pd these numbers are 32bit floats. the usual blocksize is 64samples(=floats). audio signals are passed blockwise between tilde-objects, that means a tilde-object receives 64 floats on its inlet, then processes all 64 samples and then sends them to its outlet. this happens each tick for the whole dsp tree. each tick, a whole block is processed by the first object, then passed to the next object, processed by this object, passed to the next and so on. i assume, the cpu overhead, when decreasing the blocksize, comes from the communication between the tilde objects. if the packagesize is smaller, more packages need to be passed to process the same amount of data in the same time, so more exchanges between tilde objects are needed. every tick, the 'message tree' is processed as well. so, in logical time, messages always 'happen' at block boundaries. for example, when a number is sent to the left inlet of an [osc~], the [osc~] changes its frequency exactly on the blocksize boundaries. so, in logical time, messages take effect only every 1.45ms (when running pd at 44100Hz). in real time, you can't tell when exactly something is processed, it can vary between immediately and the maximum of your soundcard buffer setting. the sound card reads the samples from the buffer at a fixed rate (the samplingrate), whereas pd does fill it at a speed, that depends on the cpuload. although pd does compute things at nondefined times, the output (of your soundcard) seems well timed, because pd puts the samples in the right order into the buffer.
What is a block, what's in it, what properties does it have. Is a
block a sample or is a block made out of a number (being the block
size) of samples? And also Jamie's question: what does the 'v' stand
for?
i think, in [vd~], it stands for 'variable' (delay). i don't know, what it means in [vline~] and [vsnapshot~], vector maybe, because the messages, they receive can have an effect within the vector (read:block), not only on block boundaries. these two objects are special, because when they receive a message, that was initally triggered by a [del] or a [metro], it has an effect within the block, because the messages generated by [del][metro] are tagged with some timestamp (is that correct?), so that [vsnapshot~]/[vline~] know, for which exact time they are meant to be executed.
if i understood IOhannes correctly, he said, that other 'translations' from pd to the 'real' world beside sending data to an audiocard cannot be timed accurately, since they lack a fixed rate, like an audiocard has it. for example, if you are talking to an arduino board, it will process the data as soon as it gets it. so if the cpu load is currently a bit higher, it will get the data probably a bit later, than when cpu load is small (is that right, IOhannes?). let's say i am running pd with a buffer of 100ms and the patch switches often between high and low cpu-load (for example it does load some audiofiles into arrays from time to time). would that mean, the maximum jitter of the arduino outputs is 100ms, although i don't have any dropouts in the audio? is that correct?
roman
Telefonate ohne weitere Kosten vom PC zum PC: http://messenger.yahoo.de
First of all thanks for all the elaborate explanations. They are all
greatly appreciated!
On 08/05/2007, at 20.06, Roman Haefeli wrote:
On Tue, 2007-05-08 at 18:37 +0200, Steffen wrote:
I understand that decreasing the block size will possible requirer more computation/logical time then there is real time enough to complete.
what do you mean by computational time? logical time and the time, the cpu needs to compute something are not the same.
Sorry. I meant the time it takes to compute the DSP.
And therefore that the information in a block is available to the program to process. Which also means that after that block has been processes the information is not longer available. Is that true?
i am afraid, i couldn't fully follow.
What i was thinking about is the information in each block, ie the
samples in each block are forgotten about when the computation/DSP of
that block is done. I'm guessing this, since some object, i guess
again, depends on the block size, that is the samples in the block.
For example if one wants to compute some mean value. - Does the block
size then become the 'window' size, where window is used as the
theoretical term in DSP?
Hallo, Steffen hat gesagt: // Steffen wrote:
And therefore that the information in a block is available to the program to process. Which also means that after that block has been processes the information is not longer available. Is that true?
i am afraid, i couldn't fully follow.
What i was thinking about is the information in each block, ie the
samples in each block are forgotten about when the computation/DSP of
that block is done.
Yes, it's gone then. But so are messages. Btw.: the [tabsend~] and [tabreceive~] objects directly operate on the sample blocks we're talking about here, as does the [print~] object, so if you want to see or influence what's happening in a block, use these.
I'm guessing this, since some object, i guess
again, depends on the block size, that is the samples in the block.
For example if one wants to compute some mean value. - Does the block
size then become the 'window' size, where window is used as the
theoretical term in DSP?
You mean "window" as in for example a FFT? Yes, that is equivalent to the block in Pd.
Frank Barknecht _ ______footils.org_ __goto10.org__
Steffen wrote:
On 08/05/2007, at 9.19, IOhannes m zmoelnig wrote:
because they do not interface with the world outside.
I feel that i don't interface with "the world" inside. I would
greatly appreciate if someone would translate the scope of this
discussion into noobish.
hi, think of it as Pd being a tool also used for non realtime renderings. in fact it is possible that Pd renders everything to a soundfile and not to the sound card. so if you have very complicated computation which cannot be done in real time because the cpu is not fast enough, that data would still be written to the soundfile without clicks. and that is because pd has its internal predictable time. if you want to trigger a message with 1000 milliseconds delay then you want to use the internal time measurement. for example if you load a 2 hours soundfile into a buffer in the first millisecond and start playing it that usually would cause Pd to clip and that is because it takes a while until the sound file is written to the buffer. Pd cannot continue with its internal measurement until all messages are finished executing. that is an example where internal time and world time would drift. the internal time is cut into pieces of 64 samples (at 44.1 khz sampling rate that is 1.6 ms). then the samples are sent to the soundcard (clocked by the soundcard) and then the next rendercycle of 64 samples starts. marius.