Missed Notes With PDC As Rewire Slave

The problem: Currently, when running Renoise as ReWire slave to whatever master, and theres something in your song that introduces latency, Renoise will miss “notes” while being triggered from the master. This only happens with PDC enabled.

The why/how/wtf? is a bit hard hard to explain, so let me try do so slowly, step by step.

An example: Lets say you are using just one FX, a bus-compressor, in your song on track 01. A bus compressor introduces a latency of 2ms on the track its sitting on, so PDC magically shifts all other tracks also by 2ms, to get everything played back perfectly in sync. This also means that the whole song in Renoise now has a latency of 2ms. Remember, track 01 + all other tracks are now shifted by 2ms!

Lets now say we are running Renoise as ReWire slave. ReWire unfortunately has no kind of support for PDC/custom latencies, so if we would simply run this song in a ReWire master, Renoise would be 2ms off - always.

OK, this sucks, you want that Renoise plays perfectly in sync with your master, so what we are currently doing, is shifting our timeline forward by 2ms:
For example, if the host plays at time 1ms, Renoise is playing time 3ms and so on. This way Renoise is again in sync with the master. This unfortunately leads to another problem:
If you start playing from the master, Renoise will always start a bit too late. Lets say you are starting the master at beat pos 2.1.1, then Renoise will start at 2.1.1 + 2ms to compensate its latency. This offset, even when its just one tiny ms, will lead to the problem that notes which start !exactly! at pos 2.1.1 are not triggered.
When you start playing from Renoise, we do a little trick to avoid this problem: We tell the master to start playing at “2.1.1 - 2ms” which means that Renoise will start exactly at 2.1.1. This only works for times greater than 1.1.1. and ONLY works if you start the song from within Renoise. Again: the ReWire master does not know anything from Renoises latency.

Maybe a simple example XRNS makes this more clear (see attachment). This is a simple drum loop with a compressor on it. This compressor, as in our example above, adds a latency of 2ms. Thats it.
Now load this song into a ReWire master of your choice and set the loop in the master from 5.1.1 to 9.1.1, to cover Renoises 2. pattern (where the amen plays).

-> With PDC in Renoise enabled, starting to play from 5.1.1 in the master will miss the drumloops start.
-> With PDC in Renoise disabled, starting to play from 5.1.1 in the master should always work as you expect it.
-> With PDC in Renoise enabled or disabled, starting to play from Renoise should always work (some ReWire masters might probably behave wrong though).

513 PDC_ReWireSlave_Example.xrns

Possible solutions/workarounds:
Now, finally: Why do I have to bore you with all these technical details? Well, because the current way we are dealing with this simply confusing if this results into “lost” notes. This feels wrong / like a bug / doesn’t make sense if you don’t know the technical details.
On the other hand, ignoring these latencies would suck as well, because then Renoise is always a bit off. 2 or 5 ms might not be a problem, but as soon as you are using lots of VSTs and lots of FX in general, this can easily sum up to noticeably more.

Possible solutions/workarounds:

  1. We ignore the problem (latencies) and prefer that notes are always triggered correctly (thats what we do with Jack Transport btw)
  2. We Ignore the latency only when starting to play. As soon as Renoise is running, it would then “catch up” the latency by playing faster until its synced. This can be annoying as well, and lead to artifacts in FX because of the BPM changes. Especially when the latencies are big.
  3. We disable PDC by default as ReWire Slave
  4. We keep things as they are and try to explain that somehow, so that everyone knows whats happening. Kind of impossible? Who the heck should understand this?

5-X Your ideas!

Any ideas, suggestions are very welcome!

Well… I already said my opinion about this back when we first discovered it.
There really is no perfect solution for this.

  1. would be a disaster. We really really need the compensation.
  2. the catch up can’t possible work when playing back longer samples? Unless you add some good stretch algorithm and stuff. This might actually work for native stuff at least… but I’m not sure it is worth all the effort.
  3. Now this could be it. When starting as slave pdc is off. If user then try to enable pdc a window or something will pop up and explain that notes can disappear on start etc.
  4. this could be more like 3. I agree we should at least explain this a little better.

