1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Added some move-operators and iterators to MidiMessageSequence

This commit is contained in:
jules 2017-07-07 11:41:20 +01:00
parent 680a0d671c
commit 20d0b3775f
2 changed files with 114 additions and 96 deletions

View file

@ -20,6 +20,12 @@
==============================================================================
*/
MidiMessageSequence::MidiEventHolder::MidiEventHolder (const MidiMessage& mm) : message (mm) {}
MidiMessageSequence::MidiEventHolder::MidiEventHolder (MidiMessage&& mm) : message (static_cast<MidiMessage&&> (mm)) {}
MidiMessageSequence::MidiEventHolder::~MidiEventHolder() {}
//==============================================================================
MidiMessageSequence::MidiMessageSequence()
{
}
@ -37,15 +43,25 @@ MidiMessageSequence& MidiMessageSequence::operator= (const MidiMessageSequence&
return *this;
}
void MidiMessageSequence::swapWith (MidiMessageSequence& other) noexcept
MidiMessageSequence::MidiMessageSequence (MidiMessageSequence&& other) noexcept
: list (static_cast<OwnedArray<MidiEventHolder>&&> (other.list))
{}
MidiMessageSequence& MidiMessageSequence::operator= (MidiMessageSequence&& other) noexcept
{
list.swapWith (other.list);
list = static_cast<OwnedArray<MidiEventHolder>&&> (other.list);
return *this;
}
MidiMessageSequence::~MidiMessageSequence()
{
}
void MidiMessageSequence::swapWith (MidiMessageSequence& other) noexcept
{
list.swapWith (other.list);
}
void MidiMessageSequence::clear()
{
list.clear();
@ -56,34 +72,37 @@ int MidiMessageSequence::getNumEvents() const noexcept
return list.size();
}
MidiMessageSequence::MidiEventHolder* MidiMessageSequence::getEventPointer (const int index) const noexcept
MidiMessageSequence::MidiEventHolder* MidiMessageSequence::getEventPointer (int index) const noexcept
{
return list [index];
return list[index];
}
double MidiMessageSequence::getTimeOfMatchingKeyUp (const int index) const noexcept
MidiMessageSequence::MidiEventHolder** MidiMessageSequence::begin() const noexcept { return list.begin(); }
MidiMessageSequence::MidiEventHolder** MidiMessageSequence::end() const noexcept { return list.end(); }
double MidiMessageSequence::getTimeOfMatchingKeyUp (int index) const noexcept
{
if (const MidiEventHolder* const meh = list [index])
if (auto* meh = list[index])
if (meh->noteOffObject != nullptr)
return meh->noteOffObject->message.getTimeStamp();
return 0.0;
}
int MidiMessageSequence::getIndexOfMatchingKeyUp (const int index) const noexcept
int MidiMessageSequence::getIndexOfMatchingKeyUp (int index) const noexcept
{
if (const MidiEventHolder* const meh = list [index])
if (auto* meh = list [index])
return list.indexOf (meh->noteOffObject);
return -1;
}
int MidiMessageSequence::getIndexOf (const MidiEventHolder* const event) const noexcept
int MidiMessageSequence::getIndexOf (const MidiEventHolder* event) const noexcept
{
return list.indexOf (event);
}
int MidiMessageSequence::getNextIndexAtTime (const double timeStamp) const noexcept
int MidiMessageSequence::getNextIndexAtTime (double timeStamp) const noexcept
{
const int numEvents = list.size();
@ -108,32 +127,38 @@ double MidiMessageSequence::getEndTime() const noexcept
double MidiMessageSequence::getEventTime (const int index) const noexcept
{
if (const MidiEventHolder* const meh = list [index])
if (auto* meh = list [index])
return meh->message.getTimeStamp();
return 0.0;
}
//==============================================================================
MidiMessageSequence::MidiEventHolder* MidiMessageSequence::addEvent (const MidiMessage& newMessage,
double timeAdjustment)
MidiMessageSequence::MidiEventHolder* MidiMessageSequence::addEvent (MidiEventHolder* newEvent, double timeAdjustment)
{
MidiEventHolder* const newOne = new MidiEventHolder (newMessage);
timeAdjustment += newMessage.getTimeStamp();
newOne->message.setTimeStamp (timeAdjustment);
newEvent->message.addToTimeStamp (timeAdjustment);
auto time = newEvent->message.getTimeStamp();
int i;
for (i = list.size(); --i >= 0;)
if (list.getUnchecked(i)->message.getTimeStamp() <= timeAdjustment)
if (list.getUnchecked(i)->message.getTimeStamp() <= time)
break;
list.insert (i + 1, newOne);
return newOne;
list.insert (i + 1, newEvent);
return newEvent;
}
void MidiMessageSequence::deleteEvent (const int index,
const bool deleteMatchingNoteUp)
MidiMessageSequence::MidiEventHolder* MidiMessageSequence::addEvent (const MidiMessage& newMessage, double timeAdjustment)
{
return addEvent (new MidiEventHolder (newMessage), timeAdjustment);
}
MidiMessageSequence::MidiEventHolder* MidiMessageSequence::addEvent (MidiMessage&& newMessage, double timeAdjustment)
{
return addEvent (new MidiEventHolder (static_cast<MidiMessage&&> (newMessage)), timeAdjustment);
}
void MidiMessageSequence::deleteEvent (int index, bool deleteMatchingNoteUp)
{
if (isPositiveAndBelow (index, list.size()))
{
@ -144,23 +169,11 @@ void MidiMessageSequence::deleteEvent (const int index,
}
}
struct MidiMessageSequenceSorter
{
static int compareElements (const MidiMessageSequence::MidiEventHolder* const first,
const MidiMessageSequence::MidiEventHolder* const second) noexcept
{
const double diff = first->message.getTimeStamp() - second->message.getTimeStamp();
return (diff > 0) - (diff < 0);
}
};
void MidiMessageSequence::addSequence (const MidiMessageSequence& other, double timeAdjustment)
{
for (int i = 0; i < other.list.size(); ++i)
for (auto* m : other)
{
const MidiMessage& m = other.list.getUnchecked(i)->message;
MidiEventHolder* const newOne = new MidiEventHolder (m);
auto newOne = new MidiEventHolder (m->message);
newOne->message.addToTimeStamp (timeAdjustment);
list.add (newOne);
}
@ -173,16 +186,14 @@ void MidiMessageSequence::addSequence (const MidiMessageSequence& other,
double firstAllowableTime,
double endOfAllowableDestTimes)
{
for (int i = 0; i < other.list.size(); ++i)
for (auto* m : other)
{
const MidiMessage& m = other.list.getUnchecked(i)->message;
const double t = m.getTimeStamp() + timeAdjustment;
auto t = m->message.getTimeStamp() + timeAdjustment;
if (t >= firstAllowableTime && t < endOfAllowableDestTimes)
{
MidiEventHolder* const newOne = new MidiEventHolder (m);
auto newOne = new MidiEventHolder (m->message);
newOne->message.setTimeStamp (t);
list.add (newOne);
}
}
@ -190,7 +201,16 @@ void MidiMessageSequence::addSequence (const MidiMessageSequence& other,
sort();
}
//==============================================================================
struct MidiMessageSequenceSorter
{
static int compareElements (const MidiMessageSequence::MidiEventHolder* first,
const MidiMessageSequence::MidiEventHolder* second) noexcept
{
auto diff = first->message.getTimeStamp() - second->message.getTimeStamp();
return (diff > 0) - (diff < 0);
}
};
void MidiMessageSequence::sort() noexcept
{
MidiMessageSequenceSorter sorter;
@ -201,30 +221,32 @@ void MidiMessageSequence::updateMatchedPairs() noexcept
{
for (int i = 0; i < list.size(); ++i)
{
MidiEventHolder* const meh = list.getUnchecked(i);
const MidiMessage& m1 = meh->message;
auto* meh = list.getUnchecked(i);
auto& m1 = meh->message;
if (m1.isNoteOn())
{
meh->noteOffObject = nullptr;
const int note = m1.getNoteNumber();
const int chan = m1.getChannel();
const int len = list.size();
auto note = m1.getNoteNumber();
auto chan = m1.getChannel();
auto len = list.size();
for (int j = i + 1; j < len; ++j)
{
const MidiMessage& m = list.getUnchecked(j)->message;
auto* meh2 = list.getUnchecked(j);
auto& m = meh2->message;
if (m.getNoteNumber() == note && m.getChannel() == chan)
{
if (m.isNoteOff())
{
meh->noteOffObject = list[j];
meh->noteOffObject = meh2;
break;
}
else if (m.isNoteOn())
if (m.isNoteOn())
{
MidiEventHolder* const newEvent = new MidiEventHolder (MidiMessage::noteOff (chan, note));
auto newEvent = new MidiEventHolder (MidiMessage::noteOff (chan, note));
list.insert (j, newEvent);
newEvent->message.setTimeStamp (m.getTimeStamp());
meh->noteOffObject = newEvent;
@ -236,13 +258,11 @@ void MidiMessageSequence::updateMatchedPairs() noexcept
}
}
void MidiMessageSequence::addTimeToMessages (const double delta) noexcept
void MidiMessageSequence::addTimeToMessages (double delta) noexcept
{
for (int i = list.size(); --i >= 0;)
{
MidiMessage& mm = list.getUnchecked(i)->message;
mm.setTimeStamp (mm.getTimeStamp() + delta);
}
if (delta != 0)
for (auto* m : list)
m->message.addToTimeStamp (delta);
}
//==============================================================================
@ -250,24 +270,17 @@ void MidiMessageSequence::extractMidiChannelMessages (const int channelNumberToE
MidiMessageSequence& destSequence,
const bool alsoIncludeMetaEvents) const
{
for (int i = 0; i < list.size(); ++i)
{
const MidiMessage& mm = list.getUnchecked(i)->message;
if (mm.isForChannel (channelNumberToExtract) || (alsoIncludeMetaEvents && mm.isMetaEvent()))
destSequence.addEvent (mm);
}
for (auto* meh : list)
if (meh->message.isForChannel (channelNumberToExtract)
|| (alsoIncludeMetaEvents && meh->message.isMetaEvent()))
destSequence.addEvent (meh->message);
}
void MidiMessageSequence::extractSysExMessages (MidiMessageSequence& destSequence) const
{
for (int i = 0; i < list.size(); ++i)
{
const MidiMessage& mm = list.getUnchecked(i)->message;
if (mm.isSysEx())
destSequence.addEvent (mm);
}
for (auto* meh : list)
if (meh->message.isSysEx())
destSequence.addEvent (meh->message);
}
void MidiMessageSequence::deleteMidiChannelMessages (const int channelNumberToRemove)
@ -285,15 +298,15 @@ void MidiMessageSequence::deleteSysExMessages()
}
//==============================================================================
void MidiMessageSequence::createControllerUpdatesForTime (const int channelNumber, const double time, Array<MidiMessage>& dest)
void MidiMessageSequence::createControllerUpdatesForTime (int channelNumber, double time, Array<MidiMessage>& dest)
{
bool doneProg = false;
bool donePitchWheel = false;
bool doneControllers[128] = { 0 };
bool doneControllers[128] = {};
for (int i = list.size(); --i >= 0;)
{
const MidiMessage& mm = list.getUnchecked(i)->message;
auto& mm = list.getUnchecked(i)->message;
if (mm.isForChannel (channelNumber) && mm.getTimeStamp() <= time)
{
@ -321,14 +334,3 @@ void MidiMessageSequence::createControllerUpdatesForTime (const int channelNumbe
}
}
}
//==============================================================================
MidiMessageSequence::MidiEventHolder::MidiEventHolder (const MidiMessage& mm)
: message (mm), noteOffObject (nullptr)
{
}
MidiMessageSequence::MidiEventHolder::~MidiEventHolder()
{
}

View file

@ -46,16 +46,10 @@ public:
MidiMessageSequence& operator= (const MidiMessageSequence&);
/** Move constructor */
MidiMessageSequence (MidiMessageSequence&& other) noexcept
: list (static_cast<OwnedArray<MidiEventHolder>&&> (other.list))
{}
MidiMessageSequence (MidiMessageSequence&&) noexcept;
/** Move assignment operator */
MidiMessageSequence& operator= (MidiMessageSequence&& other) noexcept
{
list = static_cast<OwnedArray<MidiEventHolder>&&> (other.list);
return *this;
}
MidiMessageSequence& operator= (MidiMessageSequence&&) noexcept;
/** Destructor. */
~MidiMessageSequence();
@ -86,12 +80,13 @@ public:
note-offs up-to-date after events have been moved around in the sequence
or deleted.
*/
MidiEventHolder* noteOffObject;
MidiEventHolder* noteOffObject = nullptr;
private:
//==============================================================================
friend class MidiMessageSequence;
MidiEventHolder (const MidiMessage&);
MidiEventHolder (MidiMessage&&);
JUCE_LEAK_DETECTOR (MidiEventHolder)
};
@ -105,6 +100,12 @@ public:
/** Returns a pointer to one of the events. */
MidiEventHolder* getEventPointer (int index) const noexcept;
/** Iterator for the list of MidiEventHolders */
MidiEventHolder** begin() const noexcept;
/** Iterator for the list of MidiEventHolders */
MidiEventHolder** end() const noexcept;
/** Returns the time of the note-up that matches the note-on at this index.
If the event at this index isn't a note-on, it'll just return 0.
@see MidiMessageSequence::MidiEventHolder::noteOffObject
@ -155,8 +156,21 @@ public:
that will be inserted
@see updateMatchedPairs
*/
MidiEventHolder* addEvent (const MidiMessage& newMessage,
double timeAdjustment = 0);
MidiEventHolder* addEvent (const MidiMessage& newMessage, double timeAdjustment = 0);
/** Inserts a midi message into the sequence.
The index at which the new message gets inserted will depend on its timestamp,
because the sequence is kept sorted.
Remember to call updateMatchedPairs() after adding note-on events.
@param newMessage the new message to add (an internal copy will be made)
@param timeAdjustment an optional value to add to the timestamp of the message
that will be inserted
@see updateMatchedPairs
*/
MidiEventHolder* addEvent (MidiMessage&& newMessage, double timeAdjustment = 0);
/** Deletes one of the events in the sequence.
@ -276,5 +290,7 @@ private:
friend class MidiFile;
OwnedArray<MidiEventHolder> list;
MidiEventHolder* addEvent (MidiEventHolder*, double);
JUCE_LEAK_DETECTOR (MidiMessageSequence)
};