OpenShot Library | libopenshot-audio  0.1.9
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  void noteOff (int noteNumber);
74 
75  /** Call this to clear all currently playing notes. */
76  void allNotesOff();
77 
78 private:
79  bool isLegacy = false;
80  std::unique_ptr<MPEZoneLayout::Zone> zone;
81  int channelIncrement, numChannels, firstChannel, lastChannel, midiChannelLastAssigned;
82 
83  //==============================================================================
84  struct MidiChannel
85  {
86  Array<int> notes;
87  int lastNotePlayed = -1;
88  bool isFree() const noexcept { return notes.isEmpty(); }
89  };
90  MidiChannel midiChannels[17];
91 
92  //==============================================================================
93  int findMidiChannelPlayingClosestNonequalNote (int noteNumber) noexcept;
94 };
95 
96 //==============================================================================
97 /**
98  This class handles the logic for remapping MIDI note messages from multiple MPE
99  sources onto a specified MPE zone.
100 
101  @tags{Audio}
102 */
104 {
105 public:
106  /** Used to indicate that a particular source & channel combination is not currently using MPE. */
107  static const uint32 notMPE = 0;
108 
109  /** Constructor */
111 
112  //==============================================================================
113  /** Remaps the MIDI channel of the specified MIDI message (if necessary).
114 
115  Note that the MidiMessage object passed in will have it's channel changed if it
116  needs to be remapped.
117 
118  @param message the message to be remapped
119  @param mpeSourceID the ID of the MPE source of the message. This is up to the
120  user to define and keep constant
121  */
122  void remapMidiChannelIfNeeded (MidiMessage& message, uint32 mpeSourceID) noexcept;
123 
124  //==============================================================================
125  /** Resets all the source & channel combinations. */
126  void reset() noexcept;
127 
128  /** Clears a specified channel of this MPE zone. */
129  void clearChannel (int channel) noexcept;
130 
131  /** Clears all channels in use by a specified source. */
132  void clearSource (uint32 mpeSourceID);
133 
134 private:
135  MPEZoneLayout::Zone zone;
136 
137  int channelIncrement;
138  int firstChannel, lastChannel;
139 
140  uint32 sourceAndChannel[17];
141  uint32 lastUsed[17];
142  uint32 counter = 0;
143 
144  //==============================================================================
145  bool applyRemapIfExisting (int channel, uint32 sourceAndChannelID, MidiMessage& m) noexcept;
146  int getBestChanToReuse() const noexcept;
147 
148  void zeroArrays();
149 
150  //==============================================================================
151  bool messageIsNoteData (const MidiMessage& m) { return (*m.getRawData() & 0xf0) != 0xf0; }
152 };
153 
154 } // namespace juce
155 
156 /** @}*/
This class represents the current MPE zone layout of a device capable of handling MPE...
Encapsulates a MIDI message.
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...
void noteOff(int noteNumber)
You must call this method for all note-offs that you receive so that this class can keep track of the...
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...