mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Added some move constructors for MidiFile, and tidied-up its internals a bit
This commit is contained in:
parent
bb5bbf32a9
commit
4955271ce0
2 changed files with 68 additions and 63 deletions
|
|
@ -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<OwnedArray<MidiMessageSequence>&&> (other.tracks)),
|
||||
timeFormat (other.timeFormat)
|
||||
{
|
||||
}
|
||||
|
||||
MidiFile& MidiFile::operator= (MidiFile&& other)
|
||||
{
|
||||
tracks = static_cast<OwnedArray<MidiMessageSequence>&&> (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<const uint8*> (data.getData());
|
||||
auto size = data.getSize();
|
||||
auto d = static_cast<const uint8*> (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());
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue