OpenShot Library | OpenShotAudio 0.2.2
juce_MPEUtils.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 handles the assignment of new MIDI notes to member channels of an active
33 MPE zone.
34
35 To use it, create an instance passing in the MPE zone that it should operate on
36 and then call use the findMidiChannelForNewNote() method for all note-on messages
37 and the noteOff() method for all note-off messages.
38
39 @tags{Audio}
40*/
42{
43public:
44 /** Constructor.
45
46 This will assign channels within the range of the specified MPE zone.
47 */
49
50 /** Legacy mode constructor.
51
52 This will assign channels within the specified range.
53 */
54 MPEChannelAssigner (Range<int> channelRange = Range<int> (1, 17));
55
56 /** This method will use a set of rules recommended in the MPE specification to
57 determine which member channel the specified MIDI note should be assigned to
58 and will return this channel number.
59
60 The rules have the following precedence:
61 - find a free channel on which the last note played was the same as the one specified
62 - find the next free channel in round-robin assignment
63 - find the channel number that is currently playing the closest note (but not the same)
64
65 @param noteNumber the MIDI note number to be assigned to a channel
66 @returns the zone's member channel that this note should be assigned to
67 */
68 int findMidiChannelForNewNote (int noteNumber) noexcept;
69
70 /** You must call this method for all note-offs that you receive so that this class
71 can keep track of the currently playing notes internally.
72
73 You can specify the channel number the note off happened on. If you don't, it will
74 look through all channels to find the registered midi note matching the given note number.
75 */
76 void noteOff (int noteNumber, int midiChannel = -1);
77
78 /** Call this to clear all currently playing notes. */
79 void allNotesOff();
80
81private:
82 bool isLegacy = false;
83 std::unique_ptr<MPEZoneLayout::Zone> zone;
84 int channelIncrement, numChannels, firstChannel, lastChannel, midiChannelLastAssigned;
85
86 //==============================================================================
87 struct MidiChannel
88 {
89 Array<int> notes;
90 int lastNotePlayed = -1;
91 bool isFree() const noexcept { return notes.isEmpty(); }
92 };
93 MidiChannel midiChannels[17];
94
95 //==============================================================================
96 int findMidiChannelPlayingClosestNonequalNote (int noteNumber) noexcept;
97};
98
99//==============================================================================
100/**
101 This class handles the logic for remapping MIDI note messages from multiple MPE
102 sources onto a specified MPE zone.
103
104 @tags{Audio}
105*/
107{
108public:
109 /** Used to indicate that a particular source & channel combination is not currently using MPE. */
110 static const uint32 notMPE = 0;
111
112 /** Constructor */
114
115 //==============================================================================
116 /** Remaps the MIDI channel of the specified MIDI message (if necessary).
117
118 Note that the MidiMessage object passed in will have it's channel changed if it
119 needs to be remapped.
120
121 @param message the message to be remapped
122 @param mpeSourceID the ID of the MPE source of the message. This is up to the
123 user to define and keep constant
124 */
125 void remapMidiChannelIfNeeded (MidiMessage& message, uint32 mpeSourceID) noexcept;
126
127 //==============================================================================
128 /** Resets all the source & channel combinations. */
129 void reset() noexcept;
130
131 /** Clears a specified channel of this MPE zone. */
132 void clearChannel (int channel) noexcept;
133
134 /** Clears all channels in use by a specified source. */
135 void clearSource (uint32 mpeSourceID);
136
137private:
138 MPEZoneLayout::Zone zone;
139
140 int channelIncrement;
141 int firstChannel, lastChannel;
142
143 uint32 sourceAndChannel[17];
144 uint32 lastUsed[17];
145 uint32 counter = 0;
146
147 //==============================================================================
148 bool applyRemapIfExisting (int channel, uint32 sourceAndChannelID, MidiMessage& m) noexcept;
149 int getBestChanToReuse() const noexcept;
150
151 void zeroArrays();
152
153 //==============================================================================
154 bool messageIsNoteData (const MidiMessage& m) { return (*m.getRawData() & 0xf0) != 0xf0; }
155};
156
157} // namespace juce
158
159/** @}*/
bool isEmpty() const noexcept
Returns true if the array is empty, false otherwise.
Definition: juce_Array.h:226
This class handles the assignment of new MIDI notes to member channels of an active MPE zone.
Definition: juce_MPEUtils.h:42
MPEChannelAssigner(MPEZoneLayout::Zone zoneToUse)
Constructor.
int findMidiChannelForNewNote(int noteNumber) noexcept
This method will use a set of rules recommended in the MPE specification to determine which member ch...
void noteOff(int noteNumber, int midiChannel=-1)
You must call this method for all note-offs that you receive so that this class can keep track of the...
void allNotesOff()
Call this to clear all currently playing notes.
This class handles the logic for remapping MIDI note messages from multiple MPE sources onto a specif...
void reset() noexcept
Resets all the source & channel combinations.
void remapMidiChannelIfNeeded(MidiMessage &message, uint32 mpeSourceID) noexcept
Remaps the MIDI channel of the specified MIDI message (if necessary).
static const uint32 notMPE
Used to indicate that a particular source & channel combination is not currently using MPE.
void clearChannel(int channel) noexcept
Clears a specified channel of this MPE zone.
void clearSource(uint32 mpeSourceID)
Clears all channels in use by a specified source.
MPEChannelRemapper(MPEZoneLayout::Zone zoneToRemap)
Constructor.
This class represents the current MPE zone layout of a device capable of handling MPE.
Encapsulates a MIDI message.
This struct represents an MPE zone.