How to reset plugin buffers in hosts that suspend ProcessReplacing()?

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

What I did in one of my (likely never to be released) plugins, was to listen for in coming MIDI events for "all-notes-off" (0x7b) and "all-sounds-off" (0x78). You might also want to consider resetting things if you ever receive a setProgram with a program index that is the same as your current program index... or depending on what your users would expect, maybe any setProgram received, merits a reset.

Post

No_Use wrote: Wed Jan 09, 2019 10:47 pm
Fender19 wrote: Tue Jan 08, 2019 8:06 pm MCompressor from Melda Production freezes when transport Stop is pressed but then instantly resets to 0dB gain reduction when Play is pressed.
Compressor from Dead Duck software resets to zero gain the instant Stop is pressed.
Already tried asking the devs how they do it? :)
Maybe Voitec(?) (Melda) is too busy for such stuff but the Dead Duck guy is active on KVR too iirc.
Yeah, but that would take all the fun out of it! I didn't know that, will try. Thanks!

In the meantime, how about something like this (haven't tried it yet):

ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames)
{
curPos = GetSamplePos();
if (curPos < lastPos) Reset(); //playback resumed behind stop point
if (curPos > lastPos) Reset(); //playback resumed forward of stop point
lastPos = curPos;

//---------------------------------------------------------------------------------------------------

for (int s = 0; s < nFrames; ++s, ++in1, ++in2, ++out1, ++out2)
{
lastPos += 1;
Last edited by Fender19 on Wed Jan 09, 2019 11:06 pm, edited 1 time in total.

Post

Jimbrowski-one wrote: Wed Jan 09, 2019 10:57 pm What I did in one of my (likely never to be released) plugins, was to listen for in coming MIDI events for "all-notes-off" (0x7b) and "all-sounds-off" (0x78).
Kind of doubtful Wavelab, which seems to be the actual problem host in this case, would be sending such messages to audio effect plugins...(Of course, everything is possible...)

Post

The disadvantage of the sample position workaround is that it will break a looped playback.

Post

I have something that appears to work. Not fully tested, or "sample accurate", but it seems to be working in Wavelab:

ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames)
{

curPos = GetSamplePos();
if (curPos < lastPos) Reset();//playback resumed behind block stop point
if (curPos > (lastPos + 2 * nFrames)) Reset(); //playback resumed forward of block stop point
lastPos = curPos;



Now, how to make this more accurate and robust? I'm not sure about the "2 * nFrames" since frame size can vary block-to-block. I used "2 *" nFrames to make sure there was some buffer space.

Anyhow, it's a step in the right direction (I think)!
Last edited by Fender19 on Thu Jan 10, 2019 12:34 am, edited 3 times in total.

Post

Max M. wrote: Wed Jan 09, 2019 11:50 pm The disadvantage of the sample position workaround is that it will break a looped playback.
I think there's a flag for "looped playback" that might take care of this. Would have to look it up.

Post

Fender19 wrote: Wed Jan 09, 2019 11:58 pm I have something that appears to work. Not fully tested, or "sample accurate", but it seems to be working in Wavelab:

ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames)
{

curPos = GetSamplePos();
if (curPos < lastPos) Reset();//playback resumed behind block stop point
if (curPos > (lastPos + 2 * nFrames)) Reset(); //playback resumed forward of block stop point
lastPos = curPos;



Now, how to make this more accurate and robust? I'm not sure about the "2 * nFrames" since frame size can vary block-to-block. I used "2 *" nFrames to make sure there was some buffer space.

Anyhow, it's a step in the right direction (I think)!
NOPE - I was wrong. This does not work in Wavelab. Reason: GetSamplePos() returns the TOTAL number of samples played, not WHERE it is in the track! Makes no sense! The sample count reported keeps going up no matter where I place the cursor.

Ahhhhhhhh Back to the drawing board...

Post

How difficult could it be to modify IPlug sources themselves? I've taken a quick look into its sources (not sure if that was the same version you use) - well, a bit tricky (just too much code to get trough in a few minutes) - but not undoable... If this is really about unhandled `suspend/resume` messages the fix could be very simple.

Post

Max M. wrote: Thu Jan 10, 2019 1:34 am If this is really about unhandled `suspend/resume` messages the fix could be very simple.
As far as I can see, it is not about that. The IPlug code is doing pretty much the same what the Steinberg C++ VST2 wrapper code is doing. Note that the VST2 C API itself does not have any suspend or resume calls or opcodes. The Steinberg C++ class calls its suspend() and resume() methods when the host calls the effMainsChanged opcode. IPlug actually calls its Reset() method in response to some other opcodes too.

Post

Xenakios wrote: Thu Jan 10, 2019 1:54 am VST2 C API itself does not have any suspend or resume calls or opcodes.
I Know. I used `suspend`/`resume` notation only to not confuse this with yet more different API details.
The IPlug code is doing pretty much the same
Does it? Ah, never mind, I see it now: https://github.com/olilarkin/wdl-ol/blo ... T.cpp#L440 (I'm not sure how this version matches yours though). Then it's definitely not what I suspected earlier.

Either way that's why primarily I suggested to try to monitor all WaveLab calls during stop/start - to find the exact reason/root of the problem (I still can't believe WL does not trigger any useful events at start/stop). W/o knowing exact reason the whole thing goes more like "trying to cure symptoms instead of the illness itself".

Honestly the problem surprises me a lot as it seems to be quite critical (it should affect too many effect types and be easy noticable) for none using IPlug to not face it before. On the other hand we know for sure that most of effects do not suffer from this - and I don't really believe anybody had actually to write any tricky workarounds/kludges for this. Very strange. So something somewhere in IPlug<->VST code is still the first suspect.
Last edited by Max M. on Thu Jan 10, 2019 3:55 am, edited 1 time in total.

Post

Max M. wrote: Thu Jan 10, 2019 2:51 am Honestly the problem surprises me a lot as it seems to be quite critical (it should affect too many effect types and be easy noticable) for none using IPlug to not face it before. On the other hand we know for sure that most of effects do not suffer from this - and I don't really believe anybody had actually to write any tricky workarounds/kludges for this. Very strange. So something somewhere in IPlug<->VST code is still the first suspect.
Exactly my thought, "OTHER developers must have come across this - what are THEY doing?" That's why I asked here.

I've also asked over on the WDL-OL forum (home of IPlug) and have basically received the same answer - crickets! I was hoping someone had a simple, "oh, you do this" answer.

My last thought was that maybe the "Tails" parameter has something to do with this but I've played with it a bit and that doesn't seem to be the key either.

Post

Fender19 wrote: Thu Jan 10, 2019 3:52 am
Exactly my thought, "OTHER developers must have come across this - what are THEY doing?" That's why I asked here.
You seem to be concerned about the behavior of Wavelab in particular. Maybe Wavelab just isn't a popular host for plugin developers to test with?

Post

IPlug and JUCE are missing handlers for effStartProcess and effStopProcess (from VST2.x), those sound promising but do they actually have anything to do with this?

Post

Max M. wrote: Thu Jan 10, 2019 1:34 am How difficult could it be to modify IPlug sources themselves? I've taken a quick look into its sources (not sure if that was the same version you use) - well, a bit tricky (just too much code to get trough in a few minutes) - but not undoable... If this is really about unhandled `suspend/resume` messages the fix could be very simple.
Well, checking WDL-OL master branch on Github, it seems IPlug calls Reset() on suspend (but not resume) for VST2, whenever bypass state changes (in either direction) for AU, but only in setupProcessing for VST3. Maybe there is some logic behind all this, but it seems somewhat inconsistent.

If you don't want to mess with the IPlug sources, you could try putting the reset-code in OnActivate() and see if that makes a difference. That one seems to be called in for both suspend and resume for VST2 and whenever bypass state changes for AU or VST3.

Post

Maybe Wavelab just isn't a popular host for plugin developers to test with?

Still there should be a lot of complains from WL users, like... hmm... "I hear ghost echos/reverb-tails every time I re-start my song". No idea how many widely IPlug based delays/reverbs are out there, but an overall result of the IPlug_based_plugins * type_of_effects_affected * n_of_wl_users equation cannot be that small to have no trace :) (Or can it?)

Post Reply

Return to “DSP and Plugin Development”