I asked this on the facebook group, thought I'd ask it here as well. Who cannot be happy with vanilla's OSC support and still needs mrpeach and stuff? I mean, really really need as in there's no way to deal with such OSC tasks in Vanilla. Tell me what exactly please... I know that it can happen and how, I just wanted examples in the real world, and I also believe Vanilla is fine for most use cases.
I just never use OSC as all I do is inside Pd anyway :)
I see [netsend]/[netreceive] make [udpsend]/[udpreceive] obsolete these days for OSC... but we also have [routeOSC] and [packOSC], and in Vanilla's documentation we see this: ~*no attempt is made here to clearly distinguish between the OSC address (symbols) and the following data, nor between blobs and lists of numbers - it is assumed that you know what types the message should contain. You can alternatively use the OSC objects from mrpeach which have more features than these.*~
cheers
Am 18. April 2021 09:21:57 MESZ schrieb Alexandre Torres Porres porres@gmail.com:
I asked this on the facebook group, thought I'd ask it here as well. Who cannot be happy with vanilla's OSC support and still needs mrpeach and stuff? I mean, really really need as in there's no way to deal with such OSC tasks in Vanilla.
simple: timestamps and bundles.
if your sender application uses bundles and you can't change that, you are stuck with mrpeach.
i think practically all applications I've written that send OSC data (to Pd,...) use bundles (except for toy apps, or during class when I didn't want to get sidetracked).
if jitter is a problem (and often it is, if you are transmitting notes or periodically sampled data), you *need* timestamps.
I don't really like the timestamp implementation in mrpeach (as it uses real time, rather than logical time), but better this than nothing...
mfg.hft.fsl IOhannes
On Sun, Apr 18, 2021 at 6:06 AM IOhannes m zmölnig zmoelnig@iem.at wrote:
I don't really like the timestamp implementation in mrpeach (as it uses real time, rather than logical time), but better this than nothing...
Logical time timestamps would only be accurate inside of the Pd instance. It could be added as an option but it would not conform to any OSC specification.
Martin
On 4/18/21 17:06, Martin Peach wrote:
On Sun, Apr 18, 2021 at 6:06 AM IOhannes m zmölnig zmoelnig@iem.at wrote:
I don't really like the timestamp implementation in mrpeach (as it uses real time, rather than logical time), but better this than nothing...
Logical time timestamps would only be accurate inside of the Pd instance.
i tend to disagree. there are basically two use-cases for timetags:
neither of these use-cases warrant system time.
here's a real world example: if i use Pd to send events to my drum-synth, and i want these events to be exactly 100ms apart so I'm driving it with a [metro 100], the real time of these ticks will be very jittery (depending on all sorts of things, starting with the audio buffer of Pd), up to dozens of ms.
if i codify this jitter in the timestamps, then any law abiding receive will have to do their best to reproduce this jitter.
what is the value in that? the only way to schedule two events at exact times I see is to use some "ideal" time - in Pd this is the logical time.
but it would not conform to any OSC specification.
i checked and double checked the specs but could not find anything about this. where do you get the idea that the OSC specs mandate wall clock time? OSC-1.0 speaks about "NTP format" (but this is just the structure of the 64 bits data chunk) and "the number of seconds since midnight on January 1, 1900" (but it doesn't say whether this is supposed to be wallclock or idealized)
It could be added as an option
a flag or similar would be great. there probably are use-cases where real time makes sense, why not be able to cater for both.
f,dst IOhannes
Both of you are right.
The basis for OSC timetags are of course the (NTP) system time, because that's usually the only shared time source between different apps.
However, if you schedule several events in a DSP tick, you don't want to get the current ystem time for each event, because this will cause unnecessary jitter.
What you can do instead is get the system time *once* per DSP tick and use that as the basis for scheduling/dispatching events within the tick. This is more or less what Supercollider does, BTW.
However, since Pd DSP tick computation itself can be very jittery for large hardware buffer sizes, this is not sufficient. There are basically two solutions, afaict:
a) use some dejittering/smoothing algorithm. Scsynth, for exampple, uses a DLL to filter the system time.
b) only get the system time for the very first DSP tick and for all subsequent DSP ticks increment by the *logical* block duration. This allows for sample accurate *relative* timing, but the absolute timing can suffer from clock drift. This is the default behavior of Supernova and some people actually experience problems in longer performances.
Generally, time synchronization between apps is a fundamental (unsolved) problem in computer music. See the following discussion for a starter: https://github.com/supercollider/supercollider/issues/2939.
Christof
On 18.04.2021 22:32, IOhannes m zmölnig wrote:
On 4/18/21 17:06, Martin Peach wrote:
On Sun, Apr 18, 2021 at 6:06 AM IOhannes m zmölnig zmoelnig@iem.at wrote:
I don't really like the timestamp implementation in mrpeach (as it uses real time, rather than logical time), but better this than nothing...
Logical time timestamps would only be accurate inside of the Pd instance.
i tend to disagree. there are basically two use-cases for timetags:
- reducing jitter when synthesising events on the receiver
e.g. i want to trigger a drum-synth exactly every 100ms
- reducing jitter when analysing events from the sender
e.g. i want to measure the period between two mocap frames
neither of these use-cases warrant system time.
here's a real world example: if i use Pd to send events to my drum-synth, and i want these events to be exactly 100ms apart so I'm driving it with a [metro 100], the real time of these ticks will be very jittery (depending on all sorts of things, starting with the audio buffer of Pd), up to dozens of ms.
if i codify this jitter in the timestamps, then any law abiding receive will have to do their best to reproduce this jitter.
what is the value in that? the only way to schedule two events at exact times I see is to use some "ideal" time - in Pd this is the logical time.
but it would not conform to any OSC specification.
i checked and double checked the specs but could not find anything about this. where do you get the idea that the OSC specs mandate wall clock time? OSC-1.0 speaks about "NTP format" (but this is just the structure of the 64 bits data chunk) and "the number of seconds since midnight on January 1, 1900" (but it doesn't say whether this is supposed to be wallclock or idealized)
It could be added as an option
a flag or similar would be great. there probably are use-cases where real time makes sense, why not be able to cater for both.
f,dst IOhannes
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list
On 4/18/21 10:32 PM, IOhannes m zmölnig wrote:
i checked and double checked the specs but could not find anything about this. where do you get the idea that the OSC specs mandate wall clock time? OSC-1.0 speaks about "NTP format" (but this is just the structure of the 64 bits data chunk) and "the number of seconds since midnight on January 1, 1900" (but it doesn't say whether this is supposed to be wallclock or idealized)
i just thought that maybe we are really talking about different things here.
so i'd like to clarify what I mean by "logical time".
Pd keeps an track of an internal monotonic value "pd_systime" that is incremented whenever time advances within the Pd world. the incrementation of this value is losely synched to the passing of time in the real world ("wall clock time"). "losely" insofar as the increments do not happen at exactly the same time, but the maximum difference between the wall clock time and the logical time is bound to a somewhat small value (<<1sec).
wall clock time is typically provided by the OS by means of gettimeofday() or similar.
while the two times are synched, they have different offsets. Pd's logical time simply starts whenever the Pd instance started. however, gettimeofday() counts seconds since the beginning of the epoch (currently: 1970-01-01 00:00).
to complicate things, NTP-timestamps (as used by OSC) use their own epoch that starts on 1900-01-01 00:00.
using Pd's logical time "as is" as an OSC timestamp, is of course useless (unless you are communicating withing the same Pd-instance), as all participants need to agree on a common epoch.
so what i'm really suggesting to "fix" the timestamps in [packOSC] is to use logical time for *advancing time* (and add some offset to put the timestamps into the same calendar as NTP)
so basically:
time with respect to the NTP time. e.g.: offset=seconds_from_1900_to_1970+gettimeofday()-sys_getlogicaltime()
in the actual implementation there's two issue that should be addressed:
calculation of the offset) should only be perfomed once for all the [packOSC] and [unpackOSC] objects in the running instance, so they are all tightly synched.
2038; this is still far in the future for many, but for [packOSC] birthday is about as far in the past)
gfmsdtf IOhannes
so what i'm really suggesting to "fix" the timestamps in [packOSC] is to use logical time for *advancing time* (and add some offset to put the timestamps into the same calendar as NTP)
This corresponds to 2) in my previous mail. While this sounds simple in theory, in practice you will encounter problems with clock drift sooner or later. Supernova had to introduce an option to use the system time instead of the logical time because some users had experienced issues. For a drastic example, search for "timing drift supernova" inhttps://www.listarc.bham.ac.uk/lists/sc-dev-2014/search/ https://www.listarc.bham.ac.uk/lists/sc-dev-2014/search/
In Pd there is another issue with advancing by logical time: Pd has very relaxed realtime-safety constraints and it is very common to occasionally drop some audio blocks, e.g. when opening a large patch or loading a large soundfile. Naturally, the logical time does not advance while Pd blocks, so your timestamps will be late forever.
FWIW, here's my current approach to scheduling/dispatching OSC bundles in Pd (for the next AOO release):
sample the system time *once* per DSP block
filter the time with a DLL to get rid of jitter
check for dropped audio blocks and resync the time base. This is hard
to do in a plugin. The best solution I've come up with so far is to average the last few delta times and check if it rises above a certain threshold.
All of this steps wouldn't be necessary if Pd would
give access to the (estimated) system time of the current DSP tick
resync the system time and send a notification (e.g. a message to
"pd") when the polling scheduler has to drop a block of audio
There's still a potential problem with xruns in the audio driver. Jack has a xrun callback (https://jackaudio.org/api/group__ClientCallbacks.html#ga08196c75f06d9e68f9a3...). Portaudio has input/output overflow/underflow flags that are passed to the stream callback, but it's up to the audio driver to actually provide this information. I've read somewhere that many ASIO drivers don't do this...
Christof
On 19.04.2021 09:17, IOhannes m zmoelnig wrote:
On 4/18/21 10:32 PM, IOhannes m zmölnig wrote:
i checked and double checked the specs but could not find anything about this. where do you get the idea that the OSC specs mandate wall clock time? OSC-1.0 speaks about "NTP format" (but this is just the structure of the 64 bits data chunk) and "the number of seconds since midnight on January 1, 1900" (but it doesn't say whether this is supposed to be wallclock or idealized)
i just thought that maybe we are really talking about different things here.
so i'd like to clarify what I mean by "logical time".
Pd keeps an track of an internal monotonic value "pd_systime" that is incremented whenever time advances within the Pd world. the incrementation of this value is losely synched to the passing of time in the real world ("wall clock time"). "losely" insofar as the increments do not happen at exactly the same time, but the maximum difference between the wall clock time and the logical time is bound to a somewhat small value (<<1sec).
wall clock time is typically provided by the OS by means of gettimeofday() or similar.
while the two times are synched, they have different offsets. Pd's logical time simply starts whenever the Pd instance started. however, gettimeofday() counts seconds since the beginning of the epoch (currently: 1970-01-01 00:00).
to complicate things, NTP-timestamps (as used by OSC) use their own epoch that starts on 1900-01-01 00:00.
using Pd's logical time "as is" as an OSC timestamp, is of course useless (unless you are communicating withing the same Pd-instance), as all participants need to agree on a common epoch.
so what i'm really suggesting to "fix" the timestamps in [packOSC] is to use logical time for *advancing time* (and add some offset to put the timestamps into the same calendar as NTP)
so basically:
- when packOSC gets instantiated, determine the offset of the logical
time with respect to the NTP time. e.g.: offset=seconds_from_1900_to_1970+gettimeofday()-sys_getlogicaltime()
- when creating a timestamp, use this to calculate the ideal NTP time:
now=offset+sys_getlogicaltime()
in the actual implementation there's two issue that should be addressed:
- probably the synching of logical time to wall clock time (that is:
the calculation of the offset) should only be perfomed once for all the [packOSC] and [unpackOSC] objects in the running instance, so they are all tightly synched.
- make sure to handle epochs correctly (the next unix epoch starts in
2038; this is still far in the future for many, but for [packOSC] birthday is about as far in the past)
gfmsdtf IOhannes
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list
On Mon, Apr 19, 2021 at 6:51 PM Christof Ressi info@christofressi.com wrote:
so what i'm really suggesting to "fix" the timestamps in [packOSC] is to use logical time for *advancing time* (and add some offset to put the timestamps into the same calendar as NTP)
This corresponds to 2) in my previous mail. While this sounds simple in theory, in practice you will encounter problems with clock drift sooner or later. Supernova had to introduce an option to use the system time instead of the logical time because some users had experienced issues. For a drastic example, search for "timing drift supernova" in https://www.listarc.bham.ac.uk/lists/sc-dev-2014/search/
You probably need some kind of 'resync' messages sent quasi-periodically, but when? I have implemented in [packOSC] acquiring the OS's clock time when the first instance of [packOSC] starts up, by sing a global variable for the start epoch. All subsequent timestamps are generated using that offset plus Pd's DSP clock, so all [packOSC]s in a patch will generate the same timetag for the same DSP tick. So the question is, how to do the resync when the drift gets out of hand? I do think that any fancy timing stuff should be done outside of [packOSC] and the [timetagoffset( message be used to stay in sync.
Martin
I think I had problems in the past for not having [routeOSC] and [packOSC] when sending/receiving from other software such as reaper, but I can't confirm anymore. Other softwares will work with mrpeach, but not necessarily with vanilla.
It's also convenient to use routeOSC for a cleaner patch structure, as it allows a route-style tree sorting.
I asked this on the facebook group, thought I'd ask it here as well. Who cannot be happy with vanilla's OSC support and still needs mrpeach and stuff? I mean, really really need as in there's no way to deal with such OSC tasks in Vanilla. Tell me what exactly please... I know that it can happen and how, I just wanted examples in the real world, and I also believe Vanilla is fine for most use cases.
I just never use OSC as all I do is inside Pd anyway :)
I see [netsend]/[netreceive] make [udpsend]/[udpreceive] obsolete these days for OSC... but we also have [routeOSC] and [packOSC], and in Vanilla's documentation we see this: ~/no attempt is made here to clearly distinguish between the OSC address (symbols) and the following data, nor between blobs and lists of numbers - it is assumed that you know what types the message should contain. You can alternatively use the OSC objects from mrpeach which have more features than these./~