|
|
|
@@ -39,8 +39,7 @@ namespace MidiHelpers |
|
|
|
int MidiMessage::readVariableLengthVal (const uint8* data, int& numBytesUsed) noexcept
|
|
|
|
{
|
|
|
|
numBytesUsed = 0;
|
|
|
|
int v = 0;
|
|
|
|
int i;
|
|
|
|
int v = 0, i;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
@@ -76,28 +75,9 @@ int MidiMessage::getMessageLengthFromFirstByte (const uint8 firstByte) noexcept |
|
|
|
return messageLengths [firstByte & 0x7f];
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
inline void MidiMessage::setToUseInternalData() noexcept
|
|
|
|
{
|
|
|
|
data = static_cast <uint8*> (preallocatedData.asBytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool MidiMessage::usesAllocatedData() const noexcept
|
|
|
|
{
|
|
|
|
return data != static_cast <const uint8*> (preallocatedData.asBytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void MidiMessage::freeData() noexcept
|
|
|
|
{
|
|
|
|
if (usesAllocatedData())
|
|
|
|
delete[] data;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
MidiMessage::MidiMessage() noexcept
|
|
|
|
: timeStamp (0),
|
|
|
|
data (static_cast<uint8*> (preallocatedData.asBytes)),
|
|
|
|
size (2)
|
|
|
|
: timeStamp (0), size (2)
|
|
|
|
{
|
|
|
|
preallocatedData.asBytes[0] = 0xf0;
|
|
|
|
preallocatedData.asBytes[1] = 0xf7;
|
|
|
|
@@ -109,21 +89,22 @@ MidiMessage::MidiMessage (const void* const d, const int dataSize, const double |
|
|
|
{
|
|
|
|
jassert (dataSize > 0);
|
|
|
|
|
|
|
|
if (dataSize <= 4)
|
|
|
|
setToUseInternalData();
|
|
|
|
if (dataSize > 4)
|
|
|
|
{
|
|
|
|
allocatedData.malloc (dataSize);
|
|
|
|
memcpy (allocatedData, d, (size_t) dataSize);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
data = new uint8 [dataSize];
|
|
|
|
|
|
|
|
memcpy (data, d, (size_t) dataSize);
|
|
|
|
{
|
|
|
|
memcpy (preallocatedData.asBytes, d, (size_t) dataSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
// check that the length matches the data..
|
|
|
|
jassert (size > 3 || data[0] >= 0xf0 || getMessageLengthFromFirstByte (data[0]) == size);
|
|
|
|
jassert (size > 3 || *(uint8*)d >= 0xf0 || getMessageLengthFromFirstByte (*(uint8*)d) == size);
|
|
|
|
}
|
|
|
|
|
|
|
|
MidiMessage::MidiMessage (const int byte1, const double t) noexcept
|
|
|
|
: timeStamp (t),
|
|
|
|
data (static_cast<uint8*> (preallocatedData.asBytes)),
|
|
|
|
size (1)
|
|
|
|
: timeStamp (t), size (1)
|
|
|
|
{
|
|
|
|
preallocatedData.asBytes[0] = (uint8) byte1;
|
|
|
|
|
|
|
|
@@ -132,9 +113,7 @@ MidiMessage::MidiMessage (const int byte1, const double t) noexcept |
|
|
|
}
|
|
|
|
|
|
|
|
MidiMessage::MidiMessage (const int byte1, const int byte2, const double t) noexcept
|
|
|
|
: timeStamp (t),
|
|
|
|
data (static_cast<uint8*> (preallocatedData.asBytes)),
|
|
|
|
size (2)
|
|
|
|
: timeStamp (t), size (2)
|
|
|
|
{
|
|
|
|
preallocatedData.asBytes[0] = (uint8) byte1;
|
|
|
|
preallocatedData.asBytes[1] = (uint8) byte2;
|
|
|
|
@@ -144,9 +123,7 @@ MidiMessage::MidiMessage (const int byte1, const int byte2, const double t) noex |
|
|
|
}
|
|
|
|
|
|
|
|
MidiMessage::MidiMessage (const int byte1, const int byte2, const int byte3, const double t) noexcept
|
|
|
|
: timeStamp (t),
|
|
|
|
data (static_cast<uint8*> (preallocatedData.asBytes)),
|
|
|
|
size (3)
|
|
|
|
: timeStamp (t), size (3)
|
|
|
|
{
|
|
|
|
preallocatedData.asBytes[0] = (uint8) byte1;
|
|
|
|
preallocatedData.asBytes[1] = (uint8) byte2;
|
|
|
|
@@ -157,42 +134,37 @@ MidiMessage::MidiMessage (const int byte1, const int byte2, const int byte3, con |
|
|
|
}
|
|
|
|
|
|
|
|
MidiMessage::MidiMessage (const MidiMessage& other)
|
|
|
|
: timeStamp (other.timeStamp),
|
|
|
|
size (other.size)
|
|
|
|
: timeStamp (other.timeStamp), size (other.size)
|
|
|
|
{
|
|
|
|
if (other.usesAllocatedData())
|
|
|
|
if (size > 4)
|
|
|
|
{
|
|
|
|
data = new uint8 [size];
|
|
|
|
memcpy (data, other.data, (size_t) size);
|
|
|
|
allocatedData.malloc (size);
|
|
|
|
memcpy (allocatedData, other.allocatedData, (size_t) size);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setToUseInternalData();
|
|
|
|
preallocatedData.asInt32 = other.preallocatedData.asInt32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MidiMessage::MidiMessage (const MidiMessage& other, const double newTimeStamp)
|
|
|
|
: timeStamp (newTimeStamp),
|
|
|
|
size (other.size)
|
|
|
|
: timeStamp (newTimeStamp), size (other.size)
|
|
|
|
{
|
|
|
|
if (other.usesAllocatedData())
|
|
|
|
if (size > 4)
|
|
|
|
{
|
|
|
|
data = new uint8 [size];
|
|
|
|
memcpy (data, other.data, (size_t) size);
|
|
|
|
allocatedData.malloc (size);
|
|
|
|
memcpy (allocatedData, other.allocatedData, (size_t) size);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setToUseInternalData();
|
|
|
|
preallocatedData.asInt32 = other.preallocatedData.asInt32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MidiMessage::MidiMessage (const void* src_, int sz, int& numBytesUsed, const uint8 lastStatusByte, double t)
|
|
|
|
: timeStamp (t),
|
|
|
|
data (static_cast<uint8*> (preallocatedData.asBytes))
|
|
|
|
MidiMessage::MidiMessage (const void* srcData, int sz, int& numBytesUsed, const uint8 lastStatusByte, double t)
|
|
|
|
: timeStamp (t)
|
|
|
|
{
|
|
|
|
const uint8* src = static_cast <const uint8*> (src_);
|
|
|
|
const uint8* src = static_cast <const uint8*> (srcData);
|
|
|
|
unsigned int byte = (unsigned int) *src;
|
|
|
|
|
|
|
|
if (byte < 0x80)
|
|
|
|
@@ -242,11 +214,12 @@ MidiMessage::MidiMessage (const void* src_, int sz, int& numBytesUsed, const uin |
|
|
|
++d;
|
|
|
|
}
|
|
|
|
|
|
|
|
src += numVariableLengthSysexBytes;
|
|
|
|
size = 1 + (int) (d - src);
|
|
|
|
|
|
|
|
data = new uint8 [size - numVariableLengthSysexBytes];
|
|
|
|
*data = (uint8) byte;
|
|
|
|
memcpy (data + 1, src + numVariableLengthSysexBytes, (size_t) (size - numVariableLengthSysexBytes - 1));
|
|
|
|
allocatedData.malloc (size);
|
|
|
|
*allocatedData = (uint8) byte;
|
|
|
|
memcpy (allocatedData + 1, src, (size_t) (size - 1));
|
|
|
|
}
|
|
|
|
else if (byte == 0xff)
|
|
|
|
{
|
|
|
|
@@ -254,22 +227,22 @@ MidiMessage::MidiMessage (const void* src_, int sz, int& numBytesUsed, const uin |
|
|
|
const int bytesLeft = readVariableLengthVal (src + 1, n);
|
|
|
|
size = jmin (sz + 1, n + 2 + bytesLeft);
|
|
|
|
|
|
|
|
data = new uint8 [size];
|
|
|
|
*data = (uint8) byte;
|
|
|
|
memcpy (data + 1, src, (size_t) size - 1);
|
|
|
|
allocatedData.malloc (size);
|
|
|
|
*allocatedData = (uint8) byte;
|
|
|
|
memcpy (allocatedData + 1, src, (size_t) size - 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
preallocatedData.asInt32 = 0;
|
|
|
|
size = getMessageLengthFromFirstByte ((uint8) byte);
|
|
|
|
data[0] = (uint8) byte;
|
|
|
|
preallocatedData.asBytes[0] = (uint8) byte;
|
|
|
|
|
|
|
|
if (size > 1)
|
|
|
|
{
|
|
|
|
data[1] = src[0];
|
|
|
|
preallocatedData.asBytes[1] = src[0];
|
|
|
|
|
|
|
|
if (size > 2)
|
|
|
|
data[2] = src[1];
|
|
|
|
preallocatedData.asBytes[2] = src[1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -289,16 +262,14 @@ MidiMessage& MidiMessage::operator= (const MidiMessage& other) |
|
|
|
timeStamp = other.timeStamp;
|
|
|
|
size = other.size;
|
|
|
|
|
|
|
|
freeData();
|
|
|
|
|
|
|
|
if (other.usesAllocatedData())
|
|
|
|
if (size > 4)
|
|
|
|
{
|
|
|
|
data = new uint8 [size];
|
|
|
|
memcpy (data, other.data, (size_t) size);
|
|
|
|
allocatedData.malloc (size);
|
|
|
|
memcpy (allocatedData, other.allocatedData, (size_t) size);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setToUseInternalData();
|
|
|
|
allocatedData.free();
|
|
|
|
preallocatedData.asInt32 = other.preallocatedData.asInt32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -308,19 +279,12 @@ MidiMessage& MidiMessage::operator= (const MidiMessage& other) |
|
|
|
|
|
|
|
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
|
|
|
MidiMessage::MidiMessage (MidiMessage&& other) noexcept
|
|
|
|
: timeStamp (other.timeStamp),
|
|
|
|
size (other.size)
|
|
|
|
: timeStamp (other.timeStamp), size (other.size)
|
|
|
|
{
|
|
|
|
if (other.usesAllocatedData())
|
|
|
|
{
|
|
|
|
data = other.data;
|
|
|
|
other.setToUseInternalData();
|
|
|
|
}
|
|
|
|
if (other.allocatedData != nullptr)
|
|
|
|
allocatedData.swapWith (other.allocatedData);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setToUseInternalData();
|
|
|
|
preallocatedData.asInt32 = other.preallocatedData.asInt32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MidiMessage& MidiMessage::operator= (MidiMessage&& other) noexcept
|
|
|
|
@@ -329,31 +293,19 @@ MidiMessage& MidiMessage::operator= (MidiMessage&& other) noexcept |
|
|
|
|
|
|
|
timeStamp = other.timeStamp;
|
|
|
|
size = other.size;
|
|
|
|
|
|
|
|
freeData();
|
|
|
|
|
|
|
|
if (other.usesAllocatedData())
|
|
|
|
{
|
|
|
|
data = other.data;
|
|
|
|
other.setToUseInternalData();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setToUseInternalData();
|
|
|
|
preallocatedData.asInt32 = other.preallocatedData.asInt32;
|
|
|
|
}
|
|
|
|
allocatedData.swapWith (other.allocatedData);
|
|
|
|
preallocatedData.asInt32 = other.preallocatedData.asInt32;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
MidiMessage::~MidiMessage()
|
|
|
|
{
|
|
|
|
freeData();
|
|
|
|
}
|
|
|
|
MidiMessage::~MidiMessage() {}
|
|
|
|
|
|
|
|
int MidiMessage::getChannel() const noexcept
|
|
|
|
{
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
if ((data[0] & 0xf0) != 0xf0)
|
|
|
|
return (data[0] & 0xf) + 1;
|
|
|
|
|
|
|
|
@@ -364,6 +316,8 @@ bool MidiMessage::isForChannel (const int channel) const noexcept |
|
|
|
{
|
|
|
|
jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16
|
|
|
|
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
return ((data[0] & 0xf) == channel - 1)
|
|
|
|
&& ((data[0] & 0xf0) != 0xf0);
|
|
|
|
}
|
|
|
|
@@ -372,6 +326,8 @@ void MidiMessage::setChannel (const int channel) noexcept |
|
|
|
{
|
|
|
|
jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16
|
|
|
|
|
|
|
|
uint8* const data = getData();
|
|
|
|
|
|
|
|
if ((data[0] & 0xf0) != (uint8) 0xf0)
|
|
|
|
data[0] = (uint8) ((data[0] & (uint8) 0xf0)
|
|
|
|
| (uint8)(channel - 1));
|
|
|
|
@@ -379,37 +335,43 @@ void MidiMessage::setChannel (const int channel) noexcept |
|
|
|
|
|
|
|
bool MidiMessage::isNoteOn (const bool returnTrueForVelocity0) const noexcept
|
|
|
|
{
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
return ((data[0] & 0xf0) == 0x90)
|
|
|
|
&& (returnTrueForVelocity0 || data[2] != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MidiMessage::isNoteOff (const bool returnTrueForNoteOnVelocity0) const noexcept
|
|
|
|
{
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
return ((data[0] & 0xf0) == 0x80)
|
|
|
|
|| (returnTrueForNoteOnVelocity0 && (data[2] == 0) && ((data[0] & 0xf0) == 0x90));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MidiMessage::isNoteOnOrOff() const noexcept
|
|
|
|
{
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
const int d = data[0] & 0xf0;
|
|
|
|
return (d == 0x90) || (d == 0x80);
|
|
|
|
}
|
|
|
|
|
|
|
|
int MidiMessage::getNoteNumber() const noexcept
|
|
|
|
{
|
|
|
|
return data[1];
|
|
|
|
return getRawData()[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
void MidiMessage::setNoteNumber (const int newNoteNumber) noexcept
|
|
|
|
{
|
|
|
|
if (isNoteOnOrOff())
|
|
|
|
data[1] = (uint8) (newNoteNumber & 127);
|
|
|
|
getData()[1] = (uint8) (newNoteNumber & 127);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8 MidiMessage::getVelocity() const noexcept
|
|
|
|
{
|
|
|
|
if (isNoteOnOrOff())
|
|
|
|
return data[2];
|
|
|
|
return getRawData()[2];
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
@@ -422,24 +384,27 @@ float MidiMessage::getFloatVelocity() const noexcept |
|
|
|
void MidiMessage::setVelocity (const float newVelocity) noexcept
|
|
|
|
{
|
|
|
|
if (isNoteOnOrOff())
|
|
|
|
data[2] = MidiHelpers::validVelocity (roundToInt (newVelocity * 127.0f));
|
|
|
|
getData()[2] = MidiHelpers::validVelocity (roundToInt (newVelocity * 127.0f));
|
|
|
|
}
|
|
|
|
|
|
|
|
void MidiMessage::multiplyVelocity (const float scaleFactor) noexcept
|
|
|
|
{
|
|
|
|
if (isNoteOnOrOff())
|
|
|
|
{
|
|
|
|
uint8* const data = getData();
|
|
|
|
data[2] = MidiHelpers::validVelocity (roundToInt (scaleFactor * data[2]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MidiMessage::isAftertouch() const noexcept
|
|
|
|
{
|
|
|
|
return (data[0] & 0xf0) == 0xa0;
|
|
|
|
return (getRawData()[0] & 0xf0) == 0xa0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int MidiMessage::getAfterTouchValue() const noexcept
|
|
|
|
{
|
|
|
|
jassert (isAftertouch());
|
|
|
|
return data[2];
|
|
|
|
return getRawData()[2];
|
|
|
|
}
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::aftertouchChange (const int channel,
|
|
|
|
@@ -457,13 +422,13 @@ MidiMessage MidiMessage::aftertouchChange (const int channel, |
|
|
|
|
|
|
|
bool MidiMessage::isChannelPressure() const noexcept
|
|
|
|
{
|
|
|
|
return (data[0] & 0xf0) == 0xd0;
|
|
|
|
return (getRawData()[0] & 0xf0) == 0xd0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int MidiMessage::getChannelPressureValue() const noexcept
|
|
|
|
{
|
|
|
|
jassert (isChannelPressure());
|
|
|
|
return data[1];
|
|
|
|
return getRawData()[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::channelPressureChange (const int channel, const int pressure) noexcept
|
|
|
|
@@ -474,25 +439,25 @@ MidiMessage MidiMessage::channelPressureChange (const int channel, const int pre |
|
|
|
return MidiMessage (MidiHelpers::initialByte (0xd0, channel), pressure & 0x7f);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MidiMessage::isSustainPedalOn() const noexcept { return isControllerOfType (0x40) && data[2] >= 64; }
|
|
|
|
bool MidiMessage::isSustainPedalOff() const noexcept { return isControllerOfType (0x40) && data[2] < 64; }
|
|
|
|
bool MidiMessage::isSustainPedalOn() const noexcept { return isControllerOfType (0x40) && getRawData()[2] >= 64; }
|
|
|
|
bool MidiMessage::isSustainPedalOff() const noexcept { return isControllerOfType (0x40) && getRawData()[2] < 64; }
|
|
|
|
|
|
|
|
bool MidiMessage::isSostenutoPedalOn() const noexcept { return isControllerOfType (0x42) && data[2] >= 64; }
|
|
|
|
bool MidiMessage::isSostenutoPedalOff() const noexcept { return isControllerOfType (0x42) && data[2] < 64; }
|
|
|
|
bool MidiMessage::isSostenutoPedalOn() const noexcept { return isControllerOfType (0x42) && getRawData()[2] >= 64; }
|
|
|
|
bool MidiMessage::isSostenutoPedalOff() const noexcept { return isControllerOfType (0x42) && getRawData()[2] < 64; }
|
|
|
|
|
|
|
|
bool MidiMessage::isSoftPedalOn() const noexcept { return isControllerOfType (0x43) && data[2] >= 64; }
|
|
|
|
bool MidiMessage::isSoftPedalOff() const noexcept { return isControllerOfType (0x43) && data[2] < 64; }
|
|
|
|
bool MidiMessage::isSoftPedalOn() const noexcept { return isControllerOfType (0x43) && getRawData()[2] >= 64; }
|
|
|
|
bool MidiMessage::isSoftPedalOff() const noexcept { return isControllerOfType (0x43) && getRawData()[2] < 64; }
|
|
|
|
|
|
|
|
|
|
|
|
bool MidiMessage::isProgramChange() const noexcept
|
|
|
|
{
|
|
|
|
return (data[0] & 0xf0) == 0xc0;
|
|
|
|
return (getRawData()[0] & 0xf0) == 0xc0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int MidiMessage::getProgramChangeNumber() const noexcept
|
|
|
|
{
|
|
|
|
jassert (isProgramChange());
|
|
|
|
return data[1];
|
|
|
|
return getRawData()[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::programChange (const int channel, const int programNumber) noexcept
|
|
|
|
@@ -504,12 +469,13 @@ MidiMessage MidiMessage::programChange (const int channel, const int programNumb |
|
|
|
|
|
|
|
bool MidiMessage::isPitchWheel() const noexcept
|
|
|
|
{
|
|
|
|
return (data[0] & 0xf0) == 0xe0;
|
|
|
|
return (getRawData()[0] & 0xf0) == 0xe0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int MidiMessage::getPitchWheelValue() const noexcept
|
|
|
|
{
|
|
|
|
jassert (isPitchWheel());
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
return data[1] | (data[2] << 7);
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -524,24 +490,25 @@ MidiMessage MidiMessage::pitchWheel (const int channel, const int position) noex |
|
|
|
|
|
|
|
bool MidiMessage::isController() const noexcept
|
|
|
|
{
|
|
|
|
return (data[0] & 0xf0) == 0xb0;
|
|
|
|
return (getRawData()[0] & 0xf0) == 0xb0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MidiMessage::isControllerOfType (const int controllerType) const noexcept
|
|
|
|
{
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
return (data[0] & 0xf0) == 0xb0 && data[1] == controllerType;
|
|
|
|
}
|
|
|
|
|
|
|
|
int MidiMessage::getControllerNumber() const noexcept
|
|
|
|
{
|
|
|
|
jassert (isController());
|
|
|
|
return data[1];
|
|
|
|
return getRawData()[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
int MidiMessage::getControllerValue() const noexcept
|
|
|
|
{
|
|
|
|
jassert (isController());
|
|
|
|
return data[2];
|
|
|
|
return getRawData()[2];
|
|
|
|
}
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::controllerEvent (const int channel, const int controllerType, const int value) noexcept
|
|
|
|
@@ -583,6 +550,7 @@ MidiMessage MidiMessage::allNotesOff (const int channel) noexcept |
|
|
|
|
|
|
|
bool MidiMessage::isAllNotesOff() const noexcept
|
|
|
|
{
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
return (data[0] & 0xf0) == 0xb0 && data[1] == 123;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -593,6 +561,7 @@ MidiMessage MidiMessage::allSoundOff (const int channel) noexcept |
|
|
|
|
|
|
|
bool MidiMessage::isAllSoundOff() const noexcept
|
|
|
|
{
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
return (data[0] & 0xf0) == 0xb0 && data[1] == 120;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -616,7 +585,7 @@ MidiMessage MidiMessage::masterVolume (const float volume) |
|
|
|
//==============================================================================
|
|
|
|
bool MidiMessage::isSysEx() const noexcept
|
|
|
|
{
|
|
|
|
return *data == 0xf0;
|
|
|
|
return *getRawData() == 0xf0;
|
|
|
|
}
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::createSysExMessage (const void* sysexData, const int dataSize)
|
|
|
|
@@ -641,16 +610,18 @@ int MidiMessage::getSysExDataSize() const noexcept |
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
bool MidiMessage::isMetaEvent() const noexcept { return *data == 0xff; }
|
|
|
|
bool MidiMessage::isActiveSense() const noexcept { return *data == 0xfe; }
|
|
|
|
bool MidiMessage::isMetaEvent() const noexcept { return *getRawData() == 0xff; }
|
|
|
|
bool MidiMessage::isActiveSense() const noexcept { return *getRawData() == 0xfe; }
|
|
|
|
|
|
|
|
int MidiMessage::getMetaEventType() const noexcept
|
|
|
|
{
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
return *data != 0xff ? -1 : data[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
int MidiMessage::getMetaEventLength() const noexcept
|
|
|
|
{
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
if (*data == 0xff)
|
|
|
|
{
|
|
|
|
int n;
|
|
|
|
@@ -665,7 +636,7 @@ const uint8* MidiMessage::getMetaEventData() const noexcept |
|
|
|
jassert (isMetaEvent());
|
|
|
|
|
|
|
|
int n;
|
|
|
|
const uint8* d = data + 2;
|
|
|
|
const uint8* d = getRawData() + 2;
|
|
|
|
readVariableLengthVal (d, n);
|
|
|
|
return d + n;
|
|
|
|
}
|
|
|
|
@@ -686,14 +657,14 @@ String MidiMessage::getTextFromTextMetaEvent() const |
|
|
|
CharPointer_UTF8 (textData + getMetaEventLength()));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MidiMessage::isTrackNameEvent() const noexcept { return (data[1] == 3) && (*data == 0xff); }
|
|
|
|
bool MidiMessage::isTempoMetaEvent() const noexcept { return (data[1] == 81) && (*data == 0xff); }
|
|
|
|
bool MidiMessage::isMidiChannelMetaEvent() const noexcept { return (data[1] == 0x20) && (*data == 0xff) && (data[2] == 1); }
|
|
|
|
bool MidiMessage::isTrackNameEvent() const noexcept { const uint8* data = getRawData(); return (data[1] == 3) && (*data == 0xff); }
|
|
|
|
bool MidiMessage::isTempoMetaEvent() const noexcept { const uint8* data = getRawData(); return (data[1] == 81) && (*data == 0xff); }
|
|
|
|
bool MidiMessage::isMidiChannelMetaEvent() const noexcept { const uint8* data = getRawData(); return (data[1] == 0x20) && (*data == 0xff) && (data[2] == 1); }
|
|
|
|
|
|
|
|
int MidiMessage::getMidiChannelMetaEventChannel() const noexcept
|
|
|
|
{
|
|
|
|
jassert (isMidiChannelMetaEvent());
|
|
|
|
return data[3] + 1;
|
|
|
|
return getRawData()[3] + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
double MidiMessage::getTempoSecondsPerQuarterNote() const noexcept
|
|
|
|
@@ -748,6 +719,7 @@ MidiMessage MidiMessage::tempoMetaEvent (int microsecondsPerQuarterNote) noexcep |
|
|
|
|
|
|
|
bool MidiMessage::isTimeSignatureMetaEvent() const noexcept
|
|
|
|
{
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
return (data[1] == 0x58) && (*data == (uint8) 0xff);
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -816,8 +788,8 @@ MidiMessage MidiMessage::endOfTrack() noexcept |
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
bool MidiMessage::isSongPositionPointer() const noexcept { return *data == 0xf2; }
|
|
|
|
int MidiMessage::getSongPositionPointerMidiBeat() const noexcept { return data[1] | (data[2] << 7); }
|
|
|
|
bool MidiMessage::isSongPositionPointer() const noexcept { return *getRawData() == 0xf2; }
|
|
|
|
int MidiMessage::getSongPositionPointerMidiBeat() const noexcept { const uint8* data = getRawData(); return data[1] | (data[2] << 7); }
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::songPositionPointer (const int positionInMidiBeats) noexcept
|
|
|
|
{
|
|
|
|
@@ -826,21 +798,21 @@ MidiMessage MidiMessage::songPositionPointer (const int positionInMidiBeats) noe |
|
|
|
(positionInMidiBeats >> 7) & 127);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MidiMessage::isMidiStart() const noexcept { return *data == 0xfa; }
|
|
|
|
bool MidiMessage::isMidiStart() const noexcept { return *getRawData() == 0xfa; }
|
|
|
|
MidiMessage MidiMessage::midiStart() noexcept { return MidiMessage (0xfa); }
|
|
|
|
|
|
|
|
bool MidiMessage::isMidiContinue() const noexcept { return *data == 0xfb; }
|
|
|
|
bool MidiMessage::isMidiContinue() const noexcept { return *getRawData() == 0xfb; }
|
|
|
|
MidiMessage MidiMessage::midiContinue() noexcept { return MidiMessage (0xfb); }
|
|
|
|
|
|
|
|
bool MidiMessage::isMidiStop() const noexcept { return *data == 0xfc; }
|
|
|
|
bool MidiMessage::isMidiStop() const noexcept { return *getRawData() == 0xfc; }
|
|
|
|
MidiMessage MidiMessage::midiStop() noexcept { return MidiMessage (0xfc); }
|
|
|
|
|
|
|
|
bool MidiMessage::isMidiClock() const noexcept { return *data == 0xf8; }
|
|
|
|
bool MidiMessage::isMidiClock() const noexcept { return *getRawData() == 0xf8; }
|
|
|
|
MidiMessage MidiMessage::midiClock() noexcept { return MidiMessage (0xf8); }
|
|
|
|
|
|
|
|
bool MidiMessage::isQuarterFrame() const noexcept { return *data == 0xf1; }
|
|
|
|
int MidiMessage::getQuarterFrameSequenceNumber() const noexcept { return ((int) data[1]) >> 4; }
|
|
|
|
int MidiMessage::getQuarterFrameValue() const noexcept { return ((int) data[1]) & 0x0f; }
|
|
|
|
bool MidiMessage::isQuarterFrame() const noexcept { return *getRawData() == 0xf1; }
|
|
|
|
int MidiMessage::getQuarterFrameSequenceNumber() const noexcept { return ((int) getRawData()[1]) >> 4; }
|
|
|
|
int MidiMessage::getQuarterFrameValue() const noexcept { return ((int) getRawData()[1]) & 0x0f; }
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::quarterFrame (const int sequenceNumber, const int value) noexcept
|
|
|
|
{
|
|
|
|
@@ -849,6 +821,8 @@ MidiMessage MidiMessage::quarterFrame (const int sequenceNumber, const int value |
|
|
|
|
|
|
|
bool MidiMessage::isFullFrame() const noexcept
|
|
|
|
{
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
return data[0] == 0xf0
|
|
|
|
&& data[1] == 0x7f
|
|
|
|
&& size >= 10
|
|
|
|
@@ -861,6 +835,7 @@ void MidiMessage::getFullFrameParameters (int& hours, int& minutes, int& seconds |
|
|
|
{
|
|
|
|
jassert (isFullFrame());
|
|
|
|
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
timecodeType = (SmpteTimecodeType) (data[5] >> 5);
|
|
|
|
hours = data[5] & 0x1f;
|
|
|
|
minutes = data[6];
|
|
|
|
@@ -884,6 +859,7 @@ MidiMessage MidiMessage::fullFrame (const int hours, const int minutes, |
|
|
|
|
|
|
|
bool MidiMessage::isMidiMachineControlMessage() const noexcept
|
|
|
|
{
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
return data[0] == 0xf0
|
|
|
|
&& data[1] == 0x7f
|
|
|
|
&& data[3] == 0x06
|
|
|
|
@@ -894,7 +870,7 @@ MidiMessage::MidiMachineControlCommand MidiMessage::getMidiMachineControlCommand |
|
|
|
{
|
|
|
|
jassert (isMidiMachineControlMessage());
|
|
|
|
|
|
|
|
return (MidiMachineControlCommand) data[4];
|
|
|
|
return (MidiMachineControlCommand) getRawData()[4];
|
|
|
|
}
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::midiMachineControlCommand (MidiMessage::MidiMachineControlCommand command)
|
|
|
|
@@ -907,6 +883,7 @@ MidiMessage MidiMessage::midiMachineControlCommand (MidiMessage::MidiMachineCont |
|
|
|
//==============================================================================
|
|
|
|
bool MidiMessage::isMidiMachineControlGoto (int& hours, int& minutes, int& seconds, int& frames) const noexcept
|
|
|
|
{
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
if (size >= 12
|
|
|
|
&& data[0] == 0xf0
|
|
|
|
&& data[1] == 0x7f
|
|
|
|
|