Oh wow John that might work. I didn’t think of that. The question is how does JUCE render the voices: Does it do them all synchronously? If they are all rendered simultaneously as each block is rendered this would work in principle. If each voice is rendered in blocks separately one after another it won’t work (ie. for a given block, if voice 1 renders start to finish, then voice 2 renders start to finish, etc. it won’t work).
I’m still not good at all this pointer reference business, so can I run it through and you tell me if it makes sense? In theory, is this how I would do it?
I could create variables inside my PluginProcessor.cpp private section (or does it need to be the public section) like:
float voice1Var = 0.f;
float voice2Var = 0.f;
float voice3Var = 0.f;
float voice4Var = 0.f;
float voice5Var = 0.f;
float voice6Var = 0.f;
Then where the voices are created in PluginProcessor.cpp, I can pass in a reference to them in addition to my parameters which are already going in to them and the voice number that each voice represents (so I can keep track of which var to manipulate per voice):
for (int i = 0; i < numVoices; i++) {
mMpeSynth.addVoice(new MPESynthesiserVoiceInherited(¶meters, &voice1var, &voice2var, &voice3var, &voice4var, &voice5var, &voice6var, i+1));
}
Then in each voice I can have the following under private:
float* voice1VarPtr;
float* voice2VarPtr;
float* voice3VarPtr;
float* voice4VarPtr;
float* voice5VarPtr;
float* voice6VarPtr;
int voiceNumber;
And my class constructor would be:
class MPESynthesiserVoiceInherited
: public MPESynthesiserVoice,
public AudioProcessorValueTreeState::Listener
{
public:
MPESynthesiserVoiceInherited(AudioProcessorValueTreeState* parameters, float* voice1Var, float* voice2Var, float* voice3Var, float* voice4Var, float* voice5Var, float* voice6var, int voiceNumberIn)
{
parametersPointer = parameters;
voice1VarPtr = voice1Var;
voice2VarPtr = voice2Var;
voice3VarPtr = voice3Var;
voice4VarPtr = voice4Var;
voice5VarPtr = voice5Var;
voice6VarPtr = voice6Var;
voiceNumber = voiceNumberIn;
Then I would be able to inside each voice allocate whatever value I want for each voice to its respective float variable, and all the voices could access the values for all the other voices simultaneously. So I could do the math in each voice.
I just realized after writing this up it would make more sense to do it with an array of floats rather than individual float variables. But either way the principle would be sound.
Does that make sense and is that what you were suggesting? It makes sense that it should work in principle since that’s how the parameters are getting into the voices.
The only issue is like I said that if each voice is rendered as a separate block, then maybe they won’t be synchronized. Eg. If it renders:
Voice1 block start to finish, then voice 2 block start to finish, then voice 3 block start to finish, then maybe this won’t coordinate. I’m not sure. Any thoughts?
What do you think? Thanks for your help. This would be really nice to work out a solution for that doesn’t require me rebuilding the whole JUCE synthesiser framework.