LCOV - code coverage report
Current view: top level - src/Control_Surface - Control_Surface_Class.cpp (source / functions) Hit Total Coverage
Test: e224b347cd670555e44f06608ac41bd1ace9d9d8 Lines: 15 125 12.0 %
Date: 2020-09-08 17:44:46 Functions: 4 16 25.0 %
Legend: Lines: hit not hit

          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 <AH/Arduino-Wrapper.h>
      15             : 
      16             : BEGIN_CS_NAMESPACE
      17             : 
      18             : using AH::ExtendedIOElement;
      19             : 
      20           1 : Control_Surface_ &Control_Surface_::getInstance() {
      21           1 :     static Control_Surface_ instance;
      22           1 :     return instance;
      23           0 : }
      24             : 
      25           0 : void Control_Surface_::begin() {
      26             : #if defined(ARDUINO) && defined(DEBUG_OUT)
      27             :     DEBUG_OUT.begin(AH::defaultBaudRate);
      28             :     delay(250);
      29             : #endif
      30             : 
      31           0 :     connectDefaultMIDI_Interface();
      32             : 
      33           0 :     FilteredAnalog<>::setupADC();
      34           0 :     ExtendedIOElement::beginAll();
      35           0 :     Updatable<MIDI_Interface>::beginAll();
      36           0 :     DisplayInterface::beginAll(); // initialize all displays
      37           0 :     MIDIInputElementCC::beginAll();
      38           0 :     MIDIInputElementPC::beginAll();
      39           0 :     MIDIInputElementChannelPressure::beginAll();
      40           0 :     MIDIInputElementNote::beginAll();
      41           0 :     MIDIInputElementSysEx::beginAll();
      42           0 :     Updatable<>::beginAll();
      43           0 :     Updatable<Potentiometer>::beginAll();
      44           0 :     Updatable<MotorFader>::beginAll();
      45           0 :     Updatable<Display>::beginAll();
      46           0 :     potentiometerTimer.begin();
      47           0 :     displayTimer.begin();
      48           0 : }
      49             : 
      50          35 : bool Control_Surface_::connectDefaultMIDI_Interface() {
      51          35 :     if (hasSinkPipe() || hasSourcePipe())
      52           0 :         return false;
      53          35 :     auto def = MIDI_Interface::getDefault();
      54          35 :     if (def == nullptr) {
      55           0 :         FATAL_ERROR(F("No default MIDI Interface"), 0xF123);
      56           0 :         return false;
      57             :     }
      58          35 :     *this << inpipe << *def;
      59          35 :     *this >> outpipe >> *def;
      60          35 :     return true;
      61          35 : }
      62             : 
      63           0 : void Control_Surface_::disconnectMIDI_Interfaces() {
      64           0 :     disconnectSinkPipes();
      65           0 :     disconnectSourcePipes();
      66           0 : }
      67             : 
      68           0 : void Control_Surface_::loop() {
      69           0 :     ExtendedIOElement::updateAllBufferedInputs();
      70           0 :     Updatable<>::updateAll();
      71           0 :     if (potentiometerTimer)
      72           0 :         Updatable<Potentiometer>::updateAll();
      73           0 :     updateMidiInput();
      74           0 :     updateInputs();
      75           0 :     if (displayTimer)
      76           0 :         updateDisplays();
      77           0 :     ExtendedIOElement::updateAllBufferedOutputs();
      78           0 : }
      79             : 
      80           0 : void Control_Surface_::updateMidiInput() {
      81           0 :     Updatable<MIDI_Interface>::updateAll();
      82           0 : }
      83             : 
      84         103 : void Control_Surface_::sendImpl(uint8_t header, uint8_t d1, uint8_t d2,
      85             :                                 uint8_t cn) {
      86         103 :     this->sourceMIDItoPipe(ChannelMessage{header, d1, d2, cn});
      87         103 : }
      88           0 : void Control_Surface_::sendImpl(uint8_t header, uint8_t d1, uint8_t cn) {
      89           0 :     this->sourceMIDItoPipe(ChannelMessage{header, d1, 0x00, cn});
      90           0 : }
      91           0 : void Control_Surface_::sendImpl(const uint8_t *data, size_t length,
      92             :                                 uint8_t cn) {
      93           0 :     this->sourceMIDItoPipe(SysExMessage{data, length, cn});
      94           0 : }
      95           0 : void Control_Surface_::sendImpl(uint8_t rt, uint8_t cn) {
      96           0 :     this->sourceMIDItoPipe(RealTimeMessage{rt, cn});
      97           0 : }
      98             : 
      99           0 : void Control_Surface_::sinkMIDIfromPipe(ChannelMessage midichmsg) {
     100           0 :     ChannelMessageMatcher midimsg = {midichmsg};
     101             : 
     102             : #ifdef DEBUG_MIDI_PACKETS
     103             :     // TODO: print CN
     104             :     if (midimsg.type != PROGRAM_CHANGE && midimsg.type != CHANNEL_PRESSURE)
     105             :         DEBUG(">>> " << hex << midichmsg.header << ' ' << midimsg.data1 << ' '
     106             :                      << midimsg.data2 << dec);
     107             :     else
     108             :         DEBUG(">>> " << hex << midichmsg.header << ' ' << midimsg.data1 << dec);
     109             : #endif
     110             : 
     111             :     // If the Channel Message callback exists, call it to see if we have to
     112             :     // continue handling it.
     113           0 :     if (channelMessageCallback && channelMessageCallback(midichmsg))
     114           0 :         return;
     115             : 
     116           0 :     if (midimsg.type == MIDIMessageType::CONTROL_CHANGE &&
     117           0 :         midimsg.data1 == MIDI_CC::Reset_All_Controllers) {
     118             :         // Reset All Controllers
     119           0 :         DEBUG(F("Reset All Controllers"));
     120           0 :         MIDIInputElementCC::resetAll();
     121           0 :         MIDIInputElementChannelPressure::resetAll();
     122           0 :     } else if (midimsg.type == MIDIMessageType::CONTROL_CHANGE &&
     123           0 :                midimsg.data1 == MIDI_CC::All_Notes_Off) {
     124           0 :         MIDIInputElementNote::resetAll();
     125           0 :     } else {
     126           0 :         if (midimsg.type == MIDIMessageType::CONTROL_CHANGE) {
     127             :             // Control Change
     128           0 :             DEBUGFN(F("Updating CC elements with new MIDI message."));
     129           0 :             MIDIInputElementCC::updateAllWith(midimsg);
     130             : 
     131           0 :         } else if (midimsg.type == MIDIMessageType::NOTE_OFF ||
     132           0 :                    midimsg.type == MIDIMessageType::NOTE_ON) {
     133             :             // Note
     134           0 :             DEBUGFN(F("Updating Note elements with new MIDI message."));
     135           0 :             MIDIInputElementNote::updateAllWith(midimsg);
     136             : 
     137           0 :         } else if (midimsg.type == MIDIMessageType::CHANNEL_PRESSURE) {
     138             :             // Channel Pressure
     139           0 :             DEBUGFN(F("Updating Channel Pressure elements with new "
     140             :                       "MIDI message."));
     141           0 :             MIDIInputElementChannelPressure::updateAllWith(midimsg);
     142           0 :         } else if (midimsg.type == MIDIMessageType::PROGRAM_CHANGE) {
     143             :             // Channel Pressure
     144           0 :             DEBUGFN(F("Updating Program Change elements with new "
     145             :                       "MIDI message."));
     146           0 :             MIDIInputElementPC::updateAllWith(midimsg);
     147           0 :         }
     148             :     }
     149           0 : }
     150             : 
     151           0 : void Control_Surface_::sinkMIDIfromPipe(SysExMessage msg) {
     152             :     // System Exclusive
     153             : #ifdef DEBUG_MIDI_PACKETS
     154             :     const uint8_t *data = msg.data;
     155             :     size_t len = msg.length;
     156             :     // TODO: print CN
     157             :     DEBUG_OUT << hex;
     158             :     for (size_t i = 0; i < len; i++)
     159             :         DEBUG_OUT << data[i] << ' ';
     160             :     DEBUG_OUT << dec << endl;
     161             : #endif
     162             :     // If the SysEx Message callback exists, call it to see if we have to
     163             :     // continue handling it.
     164           0 :     if (sysExMessageCallback && sysExMessageCallback(msg))
     165           0 :         return;
     166           0 :     MIDIInputElementSysEx::updateAllWith(msg);
     167           0 : }
     168             : 
     169           0 : void Control_Surface_::sinkMIDIfromPipe(RealTimeMessage rtMessage) {
     170             :     // If the Real-Time Message callback exists, call it to see if we have to
     171             :     // continue handling it.
     172           0 :     if (realTimeMessageCallback && realTimeMessageCallback(rtMessage))
     173           0 :         return;
     174             :     // TODO: handle Real-Time input
     175           0 : }
     176             : 
     177           0 : void Control_Surface_::updateInputs() {
     178           0 :     MIDIInputElementCC::updateAll();
     179           0 :     MIDIInputElementNote::updateAll();
     180           0 :     MIDIInputElementChannelPressure::updateAll();
     181           0 :     MIDIInputElementPC::updateAll();
     182           0 :     MIDIInputElementSysEx::updateAll();
     183           0 : }
     184             : 
     185           0 : void Control_Surface_::updateDisplays() {
     186           0 :     DisplayInterface *previousDisplay = nullptr;
     187           0 :     for (DisplayElement &displayElement : DisplayElement::getAll()) {
     188           0 :         DisplayInterface *thisDisplay = &displayElement.getDisplay();
     189           0 :         if (!thisDisplay->isEnabled())
     190           0 :             continue;
     191           0 :         if (thisDisplay != previousDisplay) {
     192           0 :             if (previousDisplay)
     193           0 :                 previousDisplay->display();
     194           0 :             previousDisplay = thisDisplay;
     195           0 :             thisDisplay->clearAndDrawBackground();
     196           0 :         }
     197           0 :         displayElement.draw();
     198           0 :     }
     199           0 :     if (previousDisplay)
     200           0 :         previousDisplay->display();
     201           0 : }
     202             : 
     203           1 : Control_Surface_ &Control_Surface = Control_Surface_::getInstance();
     204             : 
     205             : END_CS_NAMESPACE

Generated by: LCOV version 1.14-6-g40580cd