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. 299
      MicroMDAEPiano.ino
  2. 1
      config.h
  3. 73
      mdaEPiano.cpp
  4. 6
      mdaEPiano.h

@ -67,12 +67,16 @@ AudioConnection patchCord6(queue_r, 0, mixer_r, 0);
AudioConnection patchCord7(queue_l, 0, mixer_l, 0); AudioConnection patchCord7(queue_l, 0, mixer_l, 0);
AudioConnection patchCord8(freeverb_r, 0, mixer_r, 1); AudioConnection patchCord8(freeverb_r, 0, mixer_r, 1);
AudioConnection patchCord9(freeverb_l, 0, mixer_l, 1); AudioConnection patchCord9(freeverb_l, 0, mixer_l, 1);
#ifdef TEENSY_AUDIO_BOARD #if defined(TEENSY_AUDIO_BOARD) || defined(TGA_AUDIO_BOARD)
AudioOutputI2S i2s1; AudioOutputI2S i2s1;
AudioConnection patchCord110(mixer_r, 0, i2s1, 0); AudioConnection patchCord110(mixer_r, 0, i2s1, 0);
AudioConnection patchCord111(mixer_l, 0, i2s1, 1); AudioConnection patchCord111(mixer_l, 0, i2s1, 1);
#ifdef TEENSY_AUDIO_BOARD
AudioControlSGTL5000 sgtl5000_1; AudioControlSGTL5000 sgtl5000_1;
#else #else
AudioControlWM8731master wm8731m1;
#endif
#else
AudioOutputPT8211 pt8211_1; AudioOutputPT8211 pt8211_1;
AudioAmplifier volume_r; AudioAmplifier volume_r;
AudioAmplifier volume_l; AudioAmplifier volume_l;
@ -127,26 +131,26 @@ void setup()
Serial.begin(SERIAL_SPEED); Serial.begin(SERIAL_SPEED);
delay(220); delay(220);
/* /*
// LCD display setup // LCD display setup
lcd.init(); lcd.init();
lcd.blink_off(); lcd.blink_off();
lcd.cursor_off(); lcd.cursor_off();
lcd.backlight(); lcd.backlight();
lcd.noAutoscroll(); lcd.noAutoscroll();
lcd.clear(); lcd.clear();
lcd.display(); lcd.display();
lcd.show(0, 0, 20, " MicroMDAEPiano"); lcd.show(0, 0, 20, " MicroMDAEPiano");
lcd.show(1, 0, 16, "(c)parasiTstudio"); lcd.show(1, 0, 16, "(c)parasiTstudio");
// Encoder setup // Encoder setup
enc[0].write(INITIAL_ENC_L_VALUE); enc[0].write(INITIAL_ENC_L_VALUE);
enc_val[0] = enc[0].read(); enc_val[0] = enc[0].read();
enc[1].write(INITIAL_ENC_R_VALUE); enc[1].write(INITIAL_ENC_R_VALUE);
enc_val[1] = enc[1].read(); enc_val[1] = enc[1].read();
but[0].update(); but[0].update();
but[1].update(); but[1].update();
*/ */
// Debug output // Debug output
Serial.println(F("MicroMDAEPiano based on https://sourceforge.net/projects/mda-vst")); Serial.println(F("MicroMDAEPiano based on https://sourceforge.net/projects/mda-vst"));
@ -164,25 +168,35 @@ void setup()
// read initial EEPROM variables // read initial EEPROM variables
initial_values_from_eeprom(); 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 // start up USB host
#ifdef MIDI_DEVICE_USB_HOST #ifdef MIDI_DEVICE_USB_HOST
usb_host.begin(); 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.")); Serial.println(F("MIDI_DEVICE_USB_HOST enabled."));
#endif #endif
// check for onboard USB-MIDI // check for onboard USB-MIDI
#ifdef MIDI_DEVICE_USB #ifdef MIDI_DEVICE_USB
midi_onboard_usb.begin(); 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.")); Serial.println(F("MIDI_DEVICE_USB enabled."));
#endif #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 // start audio card
AudioNoInterrupts();
AudioMemory(AUDIO_MEM); AudioMemory(AUDIO_MEM);
#ifdef TEENSY_AUDIO_BOARD #ifdef TEENSY_AUDIO_BOARD
@ -195,6 +209,11 @@ void setup()
sgtl5000_1.volume(1.0, 1.0); sgtl5000_1.volume(1.0, 1.0);
#endif #endif
#ifdef TGA_AUDIO_BOARD
wm8731m1.enable();
wm8731m1.volume(1.0);
#endif
//set_volume(vol, vol_left, vol_right); //set_volume(vol, vol_left, vol_right);
set_volume(1.0, 1.0, 1.0); set_volume(1.0, 1.0, 1.0);
@ -228,6 +247,7 @@ void setup()
mixer_r.gain(1, 0.3); mixer_r.gain(1, 0.3);
mixer_l.gain(1, 0.3); mixer_l.gain(1, 0.3);
AudioNoInterrupts();
Serial.println(F("<setup end>")); Serial.println(F("<setup end>"));
#if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC) #if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC)
@ -236,7 +256,6 @@ void setup()
#endif #endif
} }
//************************************************************************************************* //*************************************************************************************************
//* MAIN LOOP //* MAIN LOOP
//************************************************************************************************* //*************************************************************************************************
@ -300,78 +319,186 @@ void loop()
queue_r.playBuffer(); queue_r.playBuffer();
queue_l.playBuffer(); queue_l.playBuffer();
} }
#ifdef MIDI_DEVICE_DIN
handle_input(); midi_serial.read();
#endif
#ifdef MIDI_DEVICE_USB_HOST
midi_usb.read();
#endif
#ifdef MIDI_DEVICE_USB
midi_onboard_usb.read();
#endif
} }
//************************************************************************************************* //*************************************************************************************************
//* PROGRAM FUNCTIONS //* 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 handleNoteOff(byte inChannel, byte inNumber, byte inVelocity)
while (midi_serial.read()) #ifdef MIDI_MERGE_THRU
{ #ifdef MIDI_DEVICE_USB_HOST
#ifdef DEBUG midi_usb.send(midi::NoteOff, inNumber, inVelocity, inChannel);
Serial.println(F("[MIDI-Serial]")); #endif
#ifdef MIDI_DEVICE_USB
midi_onboard_usb.send(midi::NoteOff, inNumber, inVelocity, inChannel);
#endif #endif
queue_midi_event(midi_serial.getType(), midi_serial.getData1(), midi_serial.getData2());
}
#endif #endif
}
void handleControlChange_MIDI_DEVICE_DIN(byte inChannel, byte inData1, byte inData2)
{
handleControlChange(byte inChannel, byte inData1, byte inData2)
#ifdef MIDI_MERGE_THRU
#ifdef MIDI_DEVICE_USB_HOST #ifdef MIDI_DEVICE_USB_HOST
usb_host.Task(); midi_usb.send(midi::ControlChange, inData1, inData2, inChannel);
while (midi_usb.read())
{
#ifdef DEBUG
Serial.println(F("[MIDI-USB-HOST]"));
#endif #endif
queue_midi_event(midi_usb.getType(), midi_usb.getData1(), midi_usb.getData2()); #ifdef MIDI_DEVICE_USB
} midi_onboard_usb.send(midi::ControlChange, inData1, inData2, inChannel);
#endif
#endif
}
#endif
#ifdef MIDI_DEVICE_USB_HOST
void handleNoteOn_MIDI_DEVICE_USB_HOST(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 #endif
#ifdef MIDI_DEVICE_USB #ifdef MIDI_DEVICE_USB
while (midi_onboard_usb.read()) midi_onboard_usb.send(midi::NoteOn, inNumber, inVelocity, inChannel);
{
#ifdef DEBUG
Serial.println(F("[MIDI-USB]"));
#endif #endif
queue_midi_event(midi_onboard_usb.getType(), midi_onboard_usb.getData1(), midi_onboard_usb.getData2());
}
#endif #endif
} }
bool queue_midi_event(uint8_t type, uint8_t data1, uint8_t data2) 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
midi_onboard_usb.send(midi::NoteOff, inNumber, inVelocity, inChannel);
#endif
#endif
}
void handleControlChange_MIDI_DEVICE_USB_HOST(byte inChannel, byte inData1, byte inData2)
{ {
bool ret = false; 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
}
#endif
#if defined(DEBUG) && defined(SHOW_MIDI_EVENT) #ifdef MIDI_DEVICE_USB
print_midi_event(type, data1, data2); 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 #endif
}
// check for MIDI channel void handleNoteOff_MIDI_DEVICE_USB(byte inChannel, byte inNumber, byte inVelocity)
if (midi_channel != MIDI_CHANNEL_OMNI) {
{ handleNoteOff(inChannel, inNumber, inVelocity);
uint8_t c = type & 0x0f; #ifdef MIDI_MERGE_THRU
if (c != midi_channel) #ifdef MIDI_DEVICE_DIN
{ midi_serial.send(midi::NoteOff, inNumber, inVelocity, inChannel);
#ifdef DEBUG
Serial.print(F("Ignoring MIDI data on channel "));
Serial.print(c);
Serial.print(F("(listening on "));
Serial.print(midi_channel);
Serial.println(F(")"));
#endif #endif
return (false); #ifdef MIDI_DEVICE_USB_HOST
} midi_usb.send(midi::NoteOff, inNumber, inVelocity, inChannel);
#endif
#endif
}
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);
} }
}
// now throw away the MIDI channel information void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity)
type &= 0xf0; {
if (checkMidiChannel(inChannel))
{
ep->noteOn(inNumber, 0);
}
}
ret = ep->processMidiMessage(type, data1, data2); void handleControlChange(byte inChannel, byte inData1, byte inData2)
{
if (checkMidiChannel(inChannel))
{
ep->processMidiController(inData1, inData2);
}
}
return (ret); bool checkMidiChannel(byte inChannel)
{
// check for MIDI channel
if (inChannel == MIDI_CHANNEL_OMNI)
{
return (true);
}
else if (inChannel != midi_channel)
{
#ifdef DEBUG
Serial.print(F("Ignoring MIDI data on channel "));
Serial.print(inChannel);
Serial.print(F("(listening on "));
Serial.print(midi_channel);
Serial.println(F(")"));
#endif
return (false);
}
return (true);
} }
void set_volume(float v, float vr, float vl) 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 #ifdef TEENSY_AUDIO_BOARD
sgtl5000_1.dacVolume(vol * vol_left, vol * vol_right); sgtl5000_1.dacVolume(vol * vol_left, vol * vol_right);
#elif TGA_AUDIO_BOARD
wm8731m1.volume(vol);
#else #else
volume_r.gain(vr); volume_r.gain(vr);
volume_l.gain(vl); volume_l.gain(vl);
#endif #endif
} }
//************************************************************************************************* //*************************************************************************************************
//* EEPROM FUNCTIONS //* EEPROM FUNCTIONS
//************************************************************************************************* //*************************************************************************************************
@ -503,27 +631,6 @@ uint32_t eeprom_crc32(uint16_t calc_start, uint16_t calc_bytes) // base code fro
//* DEBUG FUNCTIONS //* 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) #if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC)
void show_cpu_and_mem_usage(void) void show_cpu_and_mem_usage(void)
{ {

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

@ -228,9 +228,9 @@ void mdaEPiano::process(int16_t* outputs_r, int16_t* outputs_l)
l += l * lmod * lfo1; l += l * lmod * lfo1;
r += r * rmod * lfo1; //worth making all these local variables? r += r * rmod * lfo1; //worth making all these local variables?
r*=0.5; r *= 0.5;
l*=0.5; l *= 0.5;
if (r > 1.0) if (r > 1.0)
r = 1.0; r = 1.0;
else if (r < -1.0) else if (r < -1.0)
@ -328,63 +328,42 @@ 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; float* param = programs[curProgram].param;
switch (type) switch (data1)
{ {
case 0x80: //note off case 0x01: //mod wheel
noteOn(data1 & 0x7F, 0); modwhl = 0.0078f * (float)(data2);
if (modwhl > 0.05f) //over-ride pan/trem depth
{
rmod = lmod = modwhl; //lfo depth
if (param[4] < 0.5f) rmod = -rmod;
}
break; break;
case 0x90: //note on case 0x07: //volume
noteOn(data1 & 0x7F, data2 & 0x7F); volume = 0.00002f * (float)(data2 * data2);
break; break;
case 0xB0: //controller case 0x40: //sustain pedal
switch (data1) case 0x42: //sustenuto pedal
sustain = data2 & 0x40;
if (sustain == 0)
{ {
case 0x01: //mod wheel noteOn(SUSTAIN, 0); //end all sustained notes
modwhl = 0.0078f * (float)(data2);
if (modwhl > 0.05f) //over-ride pan/trem depth
{
rmod = lmod = modwhl; //lfo depth
if (param[4] < 0.5f) rmod = -rmod;
}
break;
case 0x07: //volume
volume = 0.00002f * (float)(data2 * data2);
break;
case 0x40: //sustain pedal
case 0x42: //sustenuto pedal
sustain = data2 & 0x40;
if (sustain == 0)
{
noteOn(SUSTAIN, 0); //end all sustained notes
}
break;
default: //all notes off
if (data1 > 0x7A)
{
for (int32_t v = 0; v < NVOICES; v++) voice[v].dec = 0.99f;
sustain = 0;
muff = 160.0f;
}
break;
} }
break; break;
case 0xC0: //program change default: //all notes off
if (data1 < NPROGS) setProgram(data1); if (data1 > 0x7A)
{
for (int32_t v = 0; v < NVOICES; v++) voice[v].dec = 0.99f;
sustain = 0;
muff = 160.0f;
}
break; break;
default: break;
} }
return (true); return (true);
} }

@ -79,7 +79,8 @@ class mdaEPiano
~mdaEPiano(); ~mdaEPiano();
virtual void process(int16_t *outputs_r, int16_t *outputs_l); 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 setProgram(int32_t program);
virtual void setParameter(int32_t index, float value); virtual void setParameter(int32_t index, float value);
virtual float getParameter(int32_t index); virtual float getParameter(int32_t index);
@ -90,10 +91,9 @@ class mdaEPiano
private: private:
void update(); //my parameter update 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, 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); float p5, float p6, float p7, float p8, float p9, float p10, float p11);
mdaEPianoProgram* programs; mdaEPianoProgram* programs;
float Fs, iFs; float Fs, iFs;

Loading…
Cancel
Save