Hey all. In response to a question on the Facebook help group, I came up with this method for syncing toes over a network.
Quite simply, SyncNode0 just grabs the frame from the local time component and sends it over UDP to SyncNode1 which uses it to update the frame of its own local time component. This does require that node1 is not actually playing, so that its timeline is actually driven by node0. (Like I said, rough and dirty).
Of course, network latency is a big issue. A hardwired LAN and QoS can help with this, but I’m still thinking about a decent way for node0 to say “The time is X, and we’re both going to play this frame at X+n,” and account for discrepancies in system time. Although this isn’t as critical as it is for audio, I’m curious how AVB and PTP pull this off.
sync_node0.toe (11.3 KB)
sync_node1.toe (4.2 KB)
Not sure about AVB, but I believe PTP information is embedded into the TCP header itself, which adds highly accurate timing information to all packets passing through the network. IIRC AVB does something similar. I don’t think that TD’s network objects currently parse this information, but it would certainly be cool if they did, particularly as you can set up a PTP server on any Linux box (or via a docker image).
Sync is a deep issue, as there are many meanings of that term across many contexts. But I’m pretty comfortable saying that syncing systems over a wireless network is going to be difficult if you’re attempting frame accurate playback (I read the FB post earlier).
TD actually supports reading of Art-Net timecode (but not writing as far as I know). You can view this by creating a DMX In CHOP, and then setting an Info CHOP to observe it. The Info CHOP channels starting with ‘arttimecode’ are the relevant ones.
It would be great if Derivative provided a way to write Art-Net timecode at some point.
The UDP DAT is a magnificent thing. PTP just specifies the payload of a UDP packet, part of that payload is a timestamp, so you could construct PTP payloads using Python and then send/receive using the UDP DAT. What’s more difficult to address is specifying the value of the DSCP field, which is in the IP header, and what QoS uses to prioritize packets. What I’m having trouble wrapping my head around with PTP is that it seems to assume that all the clocks on the network produce the same timestamp values at the same real-world time. That is, a client receives a server packet, looks at the timestamp, takes its own timestamp, finds the difference, and then the result is supposed to be how long it took the packet to get from the server to the client. But if the clocks are off by a few milliseconds, then the calculated network latency will also have that error.
That aside, what I think is interesting about AVB is that it goes a step further than simply synchronizing clocks. As I understand it, it also tells all the clients at what time to do something. So if that’s playing a frame, it says “the time is T, now that we all agree, we’re going to play frame F at time T+t”. This is obviously important for syncing video, because if you have a single image split up among multiple servers, those servers don’t just have to agree what time it is, they also have to agree at what time they play a particular frame; PTP alone won’t do that.
What I’d love to see TD implement networking-wise is an IP DAT, as well as a parameter in UDP and TCP DATs to specify the DSCP value, so that you can subject TD network traffic to QoS rules. UDP and TCP will get you far, but IGMP, for example, uses neither. I’ve built IGMP packets using Python within TD, but what’s beautiful about the networking DATs is that they abstract away having to deal with creating and managing sockets, which can be a bit tedious.