OpenShot Library | OpenShotAudio  0.2.1
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 
27 namespace 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 {
43 public:
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 
81 private:
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 {
108 public:
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 
137 private:
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 /** @}*/
This class represents the current MPE zone layout of a device capable of handling MPE...
Encapsulates a MIDI message.
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...
MPEChannelAssigner(MPEZoneLayout::Zone zoneToUse)
Constructor.
This struct represents an MPE zone.
This class handles the logic for remapping MIDI note messages from multiple MPE sources onto a specif...
This class handles the assignment of new MIDI notes to member channels of an active MPE zone...
Definition: juce_MPEUtils.h:41
void allNotesOff()
Call this to clear all currently playing notes.
bool isEmpty() const noexcept
Returns true if the array is empty, false otherwise.
Definition: juce_Array.h:226
int findMidiChannelForNewNote(int noteNumber) noexcept
This method will use a set of rules recommended in the MPE specification to determine which member ch...