26 MidiMessageSequence::MidiEventHolder::MidiEventHolder (
const MidiMessage& mm) : message (mm) {}
27 MidiMessageSequence::MidiEventHolder::MidiEventHolder (MidiMessage&& mm) : message (std::move (mm)) {}
37 list.addCopiesOf (other.list);
39 for (
int i = 0; i < list.size(); ++i)
43 if (noteOffIndex >= 0)
44 list.getUnchecked(i)->noteOffObject = list.getUnchecked (noteOffIndex);
56 : list (std::move (other.list))
62 list = std::move (other.list);
72 list.swapWith (other.list);
95 if (
auto* meh = list[index])
96 if (
auto* noteOff = meh->noteOffObject)
97 return noteOff->message.getTimeStamp();
104 if (
auto* meh = list[index])
106 if (
auto* noteOff = meh->noteOffObject)
108 for (
int i = index; i < list.size(); ++i)
109 if (list.getUnchecked(i) == noteOff)
121 return list.indexOf (event);
126 auto numEvents = list.size();
129 for (i = 0; i < numEvents; ++i)
130 if (list.getUnchecked(i)->message.getTimeStamp() >= timeStamp)
149 if (
auto* meh = list[index])
150 return meh->message.getTimeStamp();
159 auto time = newEvent->message.getTimeStamp();
162 for (i = list.size(); --i >= 0;)
163 if (list.getUnchecked(i)->message.getTimeStamp() <= time)
166 list.insert (i + 1, newEvent);
182 if (isPositiveAndBelow (index, list.size()))
184 if (deleteMatchingNoteUp)
193 for (
auto* m : other)
196 newOne->message.addToTimeStamp (timeAdjustment);
204 double timeAdjustment,
205 double firstAllowableTime,
206 double endOfAllowableDestTimes)
208 for (
auto* m : other)
210 auto t = m->message.getTimeStamp() + timeAdjustment;
212 if (t >= firstAllowableTime && t < endOfAllowableDestTimes)
215 newOne->message.setTimeStamp (t);
225 std::stable_sort (list.begin(), list.end(),
231 for (
int i = 0; i < list.size(); ++i)
233 auto* meh = list.getUnchecked(i);
234 auto& m1 = meh->message;
238 meh->noteOffObject =
nullptr;
239 auto note = m1.getNoteNumber();
240 auto chan = m1.getChannel();
241 auto len = list.size();
243 for (
int j = i + 1; j < len; ++j)
245 auto* meh2 = list.getUnchecked(j);
246 auto& m = meh2->message;
248 if (m.getNoteNumber() == note && m.getChannel() == chan)
252 meh->noteOffObject = meh2;
259 list.insert (j, newEvent);
260 newEvent->message.setTimeStamp (m.getTimeStamp());
261 meh->noteOffObject = newEvent;
274 m->message.addToTimeStamp (delta);
280 const bool alsoIncludeMetaEvents)
const
282 for (
auto* meh : list)
283 if (meh->message.isForChannel (channelNumberToExtract)
284 || (alsoIncludeMetaEvents && meh->message.isMetaEvent()))
285 destSequence.
addEvent (meh->message);
290 for (
auto* meh : list)
291 if (meh->message.isSysEx())
292 destSequence.
addEvent (meh->message);
297 for (
int i = list.size(); --i >= 0;)
298 if (list.getUnchecked(i)->message.isForChannel (channelNumberToRemove))
304 for (
int i = list.size(); --i >= 0;)
305 if (list.getUnchecked(i)->message.isSysEx())
312 bool doneProg =
false;
313 bool donePitchWheel =
false;
314 bool doneControllers[128] = {};
316 for (
int i = list.size(); --i >= 0;)
318 auto& mm = list.getUnchecked(i)->message;
320 if (mm.isForChannel (channelNumber) && mm.getTimeStamp() <= time)
322 if (mm.isProgramChange() && ! doneProg)
327 else if (mm.isPitchWheel() && ! donePitchWheel)
329 donePitchWheel =
true;
332 else if (mm.isController())
334 auto controllerNumber = mm.getControllerNumber();
335 jassert (isPositiveAndBelow (controllerNumber, 128));
337 if (! doneControllers[controllerNumber])
339 doneControllers[controllerNumber] =
true;
351 MidiMessageSequenceTest() : juce::
UnitTest (
"MidiMessageSequence") {}
353 void runTest()
override
362 beginTest (
"Start & end time");
363 expectEquals (s.getStartTime(), 0.0);
364 expectEquals (s.getEndTime(), 8.0);
365 expectEquals (s.getEventTime (1), 2.0);
367 beginTest (
"Matching note off & ons");
368 s.updateMatchedPairs();
369 expectEquals (s.getTimeOfMatchingKeyUp (0), 4.0);
370 expectEquals (s.getTimeOfMatchingKeyUp (1), 8.0);
371 expectEquals (s.getIndexOfMatchingKeyUp (0), 2);
372 expectEquals (s.getIndexOfMatchingKeyUp (1), 3);
374 beginTest (
"Time & indeces");
375 expectEquals (s.getNextIndexAtTime (0.5), 1);
376 expectEquals (s.getNextIndexAtTime (2.5), 2);
377 expectEquals (s.getNextIndexAtTime (9.0), 4);
379 beginTest (
"Deleting events");
380 s.deleteEvent (0,
true);
381 expectEquals (s.getNumEvents(), 2);
383 beginTest (
"Merging sequences");
392 s.addSequence (s2, 0.0, 0.0, 8.0);
393 s.updateMatchedPairs();
395 expectEquals (s.getNumEvents(), 7);
396 expectEquals (s.getIndexOfMatchingKeyUp (0), -1);
397 expectEquals (s.getTimeOfMatchingKeyUp (1), 5.0);
401 static MidiMessageSequenceTest midiMessageSequenceTests;