HISE FX and delay compensation
-
@Fortune said in HISE FX and delay compensation:
Juce provides a pair of functions for getting/setting the current plugin latency.
I see Engine.setLatencySamples()
What's the other part of the pair? -
@Christoph-Hart I can't seem to compile your latest scriptnode as of 2 hours ago
1>c:\program files\hise-scriptnode\stk_wrapper\stk\src\adsr.cpp(16): fatal error C1083: Cannot open include file: 'ADSR.h': No such file or directory (compiling source file ..\..\JuceLibraryCode\include_stk_wrapper.cpp)
-
@dustbro Notice the red X
-
@d-healey Where can I see this on the GitHub, and what does that mean?
-
@dustbro When Christoph "commits" an update to GitHub it is added to a timeline of all previous commits for that branch. You can view it by clicking on "commits" after you have selected a branch.
Christoph has setup the Git repo so that each time a new commit is added the code is automatically tested, if it fails the test a red X is placed next to the commit. If you see a red X then you will probably get problems if you build from that commit and you should choose an earlier or later point in the commit history to get the code from.
-
@dustbro For example, if the delay time of the plugin is 500 samples; just insert this code into the begining of the on init script;
Engine.setLatencySamples(500);
With this way, plugin reports delay compensation to the DAW in the very begining of the initialization.
I am using it on fx plugins it doesn't give errors. But it doesn't work in almost all DAWs.
-
@dustbro @Fortune Yeah I see that issue too.
Hise reports the latency to the daw successfully, but somehow compensation doesn't work (except Reaper). However Since Reaper has a great built in auto compensation, if you enter setLatencySamples, the sound starts ahead; because it compensated double :)
-
-
The idea of this entire call is to report to the host how many samples it needs to compensate (= preroll). It‘s a basic feature in JUCE which I‘ve just wrote a simple wrapper for it. Apparently it doesn‘t work for the majority of hosts but there‘s nothing else I can do.
Now I don‘t have the time currently to go through every host and check whether it works, but we can make a list here with hosts that support / don‘t support this feature, then I can take it to the JUCE team.
-
Also if anyone finds a useful information in the JUCE forum (just search for setLatencySamples), you‘ll get plenty of topics), I am happy to take that into account.
-
@Christoph-Hart I'll take a look on the forms this weekend.
-
I found this threads, they may be helpful. Also I see that they prefer to use
setLatencySamples()
inprepareToPlay
. But we're using it inonInit
, could that be the cause?https://forum.juce.com/t/cubase-latency-issues/27669
https://forum.juce.com/t/look-ahead-vs-daws-latency-compensation/30384/2
https://forum.juce.com/t/vstplugininstance-getlatencysamples/7934
-
Well,
onInit
comes way beforeprepareToPlay
, so if it's not set correctly by then, we're screwed anyway.However, I've encorporated a few things mentioned in the threads:
- resend the latency update in
prepareToPlay
if it's different than at the last call - add a static delay line to the bypassed processing chain (I thought the host would do this, but it makes sense that it's the plugins job to delay it).
While the first one is pretty cosmetic, I think the last one might be actually helpful.
Unfortunately I am not in my studio right now, so I can't test the hosts, but I pushed it to the scriptnode branch so if anyone wants to check if this improves the situation, have a go. - resend the latency update in
-
@Christoph-Hart I've just tried, result is the same :/
-
@orange @Christoph-Hart I just tested latest version of ScriptNode. Cubase is picking up the reported latency.
Gotta test to see how accurate it is. -
@dustbro Yeah Cubase can detect the latency value, there is no problem about it. You can also see that in the Cubase plugin manager.
But the problem is, wet and dry channels are not in sync. Delay still persists.
-
@Fortune got it.
-
OK, I've committed a fix for a typo that caused crackling when a delayed plugin is bypassed.
I've also made a example project with a latency of 200ms - it's just a simple delay without anything else:
https://github.com/christophhart/hise_tutorial/tree/master/LatencyTest
The sample amount will get calculated on the initialisation and the latency will be changed accordingly (so to eg. 8820 samples on 44,1 kHz).
I've tested these hosts:
- Cubase 9: Latency is reported correctly, both active and bypassed plugins are in sync
- REAPER 5: Latency is reported correctly, both active and bypassed plugins are in sync
- Ableton 9: Latency is reported correctly, both active and bypassed plugins are in sync
Please try your hosts and report back any problems:
- Compile the LatencyTest plugin as FX plugin.
- Load up your DAW and add two audio tracks with the same audio data
- Load the LatencyTest VST plugin into one of them
- Play and check that it's in sync. Bypass the plugin and play again, check that it's still in sync.
-
-
First of all, you did it, well done @Christoph-Hart !
I am pretty impressed. Especially calculating the delay time acording to sample rate and ms conversion multiplying is a clever idea. Yeah it needs some improvements but you did most of the thing. As you can see, you can do it.
My check is that:
Windows:
- It works well on Cubase 10, Reaper 5, Ableton 10, Studio One 4.5, Pro Tools 2019 Ultimate!
- In FL Studio 12 & 20- it fails again. I hear 200 ms latency unfortunately :/
Mac
- Reaper, Ableton, Studio One, Pro Tools did it very good.
- In Logic Pro X, When you insert the plugin in the channel, it takes approximately 2 seconds to sync. You can hear fade of the phase shift before synching, after 2 seconds it is in sync. This fade time can be disturbing to some users. You can improve it.
- FL Studio 20 - fails again. I hear 200 ms latency unfortunately :/
Also I have some questions;
- To calculate the delay time , can we take the delay time of the plugin with "getlatency" and use it on "setLatency"?
- I tried that code in "if / else statement" but it doesn't work properly. I usedin different oversampling modes, delay time changes when OS is on and off. For setLatency, only first statement works. Can that be done?