If it comes down to either have PDC or not for rewire, my opinion is that rewire is mostly a production tool.
Who cares if notes not always start at beginning as long as you project is in synch and simply works when you render your finished product. For larger latencies the whole rewire would be totally useless without it.
If someone IS going to use rewire in live situations (or are just very bothered of the missing notes all the time) they can always, and probably should, disable PDC and use faster non-latency plugins. Some DAW’s can also easily adjust delay for single tracks like we can in renoise to manually compensate PDC.

In other words. I’ll be happy for anything other then nr1!
2 would probably be best for most users. It would not have to work perfect as long as it will catch up pretty fast.
Some artifacts should not be a big problem I think.

Yes indeed. It wouldn’t hurt to ask them if they have plans for this?

So far there has only been one ‘update’ for rewire? (rewire1 and rewire2).
Who knows if there will be another update with PDC…

Contacting them will not hurt, but then all existing ReWire clients have to be updated as well, which will take ages and thus not finally solve the problem for now.

Something I’ve not talked about above, but which we also should think of, is that you perfect timing is even more importnat when rendering Renoise from within the master. What Renoise does with “render selections” is possible in various other masters as well. Wrong timing is quite a big problem, and that notes are missing as well…

  1. would not be hard to add because thats what we anyway do on slight timeline changes - when Renoise slightly is off the masters timeline. I might enable this here and see how this “feels”. My guess is that small latencies (< 5ms) are not really noticeable. Bigger latencies are for sure a problem.

  2. would indeed be a solution if we can’t find something better.

Another thing which I just thought of is not disabling PDC, but only ignoring the global latency. This would mean that we would compensate internally with PDC, but just avoid the shifting to the ReWire master with the song latency. So everything in Renoise would be in sync, but Renoise would not be in sync to the master… Thats still better than completely disabling PDC. The question is how/where to set this in the GUI?

Yes, that would be a nice option as well. Because some masters can manually set delay/compensate individual tracks like we can in renoise.
Then it’s easy to get the overall PDC in renoise and type it in manually in master.
Should be put in preferences?:
5. “Global Rewire PDC” checkbox or something…

Still we would have to explain all this somewhere when running renoise as slave.

Perhaps a combination of 3 and 5 would be all we need?

Reasons instruments & FX seem to introduce no latency, so they don’t have the problem + they do not support VSTs. Ableton Live as slave does not support VSTs when running as slave.

Reaper does, and also misses “notes” on starting, but a bit better than we: They compensate their tracks individually with PDC - shift the time lines per track, so only the tracks which have a latency will drop notes…

Thats it. There are no other “big” ReWire slaves beside those, so theres no real need for that.

I think you will always have this problem as long as no other host provides latency values or support PDC.
How does ReWire broadcasts latency? Does it broadcasts latency at all?
If both hosts at least know the latency between eachother, Renoise can at least make itself tight to its master and the slave can fix itself to Renoise if the other host gets triggered.

Thats exactly the problem. You can not broadcast latency in ReWire; thats not handled in the ReWire protocol…

Then let’s poke Reason for an update… they benefit from that idea as well, else there is no way of being at least able to say: “We do everything to make this tight but we can’t help it if the other host does not support everything”

Ofcourse, perhaps when using Midi Yoke as a “live-wire” you might be able to get some “latency” information (double helix synchronisation).
Send a midi signal through Midi Yoke to the other host to a channel that is being routed back to Renoise (through ReWire), then measure the signal that comes in and split in half, you might have a good approximate of the latency the other host provides.

I know…
What the ReWire engine needs is a specific delay protocol in which all hosts tell the ReWire engine how much delay the ReWire engine should compensate.
This means that it has to buffer audio from some hosts and delay the play-moment on other hosts depending at which host the play event is triggered.
This is all to allow the situation where multiple hosts are slaved of which some of them support PDC and some don’t. Yet those that don’t, cannot anticipate on anything, so the ReWire engine has to fix that.

If a host which supports PDC has to fix that the way ReWire works now, then this can probably only be realized using a virtual midi cable AFAICT.

I do not know how the ReWire protocol works exactly so this might be a stupid idea ;) but one thought that popped into my mind was that when you press play in the master, then Renoise immediately sends a stop command back to the master, starts playing till the latency is compensated and then send a start command back to the master.

