Control Surface  1.2.0
MIDI Control Surface library for Arduino
Control_Surface_Class.cpp
Go to the documentation of this file.
2 #include <AH/Debug/Debug.hpp>
12 #include <Selectors/Selector.hpp>
13 
14 #include <AH/Arduino-Wrapper.h>
15 
17 
19 
21  static Control_Surface_ instance;
22  return instance;
23 }
24 
26 #if defined(ARDUINO) && defined(DEBUG_OUT)
28  delay(250);
29 #endif
30 
32 
34  ExtendedIOElement::beginAll();
36  DisplayInterface::beginAll(); // initialize all displays
48 }
49 
51  if (hasSinkPipe() || hasSourcePipe())
52  return false;
53  auto def = MIDI_Interface::getDefault();
54  if (def == nullptr) {
55  FATAL_ERROR(F("No default MIDI Interface"), 0xF123);
56  return false;
57  }
58  *this << inpipe << *def;
59  *this >> outpipe >> *def;
60  return true;
61 }
62 
66 }
67 
69  ExtendedIOElement::updateAllBufferedInputs();
74  updateInputs();
75  if (displayTimer)
77  ExtendedIOElement::updateAllBufferedOutputs();
78 }
79 
82 }
83 
84 void Control_Surface_::sendImpl(uint8_t header, uint8_t d1, uint8_t d2,
85  uint8_t cn) {
86  this->sourceMIDItoPipe(ChannelMessage{header, d1, d2, cn});
87 }
88 void Control_Surface_::sendImpl(uint8_t header, uint8_t d1, uint8_t cn) {
89  this->sourceMIDItoPipe(ChannelMessage{header, d1, 0x00, cn});
90 }
91 void Control_Surface_::sendImpl(const uint8_t *data, size_t length,
92  uint8_t cn) {
93  this->sourceMIDItoPipe(SysExMessage{data, length, cn});
94 }
95 void Control_Surface_::sendImpl(uint8_t rt, uint8_t cn) {
96  this->sourceMIDItoPipe(RealTimeMessage{rt, cn});
97 }
98 
100  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.
114  return;
115 
116  if (midimsg.type == MIDIMessageType::CONTROL_CHANGE &&
118  // Reset All Controllers
119  DEBUG(F("Reset All Controllers"));
122  } else if (midimsg.type == MIDIMessageType::CONTROL_CHANGE &&
123  midimsg.data1 == MIDI_CC::All_Notes_Off) {
125  } else {
126  if (midimsg.type == MIDIMessageType::CONTROL_CHANGE) {
127  // Control Change
128  DEBUGFN(F("Updating CC elements with new MIDI message."));
130 
131  } else if (midimsg.type == MIDIMessageType::NOTE_OFF ||
132  midimsg.type == MIDIMessageType::NOTE_ON) {
133  // Note
134  DEBUGFN(F("Updating Note elements with new MIDI message."));
136 
137  } else if (midimsg.type == MIDIMessageType::CHANNEL_PRESSURE) {
138  // Channel Pressure
139  DEBUGFN(F("Updating Channel Pressure elements with new "
140  "MIDI message."));
142  } else if (midimsg.type == MIDIMessageType::PROGRAM_CHANGE) {
143  // Channel Pressure
144  DEBUGFN(F("Updating Program Change elements with new "
145  "MIDI message."));
147  }
148  }
149 }
150 
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.
165  return;
167 }
168 
170  // If the Real-Time Message callback exists, call it to see if we have to
171  // continue handling it.
173  return;
174  // TODO: handle Real-Time input
175 }
176 
183 }
184 
186  DisplayInterface *previousDisplay = nullptr;
187  for (DisplayElement &displayElement : DisplayElement::getAll()) {
188  DisplayInterface *thisDisplay = &displayElement.getDisplay();
189  if (!thisDisplay->isEnabled())
190  continue;
191  if (thisDisplay != previousDisplay) {
192  if (previousDisplay)
193  previousDisplay->display();
194  previousDisplay = thisDisplay;
195  thisDisplay->clearAndDrawBackground();
196  }
197  displayElement.draw();
198  }
199  if (previousDisplay)
200  previousDisplay->display();
201 }
202 
204 
ExtendedIOElement.hpp
MIDIInputElementPC::updateAllWith
static void updateAllWith(const ChannelMessageMatcher &midimsg)
Update all MIDIInputElementPC elements with a new MIDI message.
Definition: MIDIInputElementPC.hpp:75
ChannelMessageMatcher::data1
uint8_t data1
Definition: ChannelMessageMatcher.hpp:19
AH::Updatable
A super class for object that have to be updated regularly.
Definition: Updatable.hpp:195
DisplayInterface::display
virtual void display()=0
Write the frame buffer to the display.
DisplayElement
An interface for elements that draw to a display.
Definition: DisplayElement.hpp:11
MIDI_Interface::getDefault
static MIDI_Interface * getDefault()
Return the default MIDI interface.
Definition: MIDI_Interface.cpp:14
DisplayInterface::isEnabled
bool isEnabled()
Check if this display is enabled.
Definition: DisplayInterface.hpp:110
Control_Surface_::updateDisplays
void updateDisplays()
Clear, draw and display all displays.
Definition: Control_Surface_Class.cpp:185
MIDIInputElementCC::updateAllWith
static void updateAllWith(const ChannelMessageMatcher &midimsg)
Update all MIDIInputElementCC elements with a new MIDI message.
Definition: MIDIInputElementCC.hpp:76
SysExMessage
Definition: MIDI_MessageTypes.hpp:138
MIDIInputElementSysEx.hpp
SysExMessage::data
const uint8_t * data
Definition: MIDI_MessageTypes.hpp:156
MIDIInputElementNote::beginAll
static void beginAll()
Initialize all MIDIInputElementNote elements.
Definition: MIDIInputElementNote.hpp:49
DisplayInterface
An interface for displays.
Definition: DisplayInterface.hpp:14
ChannelMessageMatcher::data2
uint8_t data2
Definition: ChannelMessageMatcher.hpp:20
MIDIOutputElement.hpp
DisplayInterface::beginAll
static void beginAll()
Initialize all displays.
Definition: DisplayInterface.cpp:61
MIDIInputElementCC::resetAll
static void resetAll()
Reset all MIDIInputElementCC elements to their initial state.
Definition: MIDIInputElementCC.hpp:68
MIDI_Source::hasSinkPipe
bool hasSinkPipe() const
Check if this source is connected to a sink pipe.
Definition: MIDI_Pipes.hpp:189
AH::dec
Print & dec(Print &printer)
Definition: PrintStream.cpp:77
MIDIInputElementCC::updateAll
static void updateAll()
Update all MIDIInputElementCC elements.
Definition: MIDIInputElementCC.hpp:60
Control_Surface_::inpipe
MIDI_Pipe inpipe
Definition: Control_Surface_Class.hpp:167
MIDI_CC::All_Notes_Off
constexpr uint8_t All_Notes_Off
Definition: Control_Change.hpp:107
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:9
MIDIInputElementChannelPressure::updateAllWith
static void updateAllWith(const ChannelMessageMatcher &midimsg)
Update all MIDIInputElementChannelPressure elements with a new MIDI message.
Definition: MIDIInputElementChannelPressure.hpp:77
ChannelMessage::header
uint8_t header
MIDI status byte (message type and channel).
Definition: MIDI_MessageTypes.hpp:83
MIDIInputElementPC.hpp
ChannelMessageMatcher
Struct for easily matching MIDI messages.
Definition: ChannelMessageMatcher.hpp:10
AH::FilteredAnalog
A class that reads and filters an analog input.
Definition: FilteredAnalog.hpp:249
Control_Change.hpp
Control_Surface_::sysExMessageCallback
SysExMessageCallback sysExMessageCallback
Definition: Control_Surface_Class.hpp:165
Control_Surface_::outpipe
MIDI_Pipe outpipe
Definition: Control_Surface_Class.hpp:167
Control_Surface_::potentiometerTimer
Timer< micros > potentiometerTimer
A timer to know when to update the analog inputs.
Definition: Control_Surface_Class.hpp:130
MIDI_Source::disconnectSinkPipes
void disconnectSinkPipes()
Disconnect all sink pipes that this source sinks to (recursively).
Definition: MIDI_Pipes.cpp:79
Control_Surface_::disconnectMIDI_Interfaces
void disconnectMIDI_Interfaces()
Disconnect Control Surface from the MIDI interfaces it's connected to.
Definition: Control_Surface_Class.cpp:63
AH::ExtendedIOElement
An abstract base class for Extended Input/Output elements.
Definition: ExtendedIOElement.hpp:63
MIDI_Sink::hasSourcePipe
bool hasSourcePipe() const
Check if this sink is connected to a source pipe.
Definition: MIDI_Pipes.hpp:94
FATAL_ERROR
#define FATAL_ERROR(msg, errc)
Print the error message and error code, and stop the execution.
Definition: Error.hpp:60
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:10
AH::Timer::begin
void begin()
Initialize or reset the timer. The timer will fire immediately.
Definition: MillisMicrosTimer.hpp:41
Control_Surface_::updateMidiInput
void updateMidiInput()
Update all MIDI interfaces to receive new MIDI events.
Definition: Control_Surface_Class.cpp:80
AH::defaultBaudRate
constexpr unsigned long defaultBaudRate
The default baud rate for debug output.
Definition: AH/Settings/Settings.hpp:36
Control_Surface_Class.hpp
Control_Surface_::loop
void loop()
Update all MIDI elements, send MIDI events and read MIDI input.
Definition: Control_Surface_Class.cpp:68
Control_Surface_::getInstance
static Control_Surface_ & getInstance()
Return the static Control_Surface_ instance.
Definition: Control_Surface_Class.cpp:20
MIDIInputElementNote::resetAll
static void resetAll()
Reset all MIDIInputElementNote elements to their initial state.
Definition: MIDIInputElementNote.hpp:71
MIDIInputElementNote.hpp
Control_Surface_::sendImpl
void sendImpl(uint8_t header, uint8_t d1, uint8_t d2, uint8_t cn)
Low-level function for sending a 3-byte MIDI message.
Definition: Control_Surface_Class.cpp:84
Control_Surface
Control_Surface_ & Control_Surface
A predefined instance of the Control Surface to use in the Arduino sketches.
Definition: Control_Surface_Class.cpp:203
Arduino-Wrapper.h
MIDI_Source::sourceMIDItoPipe
void sourceMIDItoPipe(ChannelMessage)
Send a MIDI Channel Message.
Definition: MIDI_Pipes.cpp:132
RealTimeMessage
Definition: MIDI_MessageTypes.hpp:173
MIDI_Sink::disconnectSourcePipes
void disconnectSourcePipes()
Disconnect all source pipes that sink to this sink (recursively).
Definition: MIDI_Pipes.cpp:24
Control_Surface_::displayTimer
Timer< micros > displayTimer
A timer to know when to refresh the displays.
Definition: Control_Surface_Class.hpp:132
MIDIInputElementCC.hpp
MIDIInputElementNote::updateAllWith
static void updateAllWith(const ChannelMessageMatcher &midimsg)
Update all MIDIInputElementNote elements with a new MIDI message.
Definition: MIDIInputElementNote.hpp:84
AH::hex
Print & hex(Print &printer)
Definition: PrintStream.cpp:62
MIDIInputElementCC::beginAll
static void beginAll()
Initialize all MIDIInputElementCC elements.
Definition: MIDIInputElementCC.hpp:52
DEBUG_OUT
#define DEBUG_OUT
The debug output.
Definition: AH/Settings/Settings.hpp:26
MIDIInputElementPC::updateAll
static void updateAll()
Update all MIDIInputElementPC elements.
Definition: MIDIInputElementPC.hpp:63
Selector.hpp
Control_Surface_::connectDefaultMIDI_Interface
bool connectDefaultMIDI_Interface()
Connect Control Surface to the default MIDI interface.
Definition: Control_Surface_Class.cpp:50
Control_Surface_::sinkMIDIfromPipe
void sinkMIDIfromPipe(ChannelMessage msg) override
Accept an incoming MIDI Channel message.
Definition: Control_Surface_Class.cpp:99
MIDIInputElementSysEx::updateAll
static void updateAll()
Update all MIDIInputElementSysEx elements.
Definition: MIDIInputElementSysEx.hpp:67
MIDI_Notes::F
constexpr int8_t F
Definition: Notes.hpp:23
DEBUGFN
#define DEBUGFN(x)
Print an expression and its function (function name and line number) to the debug output if debugging...
Definition: Debug.hpp:93
DisplayInterface::clearAndDrawBackground
void clearAndDrawBackground()
Clear the frame buffer, and draw the custom background.
Definition: DisplayInterface.hpp:117
DisplayElement::getAll
static DoublyLinkedList< DisplayElement > & getAll()
Get the list of all DisplayElement instances.
Definition: DisplayElement.hpp:41
MIDIInputElementSysEx::updateAllWith
static void updateAllWith(SysExMessage midimsg)
Update all MIDIInputElementSysEx elements with a new MIDI message.
Definition: MIDIInputElementSysEx.hpp:90
MIDIInputElementChannelPressure::resetAll
static void resetAll()
Reset all MIDIInputElementChannelPressure elements to their initial state.
Definition: MIDIInputElementChannelPressure.hpp:56
ChannelMessage
Definition: MIDI_MessageTypes.hpp:72
Debug.hpp
Control_Surface_::updateInputs
void updateInputs()
Update all MIDIInputElements.
Definition: Control_Surface_Class.cpp:177
MIDIInputElementSysEx::beginAll
static void beginAll()
Initialize all MIDIInputElementSysEx elements.
Definition: MIDIInputElementSysEx.hpp:56
MIDIInputElementPC::beginAll
static void beginAll()
Definition: MIDIInputElementPC.hpp:42
Control_Surface_::realTimeMessageCallback
RealTimeMessageCallback realTimeMessageCallback
Definition: Control_Surface_Class.hpp:166
MIDIInputElementChannelPressure::beginAll
static void beginAll()
Definition: MIDIInputElementChannelPressure.hpp:44
MIDIInputElementNote::updateAll
static void updateAll()
Update all MIDIInputElementNote elements.
Definition: MIDIInputElementNote.hpp:60
SysExMessage::length
uint8_t length
Definition: MIDI_MessageTypes.hpp:157
MIDIInputElementChannelPressure::updateAll
static void updateAll()
Update all MIDIInputElementChannelPressure elements.
Definition: MIDIInputElementChannelPressure.hpp:65
DEBUG
#define DEBUG(x)
Print an expression to the debug output if debugging is enabled.
Definition: Debug.hpp:75
FilteredAnalog.hpp
Control_Surface_
This class ensures initialization, updating, and interaction between all other classes,...
Definition: Control_Surface_Class.hpp:27
AH::endl
Print & endl(Print &printer)
Definition: PrintStream.cpp:27
Control_Surface_::channelMessageCallback
ChannelMessageCallback channelMessageCallback
Definition: Control_Surface_Class.hpp:164
MIDIInputElementChannelPressure.hpp
Control_Surface_::begin
void begin()
Initialize the Control_Surface.
Definition: Control_Surface_Class.cpp:25
MIDI_CC::Reset_All_Controllers
constexpr uint8_t Reset_All_Controllers
Definition: Control_Change.hpp:105
ChannelMessageMatcher::type
MIDIMessageType type
Definition: ChannelMessageMatcher.hpp:17