43 enum class Type { lower, upper };
54 bool isLowerZone()
const noexcept {
return zoneType == Type::lower; }
55 bool isUpperZone()
const noexcept {
return zoneType == Type::upper; }
57 bool isActive()
const noexcept {
return numMemberChannels > 0; }
59 int getMasterChannel()
const noexcept {
return isLowerZone() ? lowerZoneMasterChannel : upperZoneMasterChannel; }
60 int getFirstMemberChannel()
const noexcept {
return isLowerZone() ? lowerZoneMasterChannel + 1 : upperZoneMasterChannel - 1; }
61 int getLastMemberChannel()
const noexcept {
return isLowerZone() ? (lowerZoneMasterChannel + numMemberChannels)
62 : (upperZoneMasterChannel - numMemberChannels); }
64 bool isUsingChannelAsMemberChannel (
int channel)
const noexcept
66 return isLowerZone() ? (lowerZoneMasterChannel < channel && channel <= getLastMemberChannel())
67 : (channel < upperZoneMasterChannel && getLastMemberChannel() <= channel);
70 bool isUsing (
int channel)
const noexcept
72 return isUsingChannelAsMemberChannel (channel) || channel == getMasterChannel();
77 return std::tie (
z.zoneType,
79 z.perNotePitchbendRange,
80 z.masterPitchbendRange);
85 return tie (*
this) == tie (other);
90 return tie (*
this) != tie (other);
94 static constexpr int lowerZoneMasterChannel = 1,
95 upperZoneMasterChannel = 16;
97 Type zoneType = Type::lower;
99 int numMemberChannels = 0;
100 int perNotePitchbendRange = 48;
101 int masterPitchbendRange = 2;
138 bool operator== (
const MPEZoneLayout& other)
const {
return lowerZone == other.lowerZone && upperZone == other.upperZone; }
149 void setLowerZone (
int numMemberChannels = 0,
150 int perNotePitchbendRange = 48,
151 int masterPitchbendRange = 2)
noexcept;
154 void setUpperZone (
int numMemberChannels = 0,
155 int perNotePitchbendRange = 48,
156 int masterPitchbendRange = 2)
noexcept;
161 void clearAllZones();
164 bool isActive()
const {
return lowerZone.isActive() || upperZone.isActive(); }
178 void processNextMidiEvent (
const MidiMessage& message);
191 void processNextMidiBuffer (
const MidiBuffer& buffer);
223 MPEZone lowerZone { MPEZone::Type::lower, 0 };
224 MPEZone upperZone { MPEZone::Type::upper, 0 };
226 MidiRPNDetector rpnDetector;
227 ListenerList<Listener> listeners;
230 void setZone (
bool,
int,
int,
int)
noexcept;
232 void processRpnMessage (MidiRPNMessage);
233 void processZoneLayoutRpnMessage (MidiRPNMessage);
234 void processPitchbendRangeRpnMessage (MidiRPNMessage);
236 void updateMasterPitchbend (MPEZone&,
int);
237 void updatePerNotePitchbendRange (MPEZone&,
int);
239 void sendLayoutChangeMessage();
240 void checkAndLimitZoneParameters (
int,
int,
int&)
noexcept;