el_supremo
Well-known member
Those functions send the midi message to USB and a hardware Serial port. The default serial port on a Teensy is Serial1. If necessary, you could edit the MIDI.h file and change it.
Pete
Pete
Those functions send the midi message to USB and a hardware Serial port. The default serial port on a Teensy is Serial1. If necessary, you could edit the MIDI.h file and change it.
Pete
//---------------------------------SET OCTAVE --------------------------------------------
int up = digitalRead(octaveup); // alias "octaveup" pin read as "up"
int down = digitalRead(octavedown); // alias "octavedown" pin read as "down"
if (up == LOW) { // if "up" button pressed
if (octave < 6) {
octave++; // constrain highest note to C8 (108)
}
while (up == LOW) { // wait until button is released
up = digitalRead(octaveup);
delay(20);
}
}
if (down == LOW) { // if "down" button pressed
if (octave > 1) {
octave--; // constrain lowest note to C1 (24)
}
while (down == LOW) { // wait until button is released
down = digitalRead(octavedown);
delay(20);
}
}
if (up == LOW && down == LOW) { // if "up" and "down" buttons both pressed
octave = 3; // return to base octave
}
//---------------------------------SET OCTAVE --------------------------------------------
int up = digitalRead(octaveup); // alias "octaveup" pin read as "up"
int down = digitalRead(octavedown); // alias "octavedown" pin read as "down"
if (up == LOW && down == LOW) { // if "up" and "down" buttons both pressed
octave = 3; // return to base octave
}
if (up == LOW) { // if "up" button pressed
if (octave < 6) {
octave++; // constrain highest note to C8 (108)
}
while (up == LOW) { // wait until button is released
up = digitalRead(octaveup);
delay(20);
}
}
if (down == LOW) { // if "down" button pressed
if (octave > 1) {
octave--; // constrain lowest note to C1 (24)
}
while (down == LOW) { // wait until button is released
down = digitalRead(octavedown);
delay(20);
}
}
Those functions send the midi message to USB and a hardware Serial port. The default serial port on a Teensy is Serial1. If necessary, you could edit the MIDI.h file and change it.
Pete
/*
https://forum.pjrc.com/threads/28816
25 Key Midi Footpedal with
Octave Up/Down, Mod, Sustain, and Volume
Created by Brad Hill on 19-06-2015
based primarily on Teensy "Buttons" with snippets from
MidiHacker's MultiButtonMIDIOctave.ino,
Graham Wykes' Miditzer Pedalboard Scanner for Teensy2.0++ board,
Lionel Cassin's "midi-bass-pedals-using-arduino.html",
G333T's video (https://www.youtube.com/watch?v=9J_tGVLD7UQ),
and various Teensy/Arduino definitions and examples.
This code is released into the Public Domain.
*/
#include <MIDI.h>
#include <Bounce.h>
const int channel = 1; // the MIDI channel number to send messages
const int ms = 5; // bounce time in ms (increase for more sensitve switches)
const int d = 25; // default delay time (ms) for "activity" LED
//
const int OCTAVE_DELAY = 50;
int LEDU = 0; // pin for octave up LED
int LEDD = 1; // pin for ocatave down LED
int octaveup = 32; // pin for octave up switch
int octavedown = 33; // pin for octave down switch
int octave = 3; // set base octave
int vpot = 38; // pin setup for volume pot
int vol; // place holder for vpot reading
int vel = 99; // fixed note velocity
// Create Bounce objects for each button. The Bounce object
// automatically deals with contact chatter or "bounce", and
// it makes detecting changes very simple.
Bounce button0 = Bounce(0, ms);
Bounce button1 = Bounce(1, ms); // 5 = 5 ms debounce time
Bounce button2 = Bounce(2, ms); // which is appropriate for good
Bounce button3 = Bounce(3, ms); // quality mechanical pushbuttons
Bounce button4 = Bounce(4, ms);
Bounce button5 = Bounce(5, ms); // if a button is too "sensitive"
Bounce button6 = Bounce(6, ms); // to rapid touch, you can
Bounce button7 = Bounce(7, ms); // increase this time.
Bounce button8 = Bounce(8, ms);
Bounce button9 = Bounce(9, ms);
Bounce button10 = Bounce(10, ms);
Bounce button11 = Bounce(11, ms);
Bounce button12 = Bounce(12, ms);
Bounce button13 = Bounce(13, ms);
Bounce button14 = Bounce(14, ms);
Bounce button15 = Bounce(15, ms);
Bounce button16 = Bounce(16, ms);
Bounce button17 = Bounce(17, ms);
Bounce button18 = Bounce(18, ms);
Bounce button19 = Bounce(19, ms);
Bounce button20 = Bounce(20, ms);
Bounce button21 = Bounce(21, ms);
Bounce button22 = Bounce(22, ms);
Bounce button23 = Bounce(23, ms);
Bounce button24 = Bounce(24, ms);
Bounce button25 = Bounce(25, ms);
Bounce button26 = Bounce(26, ms);
Bounce button27 = Bounce(27, ms);
Bounce button28 = Bounce(28, ms);
Bounce button29 = Bounce(29, ms);
Bounce button30 = Bounce(30, ms);
Bounce button31 = Bounce(31, ms);
Bounce button32 = Bounce(32, ms);
Bounce button33 = Bounce(33, ms);
Bounce button34 = Bounce(34, ms);
Bounce button35 = Bounce(35, ms);
Bounce button36 = Bounce(36, ms);
Bounce button37 = Bounce(37, ms);
Bounce button38 = Bounce(38, ms);
Bounce button39 = Bounce(39, ms);
Bounce button40 = Bounce(40, ms);
Bounce button41 = Bounce(41, ms);
Bounce button42 = Bounce(42, ms);
Bounce button43 = Bounce(43, ms);
Bounce button44 = Bounce(44, ms);
Bounce button45 = Bounce(45, ms);
// Declaring the addresses of the button objects in this array
// allows us to deal with them in a for loop
Bounce *buttons[46] = {
&button0, &button1, &button2, &button3, &button4, &button5, &button6, &button7, &button8, &button9,
&button10, &button11, &button12, &button13, &button14, &button15, &button16, &button17, &button18, &button19,
&button20, &button21, &button22, &button23, &button24, &button25, &button26, &button27, &button28, &button29,
&button30, &button31, &button32, &button33, &button34, &button35, &button36, &button37, &button38, &button39,
&button40, &button41, &button42, &button43, &button44, &button45
};
// Create functions to send usbMIDI and serial MIDI messages
void do_sendNoteOn(unsigned char note,unsigned char velocity,unsigned char channel)
{
usbMIDI.sendNoteOn(note, velocity, channel);
MIDI.sendNoteOn(note, velocity, channel);
}
void do_sendControlChange(unsigned char cmd,unsigned char value,unsigned char channel)
{
usbMIDI.sendControlChange(cmd, value, channel);
MIDI.sendControlChange(cmd, value, channel);
}
void do_octave(void)
{
//---------------------------------SET OCTAVE --------------------------------------------
int up = digitalRead(octaveup); // alias "octaveup" pin read as "up"
int down = digitalRead(octavedown); // alias "octavedown" pin read as "down"
// If both buttons are up, we have nothing to do.
if((up == HIGH) && (down == HIGH)) return;
// At least one of the buttons is down.
// wait for a few milliseconds and then read
// them both again to give time for both buttons
// to be down if the user has pushed them both.
delay(OCTAVE_DELAY);
up = digitalRead(octaveup);
down = digitalRead(octavedown);
// if "up" and "down" buttons both pressed
// return to base octave
if ((up == LOW) && (down == LOW)) {
octave = 3;
} else {
// if "up" button pressed
if (up == LOW) {
if (octave < 6) {
octave++; // constrain highest note to C8 (108)
}
}
// if "down" button pressed
if (down == LOW) {
if (octave > 1) {
octave--; // constrain lowest note to C1 (24)
}
}
}
// Wait for the button(s) to be released
while ((digitalRead(octaveup) == LOW) || (digitalRead(octavedown) == LOW)) {
delay(20);
}
}
//--------------------------SETUP-----------------------------------------------
//------------------------------------------------------------------------------
void setup() {
MIDI.begin();
// Configure the pins for input mode with pullup resistors.
// The pushbuttons connect from each pin to ground. When
// the button is pressed, the pin reads LOW because the button
// shorts it to ground. When released, the pin reads HIGH
// because the pullup resistor connects to +5 volts inside
// the chip. LOW for "on", and HIGH for "off" may seem
// backwards, but using the on-chip pullup resistors is very
// convenient. The scheme is called "active low", and it's
// very commonly used in electronics... so much that the chip
// has built-in pullup resistors!
pinMode(0, OUTPUT); // LED for "octave up"
pinMode(1, OUTPUT); // LED for "octave down"
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP); // TX output for MIDI Jack
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, OUTPUT); // Teensy++ 2.0 LED, may need 1k resistor pullup
// pins 7 to 45 are all INPUT_PULLUP
for (int i = 7; i <= 45; i++) {
pinMode(i, INPUT_PULLUP);
}
digitalWrite(6, HIGH); // Set Teensy++ fixed LED to "on"
digitalWrite(0, LOW); // Set "octave up" LED to "off"
digitalWrite(1, LOW); // Set "octave down" LED to "off
}
//--------------------------MAIN LOOP-------------------------------------
//------------------------------------------------------------------------
void loop() {
// Update all the buttons. There should not be any long
// delays in loop(), so this runs repetitively at a rate
// faster than the buttons could be pressed and released.
for (int i = 0; i <= 45; i++) {
buttons[i]->update();
}
do_octave();
vol = analogRead(vpot); // Read velocity from the volume pot
vel = map(vol, 0, 1023, 0, 127); // change the velocity range
// from "pot range" (0-1023)
// to "MIDI range" (0-127)
//----------------------READ BUTTON PINS FOR NOTE ON--------------------------------------------------
// Check each button from 7 - 31 for "falling" edge.
// Send a MIDI Note On message when each button presses
// Update the Joystick buttons only upon changes.
// falling = high (not pressed - voltage from pullup resistor)
// to low (pressed - button connects pin to ground)
for (int i = 7; i <= 31; i++) {
if (buttons[i]->fallingEdge()) {
digitalWrite(6, LOW);
do_sendNoteOn(i + 5 + (octave * 12), vel, channel); // C
delay(d);
digitalWrite(6, HIGH);
}
}
//----------------------READ BUTTON PINS FOR SUSTAIN AND MODULATION--------------
// Check sus button for "falling" edge.
// Send a MIDI CC message when button is pressed
// Update the Joystick buttons only upon changes.
// falling = high (not pressed - voltage from pullup resistor)
// to low (pressed - button connects pin to ground)
if (button35.fallingEdge()) {
do_sendControlChange(64, 127, channel); // (type=64=sus, value=127=on, MIDI channel)
}
// Check mod button for "falling" edge.
// Send a MIDI CC message when the button is pressed
// Update the Joystick buttons only upon changes.
// falling = high (not pressed - voltage from pullup resistor)
// to low (pressed - button connects pin to ground)
if (button34.fallingEdge()) {
do_sendControlChange(1, 64, channel); // (type=1=mod, value=64, MIDI channel)
}
// Check mod button for "rising" edge.
// Send a MIDI CC message when button is not pressed
// Update the Joystick buttons only upon changes.
// falling = high (not pressed - voltage from pullup resistor)
// to low (pressed - button connects pin to ground)
if (button34.risingEdge()) {
do_sendControlChange(1, 0, channel); // (type=1=mod, value=0=off, MIDI channel)
}
// Check sus button for "rising" edge.
// Send a MIDI CC message when button is not pressed
// Update the Joystick buttons only upon changes.
// rising = low (pressed - button connects pin to ground)
// to high (not pressed - voltage from pullup resistor)
if (button35.risingEdge()) {
do_sendControlChange(64, 0, channel); // (type=64=sus, value=0=off, MIDI channel)
}
//---------------READ BUTTON PINS FOR NOTE OFF-----------------------------------------
// Check each button for "rising" edge
// Send a MIDI Note Off message when each button releases
// For many types of projects, you only care when the button
// is pressed and the release isn't needed.
// rising = low (pressed - button connects pin to ground)
// to high (not pressed - voltage from pullup resistor)
for (int i = 7; i <= 31; i++) {
if (buttons[i]->risingEdge()) {
digitalWrite(6, LOW);
do_sendNoteOn(i + 5 + (octave * 12), 0, channel); // C
delay(d);
digitalWrite(6, HIGH);
}
}
// MIDI Controllers should discard incoming MIDI messages.
// http://forum.pjrc.com/threads/24179-Teensy-3-Ableton-Analog-CC-causes-midi-crash
while (usbMIDI.read()) { // ignore incoming messages
}
}
constrain(keysLast, 0x18, 0x60); //limit keyboard from C1 to C7
for(int i = 0; i < 3; i++){ //loop for modifier keys
changeButtonLast[i] = changeButton[i]; //update modifier key state
changeButton[i] = digitalRead(changePins[i]); //read state of modifier keys
if(changeButton[2] && changeButton[i] == HIGH && changeButton[i] !=
changeButtonLast[i]){ //if modifier buttons 1 or 2 are pressed while modifier button 3 is held down
changekeys(singleChanges[i], keysLast); //change keyboard base up or down in half steps
}
if(changeButton[0] && changeButton[1] == HIGH){ //if modifier buttons 1 and 2 are pressed together simultaneously
keysLast = keysBase; //revert keyboard base to C4
}
if(changeButton[i] == HIGH && changeButtonLast[i] != changeButton[i] &&
changeButton[2] == LOW){ //if modifier buttons 1 or 2 are pressed while modifier button 3 is released
changekeys(octaveChanges[i], keysLast); //change keyboard base up or down in octaves
}
}
/*
https://forum.pjrc.com/threads/28816
25 Key Midi Footpedal with
Octave Up/Down, Mod, Sustain, and Volume
Created by Brad Hill on 19-06-2015
based primarily on Teensy "Buttons" with snippets from
MidiHacker's MultiButtonMIDIOctave.ino,
Graham Wykes' Miditzer Pedalboard Scanner for Teensy2.0++ board,
Lionel Cassin's "midi-bass-pedals-using-arduino.html",
G333T's video (https://www.youtube.com/watch?v=9J_tGVLD7UQ),
and various Teensy/Arduino definitions and examples.
This code is released into the Public Domain.
*/
#include <MIDI.h>
#include <Bounce.h>
const int channel = 1; // the MIDI channel number to send messages
const int ms = 5; // bounce time in ms (increase for more sensitve switches)
const int d = 25; // default delay time (ms) for "activity" LED
//
const int OCTAVE_DELAY = 50;
int LEDU = 0; // pin for octave up LED
int LEDD = 1; // pin for ocatave down LED
int octaveup = 32; // pin for octave up switch
int octavedown = 33; // pin for octave down switch
int octave = 3; // set base octave
int vpot = 38; // pin setup for volume pot
int vol; // place holder for vpot reading
int vel = 99; // fixed note velocity
// Create Bounce objects for each button. The Bounce object
// automatically deals with contact chatter or "bounce", and
// it makes detecting changes very simple.
Bounce button0 = Bounce(0, ms);
Bounce button1 = Bounce(1, ms); // 5 = 5 ms debounce time
Bounce button2 = Bounce(2, ms); // which is appropriate for good
Bounce button3 = Bounce(3, ms); // quality mechanical pushbuttons
Bounce button4 = Bounce(4, ms);
Bounce button5 = Bounce(5, ms); // if a button is too "sensitive"
Bounce button6 = Bounce(6, ms); // to rapid touch, you can
Bounce button7 = Bounce(7, ms); // increase this time.
Bounce button8 = Bounce(8, ms);
Bounce button9 = Bounce(9, ms);
Bounce button10 = Bounce(10, ms);
Bounce button11 = Bounce(11, ms);
Bounce button12 = Bounce(12, ms);
Bounce button13 = Bounce(13, ms);
Bounce button14 = Bounce(14, ms);
Bounce button15 = Bounce(15, ms);
Bounce button16 = Bounce(16, ms);
Bounce button17 = Bounce(17, ms);
Bounce button18 = Bounce(18, ms);
Bounce button19 = Bounce(19, ms);
Bounce button20 = Bounce(20, ms);
Bounce button21 = Bounce(21, ms);
Bounce button22 = Bounce(22, ms);
Bounce button23 = Bounce(23, ms);
Bounce button24 = Bounce(24, ms);
Bounce button25 = Bounce(25, ms);
Bounce button26 = Bounce(26, ms);
Bounce button27 = Bounce(27, ms);
Bounce button28 = Bounce(28, ms);
Bounce button29 = Bounce(29, ms);
Bounce button30 = Bounce(30, ms);
Bounce button31 = Bounce(31, ms);
Bounce button32 = Bounce(32, ms);
Bounce button33 = Bounce(33, ms);
Bounce button34 = Bounce(34, ms);
Bounce button35 = Bounce(35, ms);
Bounce button36 = Bounce(36, ms);
Bounce button37 = Bounce(37, ms);
Bounce button38 = Bounce(38, ms);
Bounce button39 = Bounce(39, ms);
Bounce button40 = Bounce(40, ms);
Bounce button41 = Bounce(41, ms);
Bounce button42 = Bounce(42, ms);
Bounce button43 = Bounce(43, ms);
Bounce button44 = Bounce(44, ms);
Bounce button45 = Bounce(45, ms);
// Declaring the addresses of the button objects in this array
// allows us to deal with them in a for loop
Bounce *buttons[46] = {
&button0, &button1, &button2, &button3, &button4, &button5, &button6, &button7, &button8, &button9,
&button10, &button11, &button12, &button13, &button14, &button15, &button16, &button17, &button18, &button19,
&button20, &button21, &button22, &button23, &button24, &button25, &button26, &button27, &button28, &button29,
&button30, &button31, &button32, &button33, &button34, &button35, &button36, &button37, &button38, &button39,
&button40, &button41, &button42, &button43, &button44, &button45
};
// Create functions to send usbMIDI and serial MIDI messages
void do_sendNoteOn(unsigned char note,unsigned char velocity,unsigned char channel)
{
usbMIDI.sendNoteOn(note, velocity, channel);
MIDI.sendNoteOn(note, velocity, channel);
}
void do_sendControlChange(unsigned char cmd,unsigned char value,unsigned char channel)
{
usbMIDI.sendControlChange(cmd, value, channel);
MIDI.sendControlChange(cmd, value, channel);
}
void do_octave(void)
{
//---------------------------------SET OCTAVE --------------------------------------------
int up = digitalRead(octaveup); // alias "octaveup" pin read as "up"
int down = digitalRead(octavedown); // alias "octavedown" pin read as "down"
// If both buttons are up, we have nothing to do.
if((up == HIGH) && (down == HIGH)) return;
// At least one of the buttons is down.
// wait for a few milliseconds and then read
// them both again to give time for both buttons
// to be down if the user has pushed them both.
delay(OCTAVE_DELAY);
up = digitalRead(octaveup);
down = digitalRead(octavedown);
// if "up" and "down" buttons both pressed
// return to base octave
if ((up == LOW) && (down == LOW)) {
octave = 3;
} else {
// if "up" button pressed
if (up == LOW) {
if (octave < 6) {
octave++; // constrain highest note to C8 (108)
}
}
// if "down" button pressed
if (down == LOW) {
if (octave > 1) {
octave--; // constrain lowest note to C1 (24)
}
}
}
// Wait for the button(s) to be released
while ((digitalRead(octaveup) == LOW) || (digitalRead(octavedown) == LOW)) {
delay(20);
}
}
//--------------------------SETUP-----------------------------------------------
//------------------------------------------------------------------------------
void setup() {
MIDI.begin();
// Configure the pins for input mode with pullup resistors.
// The pushbuttons connect from each pin to ground. When
// the button is pressed, the pin reads LOW because the button
// shorts it to ground. When released, the pin reads HIGH
// because the pullup resistor connects to +5 volts inside
// the chip. LOW for "on", and HIGH for "off" may seem
// backwards, but using the on-chip pullup resistors is very
// convenient. The scheme is called "active low", and it's
// very commonly used in electronics... so much that the chip
// has built-in pullup resistors!
pinMode(0, OUTPUT); // LED for "octave up"
pinMode(1, OUTPUT); // LED for "octave down"
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP); // TX output for MIDI Jack
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, OUTPUT); // Teensy++ 2.0 LED, may need 1k resistor pullup
// pins 7 to 45 are all INPUT_PULLUP
for (int i = 7; i <= 45; i++) {
pinMode(i, INPUT_PULLUP);
}
digitalWrite(6, HIGH); // Set Teensy++ fixed LED to "on"
digitalWrite(0, LOW); // Set "octave up" LED to "off"
digitalWrite(1, LOW); // Set "octave down" LED to "off
}
//--------------------------MAIN LOOP-------------------------------------
//------------------------------------------------------------------------
void loop() {
// Update all the buttons. There should not be any long
// delays in loop(), so this runs repetitively at a rate
// faster than the buttons could be pressed and released.
for (int i = 0; i <= 45; i++) {
buttons[i]->update();
}
do_octave();
if(octave > 3){ // if the octave is above base
digitalWrite(LEDU,HIGH); // turn on "octave up" LED
} else { // otherwise leave it off
digitalWrite(LEDU,LOW);
}
if(octave < 3){ // if the current octave is below base
digitalWrite(LEDD,HIGH); // turn on the "octave down" LED
} else { // otherwise leave it off
digitalWrite(LEDD,LOW);
}
vol = analogRead(vpot); // Read velocity from the volume pot
vel = map(vol, 0, 1023, 0, 127); // change the velocity range
// from "pot range" (0-50)
// to "MIDI range" (0-127)
//----------------------READ BUTTON PINS FOR NOTE ON--------------------------------------------------
// Check each button from 7 - 31 for "falling" edge.
// Send a MIDI Note On message when each button presses
// Update the Joystick buttons only upon changes.
// falling = high (not pressed - voltage from pullup resistor)
// to low (pressed - button connects pin to ground)
for (int i = 7; i <= 31; i++) {
if (buttons[i]->fallingEdge()) {
digitalWrite(6, LOW);
do_sendNoteOn(i + 5 + (octave * 12), vel, channel); // C
delay(d);
digitalWrite(6, HIGH);
}
}
//----------------------READ BUTTON PINS FOR SUSTAIN AND MODULATION--------------
// Check sus button for "falling" edge.
// Send a MIDI CC message when button is pressed
// Update the Joystick buttons only upon changes.
// falling = high (not pressed - voltage from pullup resistor)
// to low (pressed - button connects pin to ground)
if (button35.fallingEdge()) {
do_sendControlChange(64, 127, channel); // (type=64=sus, value=127=on, MIDI channel)
}
// Check mod button for "falling" edge.
// Send a MIDI CC message when the button is pressed
// Update the Joystick buttons only upon changes.
// falling = high (not pressed - voltage from pullup resistor)
// to low (pressed - button connects pin to ground)
if (button34.fallingEdge()) {
do_sendControlChange(1, 64, channel); // (type=1=mod, value=64, MIDI channel)
}
// Check mod button for "rising" edge.
// Send a MIDI CC message when button is not pressed
// Update the Joystick buttons only upon changes.
// falling = high (not pressed - voltage from pullup resistor)
// to low (pressed - button connects pin to ground)
if (button34.risingEdge()) {
do_sendControlChange(1, 0, channel); // (type=1=mod, value=0=off, MIDI channel)
}
// Check sus button for "rising" edge.
// Send a MIDI CC message when button is not pressed
// Update the Joystick buttons only upon changes.
// rising = low (pressed - button connects pin to ground)
// to high (not pressed - voltage from pullup resistor)
if (button35.risingEdge()) {
do_sendControlChange(64, 0, channel); // (type=64=sus, value=0=off, MIDI channel)
}
//---------------READ BUTTON PINS FOR NOTE OFF-----------------------------------------
// Check each button for "rising" edge
// Send a MIDI Note Off message when each button releases
// For many types of projects, you only care when the button
// is pressed and the release isn't needed.
// rising = low (pressed - button connects pin to ground)
// to high (not pressed - voltage from pullup resistor)
for (int i = 7; i <= 31; i++) {
if (buttons[i]->risingEdge()) {
digitalWrite(6, LOW);
do_sendNoteOn(i + 5 + (octave * 12), 0, channel); // C
delay(d);
digitalWrite(6, HIGH);
}
}
// MIDI Controllers should discard incoming MIDI messages.
// http://forum.pjrc.com/threads/24179-Teensy-3-Ableton-Analog-CC-causes-midi-crash
while (usbMIDI.read()) { // ignore incoming messages
}
}
How is the 5-pin MIDI jack connected to the PC?