Control Surface main
MIDI Control Surface library for Arduino
Loading...
Searching...
No Matches
LCD.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <AH/Debug/Debug.hpp>
6#include <string.h> // memcpy
7
8#ifndef ARDUINO
9#include <cassert>
10#endif
11
13
14using AH::max;
15using AH::min;
16
17namespace MCU {
18
23 public:
26
27 static uint8_t getInstances() { return instances; }
28
29 private:
31};
50template <uint8_t BufferSize = 112>
51class LCD : public MIDIInputElementSysEx, private LCDCounter {
52 public:
64 // Null-terminate the buffer
65 buffer[BufferSize] = '\0';
66 // Fill the buffer with spaces
67 for (uint8_t i = 0; i < BufferSize; i++)
68 buffer[i] = ' ';
69 }
70
71 protected:
72 bool updateWith(SysExMessage midimsg) override {
73 // If this message is meant for a different cable than ours, return:
74 if (midimsg.getCable() != this->cable)
75 return false;
76
77 // We can't handle chunked SysEx data (yet), and it wouldn't make a ton
78 // of sense, since the default SysEx buffer size is the same size as the
79 // SysEx message we expect, so it shouldn't arrive in chunks.
80 if (!midimsg.isCompleteMessage())
81 return false;
82
83 // Format:
84 // F0 mm mm mm nn 12 oo yy... F7
85 // mm = manufacturer ID (00 00 66 for Mackie)
86 // nn = model number (10 for Logic Control, 11 for Logic Control XT)
87 // oo = offset [0x00, 0x6F]
88 // yy... = ASCII data
89 if (midimsg.data[5] != 0x12)
90 return false;
91
92 const uint8_t midiOffset = midimsg.data[6];
93 const uint8_t midiLength = midimsg.length - 8;
94 const uint8_t *text = midimsg.data + 7;
96
97 const uint8_t bufferEnd = this->offset + BufferSize;
98
99 // If there's no overlap between incoming range and the range that we're
100 // listening for, return:
101 if (midiOffset >= bufferEnd || this->offset >= midiBufferEnd)
102 // If there are other instances, maybe it'll match one of those,
103 // otherwise, stop handling this message:
104 return getInstances() == 1;
105
106 // Find the ranges that overlap between the text data in the message
107 // (src) and the range of characters we're listening for (dst):
108 uint8_t srcStart = max(0, this->offset - midiOffset);
109 uint8_t dstStart = max(0, midiOffset - this->offset);
110 uint8_t length = midiBufferEnd - midiOffset -
111 max(0, this->offset - midiOffset) -
112 max(0, midiBufferEnd - bufferEnd);
113
114 // Copy the interesting part to our buffer:
115#ifdef ARDUINO
116 memcpy(&buffer[dstStart], &text[srcStart], length);
117#else // Tests
118 for (uint8_t i = 0; i < length; ++i) {
119 buffer[dstStart + i] = text[srcStart + i];
122 }
123#endif
124
125 dirty = true;
126
127 // If this is the only instance, the others don't have to be updated
128 // anymore, so we return true to break the loop:
129 return getInstances() == 1;
130 }
131
132 public:
135
137 const char *getText() const { return buffer.data; }
138
140
143
146 bool getDirty() const { return dirty; }
148 void clearDirty() { dirty = false; }
149
151
152 private:
156 bool dirty = true;
157};
158
159} // namespace MCU
160
constexpr Cable Cable_1
Definition Cable.hpp:118
#define END_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
A type-safe class for MIDI USB Cable numbers.
Definition Cable.hpp:13
Counts the number of instances of the LCD class.
Definition LCD.hpp:22
static uint8_t getInstances()
Definition LCD.hpp:27
static uint8_t instances
Definition LCD.hpp:30
A class that represents the Mackie Control Universal LCD display and saves the text it receives.
Definition LCD.hpp:51
const char * getText() const
Get a pointer to the null-terminated display text.
Definition LCD.hpp:137
bool getDirty() const
Check if the text was updated since the last time the dirty flag was cleared.
Definition LCD.hpp:146
LCD(uint8_t offset=0, Cable cable=Cable_1)
Definition LCD.hpp:62
Cable cable
Definition LCD.hpp:155
uint8_t offset
Definition LCD.hpp:154
Array< char, BufferSize+1 > buffer
Definition LCD.hpp:153
bool dirty
Definition LCD.hpp:156
bool updateWith(SysExMessage midimsg) override
Definition LCD.hpp:72
void clearDirty()
Clear the dirty flag.
Definition LCD.hpp:148
A class for objects that listen for incoming MIDI events.
constexpr auto min(const T &a, const U &b) -> decltype(b< a ? b :a)
Return the smaller of two numbers/objects.
Definition MinMaxFix.hpp:12
constexpr auto max(const T &a, const U &b) -> decltype(a< b ? b :a)
Return the larger of two numbers/objects.
Definition MinMaxFix.hpp:19
An array wrapper for easy copying, comparing, and iterating.
Definition Array.hpp:32
T data[N]
Definition Array.hpp:33
const uint8_t * data
Cable getCable() const
Get the MIDI USB cable number of the message.
bool isCompleteMessage() const