SynthesiserSound. Why?

In the process of writing my own SoundFont parser/player (SFZero had some major flaws), I managed to get audio playback happening without using any of the stuff SynthesiserSound is there for. What is this class even for? It’s friends with SynthesiserVoice so that SynthesiserVoice can access all of its members. But you can just the same put all of those members into the SynthesiserVoice class directly.

So, what is the point of this class? Was there some idea that you’d have a Synthesiser instance that could load multiple SynthesiserSounds that work with different synth voice classes? Most synth plugins just have a single per-voice architecture model that all of their presets make use of, no? So, what is the point of this SynthesiserSound class, if we can shove all of our architecture into the Voice class itself with no loss of functionality.

Is there a solid example of a juce::Synthesiser that has multiple SynthesiserVoice implementations that require separate SynthesiserSound classes? Or does everyone end up writing their synths to only support one SynthesiserSound, and thus only need one SynthesiserVoice class?

3 Likes

I think the SynthesiserSound class is intended as a container for parameters and data the voice instances would share. I suppose that same stuff could be in the parent AudioProcessor or some other class too, though…So… :man_shrugging:

Can you reference or show an example of a synthesiser that would use multiple subclasses of SynthesiserVoice? I can’t think of one. I don’t see how you’d ever need different SynthesiserVoice architectures for a single synth.

This is my understanding as well from the “documentation.” A good case for this seems to be a wavetable synth; it does not make sense to store the same wavetable once per voice. If this is true, however, how can we access that table in our SynthesiserVoice subclass? @matkatmusic you suggest in your original post that SynthesiserVoice and SynthesiserClass are friends, but in my version (4.3.1) this is not the case. This would clarify the situation for me a bit. Does anybody know how a SynthesiserVoice subclass is intended to access SynthesiserSound subclass’s data?

By dynamic_casting :

void SineBankVoice::startNote(int midiNoteNumber, float velocity, SynthesiserSound * sound, int currentPitchWheelPosition)
{
	SineBankSound* ssc = dynamic_cast<SineBankSound*>(sound);
	if (ssc != nullptr)
	{
		// whatever needs to be done with the sound subclass
	}

edit : if your JUCE version does not have the friend thing declared, then the sound subclass of course has to have the needed data as public member variables or accessible via getter/setter functions.

Update to the latest version of Juce.