How to retain a value between processBlock calls?


#1

Newbie to Juce - and struggling to learn VST3. (VST2 seemed a lot easier!)

I am designing an envelope follower and have the envelope value defined as the variable “env” in PluginProcess.h as a “protected float”. The code is almost working - “env” is updated with new values during the processBlock loops - but I can’t seem to figure out how to make it HOLD its value between processBlock calls.

“Env” has to be initialized to 0.0 before the processing begins but I can’t to figure out WHERE to initialize it. If I initialize it inside processBlock, before the processing loops, it works - the envelope tracks the signal. HOWEVER, since the value is being reset to 0.0 in each processBlock, it doesn’t hold its value from one block to the next.

I have tried initializing “env” in the constructor, in PreparetoPlay, and several other places and when I do any of those things the code does NOT work - “env” takes on a value of 1.0 and stays there.

How is something like this normally done? Where should the variable “env” be declared and initialized to make it “remember” its latest value between processBlock calls?


#2

Declare as a class member of your AudioProcessor, like you apparently have already done? Initialize it right when declaring it in the members (possible since C++11) or in the constructor of your AudioProcessor. Additionally reset it in prepareToPlay since that method should usually reset such variables. If after doing all that it still doesn’t work, I would guess there’s a bug in your DSP code or in the way how you check the variable’s value. Or maybe you are simply testing with a signal that makes the env value be 1.0…?


#3

Thank you for the reply.

Yes, this is driving me crazy because I see nothing wrong. The only place the “env” variable is used is in the processBlock and I am initializing it in prepareToPlay.

Yet SOMETHING is changing the value of it before processBlock gets started.

Is processBlock getting called (plugin running) when a DAW is stopped? If so, what values is it sending to the plugin - all zeros? I don’t have the “check for no signal” flags set up yet - could that be doing something crazy in the code (divide by zero, etc.)? Not sure how that would end up as the value 1.0 in the variable though…


#4

processBlock may or may not be called by the host continuously. Some call it all the time, some call it when a track is record armed/input monitoring, some do tricks where it is not called when you might expect it to happen…Properly implemented hosts should call prepareToPlay and wait until it is finished before the first processBlock call, though. What host are you testing with?


#5

I’m testing in Wavelab 9 and Cakewalk by Bandlab. Exact same result in both.

I have narrowed this down a bit. The variable IS being properly initialized in “prepareToPlay” but goes to value 1.0 and stays there when it gets to this step:

env = env + 0.005 * (newlevel - env);

It’s a simple low pass filter. “Newlevel” (a float) is the new input value (-1.0 <> 1.0) and working correctly (checked).

WHAT is wrong with is code? Somehow it’s changing the value of “env” to 1.0 and doesn’t change. Maybe it’s obvious and I’ve been staring at it too long!


#6

Not sure if it is related to the problem, but are you trying to process stereo audio? Is that one env state variable enough to deal with both of the channels properly? It would be useful to see more of your code.


#7

Yes, that one env value is for both channels. I have checked the signal driving this (“newlevel”) and it is swinging +/-1.0 as it should. “env” should be a low passed version of “newlevel” but its stuck at either + or -1.0 (shows up in the DAWs as straight line at 0dB).

The code is for a correlation meter. Here is the entire block:

		FabsL = fabs(left) + 0.0000001;		//140dB down
		FabsR = fabs(right) + 0.0000001;		//140dB down

		if (FabsL >= FabsR) corr = right / left;
		else corr = left / right;

		env = env + 0.005 * (corr - env);			//lp filter corr

#8

The variables “left” and “right” end up being zeros and cause a divide by zero and thus undefined behavior or at least some kind of an error the host deals with by showing/playing you a signal that appears to be 1.0 or -1.0? Or have you somehow taken that into account? Note that the division by zero just once in the signal pipeline can cause all subsequent calculations to be messed up too, so the divide by zero case needs to always be avoided in some manner.


#9

That was it! Divide by zero error. Thank you!

Now, speaking of that, I don’t understand what happens at zero in plugins and DAWs. Floating point numbers, in audio, never go to zero (unless blanked) - just very small numbers. So what happens if you multiply the signal by “0.0 gain” like when you pull a fader all the way down? Why doesn’t every plugin and the DAW itself “blow up” with divide by zero errors, etc.?


#10

Yes, “zero” and “silence” are bit of a complicated matter with floating point numbers and DAW applications (some hosts may also be mixing in a very quiet signal to prevent denormal numbers), but it’s entirely possible real zeros may be coming from the host application that can cause a divide by zero error in a plugin if the plugin doesn’t prevent that from happening.

I am not entirely sure what you mean by 0.0 gain and divide by errors etc. DAW applications are of course coded extremely carefully so that they themselves don’t produce divide by zero errors, NaNs and infinities in the signal path…Sometimes they can mess up but it’s much more common that plugins cause such errors. I have seen many plugins doing errors like that and unfortunately done such mistakes myself too.


#11

Yes, what I mean is what happens in a DAW when you pull the fader all the way down - does it multiply the signal by exactly 0 or is there always some amount of denormal added to it?

Most DAWs have processing built in besides outboard VSTs so I would think they’d have “zero” problems internally as well. Perhaps how they address this explains why people think some DAWs have “a sound”? I know it’s very low level but it could accumulate given enough gain, tracks, etc., yes?


#12

Each DAW application does such details differently. I highly doubt those ever cause any audible differences, no matter how many signal stages, tracks etc are involved, at least if the DAW is used for actual sound and music production and not deliberately abused in some manner to make the extremely tiny differences apparent.