From 115da6d2a01e512507fa7919301906ad68380955 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Thu, 31 Jan 2019 08:59:58 +0100 Subject: [PATCH] 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. --- MicroMDAEPiano.ino | 299 ++++++++++++++++++++++++++++++--------------- config.h | 1 + mdaEPiano.cpp | 73 ++++------- mdaEPiano.h | 6 +- 4 files changed, 233 insertions(+), 146 deletions(-) diff --git a/MicroMDAEPiano.ino b/MicroMDAEPiano.ino index 5dc7013..37fefa2 100644 --- a/MicroMDAEPiano.ino +++ b/MicroMDAEPiano.ino @@ -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; @@ -127,26 +131,26 @@ void setup() Serial.begin(SERIAL_SPEED); delay(220); -/* - // LCD display setup - lcd.init(); - lcd.blink_off(); - lcd.cursor_off(); - lcd.backlight(); - lcd.noAutoscroll(); - lcd.clear(); - lcd.display(); - lcd.show(0, 0, 20, " MicroMDAEPiano"); - lcd.show(1, 0, 16, "(c)parasiTstudio"); - - // Encoder setup - enc[0].write(INITIAL_ENC_L_VALUE); - enc_val[0] = enc[0].read(); - enc[1].write(INITIAL_ENC_R_VALUE); - enc_val[1] = enc[1].read(); - but[0].update(); - but[1].update(); -*/ + /* + // LCD display setup + lcd.init(); + lcd.blink_off(); + lcd.cursor_off(); + lcd.backlight(); + lcd.noAutoscroll(); + lcd.clear(); + lcd.display(); + lcd.show(0, 0, 20, " MicroMDAEPiano"); + lcd.show(1, 0, 16, "(c)parasiTstudio"); + + // Encoder setup + enc[0].write(INITIAL_ENC_L_VALUE); + enc_val[0] = enc[0].read(); + enc[1].write(INITIAL_ENC_R_VALUE); + enc_val[1] = enc[1].read(); + but[0].update(); + but[1].update(); + */ // Debug output Serial.println(F("MicroMDAEPiano based on https://sourceforge.net/projects/mda-vst")); @@ -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("")); #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()) - { -#ifdef DEBUG - Serial.println(F("[MIDI-Serial]")); + 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 - queue_midi_event(midi_serial.getType(), midi_serial.getData1(), midi_serial.getData2()); - } #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 - usb_host.Task(); - while (midi_usb.read()) - { -#ifdef DEBUG - Serial.println(F("[MIDI-USB-HOST]")); + midi_usb.send(midi::ControlChange, inData1, inData2, inChannel); #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 #ifdef MIDI_DEVICE_USB - while (midi_onboard_usb.read()) - { -#ifdef DEBUG - Serial.println(F("[MIDI-USB]")); + midi_onboard_usb.send(midi::NoteOn, inNumber, inVelocity, inChannel); #endif - queue_midi_event(midi_onboard_usb.getType(), midi_onboard_usb.getData1(), midi_onboard_usb.getData2()); - } #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) - print_midi_event(type, data1, data2); +#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 +} - // check for MIDI channel - if (midi_channel != MIDI_CHANNEL_OMNI) - { - uint8_t c = type & 0x0f; - if (c != midi_channel) - { -#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(")")); +void handleNoteOff_MIDI_DEVICE_USB(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 - 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 - type &= 0xf0; +void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity) +{ + 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) @@ -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) { diff --git a/config.h b/config.h index 3519c03..d286b78 100644 --- a/config.h +++ b/config.h @@ -40,6 +40,7 @@ // AUDIO //#define TEENSY_AUDIO_BOARD 1 +#define TGA_AUDIO_BOARD 1 //************************************************************************************************* //* MIDI SETTINGS diff --git a/mdaEPiano.cpp b/mdaEPiano.cpp index 6dd1538..7fe3abf 100644 --- a/mdaEPiano.cpp +++ b/mdaEPiano.cpp @@ -228,9 +228,9 @@ void mdaEPiano::process(int16_t* outputs_r, int16_t* outputs_l) l += l * lmod * lfo1; r += r * rmod * lfo1; //worth making all these local variables? - r*=0.5; - l*=0.5; - + r *= 0.5; + l *= 0.5; + if (r > 1.0) 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; - switch (type) + switch (data1) { - case 0x80: //note off - noteOn(data1 & 0x7F, 0); + case 0x01: //mod wheel + 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 0x90: //note on - noteOn(data1 & 0x7F, data2 & 0x7F); + case 0x07: //volume + volume = 0.00002f * (float)(data2 * data2); break; - case 0xB0: //controller - switch (data1) + case 0x40: //sustain pedal + case 0x42: //sustenuto pedal + sustain = data2 & 0x40; + if (sustain == 0) { - case 0x01: //mod wheel - 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; + noteOn(SUSTAIN, 0); //end all sustained notes } break; - case 0xC0: //program change - if (data1 < NPROGS) setProgram(data1); + 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; - - default: break; } - return (true); } diff --git a/mdaEPiano.h b/mdaEPiano.h index 26c51cf..4ea5584 100644 --- a/mdaEPiano.h +++ b/mdaEPiano.h @@ -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,10 +91,9 @@ 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); - + mdaEPianoProgram* programs; float Fs, iFs;