Thanks for all the comments everyone - the button symbols were drawn incorrectly (the buttons are in fact the standard buttons which docdoc pointed out, with pins on the same side connected together); I have edited the post to feature the correct symbols.
I did not want to post the entire Teensy sketch as it is well over 2000 lines long and incredibly unoptimised (I have never used a single programming language before.) But here are the important MIDI bits:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <MIDI.h>
#include <MIDIUSB.h>
#include <EEPROMex.h>
MIDI_CREATE_DEFAULT_INSTANCE();
void setup() {
analogReadResolution(10);
Serial.begin(31250);
AudioMemory(470);
preset = 0; //////DEBUG
//MIDI setup
usbMIDI.begin();
usbMIDI.setHandleNoteOn(myNoteOn);
usbMIDI.setHandleNoteOff(myNoteOff);
MIDI.setHandleNoteOn(myNoteOn);
MIDI.setHandleNoteOff(myNoteOff);
MIDI.begin(MIDI_CHANNEL_OMNI);
MIDI.turnThruOff();
//Pin Setup
//pinMode(0, INPUT); //MIDI input
pinMode(4, OUTPUT); //Mux 1A
pinMode(5, OUTPUT); //Mux 1B
pinMode(6, OUTPUT); //Mux 1C
pinMode(8, OUTPUT); //Mux 2A
pinMode(9, OUTPUT); //Mux 2B
pinMode(10, OUTPUT); //Mux 2C
pinMode(11, OUTPUT); //Mux 3A
pinMode(12, OUTPUT); //Mux 3B
pinMode(24, OUTPUT); //Mux 3C
pinMode(25, OUTPUT); //Mux 4A
pinMode(26, OUTPUT); //Mux 4B
pinMode(27, OUTPUT); //Mux 4C
pinMode(28, OUTPUT); //Mux 5A
pinMode(29, OUTPUT); //Mux 5B
pinMode(30, OUTPUT); //Mux 5C
pinMode(A4, INPUT); //Mux 1 COM
pinMode(A3, INPUT); //Mux 2 COM
pinMode(A2, INPUT); //Mux 3 COM
pinMode(A1, INPUT); //Mux 4 COM
pinMode(A0, INPUT); //Mux 5 COM
//pinMode(7, OUTPUT); //DIN OUTPUT
//pinMode(20, OUTPUT); //WSel
//pinMode(21, OUTPUT); //BClk
//Mux setup init
digitalWrite(4, 0);
digitalWrite(5, 0);
digitalWrite(6, 0);
digitalWrite(8, 0);
digitalWrite(9, 0);
digitalWrite(10, 0);
digitalWrite(11, 0);
digitalWrite(12, 0);
digitalWrite(24, 0);
digitalWrite(35, 0);
digitalWrite(34, 0);
digitalWrite(33, 0);
digitalWrite(36, 0);
digitalWrite(37, 0);
digitalWrite(38, 0);
//vco setup
vcoA1.begin(vcoVol, 150, WAVEFORM_SAWTOOTH);
vcoB1.begin(vcoVol, 150, WAVEFORM_SQUARE);
vcoC1.begin(vcoVol * 1.5, 150, WAVEFORM_ARBITRARY);
sub1.begin(vcoVol * 1.5, 150, WAVEFORM_TRIANGLE);
vcoA2.begin(vcoVol, 150, WAVEFORM_SAWTOOTH);
vcoB2.begin(vcoVol, 150, WAVEFORM_SQUARE);
vcoC2.begin(vcoVol * 1.5, 150, WAVEFORM_ARBITRARY);
sub2.begin(vcoVol * 1.5, 150, WAVEFORM_TRIANGLE);
vcoA3.begin(vcoVol, 150, WAVEFORM_SAWTOOTH);
vcoB3.begin(vcoVol, 150, WAVEFORM_SQUARE);
vcoC3.begin(vcoVol * 1.5, 150, WAVEFORM_ARBITRARY);
sub3.begin(vcoVol * 1.5, 150, WAVEFORM_TRIANGLE);
vcoA4.begin(vcoVol, 150, WAVEFORM_SAWTOOTH);
vcoB4.begin(vcoVol, 150, WAVEFORM_SQUARE);
vcoC4.begin(vcoVol * 1.5, 150, WAVEFORM_ARBITRARY);
sub4.begin(vcoVol * 1.5, 150, WAVEFORM_TRIANGLE);
vcoA5.begin(vcoVol, 150, WAVEFORM_SAWTOOTH);
vcoB5.begin(vcoVol, 150, WAVEFORM_SQUARE);
vcoC5.begin(vcoVol * 1.5, 150, WAVEFORM_ARBITRARY);
sub5.begin(vcoVol * 1.5, 150, WAVEFORM_TRIANGLE);
vcoA6.begin(vcoVol, 150, WAVEFORM_SAWTOOTH);
vcoB6.begin(vcoVol, 150, WAVEFORM_SQUARE);
vcoC6.begin(vcoVol * 1.5, 150, WAVEFORM_ARBITRARY);
sub6.begin(vcoVol * 1.5, 150, WAVEFORM_TRIANGLE);
//filter setup
filter1.octaveControl(7);
filter2.octaveControl(7);
filter3.octaveControl(7);
filter4.octaveControl(7);
filter5.octaveControl(7);
filter6.octaveControl(7);
//lfo A setup
lfoA1.begin(WAVEFORM_SINE);
lfoA2.begin(WAVEFORM_SINE);
lfoA3.begin(WAVEFORM_SINE);
lfoA4.begin(WAVEFORM_SINE);
lfoA5.begin(WAVEFORM_SINE);
lfoA6.begin(WAVEFORM_SINE);
//lfo B setup
lfoB1.begin(0.5, 1, WAVEFORM_TRIANGLE);
lfoB2.begin(0.5, 1, WAVEFORM_TRIANGLE);
lfoB3.begin(0.5, 1, WAVEFORM_TRIANGLE);
lfoB4.begin(0.5, 1, WAVEFORM_TRIANGLE);
lfoB5.begin(0.5, 1, WAVEFORM_TRIANGLE);
lfoB6.begin(0.5, 1, WAVEFORM_TRIANGLE);
}
void myNoteOn(byte channel, byte note, byte velocity) {
//POLYPHONIC mode
if (mux1F > 512) { //mux1F is the designator for the toggle switch which selects between monophonic and polyphonic modes
switch (voices) {
case 0 ... 5:
if (env1on == false) {
note1freq = note;
env1.noteOn();
filterEnv1.noteOn();
env1on = true;
} else if (env2on == false) {
note2freq = note;
env2.noteOn();
filterEnv2.noteOn();
lfoAenv2.noteOn();
env2on = true;
} else if (env3on == false) {
note3freq = note;
env3.noteOn();
filterEnv3.noteOn();
lfoAenv3.noteOn();
env3on = true;
} else if (env4on == false) {
note4freq = note;
env4.noteOn();
filterEnv4.noteOn();
lfoAenv4.noteOn();
env4on = true;
} else if (env5on == false) {
note5freq = note;
env5.noteOn();
filterEnv5.noteOn();
lfoAenv5.noteOn();
env5on = true;
} else if (env6on == false) {
note6freq = note;
env6.noteOn();
filterEnv6.noteOn();
lfoAenv6.noteOn();
env6on = true;
}
voices++;
break;
}
//MONOPHONIC mode
} else if (mux1F <= 512) {
note1freq = note;
env1.noteOn();
filterEnv1.noteOn();
voices++;
}
Serial.print("Note On, ch=");
Serial.print(channel, DEC);
Serial.print(", note=");
Serial.print(note, DEC);
Serial.print(", voices=");
Serial.println(voices, DEC);
}
void myNoteOff(byte channel, byte note, byte velocity) {
//POLYPHONIC mode
if (mux1F > 512) {
switch (voices) {
case 0 ... 6:
if (note1freq == note) {
env1.noteOff();
filterEnv1.noteOff();
env1on = false;
} else if (note2freq == note) {
env2.noteOff();
filterEnv2.noteOff();
lfoAenv2.noteOff();
env2on = false;
} else if (note3freq == note) {
env3.noteOff();
filterEnv3.noteOff();
lfoAenv3.noteOff();
env3on = false;
} else if (note4freq == note) {
env4.noteOff();
filterEnv4.noteOff();
lfoAenv4.noteOff();
env4on = false;
} else if (note5freq == note) {
env5.noteOff();
filterEnv5.noteOff();
lfoAenv5.noteOff();
env5on = false;
} else if (note6freq == note) {
env6.noteOff();
filterEnv6.noteOff();
lfoAenv6.noteOff();
env6on = false;
}
voices--;
break;
}
//MONOPHONIC mode
} else if (mux1F <= 512) {
if (note1freq == note) {
env1.noteOff();
filterEnv1.noteOff();
voices--;
}
}
Serial.print("Note Off, ch=");
Serial.print(channel, DEC);
Serial.print(", note=");
Serial.print(note, DEC);
Serial.print(", voices=");
Serial.println(voices, DEC);
}
void loop() {
usbMIDI.read();
MIDI.read();
if (voices < 0) {
voices = 0;
}
//the remainder of the code here has nothing to do with MIDI processing
}
While this fragment above is not the entire Teensy sketch, it receives MIDI messages perfectly fine from the testing Nano sketch below, without generating any extra outputs:
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
void setup()
{
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
MIDI.begin(1); // Launch MIDI and listen to channel 4
}
void loop()
{
digitalWrite(LED_BUILTIN, HIGH);
MIDI.sendNoteOn(42, 127, 1); // Send pitch 42, velo 127 on channel 4
delay(1000);
MIDI.sendNoteOff(42, 127, 1);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}