Besides that I probably think PDC off by default when in ReWire-slave mode, and then, as Pysj said, if enabled a pop up that explains the problem. Or nr 2 with possibilities to turn it off and go back to the missed note behavior.

Btw. I really love this ReWire support, it makes it possible for me to work on my vocal and guitar tracks in another host without the need to first render the whole song to wav. Good work!

nr 4 sounds reasonable to me as long proppellorheads doesn’t have a solution for it themselves.

This doesn’t sound good to me.

This sounds better.


Plugins/Misc - ReWire
Rewire slave mode defaults:
:ballot_box_with_check: ‘Disable PDC’ [default: checked]
:ballot_box_with_check: ‘Ignore global latency caused by PDC’ (fix manually in the Rewire master) [default: unchecked]

[With a ‘Details’ button that would open a separate window with the explanation.]

Something like that, maybe…
Then when the user would enable PDC in slave mode, it would pop up a warning window about possible missing notes at start with links to ‘Rewire Options’ and the ‘Detailed explanation’. This warning could then be disabled, of course, just like daily tips when starting Renoise.

Why I think it makes more sense to disable PDC in Renoise by default rather then ignoring the global latency by default?
Because when a user sees that PDC is disabled in Renoise he can then quickly diagnose the cause of the latency he hears (if he hears it).
But when the whole Renoise signal is delayed and out of sync with the ‘Rewire master’ it’s perhaps more confusing. Or not? How many hosts offer a manual correction?

But I definitely agree that this should be handled by ReWire. I was wondering why ReWire doesn’t handle this many years ago…

Do you mean it’s somehow possible to avoid this when rendering?
I just tried rendering from Reaper (with Renoise slave) and it worked the same as in live playback, missing the first note.
(BTW, I couldn’t render successfuly from Reaper unless there was an audio file loaded in Reaper as well.)

No, what I meant was that it usually do not bother you that much during the composing stage to miss some notes here and there during start of playback in the middle of a song when you know they are actually there when you render the whole thing in the end (but that is just MHO, others might find this very irritating…). If you then miss the very first notes in the whole song you can always just render separate in renoise and in the host and then mix them, or just add some empty space in the beginning of the song etc…
There are workarounds for most of these problems. Like temporary turning off PDC when you render a smaller part. Or select render range some time ahead in the master etc…

Unless propellerheads (and all host/slaves miraculously will support this fast) include pdc info in later rewire versions we must have options for how this should behave now. I can’t see one solution will make this work for every situation. So then we need some options for this and inform ppl in a proper way what to do.
This is kinda like the midi support in renoise too. You can’t know how the user work, or what they use. So we have different options for midi out, and audio return etc to get the timing right.
It seems we have to live with similar options for rewire no matter what solution we end up with.

Agreed. I’ve added now a new option as suggested by you and ermi. Thanks to you all for the feedback.

In the audio configs, when ReWire slaved, there’s now a switch “Automatically compensate latencies” with a long tooltip.
When this thing is off, which is the default, we’ll not compensate PDCs global latency, thus will not miss notes. When its on, things are as they are now.
Below it also shows how much global latency the song currently has, so you can use this value in the master to compensate manually…


Sounds great. B)

Yah, sounds great to me as well.

Good idea, I hope there’s enough interest.
I’d be surprised if Propellerheads didn’t consider this before, but who knows…

Or we consider a sort of protocol that can be easily used with Rewire e.g.:

Applying delay compensation through using the "Stop" signalling protocol:  
The following sequences supply the following messages:  
2*stop + Set start position + value = delay  
The message should be delivered at the beginning of the session or when the song is not playing  
Only the slave may send their delay, the Master should perform all the compensations internally (which include it's own plugin delay values if applicable)  

This way, we don’t interfere with hosts that does not support this protocol, yet those that support it can apply it. Also: we don’t need Reason to update their library

Another thing is, an external sort of API library is used to handle the ReWire communications right?
So in most cases i think a lot of host-developers might be able to implement this quickly.
Then we don’t need trickery with repositioning at all, Masters only need to apply delay or if necessary recalculate their own internal delay.