Hosts not calling processBlockBypassed

I might be getting some things confused with the JUCE host implementation then. I would dig around in juce_VST3_Wrapper.cpp it should set the Vst::ParameterInfo::kIsBypass flag on the parameter. I’m surprised though because the only time it calls processBlockBypassed is when the bypass parameter reports that it’s bypassed and if all is correct then that bypass parameter should be the one returned by getBypassParameter. I think you also have to make sure that the bypass parameter is in your normal list of reported parameters too, although if it’s not linking with your bypass parameter JUCE must be adding one so you should see it as an additional bypass parameter. I guess if you were returning a parameter in getBypassParameter but it wasn’t included in the normal list of parameters too then there would only be one bypass parameter reported to the host (the one created by JUCE) so you would end up with processBlockBypassed working but it wouldn’t sync with your bypass parameter.

I’ve added the bypass parameter to my “normal” parameters and I’m returning it in getBypassParameter(). Both Reaper and Ableton call processBlock and processBlockBypassed then. If I bypass in the DAW neither processBlock nor processBlockBypassed are called, so I can’t do anything here…

I’ve just been looking at Reaper and indeed it doesn’t really have what I like to call a bypass (I thought it did I must have been wrong), the documentation says (emphasis mine)…

…This will toggle the bypass of the selected fx. You will no longer hear the effect(s) and they will no longer use CPU resources.

However, if I load one of the stock Apple AU plugins I can see in auval that they don’t have a bypass parameter, but in Reaper it shows a bypass parameter and a wet parameter too. These are host parameters. Unfortunately, the “bypass” parameter is as described above. I suspect Reaper are using the “wet” parameter as a way to allow users to “bypass” the plugin in a glitch-free way, but I also expect that isn’t linked to the bypass parameter in the plugin?

For VST3 I assume if you return a bypass parameter you’ll see two parameters in the list? one being the enable/disable offered by the host and the other being your bypass parameter.

One host that I remember definitely having the linking ability in the past was Cubase. AAX also makes you say which parameter is the bypass parameter so I think ProTools will link the host bypass and plugin bypass.

TBH you’re at the mercy of the host and there’s not much you can do about it :man_shrugging:. I’m also not sure you should do anything about it as you would be changing the behaviour of the host just for your plugin. If you just want to show that the plugin is bypassed in the GUI you could maybe see if releaseResources has been called, or if that’s not consistent, add a mechanism to detect that processBlock hasn’t been called (you’ll know the maximum block size and samplerate so you’ll have some rough idea of when to expect the next processBlock).

Yes, it’s not linked.

Exactly :wink:

Indeed! Actually it’s not that much of a problem that the bypass parameter is not linked. The way it behaves now is as good as it gets: If the host supports it, the bypass parameter is linked. If it doesn’t you can use my own bypass parameter for glitch-free latency compensated bypassing. If it’s not linked and you use the host’s bypass and you experience a glitch I can’t do anything about it.

1 Like

so, to summarize: adding a bypass parameter won’t always work with all hosts, but it also won’t break anything in hosts that don’t support it, so you might as well…?

Is this correct? :sweat_smile:

Just to make clear as this topic is confusing enough:
The LINKING won’t always work. Controlling your bypass parameter from your editor always works. So yes, it’s still a good idea if you don’t want to rely on the host’s bypass implementation.

2 Likes

OK, I’m confused: in looking through the JUCE docs for AudioProcessor::getBypassParameter(), it says that the host should never call processBlockBypassed if this parameter is implemented, instead using the parameter to control the bypass state.

SO… if a host does support bypass parameters and is following the Jules Rules, then it will always call processBlock() and never processBlockBypassed(), right?

And if a host does not support bypass parameters, then it will… always call processBlock() and never processBlockBypassed(), right? the only difference being that it won’t update the state of that parameter to control the bypass…?

so when exactly does processBlockBypassed get called? Ever?

Well, the host doesn’t follow those rules, both Ableton and Reaper call processBlockBypassed if the bypass parameter is implemented.
In order to be save I check the bypass parameter in the processBlock too.
So far no problem, except that the linking doesn’t work and if I use the host’s internal bypass switch neither processBlock nor processBlockBypassed get called - nothing to do here…

1 Like

gotcha. well, I guess that’s the best we can do for now!

I think the confusion from the docs might be when you use JUCE to host a plugin or any AudioProcessor, rather than when you implement a plugin. Maybe the docs should be updated to reflect that.

1 Like

Just checked this, for VST3 in Cubase and Live. The distinction Anthony mentions is relevant to VST3 -that’s how it works in Cubase.
bypass
Bypass controls the bypass parameter. When it’s on, the wrapper calls processBlockBypassed. Deactivate disables the processing callback, both of them. There’s always a bypass parameter. If you don’t provide one, the wrapper creates it. If you provide one but it’s not in your list of parameters, the wrapper adds it. VST3 doesn’t require a bypass parameter, but it defines a flag (kIsBypass) for it, and says: “special bypass parameter (only one allowed): Plug-in can handle bypass (highly recommended to export a bypass parameter for effect Plug-in)”. What the plugin does with it is not Steinberg’s business -what the Juce wrapper does is calling processBlockBypassed.

The thing is that many (most?) hosts don’t have a bypass button like the Cubase one, so the only way to use the bypass parameter as defined by VST3 is through the plugin’s own interface. That’s what happens in Live. Live’s “device activator” is like Cubase’s “activate effect”. There’s no bypass in the DAW’s interface (no button linked to the bypass parameter as defined by VST3), but the parameter is still there, because the wrapper always provides it, and if you set it, the wrapper calls processBlockBypassed. So…

If this method returns a nullptr then you can still control the bypass by calling processBlockBypassed instead of processBlock. On the other hand, if this method returns a non-null value, you should never call processBlockBypassed but use the returned parameter to control the bypass state instead.

This is the confusing part. I don’t know how Juce hosting works, but this is certainly not what the VST3 wrapper does. The wrapper checks the parameter and chooses the callback accordingly. This suggests a different scheme -to make the plugin itself check its own bypass state.

(edit) Just to clarify, I ask about this because it doesn’t match what the plugin wrappers do -they call processBlockBypassed, not processBlock, when the bypass parameter is on. Many people seem to be checking the bypass parameter in processBlock based on this indication, and I’m not sure if that’s really needed. I guessed Anthony might remember how this came up from the thread where Fabian solved the current implementation.

1 Like