|
@@ -103,7 +103,7 @@ int MidiMessage::getMessageLengthFromFirstByte (const uint8 firstByte) noexcept |
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
//==============================================================================
|
|
|
MidiMessage::MidiMessage() noexcept
|
|
|
MidiMessage::MidiMessage() noexcept
|
|
|
: timeStamp (0), size (2)
|
|
|
|
|
|
|
|
|
: size (2)
|
|
|
{
|
|
|
{
|
|
|
packedData.asBytes[0] = 0xf0;
|
|
|
packedData.asBytes[0] = 0xf0;
|
|
|
packedData.asBytes[1] = 0xf7;
|
|
|
packedData.asBytes[1] = 0xf7;
|
|
@@ -171,12 +171,12 @@ MidiMessage::MidiMessage (const void* srcData, int sz, int& numBytesUsed, const |
|
|
double t, bool sysexHasEmbeddedLength)
|
|
|
double t, bool sysexHasEmbeddedLength)
|
|
|
: timeStamp (t)
|
|
|
: timeStamp (t)
|
|
|
{
|
|
|
{
|
|
|
const uint8* src = static_cast<const uint8*> (srcData);
|
|
|
|
|
|
unsigned int byte = (unsigned int) *src;
|
|
|
|
|
|
|
|
|
auto src = static_cast<const uint8*> (srcData);
|
|
|
|
|
|
auto byte = (unsigned int) *src;
|
|
|
|
|
|
|
|
|
if (byte < 0x80)
|
|
|
if (byte < 0x80)
|
|
|
{
|
|
|
{
|
|
|
byte = (unsigned int) (uint8) lastStatusByte;
|
|
|
|
|
|
|
|
|
byte = (unsigned int) lastStatusByte;
|
|
|
numBytesUsed = -1;
|
|
|
numBytesUsed = -1;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
else
|
|
@@ -190,7 +190,7 @@ MidiMessage::MidiMessage (const void* srcData, int sz, int& numBytesUsed, const |
|
|
{
|
|
|
{
|
|
|
if (byte == 0xf0)
|
|
|
if (byte == 0xf0)
|
|
|
{
|
|
|
{
|
|
|
const uint8* d = src;
|
|
|
|
|
|
|
|
|
auto d = src;
|
|
|
bool haveReadAllLengthBytes = ! sysexHasEmbeddedLength;
|
|
|
bool haveReadAllLengthBytes = ! sysexHasEmbeddedLength;
|
|
|
int numVariableLengthSysexBytes = 0;
|
|
|
int numVariableLengthSysexBytes = 0;
|
|
|
|
|
|
|
|
@@ -221,7 +221,7 @@ MidiMessage::MidiMessage (const void* srcData, int sz, int& numBytesUsed, const |
|
|
src += numVariableLengthSysexBytes;
|
|
|
src += numVariableLengthSysexBytes;
|
|
|
size = 1 + (int) (d - src);
|
|
|
size = 1 + (int) (d - src);
|
|
|
|
|
|
|
|
|
uint8* dest = allocateSpace (size);
|
|
|
|
|
|
|
|
|
auto dest = allocateSpace (size);
|
|
|
*dest = (uint8) byte;
|
|
|
*dest = (uint8) byte;
|
|
|
memcpy (dest + 1, src, (size_t) (size - 1));
|
|
|
memcpy (dest + 1, src, (size_t) (size - 1));
|
|
|
|
|
|
|
|
@@ -233,7 +233,7 @@ MidiMessage::MidiMessage (const void* srcData, int sz, int& numBytesUsed, const |
|
|
const int bytesLeft = readVariableLengthVal (src + 1, n);
|
|
|
const int bytesLeft = readVariableLengthVal (src + 1, n);
|
|
|
size = jmin (sz + 1, n + 2 + bytesLeft);
|
|
|
size = jmin (sz + 1, n + 2 + bytesLeft);
|
|
|
|
|
|
|
|
|
uint8* dest = allocateSpace (size);
|
|
|
|
|
|
|
|
|
auto dest = allocateSpace (size);
|
|
|
*dest = (uint8) byte;
|
|
|
*dest = (uint8) byte;
|
|
|
memcpy (dest + 1, src, (size_t) size - 1);
|
|
|
memcpy (dest + 1, src, (size_t) size - 1);
|
|
|
|
|
|
|
|
@@ -316,7 +316,7 @@ uint8* MidiMessage::allocateSpace (int bytes) |
|
|
{
|
|
|
{
|
|
|
if (bytes > (int) sizeof (packedData))
|
|
|
if (bytes > (int) sizeof (packedData))
|
|
|
{
|
|
|
{
|
|
|
uint8* d = static_cast<uint8*> (std::malloc ((size_t) bytes));
|
|
|
|
|
|
|
|
|
auto d = static_cast<uint8*> (std::malloc ((size_t) bytes));
|
|
|
packedData.allocatedData = d;
|
|
|
packedData.allocatedData = d;
|
|
|
return d;
|
|
|
return d;
|
|
|
}
|
|
|
}
|
|
@@ -351,7 +351,7 @@ String MidiMessage::getDescription() const |
|
|
|
|
|
|
|
|
int MidiMessage::getChannel() const noexcept
|
|
|
int MidiMessage::getChannel() const noexcept
|
|
|
{
|
|
|
{
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
|
auto data = getRawData();
|
|
|
|
|
|
|
|
|
if ((data[0] & 0xf0) != 0xf0)
|
|
|
if ((data[0] & 0xf0) != 0xf0)
|
|
|
return (data[0] & 0xf) + 1;
|
|
|
return (data[0] & 0xf) + 1;
|
|
@@ -363,7 +363,7 @@ bool MidiMessage::isForChannel (const int channel) const noexcept |
|
|
{
|
|
|
{
|
|
|
jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16
|
|
|
jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16
|
|
|
|
|
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
|
auto data = getRawData();
|
|
|
|
|
|
|
|
|
return ((data[0] & 0xf) == channel - 1)
|
|
|
return ((data[0] & 0xf) == channel - 1)
|
|
|
&& ((data[0] & 0xf0) != 0xf0);
|
|
|
&& ((data[0] & 0xf0) != 0xf0);
|
|
@@ -373,7 +373,7 @@ void MidiMessage::setChannel (const int channel) noexcept |
|
|
{
|
|
|
{
|
|
|
jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16
|
|
|
jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16
|
|
|
|
|
|
|
|
|
uint8* const data = getData();
|
|
|
|
|
|
|
|
|
auto data = getData();
|
|
|
|
|
|
|
|
|
if ((data[0] & 0xf0) != (uint8) 0xf0)
|
|
|
if ((data[0] & 0xf0) != (uint8) 0xf0)
|
|
|
data[0] = (uint8) ((data[0] & (uint8) 0xf0)
|
|
|
data[0] = (uint8) ((data[0] & (uint8) 0xf0)
|
|
@@ -382,7 +382,7 @@ void MidiMessage::setChannel (const int channel) noexcept |
|
|
|
|
|
|
|
|
bool MidiMessage::isNoteOn (const bool returnTrueForVelocity0) const noexcept
|
|
|
bool MidiMessage::isNoteOn (const bool returnTrueForVelocity0) const noexcept
|
|
|
{
|
|
|
{
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
|
auto data = getRawData();
|
|
|
|
|
|
|
|
|
return ((data[0] & 0xf0) == 0x90)
|
|
|
return ((data[0] & 0xf0) == 0x90)
|
|
|
&& (returnTrueForVelocity0 || data[2] != 0);
|
|
|
&& (returnTrueForVelocity0 || data[2] != 0);
|
|
@@ -390,7 +390,7 @@ bool MidiMessage::isNoteOn (const bool returnTrueForVelocity0) const noexcept |
|
|
|
|
|
|
|
|
bool MidiMessage::isNoteOff (const bool returnTrueForNoteOnVelocity0) const noexcept
|
|
|
bool MidiMessage::isNoteOff (const bool returnTrueForNoteOnVelocity0) const noexcept
|
|
|
{
|
|
|
{
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
|
auto data = getRawData();
|
|
|
|
|
|
|
|
|
return ((data[0] & 0xf0) == 0x80)
|
|
|
return ((data[0] & 0xf0) == 0x80)
|
|
|
|| (returnTrueForNoteOnVelocity0 && (data[2] == 0) && ((data[0] & 0xf0) == 0x90));
|
|
|
|| (returnTrueForNoteOnVelocity0 && (data[2] == 0) && ((data[0] & 0xf0) == 0x90));
|
|
@@ -398,9 +398,7 @@ bool MidiMessage::isNoteOff (const bool returnTrueForNoteOnVelocity0) const noex |
|
|
|
|
|
|
|
|
bool MidiMessage::isNoteOnOrOff() const noexcept
|
|
|
bool MidiMessage::isNoteOnOrOff() const noexcept
|
|
|
{
|
|
|
{
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
|
|
|
|
const int d = data[0] & 0xf0;
|
|
|
|
|
|
|
|
|
auto d = getRawData()[0] & 0xf0;
|
|
|
return (d == 0x90) || (d == 0x80);
|
|
|
return (d == 0x90) || (d == 0x80);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
@@ -438,7 +436,7 @@ void MidiMessage::multiplyVelocity (const float scaleFactor) noexcept |
|
|
{
|
|
|
{
|
|
|
if (isNoteOnOrOff())
|
|
|
if (isNoteOnOrOff())
|
|
|
{
|
|
|
{
|
|
|
uint8* const data = getData();
|
|
|
|
|
|
|
|
|
auto data = getData();
|
|
|
data[2] = MidiHelpers::validVelocity (roundToInt (scaleFactor * data[2]));
|
|
|
data[2] = MidiHelpers::validVelocity (roundToInt (scaleFactor * data[2]));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -522,7 +520,7 @@ bool MidiMessage::isPitchWheel() const noexcept |
|
|
int MidiMessage::getPitchWheelValue() const noexcept
|
|
|
int MidiMessage::getPitchWheelValue() const noexcept
|
|
|
{
|
|
|
{
|
|
|
jassert (isPitchWheel());
|
|
|
jassert (isPitchWheel());
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
|
auto data = getRawData();
|
|
|
return data[1] | (data[2] << 7);
|
|
|
return data[1] | (data[2] << 7);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
@@ -542,7 +540,7 @@ bool MidiMessage::isController() const noexcept |
|
|
|
|
|
|
|
|
bool MidiMessage::isControllerOfType (const int controllerType) const noexcept
|
|
|
bool MidiMessage::isControllerOfType (const int controllerType) const noexcept
|
|
|
{
|
|
|
{
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
|
auto data = getRawData();
|
|
|
return (data[0] & 0xf0) == 0xb0 && data[1] == controllerType;
|
|
|
return (data[0] & 0xf0) == 0xb0 && data[1] == controllerType;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
@@ -610,7 +608,7 @@ MidiMessage MidiMessage::allNotesOff (const int channel) noexcept |
|
|
|
|
|
|
|
|
bool MidiMessage::isAllNotesOff() const noexcept
|
|
|
bool MidiMessage::isAllNotesOff() const noexcept
|
|
|
{
|
|
|
{
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
|
auto data = getRawData();
|
|
|
return (data[0] & 0xf0) == 0xb0 && data[1] == 123;
|
|
|
return (data[0] & 0xf0) == 0xb0 && data[1] == 123;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
@@ -621,8 +619,8 @@ MidiMessage MidiMessage::allSoundOff (const int channel) noexcept |
|
|
|
|
|
|
|
|
bool MidiMessage::isAllSoundOff() const noexcept
|
|
|
bool MidiMessage::isAllSoundOff() const noexcept
|
|
|
{
|
|
|
{
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
return (data[0] & 0xf0) == 0xb0 && data[1] == 120;
|
|
|
|
|
|
|
|
|
auto data = getRawData();
|
|
|
|
|
|
return data[1] == 120 && (data[0] & 0xf0) == 0xb0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::allControllersOff (const int channel) noexcept
|
|
|
MidiMessage MidiMessage::allControllersOff (const int channel) noexcept
|
|
@@ -632,14 +630,9 @@ MidiMessage MidiMessage::allControllersOff (const int channel) noexcept |
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::masterVolume (const float volume)
|
|
|
MidiMessage MidiMessage::masterVolume (const float volume)
|
|
|
{
|
|
|
{
|
|
|
const int vol = jlimit (0, 0x3fff, roundToInt (volume * 0x4000));
|
|
|
|
|
|
|
|
|
|
|
|
const uint8 buf[] = { 0xf0, 0x7f, 0x7f, 0x04, 0x01,
|
|
|
|
|
|
(uint8) (vol & 0x7f),
|
|
|
|
|
|
(uint8) (vol >> 7),
|
|
|
|
|
|
0xf7 };
|
|
|
|
|
|
|
|
|
auto vol = jlimit (0, 0x3fff, roundToInt (volume * 0x4000));
|
|
|
|
|
|
|
|
|
return MidiMessage (buf, 8);
|
|
|
|
|
|
|
|
|
return { 0xf0, 0x7f, 0x7f, 0x04, 0x01, vol & 0x7f, vol >> 7, 0xf7 };
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
//==============================================================================
|
|
@@ -675,13 +668,14 @@ bool MidiMessage::isActiveSense() const noexcept { return *getRawData() == 0x |
|
|
|
|
|
|
|
|
int MidiMessage::getMetaEventType() const noexcept
|
|
|
int MidiMessage::getMetaEventType() const noexcept
|
|
|
{
|
|
|
{
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
|
auto data = getRawData();
|
|
|
return *data != 0xff ? -1 : data[1];
|
|
|
return *data != 0xff ? -1 : data[1];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
int MidiMessage::getMetaEventLength() const noexcept
|
|
|
int MidiMessage::getMetaEventLength() const noexcept
|
|
|
{
|
|
|
{
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
|
auto data = getRawData();
|
|
|
|
|
|
|
|
|
if (*data == 0xff)
|
|
|
if (*data == 0xff)
|
|
|
{
|
|
|
{
|
|
|
int n;
|
|
|
int n;
|
|
@@ -696,7 +690,7 @@ const uint8* MidiMessage::getMetaEventData() const noexcept |
|
|
jassert (isMetaEvent());
|
|
|
jassert (isMetaEvent());
|
|
|
|
|
|
|
|
|
int n;
|
|
|
int n;
|
|
|
const uint8* d = getRawData() + 2;
|
|
|
|
|
|
|
|
|
auto d = getRawData() + 2;
|
|
|
readVariableLengthVal (d, n);
|
|
|
readVariableLengthVal (d, n);
|
|
|
return d + n;
|
|
|
return d + n;
|
|
|
}
|
|
|
}
|
|
@@ -706,13 +700,14 @@ bool MidiMessage::isEndOfTrackMetaEvent() const noexcept { return getMetaEven |
|
|
|
|
|
|
|
|
bool MidiMessage::isTextMetaEvent() const noexcept
|
|
|
bool MidiMessage::isTextMetaEvent() const noexcept
|
|
|
{
|
|
|
{
|
|
|
const int t = getMetaEventType();
|
|
|
|
|
|
|
|
|
auto t = getMetaEventType();
|
|
|
return t > 0 && t < 16;
|
|
|
return t > 0 && t < 16;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
String MidiMessage::getTextFromTextMetaEvent() const
|
|
|
String MidiMessage::getTextFromTextMetaEvent() const
|
|
|
{
|
|
|
{
|
|
|
const char* const textData = reinterpret_cast<const char*> (getMetaEventData());
|
|
|
|
|
|
|
|
|
auto textData = reinterpret_cast<const char*> (getMetaEventData());
|
|
|
|
|
|
|
|
|
return String (CharPointer_UTF8 (textData),
|
|
|
return String (CharPointer_UTF8 (textData),
|
|
|
CharPointer_UTF8 (textData + getMetaEventLength()));
|
|
|
CharPointer_UTF8 (textData + getMetaEventLength()));
|
|
|
}
|
|
|
}
|
|
@@ -739,7 +734,7 @@ MidiMessage MidiMessage::textMetaEvent (int type, StringRef text) |
|
|
const size_t headerLen = sizeof (header) - n;
|
|
|
const size_t headerLen = sizeof (header) - n;
|
|
|
const int totalSize = (int) (headerLen + textSize);
|
|
|
const int totalSize = (int) (headerLen + textSize);
|
|
|
|
|
|
|
|
|
uint8* const dest = result.allocateSpace (totalSize);
|
|
|
|
|
|
|
|
|
auto dest = result.allocateSpace (totalSize);
|
|
|
result.size = totalSize;
|
|
|
result.size = totalSize;
|
|
|
|
|
|
|
|
|
memcpy (dest, header + n, headerLen);
|
|
|
memcpy (dest, header + n, headerLen);
|
|
@@ -748,9 +743,9 @@ MidiMessage MidiMessage::textMetaEvent (int type, StringRef text) |
|
|
return result;
|
|
|
return result;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
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); }
|
|
|
|
|
|
|
|
|
bool MidiMessage::isTrackNameEvent() const noexcept { auto data = getRawData(); return (data[1] == 3) && (*data == 0xff); }
|
|
|
|
|
|
bool MidiMessage::isTempoMetaEvent() const noexcept { auto data = getRawData(); return (data[1] == 81) && (*data == 0xff); }
|
|
|
|
|
|
bool MidiMessage::isMidiChannelMetaEvent() const noexcept { auto data = getRawData(); return (data[1] == 0x20) && (*data == 0xff) && (data[2] == 1); }
|
|
|
|
|
|
|
|
|
int MidiMessage::getMidiChannelMetaEventChannel() const noexcept
|
|
|
int MidiMessage::getMidiChannelMetaEventChannel() const noexcept
|
|
|
{
|
|
|
{
|
|
@@ -763,7 +758,7 @@ double MidiMessage::getTempoSecondsPerQuarterNote() const noexcept |
|
|
if (! isTempoMetaEvent())
|
|
|
if (! isTempoMetaEvent())
|
|
|
return 0.0;
|
|
|
return 0.0;
|
|
|
|
|
|
|
|
|
const uint8* const d = getMetaEventData();
|
|
|
|
|
|
|
|
|
auto d = getMetaEventData();
|
|
|
|
|
|
|
|
|
return (((unsigned int) d[0] << 16)
|
|
|
return (((unsigned int) d[0] << 16)
|
|
|
| ((unsigned int) d[1] << 8)
|
|
|
| ((unsigned int) d[1] << 8)
|
|
@@ -780,37 +775,33 @@ double MidiMessage::getTempoMetaEventTickLength (const short timeFormat) const n |
|
|
|
|
|
|
|
|
return getTempoSecondsPerQuarterNote() / timeFormat;
|
|
|
return getTempoSecondsPerQuarterNote() / timeFormat;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
const int frameCode = (-timeFormat) >> 8;
|
|
|
|
|
|
double framesPerSecond;
|
|
|
|
|
|
|
|
|
|
|
|
switch (frameCode)
|
|
|
|
|
|
{
|
|
|
|
|
|
case 24: framesPerSecond = 24.0; break;
|
|
|
|
|
|
case 25: framesPerSecond = 25.0; break;
|
|
|
|
|
|
case 29: framesPerSecond = 30.0 * 1000.0 / 1001.0; break;
|
|
|
|
|
|
case 30: framesPerSecond = 30.0; break;
|
|
|
|
|
|
default: framesPerSecond = 30.0; break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
const int frameCode = (-timeFormat) >> 8;
|
|
|
|
|
|
double framesPerSecond;
|
|
|
|
|
|
|
|
|
return (1.0 / framesPerSecond) / (timeFormat & 0xff);
|
|
|
|
|
|
|
|
|
switch (frameCode)
|
|
|
|
|
|
{
|
|
|
|
|
|
case 24: framesPerSecond = 24.0; break;
|
|
|
|
|
|
case 25: framesPerSecond = 25.0; break;
|
|
|
|
|
|
case 29: framesPerSecond = 30.0 * 1000.0 / 1001.0; break;
|
|
|
|
|
|
case 30: framesPerSecond = 30.0; break;
|
|
|
|
|
|
default: framesPerSecond = 30.0; break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return (1.0 / framesPerSecond) / (timeFormat & 0xff);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::tempoMetaEvent (int microsecondsPerQuarterNote) noexcept
|
|
|
MidiMessage MidiMessage::tempoMetaEvent (int microsecondsPerQuarterNote) noexcept
|
|
|
{
|
|
|
{
|
|
|
const uint8 d[] = { 0xff, 81, 3,
|
|
|
|
|
|
(uint8) (microsecondsPerQuarterNote >> 16),
|
|
|
|
|
|
(uint8) (microsecondsPerQuarterNote >> 8),
|
|
|
|
|
|
(uint8) microsecondsPerQuarterNote };
|
|
|
|
|
|
|
|
|
|
|
|
return MidiMessage (d, 6, 0.0);
|
|
|
|
|
|
|
|
|
return { 0xff, 81, 3,
|
|
|
|
|
|
(uint8) (microsecondsPerQuarterNote >> 16),
|
|
|
|
|
|
(uint8) (microsecondsPerQuarterNote >> 8),
|
|
|
|
|
|
(uint8) microsecondsPerQuarterNote };
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
bool MidiMessage::isTimeSignatureMetaEvent() const noexcept
|
|
|
bool MidiMessage::isTimeSignatureMetaEvent() const noexcept
|
|
|
{
|
|
|
{
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
|
auto data = getRawData();
|
|
|
return (data[1] == 0x58) && (*data == (uint8) 0xff);
|
|
|
return (data[1] == 0x58) && (*data == (uint8) 0xff);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
@@ -818,7 +809,7 @@ void MidiMessage::getTimeSignatureInfo (int& numerator, int& denominator) const |
|
|
{
|
|
|
{
|
|
|
if (isTimeSignatureMetaEvent())
|
|
|
if (isTimeSignatureMetaEvent())
|
|
|
{
|
|
|
{
|
|
|
const uint8* const d = getMetaEventData();
|
|
|
|
|
|
|
|
|
auto d = getMetaEventData();
|
|
|
numerator = d[0];
|
|
|
numerator = d[0];
|
|
|
denominator = 1 << d[1];
|
|
|
denominator = 1 << d[1];
|
|
|
}
|
|
|
}
|
|
@@ -840,14 +831,12 @@ MidiMessage MidiMessage::timeSignatureMetaEvent (const int numerator, const int |
|
|
++powerOfTwo;
|
|
|
++powerOfTwo;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
const uint8 d[] = { 0xff, 0x58, 0x04, (uint8) numerator, (uint8) powerOfTwo, 1, 96 };
|
|
|
|
|
|
return MidiMessage (d, 7, 0.0);
|
|
|
|
|
|
|
|
|
return { 0xff, 0x58, 0x04, numerator, powerOfTwo, 1, 96 };
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::midiChannelMetaEvent (const int channel) noexcept
|
|
|
MidiMessage MidiMessage::midiChannelMetaEvent (const int channel) noexcept
|
|
|
{
|
|
|
{
|
|
|
const uint8 d[] = { 0xff, 0x20, 0x01, (uint8) jlimit (0, 0xff, channel - 1) };
|
|
|
|
|
|
return MidiMessage (d, 4, 0.0);
|
|
|
|
|
|
|
|
|
return { 0xff, 0x20, 0x01, jlimit (0, 0xff, channel - 1) };
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
bool MidiMessage::isKeySignatureMetaEvent() const noexcept
|
|
|
bool MidiMessage::isKeySignatureMetaEvent() const noexcept
|
|
@@ -869,37 +858,36 @@ MidiMessage MidiMessage::keySignatureMetaEvent (int numberOfSharpsOrFlats, bool |
|
|
{
|
|
|
{
|
|
|
jassert (numberOfSharpsOrFlats >= -7 && numberOfSharpsOrFlats <= 7);
|
|
|
jassert (numberOfSharpsOrFlats >= -7 && numberOfSharpsOrFlats <= 7);
|
|
|
|
|
|
|
|
|
const uint8 d[] = { 0xff, 0x59, 0x02, (uint8) numberOfSharpsOrFlats, isMinorKey ? (uint8) 1 : (uint8) 0 };
|
|
|
|
|
|
return MidiMessage (d, 5, 0.0);
|
|
|
|
|
|
|
|
|
return { 0xff, 0x59, 0x02, numberOfSharpsOrFlats, isMinorKey ? 1 : 0 };
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::endOfTrack() noexcept
|
|
|
MidiMessage MidiMessage::endOfTrack() noexcept
|
|
|
{
|
|
|
{
|
|
|
return MidiMessage (0xff, 0x2f, 0, 0.0);
|
|
|
|
|
|
|
|
|
return { 0xff, 0x2f };
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
//==============================================================================
|
|
|
bool MidiMessage::isSongPositionPointer() const noexcept { return *getRawData() == 0xf2; }
|
|
|
bool MidiMessage::isSongPositionPointer() const noexcept { return *getRawData() == 0xf2; }
|
|
|
int MidiMessage::getSongPositionPointerMidiBeat() const noexcept { const uint8* data = getRawData(); return data[1] | (data[2] << 7); }
|
|
|
|
|
|
|
|
|
int MidiMessage::getSongPositionPointerMidiBeat() const noexcept { auto data = getRawData(); return data[1] | (data[2] << 7); }
|
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::songPositionPointer (const int positionInMidiBeats) noexcept
|
|
|
MidiMessage MidiMessage::songPositionPointer (const int positionInMidiBeats) noexcept
|
|
|
{
|
|
|
{
|
|
|
return MidiMessage (0xf2,
|
|
|
|
|
|
positionInMidiBeats & 127,
|
|
|
|
|
|
(positionInMidiBeats >> 7) & 127);
|
|
|
|
|
|
|
|
|
return { 0xf2,
|
|
|
|
|
|
positionInMidiBeats & 127,
|
|
|
|
|
|
(positionInMidiBeats >> 7) & 127 };
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
bool MidiMessage::isMidiStart() const noexcept { return *getRawData() == 0xfa; }
|
|
|
|
|
|
MidiMessage MidiMessage::midiStart() noexcept { return MidiMessage (0xfa); }
|
|
|
|
|
|
|
|
|
bool MidiMessage::isMidiStart() const noexcept { return *getRawData() == 0xfa; }
|
|
|
|
|
|
MidiMessage MidiMessage::midiStart() noexcept { return MidiMessage (0xfa); }
|
|
|
|
|
|
|
|
|
bool MidiMessage::isMidiContinue() const noexcept { return *getRawData() == 0xfb; }
|
|
|
|
|
|
MidiMessage MidiMessage::midiContinue() noexcept { return MidiMessage (0xfb); }
|
|
|
|
|
|
|
|
|
bool MidiMessage::isMidiContinue() const noexcept { return *getRawData() == 0xfb; }
|
|
|
|
|
|
MidiMessage MidiMessage::midiContinue() noexcept { return MidiMessage (0xfb); }
|
|
|
|
|
|
|
|
|
bool MidiMessage::isMidiStop() const noexcept { return *getRawData() == 0xfc; }
|
|
|
|
|
|
MidiMessage MidiMessage::midiStop() noexcept { return MidiMessage (0xfc); }
|
|
|
|
|
|
|
|
|
bool MidiMessage::isMidiStop() const noexcept { return *getRawData() == 0xfc; }
|
|
|
|
|
|
MidiMessage MidiMessage::midiStop() noexcept { return MidiMessage (0xfc); }
|
|
|
|
|
|
|
|
|
bool MidiMessage::isMidiClock() const noexcept { return *getRawData() == 0xf8; }
|
|
|
|
|
|
MidiMessage MidiMessage::midiClock() noexcept { return MidiMessage (0xf8); }
|
|
|
|
|
|
|
|
|
bool MidiMessage::isMidiClock() const noexcept { return *getRawData() == 0xf8; }
|
|
|
|
|
|
MidiMessage MidiMessage::midiClock() noexcept { return MidiMessage (0xf8); }
|
|
|
|
|
|
|
|
|
bool MidiMessage::isQuarterFrame() const noexcept { return *getRawData() == 0xf1; }
|
|
|
bool MidiMessage::isQuarterFrame() const noexcept { return *getRawData() == 0xf1; }
|
|
|
int MidiMessage::getQuarterFrameSequenceNumber() const noexcept { return ((int) getRawData()[1]) >> 4; }
|
|
|
int MidiMessage::getQuarterFrameSequenceNumber() const noexcept { return ((int) getRawData()[1]) >> 4; }
|
|
@@ -912,7 +900,7 @@ MidiMessage MidiMessage::quarterFrame (const int sequenceNumber, const int value |
|
|
|
|
|
|
|
|
bool MidiMessage::isFullFrame() const noexcept
|
|
|
bool MidiMessage::isFullFrame() const noexcept
|
|
|
{
|
|
|
{
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
|
auto data = getRawData();
|
|
|
|
|
|
|
|
|
return data[0] == 0xf0
|
|
|
return data[0] == 0xf0
|
|
|
&& data[1] == 0x7f
|
|
|
&& data[1] == 0x7f
|
|
@@ -926,7 +914,7 @@ void MidiMessage::getFullFrameParameters (int& hours, int& minutes, int& seconds |
|
|
{
|
|
|
{
|
|
|
jassert (isFullFrame());
|
|
|
jassert (isFullFrame());
|
|
|
|
|
|
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
|
auto data = getRawData();
|
|
|
timecodeType = (SmpteTimecodeType) (data[5] >> 5);
|
|
|
timecodeType = (SmpteTimecodeType) (data[5] >> 5);
|
|
|
hours = data[5] & 0x1f;
|
|
|
hours = data[5] & 0x1f;
|
|
|
minutes = data[6];
|
|
|
minutes = data[6];
|
|
@@ -934,23 +922,19 @@ void MidiMessage::getFullFrameParameters (int& hours, int& minutes, int& seconds |
|
|
frames = data[8];
|
|
|
frames = data[8];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::fullFrame (const int hours, const int minutes,
|
|
|
|
|
|
const int seconds, const int frames,
|
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::fullFrame (int hours, int minutes, int seconds, int frames,
|
|
|
MidiMessage::SmpteTimecodeType timecodeType)
|
|
|
MidiMessage::SmpteTimecodeType timecodeType)
|
|
|
{
|
|
|
{
|
|
|
const uint8 d[] = { 0xf0, 0x7f, 0x7f, 0x01, 0x01,
|
|
|
|
|
|
(uint8) ((hours & 0x01f) | (timecodeType << 5)),
|
|
|
|
|
|
(uint8) minutes,
|
|
|
|
|
|
(uint8) seconds,
|
|
|
|
|
|
(uint8) frames,
|
|
|
|
|
|
0xf7 };
|
|
|
|
|
|
|
|
|
|
|
|
return MidiMessage (d, 10, 0.0);
|
|
|
|
|
|
|
|
|
return { 0xf0, 0x7f, 0x7f, 0x01, 0x01,
|
|
|
|
|
|
(hours & 0x01f) | (timecodeType << 5),
|
|
|
|
|
|
minutes, seconds, frames,
|
|
|
|
|
|
0xf7 };
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
bool MidiMessage::isMidiMachineControlMessage() const noexcept
|
|
|
bool MidiMessage::isMidiMachineControlMessage() const noexcept
|
|
|
{
|
|
|
{
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
|
auto data = getRawData();
|
|
|
|
|
|
|
|
|
return data[0] == 0xf0
|
|
|
return data[0] == 0xf0
|
|
|
&& data[1] == 0x7f
|
|
|
&& data[1] == 0x7f
|
|
|
&& data[3] == 0x06
|
|
|
&& data[3] == 0x06
|
|
@@ -966,15 +950,14 @@ MidiMessage::MidiMachineControlCommand MidiMessage::getMidiMachineControlCommand |
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::midiMachineControlCommand (MidiMessage::MidiMachineControlCommand command)
|
|
|
MidiMessage MidiMessage::midiMachineControlCommand (MidiMessage::MidiMachineControlCommand command)
|
|
|
{
|
|
|
{
|
|
|
const uint8 d[] = { 0xf0, 0x7f, 0, 6, (uint8) command, 0xf7 };
|
|
|
|
|
|
|
|
|
|
|
|
return MidiMessage (d, 6, 0.0);
|
|
|
|
|
|
|
|
|
return { 0xf0, 0x7f, 0, 6, command, 0xf7 };
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
//==============================================================================
|
|
|
bool MidiMessage::isMidiMachineControlGoto (int& hours, int& minutes, int& seconds, int& frames) const noexcept
|
|
|
bool MidiMessage::isMidiMachineControlGoto (int& hours, int& minutes, int& seconds, int& frames) const noexcept
|
|
|
{
|
|
|
{
|
|
|
const uint8* const data = getRawData();
|
|
|
|
|
|
|
|
|
auto data = getRawData();
|
|
|
|
|
|
|
|
|
if (size >= 12
|
|
|
if (size >= 12
|
|
|
&& data[0] == 0xf0
|
|
|
&& data[0] == 0xf0
|
|
|
&& data[1] == 0x7f
|
|
|
&& data[1] == 0x7f
|
|
@@ -996,14 +979,7 @@ bool MidiMessage::isMidiMachineControlGoto (int& hours, int& minutes, int& secon |
|
|
|
|
|
|
|
|
MidiMessage MidiMessage::midiMachineControlGoto (int hours, int minutes, int seconds, int frames)
|
|
|
MidiMessage MidiMessage::midiMachineControlGoto (int hours, int minutes, int seconds, int frames)
|
|
|
{
|
|
|
{
|
|
|
const uint8 d[] = { 0xf0, 0x7f, 0, 6, 0x44, 6, 1,
|
|
|
|
|
|
(uint8) hours,
|
|
|
|
|
|
(uint8) minutes,
|
|
|
|
|
|
(uint8) seconds,
|
|
|
|
|
|
(uint8) frames,
|
|
|
|
|
|
0xf7 };
|
|
|
|
|
|
|
|
|
|
|
|
return MidiMessage (d, 12, 0.0);
|
|
|
|
|
|
|
|
|
return { 0xf0, 0x7f, 0, 6, 0x44, 6, 1, hours, minutes, seconds, frames, 0xf7 };
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
//==============================================================================
|
|
|