20 static MPESourceID createUniqueMPESourceID()
noexcept
22 static MPESourceID i = 0;
26 static constexpr MPESourceID notMPE = 0;
38 MPESourceID mpeSourceID = 0;
41 bool isEmpty() const noexcept {
return messages.isEmpty(); }
42 bool isNotEmpty() const noexcept {
return ! messages.isEmpty(); }
44 int size() const noexcept {
return messages.size(); }
45 MidiMessageWithSource& operator[] (
int i) {
return messages.getReference (i); }
46 const MidiMessageWithSource& operator[] (
int i)
const {
return messages.getReference (i); }
48 MidiMessageWithSource* begin() noexcept {
return messages.begin(); }
49 const MidiMessageWithSource* begin() const noexcept {
return messages.begin(); }
50 MidiMessageWithSource* end() noexcept {
return messages.end(); }
51 const MidiMessageWithSource* end() const noexcept {
return messages.end(); }
53 void remove (
int index) { messages.remove (index); }
55 void swapWith (MidiMessageArray& other)
noexcept
57 std::swap (isAllNotesOff, other.isAllNotesOff);
58 messages.swapWith (other.messages);
63 isAllNotesOff =
false;
64 messages.clearQuick();
69 messages.add ({ m, mpeSourceID });
74 messages.add ({ std::move (m), mpeSourceID });
77 void addMidiMessage (
const juce::MidiMessage& m,
double time, MPESourceID mpeSourceID)
79 messages.add ({ m, mpeSourceID });
80 messages.getReference (messages.size() - 1).setTimeStamp (time);
85 messages.add ({ std::move (m), mpeSourceID });
86 messages.getReference (messages.size() - 1).setTimeStamp (time);
89 void add (
const MidiMessageWithSource& m)
94 void add (MidiMessageWithSource&& m)
96 messages.add (std::move (m));
99 void add (
const MidiMessageWithSource& m,
double time)
102 messages.getReference (messages.size() - 1).setTimeStamp (time);
105 void add (MidiMessageWithSource&& m,
double time)
107 messages.add (std::move (m));
108 messages.getReference (messages.size() - 1).setTimeStamp (time);
111 void copyFrom (
const MidiMessageArray& source)
117 void mergeFrom (
const MidiMessageArray& source)
119 isAllNotesOff = isAllNotesOff || source.isAllNotesOff;
121 if (source.isEmpty())
124 messages.ensureStorageAllocated (messages.size() + source.size());
126 for (
auto& m : source)
130 void mergeFromWithOffset (
const MidiMessageArray& source,
double delta)
132 isAllNotesOff = isAllNotesOff || source.isAllNotesOff;
134 if (source.isEmpty())
137 messages.ensureStorageAllocated (messages.size() + source.size());
139 for (
const auto& m : source)
141 auto copy = MidiMessageWithSource (m);
142 copy.addToTimeStamp (delta);
143 messages.add (std::move (copy));
147 void mergeFromAndClear (MidiMessageArray& source)
149 isAllNotesOff = isAllNotesOff || source.isAllNotesOff;
157 messages.ensureStorageAllocated (messages.size() + source.size());
159 for (
auto& m : source)
166 void mergeFromAndClearWithOffset (MidiMessageArray& source,
double delta)
168 isAllNotesOff = isAllNotesOff || source.isAllNotesOff;
173 addToTimestamps (delta);
177 messages.ensureStorageAllocated (messages.size() + source.size());
179 for (
auto& m : source)
181 messages.add (std::move (m));
182 messages.getReference (messages.size() - 1).addToTimeStamp (delta);
189 void mergeFromAndClearWithOffsetAndLimit (MidiMessageArray& source,
double delta,
int numItemsToTake)
191 if (numItemsToTake >= source.size())
192 return mergeFromAndClearWithOffset (source, delta);
194 isAllNotesOff = isAllNotesOff || source.isAllNotesOff;
195 messages.ensureStorageAllocated (messages.size() + numItemsToTake);
197 for (
int i = 0; i < numItemsToTake; ++i)
199 messages.add (std::move (source.messages.getReference(i)));
200 messages.getReference (messages.size() - 1).addToTimeStamp (delta);
203 source.messages.removeRange (0, numItemsToTake);
208 messages.ensureStorageAllocated (messages.size() + source.size());
210 for (
auto& m : source)
211 addMidiMessage (m, mpeSourceID);
216 void removeNoteOnsAndOffs()
218 for (
int i = messages.size(); --i >= 0;)
219 if (messages.getReference (i).isNoteOnOrOff())
223 void addToTimestamps (
double delta)
noexcept
225 for (
auto& m : messages)
226 m.addToTimeStamp (delta);
229 void addToNoteNumbers (
int delta)
noexcept
231 for (
auto& m : messages)
232 m.setNoteNumber (m.getNoteNumber() + delta);
235 void multiplyVelocities (
float factor)
noexcept
237 for (
auto& m : messages)
238 m.multiplyVelocity (factor);
241 void sortByTimestamp()
245 auto t1 = a.getTimeStamp();
246 auto t2 = b.getTimeStamp();
250 if (a.isNoteOff() && b.isNoteOn()) return true;
251 if (a.isNoteOn() && b.isNoteOff()) return false;
257 void reserve (
int size)
259 messages.ensureStorageAllocated (size);
262 bool isAllNotesOff =
false;