SynthLab SDK
|
The SynthLab SDK includes SynthLab projects that are described in detail in the synth book .Figure 1 shows the block digrams for the SynthEngine and SynthVoice Objects used in all six of the synth examples. All of these projects, as well as the example project from the programming guide here (described in SynthVoice Example and SynthEngine Example) encode the entire synth product inside of four files:
The SynthEngine was designed to be reused from the very beginning. Its role in the synth is easily pre-defined and hard-codable. Of the two objects (voice and engine), the SynthEngine is the less specific in nature, and other than instantiating and managing its array of SynthVoice objects, it is really only involved in a couple of direct synthesis tasks:
This means that once you get your SynthEngine up and running the way you like (and that may be right out-of-the-box), you may keep re-using the same object and plugin framework interface code without modification, over and over. Figure 1 below shows the block diagram for the SynthEngine object, as coded in the example voice and engine files.
In each of these projects, the SynthEngine object stores an array of SynthVoice objects that are identical. This makes the engine a mono timbral synth engine. In these examples:
This means that a complete synth can be encoded in a single SynthVoice object because the engine object does not discern between voices in its array. This means that once you have a working synth:
Fun fact: all six of the SynthLab example synths share the same source files, including the same synthvoice.h and synthvoice.cpp code as a testament to how reusable the code really is
Multi-Timbral SynthEngine
You can build multi-timbral synths with the engine and voice objects as well, to mimic a Korg synth in "Combi" mode where a different patch plays on each MIDI channel, up to 16 at a time. In this case, you need to:
The SynthLab projects exploit the SynthModle <-> ModuleCore relationship that is outlined and detailed in the SynthModule Progamming and ModuleCore Progamming sections. This means that each module loads up to four cores, each of which implements a variation on the functionality of the module. The wavetable oscillator object WTOscillator (the SynthModule) fills up all four of its module core slots with its variations that include five ModuleCore objects: traditional wavetable, morphing wavetable, drum tables, sound FX tables, and Fourier synthesized tables.
You have two choices when using the SynthModules in combination with ModuleCores (remember that SynthModules may also be implemented without cores, which simplifies the GUI programming a bit but still involves the same effort of designing and implementing the operational phase methods).
All of the SynthModules that load cores (which is every module except the DCA) have code written in their constructor that loads at least one core to use as the default. Some modules load more than one, adding them in sequence to their list of cores. If you leave this code as-is, then the synth modules and cores are already hardwired. Once set a module can't load a different core. This means for example that once you commit an oscillator to be a drum wavetable oscillator, it must remain rendering that data for the rest of the life of the synth. And, this is very much the way hardware synths operate as well.
SynthLab was designed for dynamic ModuleCore loading from the very beginning. This means that you may select different cores into their owning modules at run-time, for example changing an oscillator from drum wavetables to morphing wavetables to sound effect tables. When the core changes, two other pieces of information also change:
The synth book details all of this, and provides the theory that underlies the modules, voice, and engine. Figure 1.3 (from the book) shows a typical GUI implementation for WTOscillator. On the right side, there are four "mod knob" controls named A, B, C and D that are specific to each module core. Most cores have at least one unassigned mod knob for you to experiment with. Examine Figure 1.3 a. and b. and notice how the GUI controls connect to the module and its cores:
You will see that almost all of the synth modules follow this paradigm and include exactly 10 GUI controls per module, the exceptions are the sequencer, mod matrix, FM operator and DCA that are either too complex to shoehorn into this format, or too simple to require multiple cores and GUI controls.
Figure 1.3: the WTOscillator's interface showing the relationship between module= strings, cores and mod knob strings
If you choose to use the dynamic string version, then you will need to make calls to the engine that will return the module core strings and mod knob labels for you to apply as a result of the user changing cores on the GUI (or automation). You will also need to know how your plugin framework handles dynamic swapping of string lists and GUI control labels. Even if you don't use ASPiK or RackAFX you can still examine the function calls and code in the sample projects available at www.willpirkle.com to see how I am dynamically changing strings around.
SynthLab Examples