Control Surface
main
MIDI Control Surface library for Arduino
Toggle main menu visibility
Loading...
Searching...
No Matches
src
MIDI_Inputs
MCU
LCD.hpp
Go to the documentation of this file.
1
#pragma once
2
3
#include <
AH/Debug/Debug.hpp
>
4
#include <
AH/Math/MinMaxFix.hpp
>
5
#include <
MIDI_Inputs/MIDIInputElement.hpp
>
6
#include <string.h>
// memcpy
7
8
#ifndef ARDUINO
9
#include <cassert>
10
#endif
11
12
BEGIN_CS_NAMESPACE
13
14
using
AH::max
;
15
using
AH::min
;
16
17
namespace
MCU
{
18
22
class
LCDCounter
{
23
public
:
24
LCDCounter
() {
instances
++; }
25
~LCDCounter
() {
instances
--; }
26
27
static
uint8_t
getInstances
() {
return
instances
; }
28
29
private
:
30
static
uint8_t
instances
;
31
};
32
50
template
<u
int
8_t BufferSize = 112>
51
class
LCD
:
public
MIDIInputElementSysEx
,
private
LCDCounter
{
52
public
:
62
LCD
(uint8_t
offset
= 0,
Cable
cable
=
Cable_1
)
63
:
offset
(
offset
),
cable
(
cable
) {
64
// Null-terminate the buffer
65
buffer
[BufferSize] =
'\0'
;
66
// Fill the buffer with spaces
67
for
(uint8_t i = 0; i < BufferSize; i++)
buffer
[i] =
' '
;
68
}
69
70
protected
:
71
bool
updateWith
(
SysExMessage
midimsg)
override
{
72
// If this message is meant for a different cable than ours, return:
73
if
(midimsg.
getCable
() != this->cable)
74
return
false
;
75
76
// We can't handle chunked SysEx data (yet), and it wouldn't make a ton
77
// of sense, since the default SysEx buffer size is the same size as the
78
// SysEx message we expect, so it shouldn't arrive in chunks.
79
if
(!midimsg.
isCompleteMessage
())
80
return
false
;
81
82
// Format:
83
// F0 mm mm mm nn 12 oo yy... F7
84
// mm = manufacturer ID (00 00 66 for Mackie)
85
// nn = model number (10 for Logic Control, 11 for Logic Control XT)
86
// oo = offset [0x00, 0x6F]
87
// yy... = ASCII data
88
if
(midimsg.
data
[5] != 0x12)
89
return
false
;
90
91
const
uint8_t midiOffset = midimsg.
data
[6];
92
const
uint8_t midiLength = midimsg.
length
- 8;
93
const
uint8_t *text = midimsg.
data
+ 7;
94
const
uint8_t midiBufferEnd = midiOffset + midiLength;
95
96
const
uint8_t bufferEnd = this->
offset
+ BufferSize;
97
98
// If there's no overlap between incoming range and the range that we're
99
// listening for, return:
100
if
(midiOffset >= bufferEnd || this->
offset
>= midiBufferEnd)
101
// If there are other instances, maybe it'll match one of those,
102
// otherwise, stop handling this message:
103
return
getInstances
() == 1;
104
105
// Find the ranges that overlap between the text data in the message
106
// (src) and the range of characters we're listening for (dst):
107
uint8_t srcStart =
max
(0, this->
offset
- midiOffset);
108
uint8_t dstStart =
max
(0, midiOffset - this->
offset
);
109
uint8_t length = midiBufferEnd - midiOffset -
110
max
(0, this->
offset
- midiOffset) -
111
max
(0, midiBufferEnd - bufferEnd);
112
113
// Copy the interesting part to our buffer:
114
#ifdef ARDUINO
115
memcpy(&
buffer
[dstStart], &text[srcStart], length);
116
#else
// Tests
117
for
(uint8_t i = 0; i < length; ++i) {
118
buffer
[dstStart + i] = text[srcStart + i];
119
assert(dstStart + i < BufferSize);
120
assert(srcStart + i < midiLength);
121
}
122
#endif
123
124
markDirty
();
125
126
// If this is the only instance, the others don't have to be updated
127
// anymore, so we return true to break the loop:
128
return
getInstances
() == 1;
129
}
130
131
public
:
132
void
begin
()
override
{
markDirty
(); }
133
136
138
const
char
*
getText
()
const
{
return
buffer
.data; }
139
141
144
148
bool
getDirty
()
const
{
return
dirty
> 0; }
150
void
clearDirty
() {
151
if
(
dirty
> 0)
152
--
dirty
;
153
}
154
155
void
markDirty
() {
dirty
=
num_subscribers
> 0 ?
num_subscribers
: 1; }
156
void
addSubscriber
() { ++
num_subscribers
; }
157
void
removeSubscriber
() { --
num_subscribers
; }
158
160
161
private
:
162
Array<char, BufferSize + 1>
buffer
;
163
uint8_t
offset
;
164
Cable
cable
;
165
uint8_t
dirty
= 0;
166
uint8_t
num_subscribers
= 0;
167
};
168
169
}
// namespace MCU
170
171
END_CS_NAMESPACE
Cable_1
constexpr Cable Cable_1
Definition
Cable.hpp:118
Debug.hpp
MIDIInputElement.hpp
MIDIInputElementSysEx
MIDIInputElement< MIDIMessageType::SysExStart > MIDIInputElementSysEx
MIDI Input Element that listens for MIDI System Exclusive messages.
Definition
MIDIInputElement.hpp:150
MinMaxFix.hpp
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition
Settings/NamespaceSettings.hpp:14
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition
Settings/NamespaceSettings.hpp:11
Cable
A type-safe class for MIDI USB Cable numbers.
Definition
Cable.hpp:13
MCU::LCDCounter::getInstances
static uint8_t getInstances()
Definition
LCD.hpp:27
MCU::LCDCounter::LCDCounter
LCDCounter()
Definition
LCD.hpp:24
MCU::LCDCounter::instances
static uint8_t instances
Definition
LCD.hpp:30
MCU::LCDCounter::~LCDCounter
~LCDCounter()
Definition
LCD.hpp:25
MCU::LCD::getText
const char * getText() const
Get a pointer to the null-terminated display text.
Definition
LCD.hpp:138
MCU::LCD::markDirty
void markDirty()
Set the dirty counter to the number of subscribers (or one).
Definition
LCD.hpp:155
MCU::LCD::removeSubscriber
void removeSubscriber()
Definition
LCD.hpp:157
MCU::LCD::addSubscriber
void addSubscriber()
Definition
LCD.hpp:156
MCU::LCD::getDirty
bool getDirty() const
Check if the text was updated since the last time the dirty flag was cleared.
Definition
LCD.hpp:148
MCU::LCD::begin
void begin() override
Initialize the input element.
Definition
LCD.hpp:132
MCU::LCD::LCD
LCD(uint8_t offset=0, Cable cable=Cable_1)
Definition
LCD.hpp:62
MCU::LCD::cable
Cable cable
Definition
LCD.hpp:164
MCU::LCD::offset
uint8_t offset
Definition
LCD.hpp:163
MCU::LCD::num_subscribers
uint8_t num_subscribers
Definition
LCD.hpp:166
MCU::LCD::buffer
Array< char, BufferSize+1 > buffer
Definition
LCD.hpp:162
MCU::LCD::dirty
uint8_t dirty
Definition
LCD.hpp:165
MCU::LCD::updateWith
bool updateWith(SysExMessage midimsg) override
Definition
LCD.hpp:71
MCU::LCD::clearDirty
void clearDirty()
Clear the dirty flag.
Definition
LCD.hpp:150
AH::min
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
AH::max
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
MCU
Definition
LCDDisplay.hpp:10
AH::Array
An array wrapper for easy copying, comparing, and iterating.
Definition
Array.hpp:32
SysExMessage
Definition
MIDI_MessageTypes.hpp:305
SysExMessage::length
uint16_t length
Definition
MIDI_MessageTypes.hpp:323
SysExMessage::data
const uint8_t * data
Definition
MIDI_MessageTypes.hpp:322
SysExMessage::getCable
Cable getCable() const
Get the MIDI USB cable number of the message.
Definition
MIDI_MessageTypes.hpp:335
SysExMessage::isCompleteMessage
bool isCompleteMessage() const
Definition
MIDI_MessageTypes.hpp:348
Generated by
1.17.0