MIDI event handling rewritten: now using the system of the MIDI library to

send events to the right destinations.
Added software MIDI-THRU.
Added driver for TGA-PRO audio board.
master
Holger Wirtz 6 years ago
parent 64998dfdcd
commit 115da6d2a0
  1. 235
      MicroMDAEPiano.ino
  2. 1
      config.h
  3. 23
      mdaEPiano.cpp
  4. 4
      mdaEPiano.h

@ -67,12 +67,16 @@ AudioConnection patchCord6(queue_r, 0, mixer_r, 0);
AudioConnection patchCord7(queue_l, 0, mixer_l, 0);
AudioConnection patchCord8(freeverb_r, 0, mixer_r, 1);
AudioConnection patchCord9(freeverb_l, 0, mixer_l, 1);
#ifdef TEENSY_AUDIO_BOARD
#if defined(TEENSY_AUDIO_BOARD) || defined(TGA_AUDIO_BOARD)
AudioOutputI2S i2s1;
AudioConnection patchCord110(mixer_r, 0, i2s1, 0);
AudioConnection patchCord111(mixer_l, 0, i2s1, 1);
#ifdef TEENSY_AUDIO_BOARD
AudioControlSGTL5000 sgtl5000_1;
#else
AudioControlWM8731master wm8731m1;
#endif
#else
AudioOutputPT8211 pt8211_1;
AudioAmplifier volume_r;
AudioAmplifier volume_l;
@ -164,25 +168,35 @@ void setup()
// read initial EEPROM variables
initial_values_from_eeprom();
#ifdef MIDI_DEVICE_DIN
// Start serial MIDI
midi_serial.begin(DEFAULT_MIDI_CHANNEL);
midi_serial.setHandleNoteOn(handleNoteOn_MIDI_DEVICE_DIN);
midi_serial.setHandleNoteOff(handleNoteOff_MIDI_DEVICE_DIN);
midi_serial.setHandleControlChange(handleControlChange_MIDI_DEVICE_DIN);
Serial.println(F("MIDI_DEVICE_DIN enabled"));
#endif
// start up USB host
#ifdef MIDI_DEVICE_USB_HOST
usb_host.begin();
midi_usb.setHandleNoteOn(handleNoteOn_MIDI_DEVICE_USB_HOST);
midi_usb.setHandleNoteOff(handleNoteOff_MIDI_DEVICE_USB_HOST);
midi_usb.setHandleControlChange(handleControlChange_MIDI_DEVICE_USB_HOST);
Serial.println(F("MIDI_DEVICE_USB_HOST enabled."));
#endif
// check for onboard USB-MIDI
#ifdef MIDI_DEVICE_USB
midi_onboard_usb.begin();
midi_onboard_usb.setHandleNoteOn(handleNoteOn_MIDI_DEVICE_USB);
midi_onboard_usb.setHandleNoteOff(handleNoteOff_MIDI_DEVICE_USB);
midi_onboard_usb.setHandleControlChange(handleControlChange_MIDI_DEVICE_USB);
Serial.println(F("MIDI_DEVICE_USB enabled."));
#endif
#ifdef MIDI_DEVICE_DIN
// Start serial MIDI
midi_serial.begin(DEFAULT_MIDI_CHANNEL);
Serial.println(F("MIDI_DEVICE_DIN enabled"));
#endif
// start audio card
AudioNoInterrupts();
AudioMemory(AUDIO_MEM);
#ifdef TEENSY_AUDIO_BOARD
@ -195,6 +209,11 @@ void setup()
sgtl5000_1.volume(1.0, 1.0);
#endif
#ifdef TGA_AUDIO_BOARD
wm8731m1.enable();
wm8731m1.volume(1.0);
#endif
//set_volume(vol, vol_left, vol_right);
set_volume(1.0, 1.0, 1.0);
@ -228,6 +247,7 @@ void setup()
mixer_r.gain(1, 0.3);
mixer_l.gain(1, 0.3);
AudioNoInterrupts();
Serial.println(F("<setup end>"));
#if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC)
@ -236,7 +256,6 @@ void setup()
#endif
}
//*************************************************************************************************
//* MAIN LOOP
//*************************************************************************************************
@ -300,78 +319,186 @@ void loop()
queue_r.playBuffer();
queue_l.playBuffer();
}
handle_input();
#ifdef MIDI_DEVICE_DIN
midi_serial.read();
#endif
#ifdef MIDI_DEVICE_USB_HOST
midi_usb.read();
#endif
#ifdef MIDI_DEVICE_USB
midi_onboard_usb.read();
#endif
}
//*************************************************************************************************
//* PROGRAM FUNCTIONS
//*************************************************************************************************
#ifdef MIDI_DEVICE_DIN
void handleNoteOn_MIDI_DEVICE_DIN(byte inChannel, byte inNumber, byte inVelocity)
{
handleNoteOn(byte inChannel, byte inNumber, byte inVelocity);
#ifdef MIDI_MERGE_THRU
#ifdef MIDI_DEVICE_USB_HOST
midi_usb.send(midi::NoteOn, inNumber, inVelocity, inChannel);
#endif
#ifdef MIDI_DEVICE_USB
midi_onboard_usb.send(midi::NoteOn, inNumber, inVelocity, inChannel);
#endif
#endif
}
void handle_input(void)
void handleNoteOff_MIDI_DEVICE_DIN(byte inChannel, byte inNumber, byte inVelocity)
{
#ifdef MIDI_DEVICE_DIN
while (midi_serial.read())
handleNoteOff(byte inChannel, byte inNumber, byte inVelocity)
#ifdef MIDI_MERGE_THRU
#ifdef MIDI_DEVICE_USB_HOST
midi_usb.send(midi::NoteOff, inNumber, inVelocity, inChannel);
#endif
#ifdef MIDI_DEVICE_USB
midi_onboard_usb.send(midi::NoteOff, inNumber, inVelocity, inChannel);
#endif
#endif
}
void handleControlChange_MIDI_DEVICE_DIN(byte inChannel, byte inData1, byte inData2)
{
#ifdef DEBUG
Serial.println(F("[MIDI-Serial]"));
handleControlChange(byte inChannel, byte inData1, byte inData2)
#ifdef MIDI_MERGE_THRU
#ifdef MIDI_DEVICE_USB_HOST
midi_usb.send(midi::ControlChange, inData1, inData2, inChannel);
#endif
#ifdef MIDI_DEVICE_USB
midi_onboard_usb.send(midi::ControlChange, inData1, inData2, inChannel);
#endif
#endif
queue_midi_event(midi_serial.getType(), midi_serial.getData1(), midi_serial.getData2());
}
#endif
#ifdef MIDI_DEVICE_USB_HOST
usb_host.Task();
while (midi_usb.read())
void handleNoteOn_MIDI_DEVICE_USB_HOST(byte inChannel, byte inNumber, byte inVelocity)
{
#ifdef DEBUG
Serial.println(F("[MIDI-USB-HOST]"));
handleNoteOn(inChannel, inNumber, inVelocity);
#ifdef MIDI_MERGE_THRU
#ifdef MIDI_DEVICE_DIN
midi_serial.send(midi::NoteOn, inNumber, inVelocity, inChannel);
#endif
#ifdef MIDI_DEVICE_USB
midi_onboard_usb.send(midi::NoteOn, inNumber, inVelocity, inChannel);
#endif
#endif
queue_midi_event(midi_usb.getType(), midi_usb.getData1(), midi_usb.getData2());
}
void handleNoteOff_MIDI_DEVICE_USB_HOST(byte inChannel, byte inNumber, byte inVelocity)
{
handleNoteOff(inChannel, inNumber, inVelocity);
#ifdef MIDI_MERGE_THRU
#ifdef MIDI_DEVICE_DIN
midi_serial.send(midi::NoteOff, inNumber, inVelocity, inChannel);
#endif
#ifdef MIDI_DEVICE_USB
while (midi_onboard_usb.read())
midi_onboard_usb.send(midi::NoteOff, inNumber, inVelocity, inChannel);
#endif
#endif
}
void handleControlChange_MIDI_DEVICE_USB_HOST(byte inChannel, byte inData1, byte inData2)
{
#ifdef DEBUG
Serial.println(F("[MIDI-USB]"));
handleControlChange(inChannel, inData1, inData2);
#ifdef MIDI_MERGE_THRU
#ifdef MIDI_DEVICE_DIN
midi_serial.send(midi::ControlChange, inData1, inData2, inChannel);
#endif
#ifdef MIDI_DEVICE_USB
midi_onboard_usb.send(midi::ControlChange, inData1, inData2, inChannel);
#endif
#endif
queue_midi_event(midi_onboard_usb.getType(), midi_onboard_usb.getData1(), midi_onboard_usb.getData2());
}
#endif
#ifdef MIDI_DEVICE_USB
void handleNoteOn_MIDI_DEVICE_USB(byte inChannel, byte inNumber, byte inVelocity)
{
handleNoteOn(inChannel, inNumber, inVelocity);
#ifdef MIDI_MERGE_THRU
#ifdef MIDI_DEVICE_DIN
midi_serial.send(midi::NoteOn, inNumber, inVelocity, inChannel);
#endif
#ifdef MIDI_DEVICE_USB_HOST
midi_usb.send(midi::NoteOn, inNumber, inVelocity, inChannel);
#endif
#endif
}
bool queue_midi_event(uint8_t type, uint8_t data1, uint8_t data2)
void handleNoteOff_MIDI_DEVICE_USB(byte inChannel, byte inNumber, byte inVelocity)
{
bool ret = false;
handleNoteOff(inChannel, inNumber, inVelocity);
#ifdef MIDI_MERGE_THRU
#ifdef MIDI_DEVICE_DIN
midi_serial.send(midi::NoteOff, inNumber, inVelocity, inChannel);
#endif
#ifdef MIDI_DEVICE_USB_HOST
midi_usb.send(midi::NoteOff, inNumber, inVelocity, inChannel);
#endif
#endif
}
#if defined(DEBUG) && defined(SHOW_MIDI_EVENT)
print_midi_event(type, data1, data2);
void handleControlChange_MIDI_DEVICE_USB(byte inChannel, byte inData1, byte inData2)
{
handleControlChange(inChannel, inData1, inData2);
#ifdef MIDI_MERGE_THRU
#ifdef MIDI_DEVICE_DIN
midi_serial.send(midi::ControlChange, inData1, inData2, inChannel);
#endif
#ifdef MIDI_DEVICE_USB_HOST
midi_usb.send(midi::ControlChange, inData1, inData2, inChannel);
#endif
#endif
}
#endif
void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity)
{
if (checkMidiChannel(inChannel))
{
ep->noteOn(inNumber, inVelocity);
}
}
void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity)
{
if (checkMidiChannel(inChannel))
{
ep->noteOn(inNumber, 0);
}
}
void handleControlChange(byte inChannel, byte inData1, byte inData2)
{
if (checkMidiChannel(inChannel))
{
ep->processMidiController(inData1, inData2);
}
}
bool checkMidiChannel(byte inChannel)
{
// check for MIDI channel
if (midi_channel != MIDI_CHANNEL_OMNI)
if (inChannel == MIDI_CHANNEL_OMNI)
{
uint8_t c = type & 0x0f;
if (c != midi_channel)
return (true);
}
else if (inChannel != midi_channel)
{
#ifdef DEBUG
Serial.print(F("Ignoring MIDI data on channel "));
Serial.print(c);
Serial.print(inChannel);
Serial.print(F("(listening on "));
Serial.print(midi_channel);
Serial.println(F(")"));
#endif
return (false);
}
}
// now throw away the MIDI channel information
type &= 0xf0;
ret = ep->processMidiMessage(type, data1, data2);
return (ret);
return (true);
}
void set_volume(float v, float vr, float vl)
@ -413,13 +540,14 @@ void set_volume(float v, float vr, float vl)
#ifdef TEENSY_AUDIO_BOARD
sgtl5000_1.dacVolume(vol * vol_left, vol * vol_right);
#elif TGA_AUDIO_BOARD
wm8731m1.volume(vol);
#else
volume_r.gain(vr);
volume_l.gain(vl);
#endif
}
//*************************************************************************************************
//* EEPROM FUNCTIONS
//*************************************************************************************************
@ -503,27 +631,6 @@ uint32_t eeprom_crc32(uint16_t calc_start, uint16_t calc_bytes) // base code fro
//* DEBUG FUNCTIONS
//*************************************************************************************************
#ifdef DEBUG
#ifdef SHOW_MIDI_EVENT
void print_midi_event(uint8_t type, uint8_t data1, uint8_t data2)
{
Serial.print(F("MIDI-Channel: "));
if (midi_channel == MIDI_CHANNEL_OMNI)
Serial.print(F("OMNI"));
else
Serial.print(midi_channel, DEC);
Serial.print(F(", MIDI event type: 0x"));
if (type < 16)
Serial.print(F("0"));
Serial.print(type, HEX);
Serial.print(F(", data1: "));
Serial.print(data1, DEC);
Serial.print(F(", data2: "));
Serial.println(data2, DEC);
}
#endif
#endif
#if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC)
void show_cpu_and_mem_usage(void)
{

@ -40,6 +40,7 @@
// AUDIO
//#define TEENSY_AUDIO_BOARD 1
#define TGA_AUDIO_BOARD 1
//*************************************************************************************************
//* MIDI SETTINGS

@ -328,21 +328,10 @@ void mdaEPiano::noteOn(int32_t note, int32_t velocity)
}
}
bool mdaEPiano::processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2)
bool mdaEPiano::processMidiController(uint8_t data1, uint8_t data2)
{
float* param = programs[curProgram].param;
switch (type)
{
case 0x80: //note off
noteOn(data1 & 0x7F, 0);
break;
case 0x90: //note on
noteOn(data1 & 0x7F, data2 & 0x7F);
break;
case 0xB0: //controller
switch (data1)
{
case 0x01: //mod wheel
@ -354,7 +343,6 @@ bool mdaEPiano::processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2)
}
break;
case 0x07: //volume
volume = 0.00002f * (float)(data2 * data2);
break;
@ -377,14 +365,5 @@ bool mdaEPiano::processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2)
}
break;
}
break;
case 0xC0: //program change
if (data1 < NPROGS) setProgram(data1);
break;
default: break;
}
return (true);
}

@ -79,7 +79,8 @@ class mdaEPiano
~mdaEPiano();
virtual void process(int16_t *outputs_r, int16_t *outputs_l);
virtual bool processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2);
void noteOn(int32_t note, int32_t velocity);
virtual bool processMidiController(uint8_t data1, uint8_t data2);
virtual void setProgram(int32_t program);
virtual void setParameter(int32_t index, float value);
virtual float getParameter(int32_t index);
@ -90,7 +91,6 @@ class mdaEPiano
private:
void update(); //my parameter update
void noteOn(int32_t note, int32_t velocity);
void fillpatch(int32_t p, char *name, float p0, float p1, float p2, float p3, float p4,
float p5, float p6, float p7, float p8, float p9, float p10, float p11);

Loading…
Cancel
Save