From 4955271ce0dfed4225a63b217a0270c9a60523d7 Mon Sep 17 00:00:00 2001 From: jules Date: Wed, 31 Jan 2018 17:19:51 +0000 Subject: [PATCH] Added some move constructors for MidiFile, and tidied-up its internals a bit --- .../juce_audio_basics/midi/juce_MidiFile.cpp | 116 +++++++++--------- .../juce_audio_basics/midi/juce_MidiFile.h | 15 ++- 2 files changed, 68 insertions(+), 63 deletions(-) diff --git a/modules/juce_audio_basics/midi/juce_MidiFile.cpp b/modules/juce_audio_basics/midi/juce_MidiFile.cpp index 427451747e..65e7b0edd2 100644 --- a/modules/juce_audio_basics/midi/juce_MidiFile.cpp +++ b/modules/juce_audio_basics/midi/juce_MidiFile.cpp @@ -25,9 +25,9 @@ namespace juce namespace MidiFileHelpers { - static void writeVariableLengthInt (OutputStream& out, unsigned int v) + static void writeVariableLengthInt (OutputStream& out, uint32 v) { - unsigned int buffer = v & 0x7f; + auto buffer = v & 0x7f; while ((v >>= 7) != 0) { @@ -48,7 +48,7 @@ namespace MidiFileHelpers static bool parseMidiHeader (const uint8* &data, short& timeFormat, short& fileType, short& numberOfTracks) noexcept { - unsigned int ch = ByteOrder::bigEndianInt (data); + auto ch = ByteOrder::bigEndianInt (data); data += 4; if (ch != ByteOrder::bigEndianInt ("MThd")) @@ -74,7 +74,7 @@ namespace MidiFileHelpers return false; } - unsigned int bytesRemaining = ByteOrder::bigEndianInt (data); + auto bytesRemaining = ByteOrder::bigEndianInt (data); data += 4; fileType = (short) ByteOrder::bigEndianShort (data); data += 2; @@ -88,22 +88,22 @@ namespace MidiFileHelpers return true; } - static double convertTicksToSeconds (const double time, + static double convertTicksToSeconds (double time, const MidiMessageSequence& tempoEvents, - const int timeFormat) + int timeFormat) { if (timeFormat < 0) return time / (-(timeFormat >> 8) * (timeFormat & 0xff)); - double lastTime = 0.0, correctedTime = 0.0; - const double tickLen = 1.0 / (timeFormat & 0x7fff); - double secsPerTick = 0.5 * tickLen; - const int numEvents = tempoEvents.getNumEvents(); + double lastTime = 0, correctedTime = 0; + auto tickLen = 1.0 / (timeFormat & 0x7fff); + auto secsPerTick = 0.5 * tickLen; + auto numEvents = tempoEvents.getNumEvents(); for (int i = 0; i < numEvents; ++i) { - const MidiMessage& m = tempoEvents.getEventPointer(i)->message; - const double eventTime = m.getTimeStamp(); + auto& m = tempoEvents.getEventPointer(i)->message; + auto eventTime = m.getTimeStamp(); if (eventTime >= time) break; @@ -116,7 +116,7 @@ namespace MidiFileHelpers while (i + 1 < numEvents) { - const MidiMessage& m2 = tempoEvents.getEventPointer(i + 1)->message; + auto& m2 = tempoEvents.getEventPointer(i + 1)->message; if (m2.getTimeStamp() != eventTime) break; @@ -136,14 +136,13 @@ namespace MidiFileHelpers MidiMessageSequence& results, MethodType method) { - for (int i = 0; i < tracks.size(); ++i) + for (auto* track : tracks) { - const MidiMessageSequence& track = *tracks.getUnchecked(i); - const int numEvents = track.getNumEvents(); + auto numEvents = track->getNumEvents(); for (int j = 0; j < numEvents; ++j) { - const MidiMessage& m = track.getEventPointer(j)->message; + auto& m = track->getEventPointer(j)->message; if ((m.*method)()) results.addEvent (m); @@ -153,27 +152,32 @@ namespace MidiFileHelpers } //============================================================================== -MidiFile::MidiFile() - : timeFormat ((short) (unsigned short) 0xe728) -{ -} +MidiFile::MidiFile() : timeFormat ((short) (unsigned short) 0xe728) {} +MidiFile::~MidiFile() {} -MidiFile::~MidiFile() -{ -} - -MidiFile::MidiFile (const MidiFile& other) - : timeFormat (other.timeFormat) +MidiFile::MidiFile (const MidiFile& other) : timeFormat (other.timeFormat) { tracks.addCopiesOf (other.tracks); } MidiFile& MidiFile::operator= (const MidiFile& other) { - timeFormat = other.timeFormat; tracks.clear(); tracks.addCopiesOf (other.tracks); + timeFormat = other.timeFormat; + return *this; +} +MidiFile::MidiFile (MidiFile&& other) + : tracks (static_cast&&> (other.tracks)), + timeFormat (other.timeFormat) +{ +} + +MidiFile& MidiFile::operator= (MidiFile&& other) +{ + tracks = static_cast&&> (other.tracks); + timeFormat = other.timeFormat; return *this; } @@ -188,9 +192,9 @@ int MidiFile::getNumTracks() const noexcept return tracks.size(); } -const MidiMessageSequence* MidiFile::getTrack (const int index) const noexcept +const MidiMessageSequence* MidiFile::getTrack (int index) const noexcept { - return tracks [index]; + return tracks[index]; } void MidiFile::addTrack (const MidiMessageSequence& trackSequence) @@ -204,13 +208,12 @@ short MidiFile::getTimeFormat() const noexcept return timeFormat; } -void MidiFile::setTicksPerQuarterNote (const int ticks) noexcept +void MidiFile::setTicksPerQuarterNote (int ticks) noexcept { timeFormat = (short) ticks; } -void MidiFile::setSmpteTimeFormat (const int framesPerSecond, - const int subframeResolution) noexcept +void MidiFile::setSmpteTimeFormat (int framesPerSecond, int subframeResolution) noexcept { timeFormat = (short) (((-framesPerSecond) << 8) | subframeResolution); } @@ -235,8 +238,8 @@ double MidiFile::getLastTimestamp() const { double t = 0.0; - for (int i = tracks.size(); --i >= 0;) - t = jmax (t, tracks.getUnchecked(i)->getEndTime()); + for (auto* ms : tracks) + t = jmax (t, ms->getEndTime()); return t; } @@ -252,8 +255,8 @@ bool MidiFile::readFrom (InputStream& sourceStream) // (put a sanity-check on the file size, as midi files are generally small) if (sourceStream.readIntoMemoryBlock (data, maxSensibleMidiFileSize)) { - size_t size = data.getSize(); - const uint8* d = static_cast (data.getData()); + auto size = data.getSize(); + auto d = static_cast (data.getData()); short fileType, expectedTracks; if (size > 16 && MidiFileHelpers::parseMidiHeader (d, timeFormat, fileType, expectedTracks)) @@ -264,9 +267,9 @@ bool MidiFile::readFrom (InputStream& sourceStream) while (size > 0 && track < expectedTracks) { - const int chunkType = (int) ByteOrder::bigEndianInt (d); + auto chunkType = (int) ByteOrder::bigEndianInt (d); d += 4; - const int chunkSize = (int) ByteOrder::bigEndianInt (d); + auto chunkSize = (int) ByteOrder::bigEndianInt (d); d += 4; if (chunkSize <= 0) @@ -297,7 +300,7 @@ void MidiFile::readNextTrack (const uint8* data, int size) while (size > 0) { int bytesUsed; - const int delay = MidiMessage::readVariableLengthVal (data, bytesUsed); + auto delay = MidiMessage::readVariableLengthVal (data, bytesUsed); data += bytesUsed; size -= bytesUsed; time += delay; @@ -313,7 +316,8 @@ void MidiFile::readNextTrack (const uint8* data, int size) result.addEvent (mm); - const uint8 firstByte = *(mm.getRawData()); + auto firstByte = *(mm.getRawData()); + if ((firstByte & 0xf0) != 0xf0) lastStatusByte = firstByte; } @@ -345,13 +349,11 @@ void MidiFile::convertTimestampTicksToSeconds() if (timeFormat != 0) { - for (int i = 0; i < tracks.size(); ++i) + for (auto* ms : tracks) { - const MidiMessageSequence& ms = *tracks.getUnchecked(i); - - for (int j = ms.getNumEvents(); --j >= 0;) + for (int j = ms->getNumEvents(); --j >= 0;) { - MidiMessage& m = ms.getEventPointer(j)->message; + auto& m = ms->getEventPointer(j)->message; m.setTimeStamp (MidiFileHelpers::convertTicksToSeconds (m.getTimeStamp(), tempoEvents, timeFormat)); } } @@ -369,18 +371,17 @@ bool MidiFile::writeTo (OutputStream& out, int midiFileType) if (! out.writeShortBigEndian ((short) tracks.size())) return false; if (! out.writeShortBigEndian (timeFormat)) return false; - for (int i = 0; i < tracks.size(); ++i) - if (! writeTrack (out, i)) + for (auto* ms : tracks) + if (! writeTrack (out, *ms)) return false; out.flush(); return true; } -bool MidiFile::writeTrack (OutputStream& mainOut, const int trackNum) +bool MidiFile::writeTrack (OutputStream& mainOut, const MidiMessageSequence& ms) { MemoryOutputStream out; - const MidiMessageSequence& ms = *tracks.getUnchecked (trackNum); int lastTick = 0; uint8 lastStatusByte = 0; @@ -388,20 +389,19 @@ bool MidiFile::writeTrack (OutputStream& mainOut, const int trackNum) for (int i = 0; i < ms.getNumEvents(); ++i) { - const MidiMessage& mm = ms.getEventPointer(i)->message; + auto& mm = ms.getEventPointer(i)->message; if (mm.isEndOfTrackMetaEvent()) endOfTrackEventWritten = true; - const int tick = roundToInt (mm.getTimeStamp()); - const int delta = jmax (0, tick - lastTick); + auto tick = roundToInt (mm.getTimeStamp()); + auto delta = jmax (0, tick - lastTick); MidiFileHelpers::writeVariableLengthInt (out, (uint32) delta); lastTick = tick; - const uint8* data = mm.getRawData(); - int dataSize = mm.getRawDataSize(); - - const uint8 statusByte = data[0]; + auto* data = mm.getRawData(); + auto dataSize = mm.getRawDataSize(); + auto statusByte = data[0]; if (statusByte == lastStatusByte && (statusByte & 0xf0) != 0xf0 @@ -428,7 +428,7 @@ bool MidiFile::writeTrack (OutputStream& mainOut, const int trackNum) if (! endOfTrackEventWritten) { out.writeByte (0); // (tick delta) - const MidiMessage m (MidiMessage::endOfTrack()); + auto m = MidiMessage::endOfTrack(); out.write (m.getRawData(), (size_t) m.getRawDataSize()); } diff --git a/modules/juce_audio_basics/midi/juce_MidiFile.h b/modules/juce_audio_basics/midi/juce_MidiFile.h index b06589d299..a5707264d1 100644 --- a/modules/juce_audio_basics/midi/juce_MidiFile.h +++ b/modules/juce_audio_basics/midi/juce_MidiFile.h @@ -40,18 +40,23 @@ class JUCE_API MidiFile { public: //============================================================================== - /** Creates an empty MidiFile object. - */ + /** Creates an empty MidiFile object. */ MidiFile(); /** Destructor. */ ~MidiFile(); /** Creates a copy of another MidiFile. */ - MidiFile (const MidiFile& other); + MidiFile (const MidiFile&); /** Copies from another MidiFile object */ - MidiFile& operator= (const MidiFile& other); + MidiFile& operator= (const MidiFile&); + + /** Creates a copy of another MidiFile. */ + MidiFile (MidiFile&&); + + /** Copies from another MidiFile object */ + MidiFile& operator= (MidiFile&&); //============================================================================== /** Returns the number of tracks in the file. @@ -174,7 +179,7 @@ private: short timeFormat; void readNextTrack (const uint8*, int size); - bool writeTrack (OutputStream&, int trackNum); + bool writeTrack (OutputStream&, const MidiMessageSequence&); JUCE_LEAK_DETECTOR (MidiFile) };