OpenShot Audio Library | OpenShotAudio 0.4.0
Loading...
Searching...
No Matches
juce_MPEZoneLayout.h
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
26//==============================================================================
41struct MPEZone
42{
43 enum class Type { lower, upper };
44
45 MPEZone() = default;
46
47 MPEZone (Type type, int memberChannels = 0, int perNotePitchbend = 48, int masterPitchbend = 2)
48 : zoneType (type),
49 numMemberChannels (memberChannels),
50 perNotePitchbendRange (perNotePitchbend),
51 masterPitchbendRange (masterPitchbend)
52 {}
53
54 bool isLowerZone() const noexcept { return zoneType == Type::lower; }
55 bool isUpperZone() const noexcept { return zoneType == Type::upper; }
56
57 bool isActive() const noexcept { return numMemberChannels > 0; }
58
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); }
63
64 bool isUsingChannelAsMemberChannel (int channel) const noexcept
65 {
66 return isLowerZone() ? (lowerZoneMasterChannel < channel && channel <= getLastMemberChannel())
67 : (channel < upperZoneMasterChannel && getLastMemberChannel() <= channel);
68 }
69
70 bool isUsing (int channel) const noexcept
71 {
72 return isUsingChannelAsMemberChannel (channel) || channel == getMasterChannel();
73 }
74
75 static auto tie (const MPEZone& z)
76 {
77 return std::tie (z.zoneType,
78 z.numMemberChannels,
79 z.perNotePitchbendRange,
80 z.masterPitchbendRange);
81 }
82
83 bool operator== (const MPEZone& other) const
84 {
85 return tie (*this) == tie (other);
86 }
87
88 bool operator!= (const MPEZone& other) const
89 {
90 return tie (*this) != tie (other);
91 }
92
93 //==============================================================================
94 static constexpr int lowerZoneMasterChannel = 1,
95 upperZoneMasterChannel = 16;
96
97 Type zoneType = Type::lower;
98
99 int numMemberChannels = 0;
100 int perNotePitchbendRange = 48;
101 int masterPitchbendRange = 2;
102};
103
104//==============================================================================
122class JUCE_API MPEZoneLayout
123{
124public:
125 //==============================================================================
127 MPEZoneLayout() = default;
128
130 MPEZoneLayout (MPEZone lower, MPEZone upper);
131
134
135 MPEZoneLayout (const MPEZoneLayout& other);
137
138 bool operator== (const MPEZoneLayout& other) const { return lowerZone == other.lowerZone && upperZone == other.upperZone; }
139 bool operator!= (const MPEZoneLayout& other) const { return ! operator== (other); }
140
141 //==============================================================================
143 MPEZone getLowerZone() const noexcept { return lowerZone; }
144
146 MPEZone getUpperZone() const noexcept { return upperZone; }
147
149 void setLowerZone (int numMemberChannels = 0,
150 int perNotePitchbendRange = 48,
151 int masterPitchbendRange = 2) noexcept;
152
154 void setUpperZone (int numMemberChannels = 0,
155 int perNotePitchbendRange = 48,
156 int masterPitchbendRange = 2) noexcept;
157
161 void clearAllZones();
162
164 bool isActive() const { return lowerZone.isActive() || upperZone.isActive(); }
165
166 //==============================================================================
178 void processNextMidiEvent (const MidiMessage& message);
179
191 void processNextMidiBuffer (const MidiBuffer& buffer);
192
193 //==============================================================================
198 {
199 public:
201 virtual ~Listener() = default;
202
207 virtual void zoneLayoutChanged (const MPEZoneLayout& layout) = 0;
208 };
209
210 //==============================================================================
212 void addListener (Listener* const listenerToAdd) noexcept;
213
215 void removeListener (Listener* const listenerToRemove) noexcept;
216
217 #ifndef DOXYGEN
218 using Zone = MPEZone;
219 #endif
220
221private:
222 //==============================================================================
223 MPEZone lowerZone { MPEZone::Type::lower, 0 };
224 MPEZone upperZone { MPEZone::Type::upper, 0 };
225
226 MidiRPNDetector rpnDetector;
227 ListenerList<Listener> listeners;
228
229 //==============================================================================
230 void setZone (bool, int, int, int) noexcept;
231
232 void processRpnMessage (MidiRPNMessage);
233 void processZoneLayoutRpnMessage (MidiRPNMessage);
234 void processPitchbendRangeRpnMessage (MidiRPNMessage);
235
236 void updateMasterPitchbend (MPEZone&, int);
237 void updatePerNotePitchbendRange (MPEZone&, int);
238
239 void sendLayoutChangeMessage();
240 void checkAndLimitZoneParameters (int, int, int&) noexcept;
241};
242
243} // namespace juce
virtual void zoneLayoutChanged(const MPEZoneLayout &layout)=0
virtual ~Listener()=default
MPEZone getUpperZone() const noexcept
MPEZoneLayout()=default
MPEZone getLowerZone() const noexcept