28 inline uint8 initialByte (
const int type,
const int channel) noexcept
30 return (uint8) (type | jlimit (0, 15, channel - 1));
33 inline uint8 validVelocity (
const int v) noexcept
35 return (uint8) jlimit (0, 127, v);
42 jassert (v >= 0 && v <= 1.0f);
45 return MidiHelpers::validVelocity (roundToInt (v * 127.0f));
49 const float pitchbendRange) noexcept
52 jassert (std::abs (pitchbend) <= pitchbendRange);
54 return static_cast<uint16
> (pitchbend > 0.0f
55 ? jmap (pitchbend, 0.0f, pitchbendRange, 8192.0f, 16383.0f)
56 : jmap (pitchbend, -pitchbendRange, 0.0f, 0.0f, 8192.0f));
69 if (++numBytesUsed > 6)
72 v = (v << 7) + (i & 0x7f);
82 jassert (firstByte >= 0x80 && firstByte != 0xf0 && firstByte != 0xf7);
84 static const char messageLengths[] =
86 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
87 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
88 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
89 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
90 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
91 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
92 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
93 1, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
96 return messageLengths[firstByte & 0x7f];
103 packedData.asBytes[0] = 0xf0;
104 packedData.asBytes[1] = 0xf7;
108 : timeStamp (t), size (dataSize)
110 jassert (dataSize > 0);
114 memcpy (allocateSpace (dataSize), d, (
size_t) dataSize);
118 : timeStamp (t), size (1)
120 packedData.asBytes[0] = (uint8) byte1;
127 : timeStamp (t), size (2)
129 packedData.asBytes[0] = (uint8) byte1;
130 packedData.asBytes[1] = (uint8) byte2;
137 : timeStamp (t), size (3)
139 packedData.asBytes[0] = (uint8) byte1;
140 packedData.asBytes[1] = (uint8) byte2;
141 packedData.asBytes[2] = (uint8) byte3;
148 : timeStamp (other.timeStamp), size (other.size)
150 if (isHeapAllocated())
151 memcpy (allocateSpace (size), other.getData(), (size_t) size);
153 packedData.allocatedData = other.packedData.allocatedData;
157 : timeStamp (newTimeStamp), size (other.size)
159 if (isHeapAllocated())
160 memcpy (allocateSpace (size), other.getData(), (size_t) size);
162 packedData.allocatedData = other.packedData.allocatedData;
166 double t,
bool sysexHasEmbeddedLength)
169 auto src =
static_cast<const uint8*
> (srcData);
170 auto byte = (
unsigned int) *src;
174 byte = (
unsigned int) lastStatusByte;
189 bool haveReadAllLengthBytes = ! sysexHasEmbeddedLength;
190 int numVariableLengthSysexBytes = 0;
202 if (haveReadAllLengthBytes)
205 ++numVariableLengthSysexBytes;
207 else if (! haveReadAllLengthBytes)
209 haveReadAllLengthBytes =
true;
210 ++numVariableLengthSysexBytes;
216 src += numVariableLengthSysexBytes;
217 size = 1 + (int) (d - src);
219 auto dest = allocateSpace (size);
220 *dest = (uint8) byte;
221 memcpy (dest + 1, src, (
size_t) (size - 1));
223 numBytesUsed += (numVariableLengthSysexBytes + size);
225 else if (byte == 0xff)
235 size = jmin (sz + 1, n + 2 + bytesLeft);
238 auto dest = allocateSpace (size);
239 *dest = (uint8) byte;
240 memcpy (dest + 1, src, (
size_t) size - 1);
242 numBytesUsed += size;
247 packedData.asBytes[0] = (uint8) byte;
251 packedData.asBytes[1] = (sz > 0 ? src[0] : 0);
254 packedData.asBytes[2] = (sz > 1 ? src[1] : 0);
257 numBytesUsed += jmin (size, sz + 1);
262 packedData.allocatedData =
nullptr;
271 if (other.isHeapAllocated())
273 if (isHeapAllocated())
274 packedData.allocatedData = static_cast<uint8*> (std::realloc (packedData.allocatedData, (
size_t) other.size));
276 packedData.allocatedData =
static_cast<uint8*
> (std::malloc ((
size_t) other.size));
278 memcpy (packedData.allocatedData, other.packedData.allocatedData, (
size_t) other.size);
282 if (isHeapAllocated())
283 std::free (packedData.allocatedData);
285 packedData.allocatedData = other.packedData.allocatedData;
288 timeStamp = other.timeStamp;
296 : timeStamp (other.timeStamp), size (other.size)
298 packedData.allocatedData = other.packedData.allocatedData;
304 packedData.allocatedData = other.packedData.allocatedData;
305 timeStamp = other.timeStamp;
313 if (isHeapAllocated())
314 std::free (packedData.allocatedData);
317 uint8* MidiMessage::allocateSpace (
int bytes)
319 if (bytes > (
int)
sizeof (packedData))
321 auto d =
static_cast<uint8*
> (std::malloc ((
size_t) bytes));
322 packedData.allocatedData = d;
326 return packedData.asBytes;
356 return { *
this, newTimestamp };
363 if ((data[0] & 0xf0) != 0xf0)
364 return (data[0] & 0xf) + 1;
371 jassert (channel > 0 && channel <= 16);
375 return ((data[0] & 0xf) == channel - 1)
376 && ((data[0] & 0xf0) != 0xf0);
381 jassert (channel > 0 && channel <= 16);
383 auto data = getData();
385 if ((data[0] & 0xf0) != (uint8) 0xf0)
386 data[0] = (uint8) ((data[0] & (uint8) 0xf0)
387 | (uint8)(channel - 1));
394 return ((data[0] & 0xf0) == 0x90)
395 && (returnTrueForVelocity0 || data[2] != 0);
402 return ((data[0] & 0xf0) == 0x80)
403 || (returnTrueForNoteOnVelocity0 && (data[2] == 0) && ((data[0] & 0xf0) == 0x90));
409 return (d == 0x90) || (d == 0x80);
420 getData()[1] = (uint8) (newNoteNumber & 127);
446 auto data = getData();
447 data[2] = MidiHelpers::validVelocity (roundToInt (scaleFactor * data[2]));
464 const int aftertouchValue) noexcept
466 jassert (channel > 0 && channel <= 16);
467 jassert (isPositiveAndBelow (noteNum, 128));
468 jassert (isPositiveAndBelow (aftertouchValue, 128));
470 return MidiMessage (MidiHelpers::initialByte (0xa0, channel),
472 aftertouchValue & 0x7f);
488 jassert (channel > 0 && channel <= 16);
489 jassert (isPositiveAndBelow (pressure, 128));
491 return MidiMessage (MidiHelpers::initialByte (0xd0, channel), pressure & 0x7f);
517 jassert (channel > 0 && channel <= 16);
519 return MidiMessage (MidiHelpers::initialByte (0xc0, channel), programNumber & 0x7f);
531 return data[1] | (data[2] << 7);
536 jassert (channel > 0 && channel <= 16);
537 jassert (isPositiveAndBelow (position, 0x4000));
539 return MidiMessage (MidiHelpers::initialByte (0xe0, channel),
540 position & 127, (position >> 7) & 127);
551 return (data[0] & 0xf0) == 0xb0 && data[1] == controllerType;
569 jassert (channel > 0 && channel <= 16);
571 return MidiMessage (MidiHelpers::initialByte (0xb0, channel),
572 controllerType & 127, value & 127);
577 jassert (channel > 0 && channel <= 16);
578 jassert (isPositiveAndBelow (noteNumber, 128));
580 return MidiMessage (MidiHelpers::initialByte (0x90, channel),
581 noteNumber & 127, MidiHelpers::validVelocity (velocity));
591 jassert (channel > 0 && channel <= 16);
592 jassert (isPositiveAndBelow (noteNumber, 128));
594 return MidiMessage (MidiHelpers::initialByte (0x80, channel),
595 noteNumber & 127, MidiHelpers::validVelocity (velocity));
605 jassert (channel > 0 && channel <= 16);
606 jassert (isPositiveAndBelow (noteNumber, 128));
608 return MidiMessage (MidiHelpers::initialByte (0x80, channel), noteNumber & 127, 0);
619 return (data[0] & 0xf0) == 0xb0 && data[1] == 123;
630 return data[1] == 120 && (data[0] & 0xf0) == 0xb0;
636 return (data[0] & 0xf0) == 0xb0 && data[1] == 121;
646 auto vol = jlimit (0, 0x3fff, roundToInt (volume * 0x4000));
648 return { 0xf0, 0x7f, 0x7f, 0x04, 0x01, vol & 0x7f, vol >> 7, 0xf7 };
662 memcpy (m + 1, sysexData, (
size_t) dataSize);
663 m[dataSize + 1] = 0xf7;
675 return isSysEx() ? size - 2 : 0;
685 return *data != 0xff ? -1 : data[1];
717 return t > 0 && t < 16;
730 jassert (type > 0 && type < 16);
737 size_t n =
sizeof (header);
739 header[--n] = (uint8) (textSize & 0x7f);
741 for (
size_t i = textSize; (i >>= 7) != 0;)
742 header[--n] = (uint8) ((i & 0x7f) | 0x80);
744 header[--n] = (uint8) type;
747 const size_t headerLen =
sizeof (header) - n;
748 const int totalSize = (int) (headerLen + textSize);
750 auto dest = result.allocateSpace (totalSize);
751 result.size = totalSize;
753 memcpy (dest, header + n, headerLen);
776 return (((
unsigned int) d[0] << 16)
777 | ((
unsigned int) d[1] << 8)
787 return 0.5 / timeFormat;
792 const int frameCode = (-timeFormat) >> 8;
793 double framesPerSecond;
797 case 24: framesPerSecond = 24.0;
break;
798 case 25: framesPerSecond = 25.0;
break;
799 case 29: framesPerSecond = 30.0 * 1000.0 / 1001.0;
break;
800 case 30: framesPerSecond = 30.0;
break;
801 default: framesPerSecond = 30.0;
break;
804 return (1.0 / framesPerSecond) / (timeFormat & 0xff);
809 return { 0xff, 81, 3,
810 (uint8) (microsecondsPerQuarterNote >> 16),
811 (uint8) (microsecondsPerQuarterNote >> 8),
812 (uint8) microsecondsPerQuarterNote };
818 return (data[1] == 0x58) && (*data == (uint8) 0xff);
827 denominator = 1 << d[1];
841 while (n < denominator)
847 return { 0xff, 0x58, 0x04, numerator, powerOfTwo, 1, 96 };
852 return { 0xff, 0x20, 0x01, jlimit (0, 0xff, channel - 1) };
872 jassert (numberOfSharpsOrFlats >= -7 && numberOfSharpsOrFlats <= 7);
874 return { 0xff, 0x59, 0x02, numberOfSharpsOrFlats, isMinorKey ? 1 : 0 };
879 return { 0xff, 0x2f, 0x00 };
889 positionInMidiBeats & 127,
890 (positionInMidiBeats >> 7) & 127 };
911 return MidiMessage (0xf1, (sequenceNumber << 4) | value);
918 return data[0] == 0xf0
932 hours = data[5] & 0x1f;
941 return { 0xf0, 0x7f, 0x7f, 0x01, 0x01,
942 (hours & 0x01f) | (timecodeType << 5),
943 minutes, seconds, frames,
951 return data[0] == 0xf0
966 return { 0xf0, 0x7f, 0, 6, command, 0xf7 };
982 hours = data[7] % 24;
995 return { 0xf0, 0x7f, 0, 6, 0x44, 6, 1, hours, minutes, seconds, frames, 0xf7 };
1001 static const char*
const sharpNoteNames[] = {
"C",
"C#",
"D",
"D#",
"E",
"F",
"F#",
"G",
"G#",
"A",
"A#",
"B" };
1002 static const char*
const flatNoteNames[] = {
"C",
"Db",
"D",
"Eb",
"E",
"F",
"Gb",
"G",
"Ab",
"A",
"Bb",
"B" };
1004 if (isPositiveAndBelow (note, 128))
1006 String s (useSharps ? sharpNoteNames[note % 12]
1007 : flatNoteNames [note % 12]);
1009 if (includeOctaveNumber)
1010 s << (note / 12 + (octaveNumForMiddleC - 5));
1020 return frequencyOfA * std::pow (2.0, (noteNumber - 69) / 12.0);
1025 return ((1 << (noteNumber % 12)) & 0x054a) != 0;
1030 static const char* names[] =
1032 NEEDS_TRANS(
"Acoustic Grand Piano"), NEEDS_TRANS(
"Bright Acoustic Piano"), NEEDS_TRANS(
"Electric Grand Piano"), NEEDS_TRANS(
"Honky-tonk Piano"),
1033 NEEDS_TRANS(
"Electric Piano 1"), NEEDS_TRANS(
"Electric Piano 2"), NEEDS_TRANS(
"Harpsichord"), NEEDS_TRANS(
"Clavinet"),
1034 NEEDS_TRANS(
"Celesta"), NEEDS_TRANS(
"Glockenspiel"), NEEDS_TRANS(
"Music Box"), NEEDS_TRANS(
"Vibraphone"),
1035 NEEDS_TRANS(
"Marimba"), NEEDS_TRANS(
"Xylophone"), NEEDS_TRANS(
"Tubular Bells"), NEEDS_TRANS(
"Dulcimer"),
1036 NEEDS_TRANS(
"Drawbar Organ"), NEEDS_TRANS(
"Percussive Organ"), NEEDS_TRANS(
"Rock Organ"), NEEDS_TRANS(
"Church Organ"),
1037 NEEDS_TRANS(
"Reed Organ"), NEEDS_TRANS(
"Accordion"), NEEDS_TRANS(
"Harmonica"), NEEDS_TRANS(
"Tango Accordion"),
1038 NEEDS_TRANS(
"Acoustic Guitar (nylon)"), NEEDS_TRANS(
"Acoustic Guitar (steel)"), NEEDS_TRANS(
"Electric Guitar (jazz)"), NEEDS_TRANS(
"Electric Guitar (clean)"),
1039 NEEDS_TRANS(
"Electric Guitar (mute)"), NEEDS_TRANS(
"Overdriven Guitar"), NEEDS_TRANS(
"Distortion Guitar"), NEEDS_TRANS(
"Guitar Harmonics"),
1040 NEEDS_TRANS(
"Acoustic Bass"), NEEDS_TRANS(
"Electric Bass (finger)"), NEEDS_TRANS(
"Electric Bass (pick)"), NEEDS_TRANS(
"Fretless Bass"),
1041 NEEDS_TRANS(
"Slap Bass 1"), NEEDS_TRANS(
"Slap Bass 2"), NEEDS_TRANS(
"Synth Bass 1"), NEEDS_TRANS(
"Synth Bass 2"),
1042 NEEDS_TRANS(
"Violin"), NEEDS_TRANS(
"Viola"), NEEDS_TRANS(
"Cello"), NEEDS_TRANS(
"Contrabass"),
1043 NEEDS_TRANS(
"Tremolo Strings"), NEEDS_TRANS(
"Pizzicato Strings"), NEEDS_TRANS(
"Orchestral Harp"), NEEDS_TRANS(
"Timpani"),
1044 NEEDS_TRANS(
"String Ensemble 1"), NEEDS_TRANS(
"String Ensemble 2"), NEEDS_TRANS(
"SynthStrings 1"), NEEDS_TRANS(
"SynthStrings 2"),
1045 NEEDS_TRANS(
"Choir Aahs"), NEEDS_TRANS(
"Voice Oohs"), NEEDS_TRANS(
"Synth Voice"), NEEDS_TRANS(
"Orchestra Hit"),
1046 NEEDS_TRANS(
"Trumpet"), NEEDS_TRANS(
"Trombone"), NEEDS_TRANS(
"Tuba"), NEEDS_TRANS(
"Muted Trumpet"),
1047 NEEDS_TRANS(
"French Horn"), NEEDS_TRANS(
"Brass Section"), NEEDS_TRANS(
"SynthBrass 1"), NEEDS_TRANS(
"SynthBrass 2"),
1048 NEEDS_TRANS(
"Soprano Sax"), NEEDS_TRANS(
"Alto Sax"), NEEDS_TRANS(
"Tenor Sax"), NEEDS_TRANS(
"Baritone Sax"),
1049 NEEDS_TRANS(
"Oboe"), NEEDS_TRANS(
"English Horn"), NEEDS_TRANS(
"Bassoon"), NEEDS_TRANS(
"Clarinet"),
1050 NEEDS_TRANS(
"Piccolo"), NEEDS_TRANS(
"Flute"), NEEDS_TRANS(
"Recorder"), NEEDS_TRANS(
"Pan Flute"),
1051 NEEDS_TRANS(
"Blown Bottle"), NEEDS_TRANS(
"Shakuhachi"), NEEDS_TRANS(
"Whistle"), NEEDS_TRANS(
"Ocarina"),
1052 NEEDS_TRANS(
"Lead 1 (square)"), NEEDS_TRANS(
"Lead 2 (sawtooth)"), NEEDS_TRANS(
"Lead 3 (calliope)"), NEEDS_TRANS(
"Lead 4 (chiff)"),
1053 NEEDS_TRANS(
"Lead 5 (charang)"), NEEDS_TRANS(
"Lead 6 (voice)"), NEEDS_TRANS(
"Lead 7 (fifths)"), NEEDS_TRANS(
"Lead 8 (bass+lead)"),
1054 NEEDS_TRANS(
"Pad 1 (new age)"), NEEDS_TRANS(
"Pad 2 (warm)"), NEEDS_TRANS(
"Pad 3 (polysynth)"), NEEDS_TRANS(
"Pad 4 (choir)"),
1055 NEEDS_TRANS(
"Pad 5 (bowed)"), NEEDS_TRANS(
"Pad 6 (metallic)"), NEEDS_TRANS(
"Pad 7 (halo)"), NEEDS_TRANS(
"Pad 8 (sweep)"),
1056 NEEDS_TRANS(
"FX 1 (rain)"), NEEDS_TRANS(
"FX 2 (soundtrack)"), NEEDS_TRANS(
"FX 3 (crystal)"), NEEDS_TRANS(
"FX 4 (atmosphere)"),
1057 NEEDS_TRANS(
"FX 5 (brightness)"), NEEDS_TRANS(
"FX 6 (goblins)"), NEEDS_TRANS(
"FX 7 (echoes)"), NEEDS_TRANS(
"FX 8 (sci-fi)"),
1058 NEEDS_TRANS(
"Sitar"), NEEDS_TRANS(
"Banjo"), NEEDS_TRANS(
"Shamisen"), NEEDS_TRANS(
"Koto"),
1059 NEEDS_TRANS(
"Kalimba"), NEEDS_TRANS(
"Bag pipe"), NEEDS_TRANS(
"Fiddle"), NEEDS_TRANS(
"Shanai"),
1060 NEEDS_TRANS(
"Tinkle Bell"), NEEDS_TRANS(
"Agogo"), NEEDS_TRANS(
"Steel Drums"), NEEDS_TRANS(
"Woodblock"),
1061 NEEDS_TRANS(
"Taiko Drum"), NEEDS_TRANS(
"Melodic Tom"), NEEDS_TRANS(
"Synth Drum"), NEEDS_TRANS(
"Reverse Cymbal"),
1062 NEEDS_TRANS(
"Guitar Fret Noise"), NEEDS_TRANS(
"Breath Noise"), NEEDS_TRANS(
"Seashore"), NEEDS_TRANS(
"Bird Tweet"),
1063 NEEDS_TRANS(
"Telephone Ring"), NEEDS_TRANS(
"Helicopter"), NEEDS_TRANS(
"Applause"), NEEDS_TRANS(
"Gunshot")
1066 return isPositiveAndBelow (n, numElementsInArray (names)) ? names[n] :
nullptr;
1071 static const char* names[] =
1073 NEEDS_TRANS(
"Piano"), NEEDS_TRANS(
"Chromatic Percussion"), NEEDS_TRANS(
"Organ"), NEEDS_TRANS(
"Guitar"),
1074 NEEDS_TRANS(
"Bass"), NEEDS_TRANS(
"Strings"), NEEDS_TRANS(
"Ensemble"), NEEDS_TRANS(
"Brass"),
1075 NEEDS_TRANS(
"Reed"), NEEDS_TRANS(
"Pipe"), NEEDS_TRANS(
"Synth Lead"), NEEDS_TRANS(
"Synth Pad"),
1076 NEEDS_TRANS(
"Synth Effects"), NEEDS_TRANS(
"Ethnic"), NEEDS_TRANS(
"Percussive"), NEEDS_TRANS(
"Sound Effects")
1079 return isPositiveAndBelow (n, numElementsInArray (names)) ? names[n] :
nullptr;
1084 static const char* names[] =
1086 NEEDS_TRANS(
"Acoustic Bass Drum"), NEEDS_TRANS(
"Bass Drum 1"), NEEDS_TRANS(
"Side Stick"), NEEDS_TRANS(
"Acoustic Snare"),
1087 NEEDS_TRANS(
"Hand Clap"), NEEDS_TRANS(
"Electric Snare"), NEEDS_TRANS(
"Low Floor Tom"), NEEDS_TRANS(
"Closed Hi-Hat"),
1088 NEEDS_TRANS(
"High Floor Tom"), NEEDS_TRANS(
"Pedal Hi-Hat"), NEEDS_TRANS(
"Low Tom"), NEEDS_TRANS(
"Open Hi-Hat"),
1089 NEEDS_TRANS(
"Low-Mid Tom"), NEEDS_TRANS(
"Hi-Mid Tom"), NEEDS_TRANS(
"Crash Cymbal 1"), NEEDS_TRANS(
"High Tom"),
1090 NEEDS_TRANS(
"Ride Cymbal 1"), NEEDS_TRANS(
"Chinese Cymbal"), NEEDS_TRANS(
"Ride Bell"), NEEDS_TRANS(
"Tambourine"),
1091 NEEDS_TRANS(
"Splash Cymbal"), NEEDS_TRANS(
"Cowbell"), NEEDS_TRANS(
"Crash Cymbal 2"), NEEDS_TRANS(
"Vibraslap"),
1092 NEEDS_TRANS(
"Ride Cymbal 2"), NEEDS_TRANS(
"Hi Bongo"), NEEDS_TRANS(
"Low Bongo"), NEEDS_TRANS(
"Mute Hi Conga"),
1093 NEEDS_TRANS(
"Open Hi Conga"), NEEDS_TRANS(
"Low Conga"), NEEDS_TRANS(
"High Timbale"), NEEDS_TRANS(
"Low Timbale"),
1094 NEEDS_TRANS(
"High Agogo"), NEEDS_TRANS(
"Low Agogo"), NEEDS_TRANS(
"Cabasa"), NEEDS_TRANS(
"Maracas"),
1095 NEEDS_TRANS(
"Short Whistle"), NEEDS_TRANS(
"Long Whistle"), NEEDS_TRANS(
"Short Guiro"), NEEDS_TRANS(
"Long Guiro"),
1096 NEEDS_TRANS(
"Claves"), NEEDS_TRANS(
"Hi Wood Block"), NEEDS_TRANS(
"Low Wood Block"), NEEDS_TRANS(
"Mute Cuica"),
1097 NEEDS_TRANS(
"Open Cuica"), NEEDS_TRANS(
"Mute Triangle"), NEEDS_TRANS(
"Open Triangle")
1100 return (n >= 35 && n <= 81) ? names[n - 35] :
nullptr;
1105 static const char* names[] =
1107 NEEDS_TRANS(
"Bank Select"), NEEDS_TRANS(
"Modulation Wheel (coarse)"), NEEDS_TRANS(
"Breath controller (coarse)"),
1109 NEEDS_TRANS(
"Foot Pedal (coarse)"), NEEDS_TRANS(
"Portamento Time (coarse)"), NEEDS_TRANS(
"Data Entry (coarse)"),
1110 NEEDS_TRANS(
"Volume (coarse)"), NEEDS_TRANS(
"Balance (coarse)"),
1112 NEEDS_TRANS(
"Pan position (coarse)"), NEEDS_TRANS(
"Expression (coarse)"), NEEDS_TRANS(
"Effect Control 1 (coarse)"),
1113 NEEDS_TRANS(
"Effect Control 2 (coarse)"),
1115 NEEDS_TRANS(
"General Purpose Slider 1"), NEEDS_TRANS(
"General Purpose Slider 2"),
1116 NEEDS_TRANS(
"General Purpose Slider 3"), NEEDS_TRANS(
"General Purpose Slider 4"),
1117 nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
1118 NEEDS_TRANS(
"Bank Select (fine)"), NEEDS_TRANS(
"Modulation Wheel (fine)"), NEEDS_TRANS(
"Breath controller (fine)"),
1120 NEEDS_TRANS(
"Foot Pedal (fine)"), NEEDS_TRANS(
"Portamento Time (fine)"), NEEDS_TRANS(
"Data Entry (fine)"), NEEDS_TRANS(
"Volume (fine)"),
1121 NEEDS_TRANS(
"Balance (fine)"),
nullptr, NEEDS_TRANS(
"Pan position (fine)"), NEEDS_TRANS(
"Expression (fine)"),
1122 NEEDS_TRANS(
"Effect Control 1 (fine)"), NEEDS_TRANS(
"Effect Control 2 (fine)"),
1123 nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
1124 nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
1125 NEEDS_TRANS(
"Hold Pedal (on/off)"), NEEDS_TRANS(
"Portamento (on/off)"), NEEDS_TRANS(
"Sustenuto Pedal (on/off)"), NEEDS_TRANS(
"Soft Pedal (on/off)"),
1126 NEEDS_TRANS(
"Legato Pedal (on/off)"), NEEDS_TRANS(
"Hold 2 Pedal (on/off)"), NEEDS_TRANS(
"Sound Variation"), NEEDS_TRANS(
"Sound Timbre"),
1127 NEEDS_TRANS(
"Sound Release Time"), NEEDS_TRANS(
"Sound Attack Time"), NEEDS_TRANS(
"Sound Brightness"), NEEDS_TRANS(
"Sound Control 6"),
1128 NEEDS_TRANS(
"Sound Control 7"), NEEDS_TRANS(
"Sound Control 8"), NEEDS_TRANS(
"Sound Control 9"), NEEDS_TRANS(
"Sound Control 10"),
1129 NEEDS_TRANS(
"General Purpose Button 1 (on/off)"), NEEDS_TRANS(
"General Purpose Button 2 (on/off)"),
1130 NEEDS_TRANS(
"General Purpose Button 3 (on/off)"), NEEDS_TRANS(
"General Purpose Button 4 (on/off)"),
1131 nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
1132 NEEDS_TRANS(
"Reverb Level"), NEEDS_TRANS(
"Tremolo Level"), NEEDS_TRANS(
"Chorus Level"), NEEDS_TRANS(
"Celeste Level"),
1133 NEEDS_TRANS(
"Phaser Level"), NEEDS_TRANS(
"Data Button increment"), NEEDS_TRANS(
"Data Button decrement"), NEEDS_TRANS(
"Non-registered Parameter (fine)"),
1134 NEEDS_TRANS(
"Non-registered Parameter (coarse)"), NEEDS_TRANS(
"Registered Parameter (fine)"), NEEDS_TRANS(
"Registered Parameter (coarse)"),
1135 nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
1136 nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
1137 NEEDS_TRANS(
"All Sound Off"), NEEDS_TRANS(
"All Controllers Off"), NEEDS_TRANS(
"Local Keyboard (on/off)"), NEEDS_TRANS(
"All Notes Off"),
1138 NEEDS_TRANS(
"Omni Mode Off"), NEEDS_TRANS(
"Omni Mode On"), NEEDS_TRANS(
"Mono Operation"), NEEDS_TRANS(
"Poly Operation")
1141 return isPositiveAndBelow (n, numElementsInArray (names)) ? names[n] :
nullptr;
bool isResetAllControllers() const noexcept
Checks whether this message is a reset all controllers message.
bool isMidiStop() const noexcept
Returns true if this is a midi stop event.
static const char * getControllerName(int controllerNumber)
Returns the name of a controller type number, or nullptr if unknown for this controller number...
bool isMidiMachineControlGoto(int &hours, int &minutes, int &seconds, int &frames) const noexcept
Checks whether this is an MMC "goto" message.
MidiMessage & operator=(const MidiMessage &other)
Copies this message from another one.
void getTimeSignatureInfo(int &numerator, int &denominator) const noexcept
Returns the time-signature values from a time-signature meta-event.
bool isAftertouch() const noexcept
Returns true if the message is an aftertouch event.
static MidiMessage allSoundOff(int channel) noexcept
Creates an all-sound-off message.
static MidiMessage channelPressureChange(int channel, int pressure) noexcept
Creates a channel-pressure change event.
String getTextFromTextMetaEvent() const
Returns the text from a text meta-event.
bool isPitchWheel() const noexcept
Returns true if the message is a pitch-wheel move.
static String getMidiNoteName(int noteNumber, bool useSharps, bool includeOctaveNumber, int octaveNumForMiddleC)
Returns the name of a midi note number.
int getAfterTouchValue() const noexcept
Returns the amount of aftertouch from an aftertouch messages.
double getTempoMetaEventTickLength(short timeFormat) const noexcept
Returns the tick length from a tempo meta-event.
const uint8 * getSysExData() const noexcept
Returns a pointer to the sysex data inside the message.
int getMidiChannelMetaEventChannel() const noexcept
Returns the channel number from a channel meta-event.
Encapsulates a MIDI message.
bool isMetaEvent() const noexcept
Returns true if this event is a meta-event.
static uint8 floatValueToMidiByte(float valueBetween0and1) noexcept
Converts a floating-point value between 0 and 1 to a MIDI 7-bit value between 0 and 127...
A simple class for holding temporary references to a string literal or String.
int getQuarterFrameValue() const noexcept
Returns the value from a quarter-frame message.
int getMetaEventLength() const noexcept
Returns the length of the data for a meta-event.
bool isAllNotesOff() const noexcept
Checks whether this message is an all-notes-off message.
static MidiMessage songPositionPointer(int positionInMidiBeats) noexcept
Creates a song-position-pointer message.
void setVelocity(float newVelocity) noexcept
Changes the velocity of a note-on or note-off message.
static MidiMessage tempoMetaEvent(int microsecondsPerQuarterNote) noexcept
Creates a tempo meta-event.
static bool isMidiNoteBlack(int noteNumber) noexcept
Returns true if the given midi note number is a black key.
static const char * getRhythmInstrumentName(int midiNoteNumber)
Returns the standard name of a channel 10 percussion sound, or nullptr if unknown for this note numbe...
static MidiMessage pitchWheel(int channel, int position) noexcept
Creates a pitch-wheel move message.
bool isKeySignatureMajorKey() const noexcept
Returns true if this key-signature event is major, or false if it's minor.
int getRawDataSize() const noexcept
Returns the number of bytes of data in the message.
static MidiMessage createSysExMessage(const void *sysexData, int dataSize)
Creates a system-exclusive message.
bool isMidiStart() const noexcept
Returns true if this is a midi start event.
static MidiMessage textMetaEvent(int type, StringRef text)
Creates a text meta-event.
MidiMessage withTimeStamp(double newTimestamp) const
Return a copy of this message with a new timestamp.
static MidiMessage timeSignatureMetaEvent(int numerator, int denominator)
Creates a time-signature meta-event.
void getFullFrameParameters(int &hours, int &minutes, int &seconds, int &frames, SmpteTimecodeType &timecodeType) const noexcept
Extracts the timecode information from a full-frame midi timecode message.
bool isSongPositionPointer() const noexcept
Returns true if this is a song-position-pointer message.
bool isSustainPedalOff() const noexcept
Returns true if this message is a 'sustain pedal up' controller message.
bool isProgramChange() const noexcept
Returns true if the message is a program (patch) change message.
String getDescription() const
Returns a human-readable description of the midi message as a string, for example "Note On C#3 Veloci...
bool isFullFrame() const noexcept
Returns true if this is a full-frame midi timecode message.
bool isTimeSignatureMetaEvent() const noexcept
Returns true if this is a 'time-signature' meta-event.
static const char * getGMInstrumentBankName(int midiBankNumber)
Returns the name of a bank of GM instruments, or nullptr if unknown for this bank number...
bool isControllerOfType(int controllerType) const noexcept
Returns true if this message is a controller message and if it has the specified controller type...
void setNoteNumber(int newNoteNumber) noexcept
Changes the midi note number of a note-on or note-off message.
bool isMidiChannelMetaEvent() const noexcept
Returns true if this is a 'channel' meta-event.
static MidiMessage midiMachineControlCommand(MidiMachineControlCommand command)
Creates an MMC message.
static MidiMessage noteOff(int channel, int noteNumber, float velocity) noexcept
Creates a key-up message.
static MidiMessage endOfTrack() noexcept
Creates an end-of-track meta-event.
bool isSostenutoPedalOn() const noexcept
Returns true if this message is a 'sostenuto pedal down' controller message.
bool isMidiClock() const noexcept
Returns true if this is a midi clock event.
bool isEndOfTrackMetaEvent() const noexcept
Returns true if this is an 'end-of-track' meta-event.
static MidiMessage fullFrame(int hours, int minutes, int seconds, int frames, SmpteTimecodeType timecodeType)
Creates a full-frame MTC message.
int getSongPositionPointerMidiBeat() const noexcept
Returns the midi beat-number of a song-position-pointer message.
static int getMessageLengthFromFirstByte(uint8 firstByte) noexcept
Based on the first byte of a short midi message, this uses a lookup table to return the message lengt...
int getControllerNumber() const noexcept
Returns the controller number of a controller message.
int getChannel() const noexcept
Returns the midi channel associated with the message.
MidiMachineControlCommand
Types of MMC command.
void multiplyVelocity(float scaleFactor) noexcept
Multiplies the velocity of a note-on or note-off message by a given amount.
bool isController() const noexcept
Returns true if this is a midi controller message.
bool isTempoMetaEvent() const noexcept
Returns true if this is a 'tempo' meta-event.
void setChannel(int newChannelNumber) noexcept
Changes the message's midi channel.
MidiMachineControlCommand getMidiMachineControlCommand() const noexcept
For an MMC message, this returns its type.
bool isMidiMachineControlMessage() const noexcept
Checks whether this is an MMC message.
uint8 getVelocity() const noexcept
Returns the velocity of a note-on or note-off message.
static MidiMessage midiClock() noexcept
Creates a midi clock event.
static uint16 pitchbendToPitchwheelPos(float pitchbendInSemitones, float pitchbendRangeInSemitones) noexcept
Converts a pitchbend value in semitones to a MIDI 14-bit pitchwheel position value.
static MidiMessage allControllersOff(int channel) noexcept
Creates an all-controllers-off message.
static MidiMessage allNotesOff(int channel) noexcept
Creates an all-notes-off message.
static String toHexString(IntegerType number)
Returns a string representing this numeric value in hexadecimal.
SmpteTimecodeType
SMPTE timecode types.
CharType * getAddress() const noexcept
Returns the address that this pointer is pointing to.
bool isChannelPressure() const noexcept
Returns true if the message is a channel-pressure change event.
static MidiMessage controllerEvent(int channel, int controllerType, int value) noexcept
Creates a controller message.
float getFloatVelocity() const noexcept
Returns the velocity of a note-on or note-off message.
bool isSysEx() const noexcept
Returns true if this is a system-exclusive message.
int getProgramChangeNumber() const noexcept
Returns the new program number of a program change message.
static const char * getGMInstrumentName(int midiInstrumentNumber)
Returns the standard name of a GM instrument, or nullptr if unknown for this index.
static MidiMessage quarterFrame(int sequenceNumber, int value) noexcept
Creates a quarter-frame MTC message.
int getPitchWheelValue() const noexcept
Returns the pitch wheel position from a pitch-wheel move message.
int getChannelPressureValue() const noexcept
Returns the pressure from a channel pressure change message.
static MidiMessage midiChannelMetaEvent(int channel) noexcept
Creates a midi channel meta-event.
bool isNoteOff(bool returnTrueForNoteOnVelocity0=true) const noexcept
Returns true if this message is a 'key-up' event.
static MidiMessage programChange(int channel, int programNumber) noexcept
Creates a program-change message.
bool isEmpty() const noexcept
Returns true if the string contains no characters.
int getKeySignatureNumberOfSharpsOrFlats() const noexcept
Returns the key from a key-signature meta-event.
String::CharPointerType text
The text that is referenced.
int getQuarterFrameSequenceNumber() const noexcept
Returns the sequence number of a quarter-frame midi timecode message.
MidiMessage() noexcept
Creates an active-sense message.
bool isSustainPedalOn() const noexcept
Returns true if this message is a 'sustain pedal down' controller message.
bool isTrackMetaEvent() const noexcept
Returns true if this is a 'track' meta-event.
static int readVariableLengthVal(const uint8 *data, int &numBytesUsed) noexcept
Reads a midi variable-length integer.
bool isNoteOn(bool returnTrueForVelocity0=false) const noexcept
Returns true if this message is a 'key-down' event.
static double getMidiNoteInHertz(int noteNumber, double frequencyOfA=440.0) noexcept
Returns the frequency of a midi note number.
int getSysExDataSize() const noexcept
Returns the size of the sysex data.
static MidiMessage midiStart() noexcept
Creates a midi start event.
const uint8 * getRawData() const noexcept
Returns a pointer to the raw midi data.
const uint8 * getMetaEventData() const noexcept
Returns a pointer to the data in a meta-event.
static MidiMessage midiMachineControlGoto(int hours, int minutes, int seconds, int frames)
Creates an MMC "goto" message.
bool isActiveSense() const noexcept
Returns true if this is an active-sense message.
bool isSoftPedalOff() const noexcept
Returns true if this message is a 'soft pedal up' controller message.
bool isKeySignatureMetaEvent() const noexcept
Returns true if this is a 'key-signature' meta-event.
int getControllerValue() const noexcept
Returns the controller value from a controller message.
static MidiMessage midiStop() noexcept
Creates a midi stop event.
bool isQuarterFrame() const noexcept
Returns true if this is a quarter-frame midi timecode message.
bool isTextMetaEvent() const noexcept
Returns true if this is a 'text' meta-event.
static MidiMessage masterVolume(float volume)
Creates a master-volume change message.
bool isNoteOnOrOff() const noexcept
Returns true if this message is a 'key-down' or 'key-up' event.
bool isMidiContinue() const noexcept
Returns true if this is a midi continue event.
~MidiMessage() noexcept
Destructor.
int getNoteNumber() const noexcept
Returns the midi note number for note-on and note-off messages.
static MidiMessage keySignatureMetaEvent(int numberOfSharpsOrFlats, bool isMinorKey)
Creates a key-signature meta-event.
int getMetaEventType() const noexcept
Returns a meta-event's type number.
bool isTrackNameEvent() const noexcept
Returns true if this is an 'track name' meta-event.
double getTempoSecondsPerQuarterNote() const noexcept
Calculates the seconds-per-quarter-note from a tempo meta-event.
static MidiMessage aftertouchChange(int channel, int noteNumber, int aftertouchAmount) noexcept
Creates an aftertouch message.
static MidiMessage midiContinue() noexcept
Creates a midi continue event.
bool isSoftPedalOn() const noexcept
Returns true if this message is a 'soft pedal down' controller message.
static MidiMessage noteOn(int channel, int noteNumber, float velocity) noexcept
Creates a key-down message (using a floating-point velocity).
bool isSostenutoPedalOff() const noexcept
Returns true if this message is a 'sostenuto pedal up' controller message.
bool isForChannel(int channelNumber) const noexcept
Returns true if the message applies to the given midi channel.
size_t sizeInBytes() const noexcept
Returns the number of bytes that are used to represent this string.
Wraps a pointer to a null-terminated UTF-8 character string, and provides various methods to operate ...
bool isAllSoundOff() const noexcept
Checks whether this message is an all-sound-off message.