This project has moved and is read-only. For the latest updates, please go here.

ProcessReplacing, number of channels?

Topics: Audio, Backward Compatibility, Defect?, Exception, Host Compatibility, Host Development, Host Processing
Apr 20, 2014 at 3:58 PM
Edited Apr 20, 2014 at 4:16 PM
I've had a hard time figuring out how many channels I should put in these buffers:
void ProcessReplacing(VstAudioBuffer[] inputs, VstAudioBuffer[] outputs);

Haven't found any kind of guidelines anywhere. Some professional plugins support a lot of channels and they will poke memory on all of them. From what I've seen so far, the host can't set a number of channels different than the plugin, right?

If I build a buffer smaller than what the plugin ask for it will read memory out of bounds.
So I've used these values to initialize my buffers and it went pretty good:

Until I stumbled on midi plugins who say they process audio in the CanDo but ask for 0 inputs and 0 outputs, yet still read/write memory in the buffer.

It seems these plugins are either made with SynthEdit/SynthMaker or were started from boiler plate code like this one:
MyPlug::MyPlug(audioMasterCallback audioMaster) : AudioEffectX (audioMaster, 1, 1)
   // No audio channels it's a midi plugin
   setNumInputs = 0;
   setNumOutputs = 0;

   // I dunno what this does... let's not touch it

void processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames);
   // I dunno what this does...  let's not touch it
   float *in1  =  inputs[0];
   float *in2  =  inputs[1];
   float *out1 = outputs[0];
   float *out2 = outputs[1];

   while (--sampleFrames >= 0)
      // Let's put 0 so it can compile.
      (*out1++) = 0;
      (*out2++) = 0;
The rule I've come up to deal with this madness is to build a 2 input / 2 output channels if the plugin say yes to canProcessReplacing but declares an input/output size of 0. Otherwise I give them the number of channels they want.
Is there a better way of dealing with the buffer size issues?
Apr 21, 2014 at 9:36 AM
Because the (original C++) VST spec is not very concrete in some crucial places - there is a lot of variance on how these specs were interpreted. And because of that some programmers (both Host and plugin) had to do some workarounds to get it all to work. Unfortunately some of these variations are simple plain bugs (like the situation you describe). After a few years its hard to discern original spec from organic growth (bugs included).

Always keeping a minimum of a stereo bus seems like a fair compromise.

Concerning the buffer length of the buffers passed onto the Processing method - there has been a lot of debate on that. Some say you should always pass the BlockSize length, others say you should (as a plugin) always check the length on each Process call and that BlockSize is only an indication to initialize internal structures, some say the length should always be a multiple of 2. Again, variation grew over time...

I have been thinking about writing a Host recently and figured I would build a plugin test framework into the host. That way you can give intelligent (technical) feedback on the plugin that is added to the Host. That test framework would test all the rules that your Host 'assumes' or uses on dealing with plugins. If a plugin does not pass the mandatory tests, you simply refuse to load it into the host. That way you have an isolated piece of code that deals with plugin problems and the rest of the code of your host can be optimized to work with that set of 'assumptions'.
Apr 21, 2014 at 11:34 AM
Thanks for the clear information. I agree the host should always pass the block size and hopefully the audio interface too, otherwise we are all delagating the problem down to the end user. Buffers being a multiple of 2 is a no brainer too. Pretty interesting the idea of validating a plugin. So far I haven't made a ton of exceptions in my code, it's like web development, trying to find a middle ground that satisfies most browser/plugins. Vst specs are not superb but I'll take them over html/javascript/css anyday :)
Apr 21, 2014 at 1:23 PM
Some hosts (FL I think) break up the BlockSize buffers to allow for sample accurate parameter changes. So the pass in part of the buffer with size < BlockSize - then change a parameter value on the plugin - then pass in the rest of the audio buffer. Some plugins rely heavily on the audio buffers always being of BlockSize size, other plugins can easily handle variable processing sample buffer size...