
Yoshimi very heavily uses switch statements, some of which are truly massive. This might raise some alarm when viewed but is quite deliberate. In order to make all of this accessible to developers a spreadsheet was built up at the same time. This is "dev_notes/Yoshimi Control Numbers.ods" and has details of every command currently implemented (and a few still being considered).

The development has been very much an incremental process, initially with numerical entries and large gaps to create grouping, allow for changes, and give a clearer idea of the various structures.

The intention was then to collapse all the gaps to give more efficient switch statements. However in the intervening time several CLI users have been using the direct access method to reach controls that were not yet available formally. Although this is now done, the actual values are being left as they are until (at least) the next release. This is further complicated by the fact that MIDI-learn references some of these numbers, and people will have saved such files. Therefore many of these will now remain fixed.

However, now that command structure is pretty much settled, the numbers have been changed to global, yet isolated and meaningful names.

 e.g.
 namespace OSCILLATOR // usage OSCILLATOR::control::phaseRandomness
{
    enum control : unsigned char {
        phaseRandomness = 0,
        magType, // Linear, -40dB, -60dB, -80dB, -100dB
        harmonicAmplitudeRandomness,
        harmonicRandomnessType, // None, Power, Sine
...
...

and this translates to:
switch (control)
    {
        case OSCILLATOR::control::phaseRandomness:
...
...

The use of namespaces combined with typed enumerators not only gives clear compartmentalised  identifiers, but also gives isolation between sections, protecting against name clashes. It is also still compatible with integers and unsigned chars without needing typecasting. This is important, as all these are passed through ring buffers using the central CommandBlock structure - which is now also defined here.

Another point worth mentioning is that Yoshimi has different priorities for access to the structure based on the following reasoning:

1/
Don't handle data that's not actually wanted.

2/
Limits and defaults are static so can be read directly at any time with a cut-down version of the overall structure.
e.g. all part level volume controls have the same max, min, and default, so no need to test part and kit numbers.

Other reads may be wanted in bulk from time to time (such as updating a GUI when a new patch set is loaded) so should be as fast as possible, but at the same time must wait briefly if a parameter is being changed.

Writes are the only thing that can make dynamic reads wait. This ensures these reads will *always* be seeing valid data.

Writes are also much more complicated. In the first place, we have made them all serial and synchronous with the audio thread (if they were not already) so how do you realistically time something going through a ring buffer, interleaved with other 'somethings'?

The final wrinkle with writes is that they don't always do what they seem to. Loading an instrument patch for example, just sets a flag to mute the part, then passes the data to a low priority thread. This can take its time updating the part (as nothing can now read it) and when complete, clear the flag again.

