Line data Source code
1 : #pragma once 2 : 3 : #include <AH/Debug/Debug.hpp> 4 : #include <AH/Math/MinMaxFix.hpp> 5 : #include <MIDI_Inputs/MIDIInputElementSysEx.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 : 19 : class LCDCounter { 20 : public: 21 12 : LCDCounter() { instances++; } 22 12 : ~LCDCounter() { instances--; } 23 : 24 15 : static uint8_t getInstances() { return instances; } 25 : 26 : private: 27 : static uint8_t instances; 28 : }; 29 : 30 : template <uint8_t BufferSize = 120> 31 12 : class LCD : public MIDIInputElementSysEx, private LCDCounter { 32 : public: 33 12 : LCD(uint8_t offset = 0, uint8_t CN = 0) 34 12 : : MIDIInputElementSysEx{CN}, offset{offset} { 35 12 : buffer[BufferSize] = '\0'; 36 72 : for (uint8_t i = 0; i < BufferSize; i++) 37 60 : buffer[i] = ' '; 38 12 : } 39 : 40 12 : const char *getText() const { return &buffer[0]; } 41 : 42 : private: 43 15 : bool updateImpl(SysExMessage midimsg) override { 44 : // Format: 45 : // F0 mm mm mm nn 12 oo yy... F7 46 : // mm = manufacturer ID (00 00 66 for Mackie) 47 : // nn = model number (10 for Logic Control, 11 for Logic Control XT) 48 : // oo = offset [0x00, 0x6F] 49 : // yy... = ASCII data 50 15 : if (midimsg.data[5] != 0x12) 51 0 : return false; 52 : 53 15 : const uint8_t midiOffset = midimsg.data[6]; 54 15 : const uint8_t midiLength = midimsg.length - 8; 55 15 : const uint8_t *text = midimsg.data + 7; 56 15 : const uint8_t midiBufferEnd = midiOffset + midiLength; 57 : 58 15 : const uint8_t bufferEnd = this->offset + BufferSize; 59 : 60 : // no overlap between incoming range and this range 61 15 : if (midiOffset >= bufferEnd || this->offset >= midiBufferEnd) 62 2 : return getInstances() == 1; 63 : 64 13 : uint8_t srcStart = max(0, this->offset - midiOffset); 65 13 : uint8_t dstStart = max(0, midiOffset - this->offset); 66 39 : uint8_t length = midiBufferEnd - midiOffset - 67 26 : max(0, this->offset - midiOffset) - 68 13 : max(0, midiBufferEnd - bufferEnd); 69 : // uint8_t length = 70 : // BufferSize - // 71 : // max(0, midiOffset - this->offset) - // 72 : // max(0, BufferSize - midiLength - (midiOffset - this->offset)); // 73 : 74 13 : DEBUGVAL(this->offset, midiOffset, BufferSize, midiLength, srcStart, 75 : dstStart, length); 76 : 77 : #ifdef ARDUINO 78 : memcpy(&buffer[dstStart], &text[srcStart], length); 79 : #else 80 57 : for (uint8_t i = 0; i < length; ++i) { 81 44 : buffer[dstStart + i] = text[srcStart + i]; 82 44 : assert(dstStart + i < BufferSize); 83 44 : assert(srcStart + i < midiLength); 84 44 : } 85 : #endif 86 : 87 13 : DEBUGFN(getText()); 88 : 89 : // If this is the only instance, the others don't have to be updated 90 : // anymore 91 13 : return getInstances() == 1; 92 15 : } 93 : 94 : Array<char, BufferSize + 1> buffer; 95 : uint8_t offset; 96 : }; 97 : 98 : } // namespace MCU 99 : 100 : END_CS_NAMESPACE