33class MidiDataConcatenator
36 MidiDataConcatenator (
int initialBufferSize)
37 : pendingSysexData ((
size_t) initialBufferSize)
43 currentMessageLen = 0;
48 template <
typename UserDataType,
typename CallbackType>
49 void pushMidiData (
const void* inputData,
int numBytes,
double time,
50 UserDataType* input, CallbackType& callback)
52 auto d =
static_cast<const uint8*
> (inputData);
58 if (pendingSysexSize != 0 || nextByte == 0xf0)
60 processSysex (d, numBytes, time, input, callback);
61 currentMessageLen = 0;
68 if (isRealtimeMessage (nextByte))
70 callback.handleIncomingMidiMessage (input,
MidiMessage (nextByte, time));
76 if (isInitialByte (nextByte))
78 currentMessage[0] = nextByte;
79 currentMessageLen = 1;
81 else if (currentMessageLen > 0 && currentMessageLen < 3)
83 currentMessage[currentMessageLen++] = nextByte;
88 currentMessageLen = 0;
94 if (expectedLength == currentMessageLen)
96 callback.handleIncomingMidiMessage (input,
MidiMessage (currentMessage, expectedLength, time));
97 currentMessageLen = 1;
103 template <
typename UserDataType,
typename CallbackType>
104 void processSysex (
const uint8*& d,
int& numBytes,
double time,
105 UserDataType* input, CallbackType& callback)
109 pendingSysexSize = 0;
110 pendingSysexTime = time;
113 pendingSysexData.ensureSize ((
size_t) (pendingSysexSize + numBytes),
false);
114 auto totalMessage =
static_cast<uint8*
> (pendingSysexData.getData());
115 auto dest = totalMessage + pendingSysexSize;
119 if (pendingSysexSize > 0 && isStatusByte (*d))
129 if (*d >= 0xfa || *d == 0xf8)
131 callback.handleIncomingMidiMessage (input,
MidiMessage (*d, time));
137 pendingSysexSize = 0;
143 callback.handleIncomingMidiMessage (input, m);
158 while (numBytes > 0);
160 if (pendingSysexSize > 0)
162 if (totalMessage [pendingSysexSize - 1] == 0xf7)
164 callback.handleIncomingMidiMessage (input,
MidiMessage (totalMessage, pendingSysexSize, pendingSysexTime));
165 pendingSysexSize = 0;
169 callback.handlePartialSysexMessage (input, totalMessage, pendingSysexSize, pendingSysexTime);
174 static bool isRealtimeMessage (uint8
byte) {
return byte >= 0xf8 &&
byte <= 0xfe; }
175 static bool isStatusByte (uint8
byte) {
return byte >= 0x80; }
176 static bool isInitialByte (uint8
byte) {
return isStatusByte (
byte) &&
byte != 0xf7; }
178 uint8 currentMessage[3];
179 int currentMessageLen = 0;
182 double pendingSysexTime = 0;
183 int pendingSysexSize = 0;
185 JUCE_DECLARE_NON_COPYABLE (MidiDataConcatenator)