Although not present on the original minimoog, midi is something so omnipresent and usefull I couldn't not implement it.
It happens it is quite easy to do with the Arduino environment, thanks to this library from FortySevenEffects. It's even easier with Teensy, has the library is automatically implemented when you choose MIDI as the kind of USB output.
There are two "kinds" of midi on the synth. One is what is expected from a modern music instrument, i.e. the ability to interact with other instruments.
This part is pretty straightforward for now : the synth appears as a MIDI USB device when connected on a computer (or anything where you can plug a MIDI device via USB). Key press, pitchbend and modulation are transmitted whenever they change, and can be received and processed by the synth as well.
The second MIDI kind is the one used for communication between the Teensy that handles the audio processing, and the two Arduino Mega that read keyboard switches and potentiometers.
The keyboard is easy : the Arduino simply sends note on when a key is pressed, and note off when released. As the keybed used is not velocity sensitive, a default velocity of 64 has been chosen. The only thing to note is that the keys start at 0 (midi note 0, C-1), and they are offset in the Teensy part. It makes things easier to apply octave offset, among other things.
For controls, I tried to stick as much as possible to the midi specification. For some it's easy. For example MIDI defines CC1 as modulation wheel. CC5 is portamento time. Whenever it was possible, the official CC number was used to map functions sent from Arduinos to teensy. Most MIDI messages use a 7-bits value to send information. for some controls it's ok, but I had fear that for others it would not be a fine enough resolution. It happens that (probably) for this reason, the first 32 control change are 14 bits wide, with the 7 MSB sent on CC0-CC31, and the associate 7LSB sent on CC32-63. So some controls have been mapped to undefined CC in the 0-31 + 32-63 range. It's the case for both general and filter envelopes, filter cutoff frequency and resonance, the five mix knobs, to name a few. Attack and release often use CC73 & 72, filter cuttoff CC74. They have been assigned to CC59, 60 & 52, respectively.
This poses a problem. Using the "official" control change numbers would have enable to simply map internal controls to external MIDI. Here is how it's done on Teensy :
- for note on messages, the internal handler handleInternalNoteOn() applies offsets to what is received from Mega 1, for the octave transpose, echoes this offset note to external MIDI OUT, and to the general function that also handles external MIDI IN, handleNoteOn().
- Same thing for note off.
- Same thing for pitchbend.
- Control change is only handled internally for now. Same principle could be applied, however as some controls have been remapped to others numbers, most of them should be handled separately. Because of the different CC number, and because of the different resolution. For now none are implemented from external MIDI, even those who have the number defined by the MIDI specification.
There is room for improvement here. As much as possible of the controls should be accessed through MIDI when connecting the synth to a computer or anything else, but having those numbers would mean having to handlers, and probably using setting functions for every control, capable of handling 14 and 7-bits wide ranges, instead of this unique handler with this looong switch/case statement.
It would also open the door to something usefull : the ability to save and recall presets.
Two websites have been used for checking which CC numbers to use :