cs-midi/MIDI_Inputs/NoteCCKPRange.hpp

111 lines
3.2 KiB
C++

#pragma once
#include "MIDIInputElementMatchers.hpp"
BEGIN_CS_NAMESPACE
template <MIDIMessageType Type, uint8_t RangeLen>
class NoteCCKPRange
: public MatchingMIDIInputElement<Type, TwoByteRangeMIDIMatcher> {
public:
using Matcher = TwoByteRangeMIDIMatcher;
NoteCCKPRange(MIDIAddress address)
: MatchingMIDIInputElement<Type, Matcher>({address, RangeLen}) {}
private:
bool handleUpdateImpl(typename Matcher::Result match) {
bool newdirty = values[match.index] != match.value;
values[match.index] = match.value;
return newdirty;
}
void handleUpdate(typename Matcher::Result match) override {
dirty |= handleUpdateImpl(match);
}
public:
uint8_t getValue(uint8_t index) const { return values[index]; }
void reset() override {
values = {{}};
dirty = true;
}
bool getDirty() const { return dirty; }
void clearDirty() { dirty = false; }
private:
AH::Array<uint8_t, RangeLen> values = {{}};
bool dirty = true;
};
template <uint8_t RangeLen>
using NoteRange = NoteCCKPRange<MIDIMessageType::NoteOn, RangeLen>;
template <uint8_t RangeLen>
using CCRange = NoteCCKPRange<MIDIMessageType::ControlChange, RangeLen>;
template <uint8_t RangeLen>
using KPRange = NoteCCKPRange<MIDIMessageType::KeyPressure, RangeLen>;
namespace Bankable {
template <MIDIMessageType Type, uint8_t BankSize, uint8_t RangeLen>
class NoteCCKPRange : public BankableMatchingMIDIInputElement<
Type, BankableTwoByteRangeMIDIMatcher<BankSize>> {
public:
using Matcher = BankableTwoByteRangeMIDIMatcher<BankSize>;
NoteCCKPRange(BankConfig<BankSize> config, MIDIAddress address)
: BankableMatchingMIDIInputElement<Type, Matcher>(
{config, address, RangeLen}) {}
protected:
bool handleUpdateImpl(typename Matcher::Result match) {
bool newdirty = values[match.bankIndex][match.index] != match.value &&
match.bankIndex == this->getActiveBank();
values[match.bankIndex][match.index] = match.value;
return newdirty;
}
void handleUpdate(typename Matcher::Result match) override {
dirty |= handleUpdateImpl(match);
}
public:
uint8_t getValue(uint8_t index) const {
return values[this->getActiveBank()][index];
}
uint8_t getValue(uint8_t bank, uint8_t index) const {
return values[bank][index];
}
void reset() override {
values = {{{}}};
dirty = true;
}
bool getDirty() const { return dirty; }
void clearDirty() { dirty = false; }
protected:
void onBankSettingChange() override { dirty = true; }
private:
AH::Array2D<uint8_t, BankSize, RangeLen> values = {{{}}};
protected:
bool dirty = true;
};
template <uint8_t BankSize, uint8_t RangeLen>
using NoteRange = NoteCCKPRange<MIDIMessageType::NoteOn, BankSize, RangeLen>;
template <uint8_t BankSize, uint8_t RangeLen>
using CCRange =
NoteCCKPRange<MIDIMessageType::ControlChange, BankSize, RangeLen>;
template <uint8_t BankSize, uint8_t RangeLen>
using KPRange = NoteCCKPRange<MIDIMessageType::KeyPressure, BankSize, RangeLen>;
} // namespace Bankable
END_CS_NAMESPACE