Line data Source code
1 : #include "Control_Surface_Class.hpp" 2 : #include <AH/Debug/Debug.hpp> 3 : #include <AH/Hardware/ExtendedInputOutput/ExtendedIOElement.hpp> 4 : #include <AH/Hardware/FilteredAnalog.hpp> 5 : #include <MIDI_Constants/Control_Change.hpp> 6 : #include <MIDI_Inputs/MIDIInputElementCC.hpp> 7 : #include <MIDI_Inputs/MIDIInputElementChannelPressure.hpp> 8 : #include <MIDI_Inputs/MIDIInputElementNote.hpp> 9 : #include <MIDI_Inputs/MIDIInputElementPC.hpp> 10 : #include <MIDI_Inputs/MIDIInputElementSysEx.hpp> 11 : #include <MIDI_Outputs/Abstract/MIDIOutputElement.hpp> 12 : #include <Selectors/Selector.hpp> 13 : 14 : #include <Arduino.h> 15 : 16 : BEGIN_CS_NAMESPACE 17 : 18 : using AH::ExtendedIOElement; 19 : 20 2 : Control_Surface_ &Control_Surface_::getInstance() { 21 2 : static Control_Surface_ instance; 22 2 : return instance; 23 0 : } 24 : 25 0 : void Control_Surface_::begin() { 26 : #if defined(ARDUINO) && defined(DEBUG_OUT) 27 : DEBUG_OUT.begin(defaultBaudRate); 28 : delay(250); 29 : #endif 30 0 : FilteredAnalog<>::setupADC(); 31 0 : ExtendedIOElement::beginAll(); 32 0 : MIDI().begin(); // initialize the MIDI interface 33 0 : MIDI().setCallbacks(this); 34 0 : DisplayInterface::beginAll(); // initialize all displays 35 0 : MIDIInputElementCC::beginAll(); 36 0 : MIDIInputElementPC::beginAll(); 37 0 : MIDIInputElementChannelPressure::beginAll(); 38 0 : MIDIInputElementNote::beginAll(); 39 0 : MIDIInputElementSysEx::beginAll(); 40 0 : Updatable<>::beginAll(); 41 0 : Updatable<Potentiometer>::beginAll(); 42 0 : Updatable<MotorFader>::beginAll(); 43 0 : Updatable<Display>::beginAll(); 44 0 : potentiometerTimer.begin(); 45 0 : displayTimer.begin(); 46 0 : } 47 : 48 0 : void Control_Surface_::loop() { 49 0 : Updatable<>::updateAll(); 50 0 : if (potentiometerTimer) 51 0 : Updatable<Potentiometer>::updateAll(); 52 0 : updateMidiInput(); 53 0 : updateInputs(); 54 0 : if (displayTimer) 55 0 : updateDisplays(); 56 0 : } 57 : 58 94 : MIDI_Interface &Control_Surface_::MIDI() { 59 94 : MIDI_Interface *midi = MIDI_Interface::getDefault(); 60 94 : if (midi == nullptr) 61 0 : FATAL_ERROR(F("No default MIDI interface is selected."), 0xDEAD); 62 : 63 94 : return *midi; 64 0 : } 65 : 66 0 : void Control_Surface_::updateMidiInput() { 67 0 : MIDI_Interface &midi = MIDI(); 68 0 : midi.update(); 69 0 : } 70 : 71 0 : void Control_Surface_::onChannelMessage(Parsing_MIDI_Interface &midi) { 72 0 : ChannelMessage midichmsg = midi.getChannelMessage(); 73 0 : ChannelMessageMatcher midimsg = {midichmsg}; 74 : 75 : #ifdef DEBUG_MIDI_PACKETS 76 : // TODO: print CN 77 : if (midimsg.type != PROGRAM_CHANGE && midimsg.type != CHANNEL_PRESSURE) 78 : DEBUG(">>> " << hex << midichmsg.header << ' ' << midimsg.data1 << ' ' 79 : << midimsg.data2 << dec); 80 : else 81 : DEBUG(">>> " << hex << midichmsg.header << ' ' << midimsg.data1 << dec); 82 : #endif 83 : 84 : // If the Channel Message callback exists, call it to see if we have to 85 : // continue handling it. 86 0 : if (channelMessageCallback && channelMessageCallback(midichmsg)) 87 0 : return; 88 : 89 0 : if (midimsg.type == CC && midimsg.data1 == 0x79) { 90 : // Reset All Controllers 91 0 : DEBUG(F("Reset All Controllers")); 92 0 : MIDIInputElementCC::resetAll(); 93 0 : MIDIInputElementChannelPressure::resetAll(); 94 0 : } else if (midimsg.type == CC && midimsg.data1 == MIDI_CC::All_Notes_Off) { 95 0 : MIDIInputElementNote::resetAll(); 96 0 : } else { 97 0 : if (midimsg.type == CC) { 98 : // Control Change 99 0 : DEBUGFN(F("Updating CC elements with new MIDI message.")); 100 0 : MIDIInputElementCC::updateAllWith(midimsg); 101 : 102 0 : } else if (midimsg.type == NOTE_OFF || midimsg.type == NOTE_ON) { 103 : // Note 104 0 : DEBUGFN(F("Updating Note elements with new MIDI message.")); 105 0 : MIDIInputElementNote::updateAllWith(midimsg); 106 : 107 0 : } else if (midimsg.type == CHANNEL_PRESSURE) { 108 : // Channel Pressure 109 0 : DEBUGFN(F("Updating Channel Pressure elements with new " 110 : "MIDI message.")); 111 0 : MIDIInputElementChannelPressure::updateAllWith(midimsg); 112 0 : } else if (midimsg.type == PROGRAM_CHANGE) { 113 : // Channel Pressure 114 0 : DEBUGFN(F("Updating Program Change elements with new " 115 : "MIDI message.")); 116 0 : MIDIInputElementPC::updateAllWith(midimsg); 117 0 : } 118 : } 119 0 : } 120 : 121 0 : void Control_Surface_::onSysExMessage(Parsing_MIDI_Interface &midi) { 122 : // System Exclusive 123 0 : SysExMessage msg = midi.getSysExMessage(); 124 : #ifdef DEBUG_MIDI_PACKETS 125 : const uint8_t *data = msg.data; 126 : size_t len = msg.length; 127 : // TODO: print CN 128 : DEBUG_OUT << hex; 129 : for (size_t i = 0; i < len; i++) 130 : DEBUG_OUT << data[i] << ' '; 131 : DEBUG_OUT << dec << endl; 132 : #endif 133 : // If the SysEx Message callback exists, call it to see if we have to 134 : // continue handling it. 135 0 : if (sysExMessageCallback && sysExMessageCallback(msg)) 136 0 : return; 137 0 : MIDIInputElementSysEx::updateAllWith(msg); 138 0 : } 139 : 140 0 : void Control_Surface_::onRealtimeMessage(Parsing_MIDI_Interface &midi, 141 : uint8_t message) { 142 0 : RealTimeMessage rtMessage = {message, midi.getCN()}; 143 : // If the Real-Time Message callback exists, call it to see if we have to 144 : // continue handling it. 145 0 : if (realTimeMessageCallback && realTimeMessageCallback(rtMessage)) 146 0 : return; 147 : // TODO: handle Real-Time input 148 0 : } 149 : 150 0 : void Control_Surface_::updateInputs() { 151 0 : MIDIInputElementCC::updateAll(); 152 0 : MIDIInputElementNote::updateAll(); 153 0 : MIDIInputElementChannelPressure::updateAll(); 154 0 : MIDIInputElementPC::updateAll(); 155 0 : MIDIInputElementSysEx::updateAll(); 156 0 : } 157 : 158 0 : void Control_Surface_::updateDisplays() { 159 0 : DisplayInterface *previousDisplay = nullptr; 160 0 : for (DisplayElement &displayElement : DisplayElement::getAll()) { 161 0 : DisplayInterface *thisDisplay = &displayElement.getDisplay(); 162 0 : if (thisDisplay != previousDisplay) { 163 0 : if (previousDisplay) 164 0 : previousDisplay->display(); 165 0 : thisDisplay->clearAndDrawBackground(); 166 0 : } 167 0 : displayElement.draw(); 168 0 : previousDisplay = thisDisplay; 169 : } 170 0 : if (previousDisplay) 171 0 : previousDisplay->display(); 172 0 : } 173 : 174 2 : Control_Surface_ &Control_Surface = Control_Surface_::getInstance(); 175 : 176 : END_CS_NAMESPACE