How to pass an array of buffers from processor renderNextBlock to voice renderNextBlock

This is actually a bit related to a 9 day old post of mine on “Trying to do some DSP processing on single voices” here Trying to do some DSP processing on single voices.

For a special need, I need to pass an array of 8 AudioBuffer’s, inside “processBlock” in PluginProcessor to voices in “SynthVoice.h” which has it’s own local array of 8 buffers and where I am doing single voice processing, and which are at the end added to the passed buffers, and back in “processBlock” in PluginProcessor some of these may be further DSP processed,and finally added to the “normal” “processBlock” buffer. All buffers are of type AudioBuffer and allocated to same number of channels and size.

Sorry it may sound, phun intended, complicated and I guess it is, but I am trying to do something I’ve have never seen before on a synthesizer. Anyways all is good if I pass one buffer of an array at a time using either of the below methods in “processBlock”;

AudioBuffer<float>& TGPtr = TGBuffer[0];
mySynth.renderNextBlock (TGPtr, midiMessages, 0, buffer.getNumSamples ());

or

mySynth.renderNextBlock (TGBuffer[0], midiMessages, 0, buffer.getNumSamples ());

and over in “SynthVoice.h” I got;

void renderNextBlock (AudioBuffer<float>& outputBuffer, int startSample, int numSamples)

So what I really needed to do was something like this;

AudioBuffer<float>* arrayPtr[8];
for (int i = 0; i < 8; i++)
     arrayPtr[i] = &TGBuffer[i];
mySynth.renderNextBlock (arrayPtr, midiMessages, 0, buffer.getNumSamples ());

and over in “SynthVoice.h” something like this;

void renderNextBlock (AudioBuffer<float>* outputBuffer[], int startSample, int numSamples)

I humbly admit that my lack of knowledge with pointers is probably why I can not get this to work. Any help will be greatly appreciated, but let me add I won’t be offended with replies linking to “C++ Pointers for Dummies”.

void renderNextBlock (AudioBuffer<float>** outputBuffer, int startSample, int numSamples)
1 Like

Thank you very much for taking time to help.

One problem is when I do your suggestion with two “**”, or just with one “*”, in my PluginProcessor’s constructor where I add voices, "SynthVoice () error red lines saying "object of abstract class type is not allowed pure virtual function … has no overrider.

mySynth.addVoice (new SynthVoice ());

And to make it clear, in the “renderNextBlock” in “SynthVoice.h” I want to be able to do this;

// After getting samples into local voice buffers I then process

//  And finally I need to transfer global voice buffers like so, 
// which works fine when I just do one like outputBuffer[0] or outputBuffer[1] etc.

for (tg = 0; tg < maxModules; tg++)
{
	outputBuffer[tg].addFrom (0, renderStartSample, TGVoiceBuffer[tg], 0, 0, renderNumSamples);
	outputBuffer[tg].addFrom (1, renderStartSample, TGVoiceBuffer[tg], 1, 0, renderNumSamples);

		// Clear local buffers
		TGVoiceBuffer[tg].clear ();
}

I was just letting you know how to pass a pointer to an array of pointers as a parameter. :slight_smile: obviously there are other things to consider. For example, when you say SynthVoice, I assume you mean a class you have derived from the JUCE SynthesiserVoice class, which requires you implement the renderNextBlock with the specified parameter list.

virtual void renderNextBlock (AudioBuffer<float>& outputBuffer,
                                  int startSample,
                                  int numSamples) = 0;

So you have to implement that function with those parameters. I don’t fully understand what you are trying to do, but maybe you can have a new function that takes the array of pointers, and then calls this required API with each one?

Ok I understand and appreciate the first part very much, thanks!

And yes SynthVoice is derived from SynthesiserVoice class.

I already tried as you suggested and make my own function in SynthVoice to have the correct parameters and then call the API required as suggested, but I can’t seem to reference it from PluginProcessor.

For example if I create this over in SynthVoice as a quick test;

void myRenderNextBlock (int test)
	{}

Just like I call the “normal” renderNextBlock via;

mySynth.renderNextBlock (TGBuffer[0], midiMessages, 0, buffer.getNumSamples ());

I quite naively, obviously, thought I could do this;

mySynth.myRenderNextBlock (0);

FYI: For now, although I am still very interested in my original question and how to implement, I have gone ahead and made the 8 buffers accessible also to SynthVoice by making them global. That means I no longer have to pass any buffer pointer to SynthVoice’s renderNextBlock, although I still pass “buffer” to pass something as it is needed.

Then in SynthVoice I gather samples to the local array of voice buffers, array equal to how many tone generators (oscillators) I have, and in the end add them to the “global” tone generator buffers, and finally to main buffer.

What I can do now, and which is what I was trying to do, have each stage of my custom 8-stage loopable, and with adjustable knee, ADSR based on milliseconds, invoke one or more of the 8 tone generators, in other words for the attack stage the ADSR could be set to only sound TG1, another stage sound TG2, and so on, until release stage which could sound TG8, any combination possible, one, several, or all TG’s at any ADSR stage. If that was not enough since I process effects back in the PluginProcessor individually for each TG, I can therefore have a reverb only in the attack stage for example, and a delay only in the release stage, therefore making for a quite uniquely evolving sound!