I have put together a modal synth I am very happy with. Currently each voice has an OwnedArray of “ModalUnit” objects. Each modal unit synthesizes for one mode of the voice, either with a sine wave or resonant bandpass. The array of 50-100+ modal units (each which has its own frequency/decay settings, etc) combines to create a final voice.
I am managing this with the creation of:
OwnedArray<ModalUnit> mModalUnits;
The modal array is initialized like this in the voice on startup:
for (int i = 0; i < numPartials; i++) {
ModalUnit* unit = new ModalUnit(i + 1);
unit->setSampleRate(mSampleRate);
unit->setResoQSmoothingTime(*parametersPointer->getRawParameterValue(id_QSmoothSec));
...//other basic setup functions every unit must go through
mModalUnits.add(unit);
}
Then when a parameter is changed in the voice, it is updated into the units like this:
for (int i = 0; i < mModalUnits.size(); i++) {
ModalUnit* unit = mModalUnits.getUnchecked(i);
unit->setVelocity(velocityVar);
unit->setFrequencyBaseRaw(frequencyFinal);
...//other per sample or note or knob change or get output functions as needed
}
This is all working rather well. However, I would like to adapt this to make it a bit more complicated. In physical modeling synthesis, for example, you might have an array to simulate horizontal vibrations of a string and an array to simulate vertical vibrations.
I would like to set up an array of arrays of modal units, so I might have:
“STRING” ARRAY POSITION ZERO → contains 50 modalUnits
“STRING” ARRAY POSITION ONE → contains another 50 modalUnits
This way I could iterate through the array of all 100 units when wanted, or I could specify if I want to iterate through the first 50 modalUnits or second 50 modalUnits separately (ie. for group specific changes).
I think I need to declare this as:
OwnedArray<OwnedArray<ModalUnit>> arrayOfStrings;
Would I then initialize this like so:
numStrings = 2;
numPartials = 50;
for (int i = 0; i < numStrings; i++) {
OwnedArray* string = new OwnedArray;
for (int j = 0; j < numPartials; j++) {
ModalUnit* unit = new ModalUnit(j + 1);
unit->setSampleRate(mSampleRate);
unit->setResoQSmoothingTime(*parametersPointer->getRawParameterValue(id_QSmoothSec));
string.add(unit);
}
arrayOfStrings.add(string);
}
Then to iterate through all the strings and units, it would be like this:
for (int i = 0; i < arrayOfStrings.size(); i++) {
OwnedArray* string = arrayOfStrings.getUnchecked(i);
for (int j = 0; j < string.size(); j++) {
ModalUnit* unit = string.getUnchecked(j);
unit->setVelocity(velocityVar);
unit->setFrequencyBaseRaw(frequencyFinal);
...//other per sample or note or knob change or get output functions as needed
}
}
Or if I wanted to just iterate through the second “string”:
for (int i = 1; i < 2; i++) {
OwnedArray* string = arrayOfStrings.getUnchecked(i);
for (int j = 0; j < string.size(); j++) {
ModalUnit* unit = string.getUnchecked(j);
unit->setVelocity(velocityVar);
unit->setFrequencyBaseRaw(frequencyFinal);
...//other per sample or note or knob change or get output functions as needed
}
}
Does this look correct or like it should work?
I can’t think of a foolproof way of testing it except to really dismantle my synth and put it back together this way or start doing some tricky debugging games which could take a while. I’m not that good with this sort of thing, so I thought it might be quicker just to ask if I’m on the right track before I dig into all that and maybe make a mess.
Any help is very appreciated as always. Thanks.

