OpenShot Library | libopenshot-audio 0.2.0
juce_MPEZoneLayout.h
1
2/** @weakgroup juce_audio_basics-mpe
3 * @{
4 */
5/*
6 ==============================================================================
7
8 This file is part of the JUCE library.
9 Copyright (c) 2017 - ROLI Ltd.
10
11 JUCE is an open source library subject to commercial or open-source
12 licensing.
13
14 The code included in this file is provided under the terms of the ISC license
15 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
16 To use, copy, modify, and/or distribute this software for any purpose with or
17 without fee is hereby granted provided that the above copyright notice and
18 this permission notice appear in all copies.
19
20 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22 DISCLAIMED.
23
24 ==============================================================================
25*/
26
27namespace juce
28{
29
30//==============================================================================
31/**
32 This class represents the current MPE zone layout of a device capable of handling MPE.
33
34 An MPE device can have up to two zones: a lower zone with master channel 1 and
35 allocated MIDI channels increasing from channel 2, and an upper zone with master
36 channel 16 and allocated MIDI channels decreasing from channel 15. MPE mode is
37 enabled on a device when one of these zones is active and disabled when both
38 are inactive.
39
40 Use the MPEMessages helper class to convert the zone layout represented
41 by this object to MIDI message sequences that you can send to an Expressive
42 MIDI device to set its zone layout, add zones etc.
43
44 @see MPEInstrument
45
46 @tags{Audio}
47*/
49{
50public:
51 /** Default constructor.
52
53 This will create a layout with inactive lower and upper zones, representing
54 a device with MPE mode disabled.
55
56 You can set the lower or upper MPE zones using the setZone() method.
57
58 @see setZone
59 */
60 MPEZoneLayout() noexcept;
61
62 /** Copy constuctor.
63 This will not copy the listeners registered to the MPEZoneLayout.
64 */
66
67 /** Copy assignment operator.
68 This will not copy the listeners registered to the MPEZoneLayout.
69 */
71
72 //==============================================================================
73 /**
74 This struct represents an MPE zone.
75
76 It can either be a lower or an upper zone, where:
77 - A lower zone encompasses master channel 1 and an arbitrary number of ascending
78 MIDI channels, increasing from channel 2.
79 - An upper zone encompasses master channel 16 and an arbitrary number of descending
80 MIDI channels, decreasing from channel 15.
81
82 It also defines a pitchbend range (in semitones) to be applied for per-note pitchbends and
83 master pitchbends, respectively.
84 */
85 struct Zone
86 {
87 Zone (const Zone& other) = default;
88
89 bool isLowerZone() const noexcept { return lowerZone; }
90 bool isUpperZone() const noexcept { return ! lowerZone; }
91
92 bool isActive() const noexcept { return numMemberChannels > 0; }
93
94 int getMasterChannel() const noexcept { return lowerZone ? 1 : 16; }
95 int getFirstMemberChannel() const noexcept { return lowerZone ? 2 : 15; }
96 int getLastMemberChannel() const noexcept { return lowerZone ? (1 + numMemberChannels)
97 : (16 - numMemberChannels); }
98
99 bool isUsingChannelAsMemberChannel (int channel) const noexcept
100 {
101 return lowerZone ? (channel > 1 && channel <= 1 + numMemberChannels)
102 : (channel < 16 && channel >= 16 - numMemberChannels);
103 }
104
105 bool operator== (const Zone& other) const noexcept { return lowerZone == other.lowerZone
106 && numMemberChannels == other.numMemberChannels
107 && perNotePitchbendRange == other.perNotePitchbendRange
108 && masterPitchbendRange == other.masterPitchbendRange; }
109
110 bool operator!= (const Zone& other) const noexcept { return ! operator== (other); }
111
112 int numMemberChannels;
113 int perNotePitchbendRange;
114 int masterPitchbendRange;
115
116 private:
117 friend class MPEZoneLayout;
118
119 Zone (bool lower, int memberChans = 0, int perNotePb = 48, int masterPb = 2) noexcept
120 : numMemberChannels (memberChans),
121 perNotePitchbendRange (perNotePb),
122 masterPitchbendRange (masterPb),
123 lowerZone (lower)
124 {
125 }
126
127 bool lowerZone;
128 };
129
130 /** Sets the lower zone of this layout. */
131 void setLowerZone (int numMemberChannels = 0,
132 int perNotePitchbendRange = 48,
133 int masterPitchbendRange = 2) noexcept;
134
135 /** Sets the upper zone of this layout. */
136 void setUpperZone (int numMemberChannels = 0,
137 int perNotePitchbendRange = 48,
138 int masterPitchbendRange = 2) noexcept;
139
140 /** Returns a struct representing the lower MPE zone. */
141 const Zone getLowerZone() const noexcept { return lowerZone; }
142
143 /** Returns a struct representing the upper MPE zone. */
144 const Zone getUpperZone() const noexcept { return upperZone; }
145
146 /** Clears the lower and upper zones of this layout, making them both inactive
147 and disabling MPE mode.
148 */
149 void clearAllZones();
150
151 //==============================================================================
152 /** Pass incoming MIDI messages to an object of this class if you want the
153 zone layout to properly react to MPE RPN messages like an
154 MPE device.
155
156 MPEMessages::rpnNumber will add or remove zones; RPN 0 will
157 set the per-note or master pitchbend ranges.
158
159 Any other MIDI messages will be ignored by this class.
160
161 @see MPEMessages
162 */
163 void processNextMidiEvent (const MidiMessage& message);
164
165 /** Pass incoming MIDI buffers to an object of this class if you want the
166 zone layout to properly react to MPE RPN messages like an
167 MPE device.
168
169 MPEMessages::rpnNumber will add or remove zones; RPN 0 will
170 set the per-note or master pitchbend ranges.
171
172 Any other MIDI messages will be ignored by this class.
173
174 @see MPEMessages
175 */
176 void processNextMidiBuffer (const MidiBuffer& buffer);
177
178 //==============================================================================
179 /** Listener class. Derive from this class to allow your class to be
180 notified about changes to the zone layout.
181 */
183 {
184 public:
185 /** Destructor. */
186 virtual ~Listener() = default;
187
188 /** Implement this callback to be notified about any changes to this
189 MPEZoneLayout. Will be called whenever a zone is added, zones are
190 removed, or any zone's master or note pitchbend ranges change.
191 */
192 virtual void zoneLayoutChanged (const MPEZoneLayout& layout) = 0;
193 };
194
195 //==============================================================================
196 /** Adds a listener. */
197 void addListener (Listener* const listenerToAdd) noexcept;
198
199 /** Removes a listener. */
200 void removeListener (Listener* const listenerToRemove) noexcept;
201
202private:
203 //==============================================================================
204 Zone lowerZone { true, 0 };
205 Zone upperZone { false, 0 };
206
207 MidiRPNDetector rpnDetector;
208 ListenerList<Listener> listeners;
209
210 //==============================================================================
211 void setZone (bool, int, int, int) noexcept;
212
213 void processRpnMessage (MidiRPNMessage);
214 void processZoneLayoutRpnMessage (MidiRPNMessage);
215 void processPitchbendRangeRpnMessage (MidiRPNMessage);
216
217 void updateMasterPitchbend (Zone&, int);
218 void updatePerNotePitchbendRange (Zone&, int);
219
220 void sendLayoutChangeMessage();
221 void checkAndLimitZoneParameters (int, int, int&) noexcept;
222};
223
224} // namespace juce
225
226/** @}*/
Holds a resizable array of primitive or copy-by-value objects.
Definition juce_Array.h:60
virtual void zoneLayoutChanged(const MPEZoneLayout &layout)=0
Implement this callback to be notified about any changes to this MPEZoneLayout.
virtual ~Listener()=default
Destructor.
This class represents the current MPE zone layout of a device capable of handling MPE.
const Zone getUpperZone() const noexcept
Returns a struct representing the upper MPE zone.
Holds a sequence of time-stamped midi events.
Encapsulates a MIDI message.
#define JUCE_API
This macro is added to all JUCE public class declarations.
This struct represents an MPE zone.