Line data Source code
1 : #pragma once
2 :
3 : #include <AH/Settings/Warnings.hpp>
4 : AH_DIAGNOSTIC_WERROR()
5 :
6 : #include <AH/Hardware/ExtendedInputOutput/ExtendedInputOutput.hpp>
7 : #include <AH/Math/IncreaseBitDepth.hpp>
8 : #include <MIDI_Inputs/NoteCCRange.hpp>
9 :
10 : BEGIN_CS_NAMESPACE
11 :
12 : /// Callback for Note or CC range or value input that displays the value to a
13 : /// normal on/off LED.
14 : template <uint8_t NumLEDs>
15 1 : class NoteCCLED : public SimpleNoteCCValueCallback {
16 : public:
17 1 : NoteCCLED(const PinList<NumLEDs> &ledPins) : ledPins(ledPins) {}
18 :
19 : void setThreshold(uint8_t threshold) { this->threshold = threshold; }
20 : uint8_t getThreshold() const { return this->threshold; }
21 :
22 1 : void begin(const INoteCCValue &t) override {
23 2 : for (pin_t pin : ledPins)
24 1 : AH::ExtIO::pinMode(pin, OUTPUT);
25 1 : updateAll(t);
26 1 : }
27 :
28 3 : void update(const INoteCCValue &t, uint8_t index) override {
29 3 : uint8_t value = t.getValue(index);
30 3 : bool state = value > threshold;
31 3 : AH::ExtIO::digitalWrite(ledPins[index], state ? HIGH : LOW);
32 3 : }
33 :
34 : private:
35 : PinList<NumLEDs> ledPins;
36 1 : uint8_t threshold = 0x00;
37 : };
38 :
39 : /// Callback for Note or CC range or value input that displays the value to a
40 : /// PWM LED.
41 : template <uint8_t NumLEDs>
42 1 : class NoteCCLEDPWM : public SimpleNoteCCValueCallback {
43 : public:
44 1 : NoteCCLEDPWM(const PinList<NumLEDs> &ledPins) : ledPins(ledPins) {}
45 :
46 1 : void begin(const INoteCCValue &t) override {
47 2 : for (pin_t pin : ledPins)
48 1 : AH::ExtIO::pinMode(pin, OUTPUT);
49 1 : updateAll(t);
50 1 : }
51 :
52 4 : void update(const INoteCCValue &t, uint8_t index) override {
53 4 : uint8_t value = AH::increaseBitDepth<8, 7, uint8_t>(t.getValue(index));
54 4 : AH::ExtIO::analogWrite(ledPins[index], value);
55 4 : }
56 :
57 : private:
58 : PinList<NumLEDs> ledPins;
59 : };
60 :
61 : // :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //
62 : // Everything below is just definitions of type aliases to make the library
63 : // easier to use.
64 : //
65 : // It defines MIDI elements that listen to (a single, a range of)
66 : // (MIDI Note, MIDI Control Change) message(s) that display the values of
67 : // these messages using normal on/off or PWM LEDs.
68 : // :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //
69 :
70 : // --------------------------------- ON/OFF --------------------------------- //
71 :
72 : /// @addtogroup midi-input-elements-leds
73 : /// @{
74 :
75 : /**
76 : * @brief MIDI Input Element that listens for MIDI Note messages in a given
77 : * range, and displays their values by turning on/off LEDs depending on
78 : * whether the MIDI note velocity is above or below a certain
79 : * threshold.
80 : *
81 : * @tparam RangeLen
82 : * The length of the range of MIDI note numbers to listen for.
83 : */
84 : template <uint8_t RangeLen>
85 : class NoteRangeLEDs : public GenericNoteCCRange<MIDIInputElementNote, RangeLen,
86 : NoteCCLED<RangeLen>> {
87 : public:
88 : /**
89 : * @brief Construct a new NoteRangeLEDs object.
90 : *
91 : * @param ledPins
92 : * A list of pin numbers with the LEDs connected.
93 : * @param address
94 : * The first address in the range. The entire range is defined by
95 : * this address and the `RangeLen` template parameter.
96 : * For example, if `address = 10` and `RangeLen = 4`, the this
97 : * object will listen to addresses 10, 11, 12, 13.
98 : */
99 : NoteRangeLEDs(const PinList<RangeLen> &ledPins, MIDIAddress address)
100 : : GenericNoteCCRange<MIDIInputElementNote, RangeLen,
101 : NoteCCLED<RangeLen>>{
102 : address,
103 : {ledPins},
104 : } {}
105 : };
106 :
107 : /**
108 : * @brief MIDI Input Element that listens for MIDI Note messages for the given
109 : * note, and displays its value by turning on/off an LED depending on
110 : * whether the MIDI note velocity is above or below a certain
111 : * threshold.
112 : */
113 1 : class NoteValueLED
114 : : public GenericNoteCCRange<MIDIInputElementNote, 1, NoteCCLED<1>> {
115 : public:
116 : /**
117 : * @brief Construct a new NoteValueLED object.
118 : *
119 : * @param ledPin
120 : * The pin number with the LED connected.
121 : * @param address
122 : * The MIDI address to listen to.
123 : */
124 1 : NoteValueLED(pin_t ledPin, MIDIAddress address)
125 1 : : GenericNoteCCRange<MIDIInputElementNote, 1, NoteCCLED<1>>{
126 1 : address,
127 1 : {{ledPin}},
128 2 : } {}
129 : };
130 :
131 : /// Deprecated.
132 : /// @see NoteValueLED
133 : using MIDINoteLED [[deprecated("Use NoteValueLED instead")]] = NoteValueLED;
134 :
135 : /**
136 : * @brief MIDI Input Element that listens for MIDI Control Change messages in
137 : * a given range, and displays their values by turning on/off LEDs
138 : * depending on whether the controller value is above or below a
139 : * certain threshold.
140 : *
141 : * @tparam RangeLen
142 : * The length of the range of MIDI controllers to listen for.
143 : */
144 : template <uint8_t RangeLen>
145 : class CCRangeLEDs : public GenericNoteCCRange<MIDIInputElementCC, RangeLen,
146 : NoteCCLED<RangeLen>> {
147 : public:
148 : /**
149 : * @brief Construct a new CCRangeLEDs object.
150 : *
151 : * @param ledPins
152 : * A list of pin numbers with the LEDs connected.
153 : * @param address
154 : * The first address in the range. The entire range is defined by
155 : * this address and the `RangeLen` template parameter.
156 : * For example, if `address = 10` and `RangeLen = 4`, the this
157 : * object will listen to addresses 10, 11, 12, 13.
158 : */
159 : CCRangeLEDs(const PinList<RangeLen> &ledPins, MIDIAddress address)
160 : : GenericNoteCCRange<MIDIInputElementCC, RangeLen, NoteCCLED<RangeLen>>{
161 : address,
162 : {ledPins},
163 : } {}
164 : };
165 :
166 : /**
167 : * @brief MIDI Input Element that listens for MIDI Control Change messages for
168 : * the given controller, and displays its value by turning on/off an
169 : * LED depending on whether the MIDI controller value is above or below
170 : * a certain threshold.
171 : */
172 : class CCValueLED
173 : : public GenericNoteCCRange<MIDIInputElementCC, 1, NoteCCLED<1>> {
174 : public:
175 : /**
176 : * @brief Construct a new CCValueLED object.
177 : *
178 : * @param ledPin
179 : * The pin number with the LED connected.
180 : * @param address
181 : * The MIDI address to listen to.
182 : */
183 : CCValueLED(pin_t ledPin, MIDIAddress address)
184 : : GenericNoteCCRange<MIDIInputElementCC, 1, NoteCCLED<1>>{
185 : address,
186 : {{ledPin}},
187 : } {}
188 : };
189 :
190 : /// @}
191 :
192 : namespace Bankable {
193 :
194 : /// @addtogroup midi-input-elements-leds
195 : /// @{
196 :
197 : template <uint8_t RangeLen, uint8_t BankSize>
198 : class NoteRangeLEDs : public GenericNoteCCRange<MIDIInputElementNote, RangeLen,
199 : BankSize, NoteCCLED<RangeLen>> {
200 : public:
201 : NoteRangeLEDs(BankConfig<BankSize> config, const PinList<RangeLen> &ledPins,
202 : MIDIAddress address)
203 : : GenericNoteCCRange<MIDIInputElementNote, RangeLen, BankSize,
204 : NoteCCLED<RangeLen>>{
205 : config,
206 : address,
207 : {ledPins},
208 : } {}
209 : };
210 :
211 : template <uint8_t BankSize>
212 : class NoteValueLED : public GenericNoteCCRange<MIDIInputElementNote, 1,
213 : BankSize, NoteCCLED<1>> {
214 : public:
215 : NoteValueLED(BankConfig<BankSize> config, pin_t ledPin, MIDIAddress address)
216 : : GenericNoteCCRange<MIDIInputElementNote, 1, BankSize, NoteCCLED<1>>{
217 : config,
218 : address,
219 : {{ledPin}},
220 : } {}
221 : };
222 :
223 : /// Deprecated.
224 : /// @see Bankable::NoteValueLED
225 : template <uint8_t BankSize>
226 : using MIDINoteLED [[deprecated("Use NoteValueLED instead")]] =
227 : NoteValueLED<BankSize>;
228 :
229 : template <uint8_t RangeLen, uint8_t BankSize>
230 : class CCRangeLEDs : public GenericNoteCCRange<MIDIInputElementCC, RangeLen,
231 : BankSize, NoteCCLED<RangeLen>> {
232 : public:
233 : CCRangeLEDs(BankConfig<BankSize> config, const PinList<RangeLen> &ledPins,
234 : const MIDIAddress &address)
235 : : GenericNoteCCRange<MIDIInputElementCC, RangeLen, BankSize,
236 : NoteCCLED<RangeLen>>{
237 : config,
238 : address,
239 : {ledPins},
240 : } {}
241 : };
242 :
243 : template <uint8_t BankSize>
244 : class CCValueLED
245 : : public GenericNoteCCRange<MIDIInputElementCC, 1, BankSize, NoteCCLED<1>> {
246 : public:
247 : CCValueLED(BankConfig<BankSize> config, pin_t ledPin,
248 : const MIDIAddress &address)
249 : : GenericNoteCCRange<MIDIInputElementCC, 1, BankSize, NoteCCLED<1>>{
250 : config,
251 : address,
252 : {{ledPin}},
253 : } {}
254 : };
255 :
256 : /// @}
257 :
258 : } // namespace Bankable
259 :
260 : // ----------------------------------- PWM ---------------------------------- //
261 :
262 : /// @addtogroup midi-input-elements-leds
263 : /// @{
264 :
265 : /**
266 : * @brief MIDI Input Element that listens for MIDI Note messages in a given
267 : * range, and displays their velocity values by changing the brightness
268 : * of LEDs using PWM (`analogWrite`).
269 : *
270 : * @tparam RangeLen
271 : * The length of the range of MIDI note numbers to listen for.
272 : */
273 : template <uint8_t RangeLen>
274 : class NoteRangeLEDsPWM
275 : : public GenericNoteCCRange<MIDIInputElementNote, RangeLen,
276 : NoteCCLEDPWM<RangeLen>> {
277 : public:
278 : /**
279 : * @brief Construct a new NoteRangeLEDsPWM object.
280 : *
281 : * @param ledPins
282 : * A list of pin numbers with the LEDs connected.
283 : * @param address
284 : * The first address in the range. The entire range is defined by
285 : * this address and the `RangeLen` template parameter.
286 : * For example, if `address = 10` and `RangeLen = 4`, the this
287 : * object will listen to addresses 10, 11, 12, 13.
288 : */
289 : NoteRangeLEDsPWM(const PinList<RangeLen> &ledPins, MIDIAddress address)
290 : : GenericNoteCCRange<MIDIInputElementNote, RangeLen,
291 : NoteCCLEDPWM<RangeLen>>{
292 : address,
293 : {ledPins},
294 : } {}
295 : };
296 :
297 : /**
298 : * @brief MIDI Input Element that listens for MIDI Note messages for the given
299 : * note, and displays its velocity value by changing the brightness
300 : * of an LED using PWM (`analogWrite`).
301 : */
302 1 : class NoteValueLEDPWM
303 : : public GenericNoteCCRange<MIDIInputElementNote, 1, NoteCCLEDPWM<1>> {
304 : public:
305 : /**
306 : * @brief Construct a new NoteValueLEDPWM object.
307 : *
308 : * @param ledPin
309 : * The pin number with the LED connected.
310 : * @param address
311 : * The MIDI address to listen to.
312 : */
313 1 : NoteValueLEDPWM(pin_t ledPin, MIDIAddress address)
314 1 : : GenericNoteCCRange<MIDIInputElementNote, 1, NoteCCLEDPWM<1>>{
315 1 : address,
316 1 : {{ledPin}},
317 2 : } {}
318 : };
319 :
320 : /**
321 : * @brief MIDI Input Element that listens for MIDI Control Change messages in
322 : * a given range, and displays their values by changing the brightness
323 : * of LEDs using PWM (`analogWrite`).
324 : *
325 : * @tparam RangeLen
326 : * The length of the range of MIDI controllers to listen for.
327 : */
328 : template <uint8_t RangeLen>
329 : class CCRangeLEDsPWM : public GenericNoteCCRange<MIDIInputElementCC, RangeLen,
330 : NoteCCLEDPWM<RangeLen>> {
331 : public:
332 : /**
333 : * @brief Construct a new CCRangeLEDsPWM object.
334 : *
335 : * @param ledPins
336 : * A list of pin numbers with the LEDs connected.
337 : * @param address
338 : * The first address in the range. The entire range is defined by
339 : * this address and the `RangeLen` template parameter.
340 : * For example, if `address = 10` and `RangeLen = 4`, the this
341 : * object will listen to addresses 10, 11, 12, 13.
342 : */
343 : CCRangeLEDsPWM(const PinList<RangeLen> &ledPins, MIDIAddress address)
344 : : GenericNoteCCRange<MIDIInputElementCC, RangeLen,
345 : NoteCCLEDPWM<RangeLen>>{
346 : address,
347 : {ledPins},
348 : } {}
349 : };
350 :
351 : /**
352 : * @brief MIDI Input Element that listens for MIDI Control Change messages for
353 : * the given controller, and displays its value by changing the
354 : * brightness of an LED using PWM (`analogWrite`).
355 : */
356 : class CCValueLEDPWM
357 : : public GenericNoteCCRange<MIDIInputElementCC, 1, NoteCCLEDPWM<1>> {
358 : public:
359 : /**
360 : * @brief Construct a new CCValueLEDPWM object.
361 : *
362 : * @param ledPin
363 : * The pin number with the LED connected.
364 : * @param address
365 : * The MIDI address to listen to.
366 : */
367 : CCValueLEDPWM(pin_t ledPin, MIDIAddress address)
368 : : GenericNoteCCRange<MIDIInputElementCC, 1, NoteCCLEDPWM<1>>{
369 : address,
370 : {{ledPin}},
371 : } {}
372 : };
373 :
374 : /// @}
375 :
376 : namespace Bankable {
377 :
378 : /// @addtogroup midi-input-elements-leds
379 : /// @{
380 :
381 : template <uint8_t RangeLen, uint8_t BankSize>
382 : class NoteRangeLEDsPWM
383 : : public GenericNoteCCRange<MIDIInputElementNote, RangeLen, BankSize,
384 : NoteCCLEDPWM<RangeLen>> {
385 : public:
386 : NoteRangeLEDsPWM(BankConfig<BankSize> config,
387 : const PinList<RangeLen> &ledPins,
388 : const MIDIAddress &address)
389 : : GenericNoteCCRange<MIDIInputElementNote, RangeLen, BankSize,
390 : NoteCCLEDPWM<RangeLen>>{
391 : config,
392 : address,
393 : {ledPins},
394 : } {}
395 : };
396 :
397 : template <uint8_t BankSize>
398 : class NoteValueLEDPWM : public GenericNoteCCRange<MIDIInputElementNote, 1,
399 : BankSize, NoteCCLEDPWM<1>> {
400 : public:
401 : NoteValueLEDPWM(BankConfig<BankSize> config, pin_t ledPin,
402 : const MIDIAddress &address)
403 : : GenericNoteCCRange<MIDIInputElementNote, 1, BankSize,
404 : NoteCCLEDPWM<1>>{
405 : config,
406 : address,
407 : {{ledPin}},
408 : } {}
409 : };
410 :
411 : template <uint8_t RangeLen, uint8_t BankSize>
412 : class CCRangeLEDsPWM
413 : : public GenericNoteCCRange<MIDIInputElementCC, RangeLen, BankSize,
414 : NoteCCLEDPWM<RangeLen>> {
415 : public:
416 : CCRangeLEDsPWM(BankConfig<BankSize> config,
417 : const PinList<RangeLen> &ledPins, const MIDIAddress &address)
418 : : GenericNoteCCRange<MIDIInputElementCC, RangeLen, BankSize,
419 : NoteCCLEDPWM<RangeLen>>{
420 : config,
421 : address,
422 : {ledPins},
423 : } {}
424 : };
425 :
426 : template <uint8_t BankSize>
427 : class CCValueLEDPWM : public GenericNoteCCRange<MIDIInputElementCC, 1, BankSize,
428 : NoteCCLEDPWM<1>> {
429 : public:
430 : CCValueLEDPWM(BankConfig<BankSize> config, pin_t ledPin,
431 : const MIDIAddress &address)
432 : : GenericNoteCCRange<MIDIInputElementCC, 1, BankSize, NoteCCLEDPWM<1>>{
433 : config,
434 : address,
435 : {{ledPin}},
436 : } {}
437 : };
438 :
439 : /// @}
440 :
441 : } // namespace Bankable
442 :
443 : END_CS_NAMESPACE
444 :
445 : AH_DIAGNOSTIC_POP()
|