Simulation - wrightflyer/Synth GitHub Wiki

Intro

By a strange coincidence my day job involves writing simulators so I'm a great fan for development!

A simulator lets you test out the core of something before the fancy eye-candy that will ultimately drive it is ready (either the hardware (often true in the commercial world) or the supporting software).

So in this project simulation is used in a number of ways.

Controller simulation

A synth is a system with a lot of "twiddly bits". To test stuff out you need to be able to twiddle all the adjustable things. Ultimately you are going to put the thing in some kind of box with knobs, joysticks, sliders or whatever connected to it but before you have got the bits, wired them together, written the software to read and inject their values how can you develop the core synth engine? This is where some kind of simulator comes in.

A real keyboard/controller

One such form of "simulator" is simply to get a pre-made unit that has keys, knobs, sliders and so on. So one could say that the 2nd hand Alesis QX25 that I purchased on ebay as part of this development:

Alesis QX25

is a form of simulator. Apart from the obvious keyboard part it has one slider and 8 knobs (actually "encoders") that can be configured to send data. The way it does that is that you assign a MIDI "CC" (Continuous Controller) to each knob (they range from 0 to 127 like most things in MIDI) then as you move the knob you have assigned to CC number 97 (say) it will, itself, output values from 0 .. 127. As there are 128 (0..127) CC numbers in theory you can pass control values for 128 different parameters you might want to change but from a useful page at:

Midi CC numbers

one finds that many are already assigned a standard use and so the "unused" ones turn out to be:

  • 3
  • 9
  • 14-15
  • 20-31
  • 85-90 *102-119

So before starting to use any others it seems wise to allocate controls from these numbers. So in the INO code from the synth one finds:

void OnControlChange(byte channel, byte control /* CC num*/, byte value /* 0 .. 127 */) {
  switch(control) {
    case 100:
    case 101:
    case 102:
    case 103:
    case 104:
    case 105:
    case 106:
    case 107:
    case 108:
    case 109:
    case 110:
    case 111:
    case 116:
    case 117:
    case 112:
    case 114:
    case 20:
    case 113:
    case 115:
    case 21:
    case 118:
    case 23:
    case 25:
    case 119:
    case 26:
    case 27:
    case 22:
    case 24:
    case 28:
    case 29:

and this list is likely to get longer. These are the CC numbers that the synth will respond to changes in. As seen already, one way is to configure a MIDI keyboard controller and have a knob send CC 103 or CC 27 or whatever.

But as the code snippet shows the synth (even at this early stage) uses a LOT of CC numbers and the QX25 only has nine definable sources so if you want to control more you may have to do it some other way. Now in the excellent series of videos from Dave at Notes and Volts he introduced the use of a tool called Pure Data

Pure Data

This is a real oddity. I would actually call it a "program language" but it's not one where you just write line after line of code with while/for/if and so on. It's a "visual language". You start by getting it from:

Pure Data download

The the way you "program" it is to place objects (which can be data sources, decision makers, data outputs etc) and then wire them together. Here is the simplest of "programs":

A Pure Data program

When you "run" this - that is on the Edit menu you untick "Edit Mode" so the controls become "live" then the item at the top is known as "bang" - each time you click it with the mouse it causes its output to trigger. That is connected to the "random" object that is set to pick random numbers from 0 to 9 and then this is fed to a print object that outputs the result. So when run and each time the "bang" is clicked a new output appears in Pure Data's main window:

Output of program

Of course having something that outputs a random number each time you click a mouse is all very well but how does this help a synthesizer design? Well the fact is that Pure Data is principally an audio/MIDI tool so it has a rich set of program objects for doing things in MIDI and it knows how to open a MIDI output connection and send data to it. So you could use those same "bangs" to layout a keyboard and then send a particular MIDI noteOn/noteOff sequence each time one was clicked (or a key pressed on the keyboard) or you could layout sliders and other controls that, when moved, sent 0..127 values to a specific MIDI CC id through the connected MIDI interface. Which brings me to:

Original PD controller layout

Which is the layout I originally laid out and coded in Pure Data for my synth design. Behind the scenes it was quite complex:

Synth in Pure Data

Then I was googling about for something quite different and stumbled upon "Ctrlr"

Ctrlr for making MIDI front ends

Ctrlr is to be found here:

Ctrlr website

and from there you download it at:

Ctrlr download

Those are listed in a funny order. I got 6.0.26 from 7th Oct 2019.

This software has just one goal in life and that is to make the slickest looking control panels for MIDI control you could possibly image. There are a whole load of examples listed at:

Example panels

Many are commercial so you'd have to pay to access them but a number are "open" and it's a great way to see "behind the scenes" to see how various forms of control can be created. It took me ages to realise that for my control to select Sine/Sawtooth/Square etc that what I should use is a "uiListBox" for example. So download and study the examples first. In the end I made:

My Ctrlr front end

Sure it's not as fancy looking as some of the things other have managed to do with Ctrlr:

Fancy example

but it's early days and I'm still learning. In use it's very like Microsoft resource editor for Visual Basic / C# etc in that you place base objects then a "properties panel" at the side lets you adjust 100's of different settings for the object:

Editing with Ctrlr

This is editing the Wave selector for Osc1 and just shows the MIDI info (mainly) so this is saying that control has MIDI CC number 116. One "trick" I learned from studying other designs (because, frankly, the documentation for this excellent software is atrocious) is that when you want to send various values for elements in a selector like this you do it as:

Sine=8
Sawtooth=24
Rev Saw=40
Square=56
Triangle=72
Samp/Hold=88
Arbitrary=104

Everything after the '=' (and including) does not display but this allows you to set the "value" that is sent on the CC number for that selection.

As one can see "Ctrlr" allows you to produce much more graphically appealing user interfaces.