Index: Source/modules/webmidi/MIDIInput.cpp |
diff --git a/Source/modules/webmidi/MIDIInput.cpp b/Source/modules/webmidi/MIDIInput.cpp |
index a5dee099588ff1cf228b26c9234b4e538f9e97da..1e9e62c80095d7bcfaa742d97850f4bb4e8f32a0 100644 |
--- a/Source/modules/webmidi/MIDIInput.cpp |
+++ b/Source/modules/webmidi/MIDIInput.cpp |
@@ -49,10 +49,30 @@ void MIDIInput::didReceiveMIDIData(unsigned portIndex, const unsigned char* data |
{ |
ASSERT(isMainThread()); |
- RefPtr<Uint8Array> array = Uint8Array::create(length); |
- array->setRange(data, length, 0); |
+ // The received MIDI data may contain one or more messages. |
+ // The Web MIDI API requires that a separate event be dispatched for each message, |
+ // so we walk through the data and dispatch one at a time. |
+ size_t i = 0; |
+ while (i < length) { |
+ unsigned char status = data[i]; |
+ unsigned char strippedStatus = status & 0xf0; |
- dispatchEvent(MIDIMessageEvent::create(timeStamp, array)); |
+ // FIXME: support System Exclusive. |
+ if (strippedStatus >= 0xf0) |
+ break; |
+ |
+ // All non System Exclusive messages have a total size of 3 except for Program Change and Channel Pressure. |
+ size_t totalMessageSize = (strippedStatus == 0xc0 || strippedStatus == 0xd0) ? 2 : 3; |
+ |
+ if (i + totalMessageSize <= length) { |
+ RefPtr<Uint8Array> array = Uint8Array::create(totalMessageSize); |
+ array->setRange(data + i, totalMessageSize, 0); |
+ |
+ dispatchEvent(MIDIMessageEvent::create(timeStamp, array)); |
+ } |
+ |
+ i += totalMessageSize; |
+ } |
} |
} // namespace WebCore |