Skip to content

Commit e22f4f7

Browse files
authored
Merge pull request #109 from arduino-libraries/dropfix
Fixed midi input event loss issue with high data rates
2 parents 19edeb1 + def8be1 commit e22f4f7

File tree

1 file changed

+22
-8
lines changed

1 file changed

+22
-8
lines changed

src/MIDIUSB.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,28 +80,42 @@ void MIDI_::accept(void)
8080
ring_bufferMIDI *buffer = &midi_rx_buffer;
8181
uint32_t i = (uint32_t)(buffer->head+1) % MIDI_BUFFER_SIZE;
8282

83+
// The USB_Recv() call apparently tosses away available incoming data that isn't fully read
84+
// so you must provide it with enough space to prevent dropped MIDI events, because there can be more than one
85+
// MIDI packet available per USB_Recv() call.
86+
// Here we support up to 8 events per recv (observed hi-rate midi streams can require this,
87+
// but it could be bigger with sysex dumps, so this might need to be raised even more)
88+
midiEventPacket_t event[8];
89+
8390
// if we should be storing the received character into the location
8491
// just before the tail (meaning that the head would advance to the
8592
// current location of the tail), we're about to overflow the buffer
8693
// and so we don't write the character or advance the head.
8794
while (i != buffer->tail) {
8895
int c;
89-
midiEventPacket_t event;
9096
if (!USB_Available(MIDI_RX)) {
9197
#if defined(ARDUINO_ARCH_SAM)
9298
udd_ack_fifocon(MIDI_RX);
9399
#endif
94-
//break;
100+
break; // appears to be needed now that we have larger possible reads
95101
}
96-
c = USB_Recv(MIDI_RX, &event, sizeof(event) );
102+
c = USB_Recv(MIDI_RX, event, sizeof(event) );
97103

98-
//MIDI packet has to be 4 bytes
99-
if(c < 4)
104+
if(c < 4) {
100105
return;
101-
buffer->midiEvent[buffer->head] = event;
102-
buffer->head = i;
106+
}
103107

104-
i = (i + 1) % MIDI_BUFFER_SIZE;
108+
// each MIDI packet is 4 bytes
109+
// but there could be more than one midi packet per receive
110+
int pos = 0 ;
111+
while (i != buffer->tail && c >= 4) {
112+
buffer->midiEvent[buffer->head] = event[pos];
113+
buffer->head = i;
114+
115+
i = (i + 1) % MIDI_BUFFER_SIZE;
116+
c -= 4;
117+
++pos;
118+
}
105119
}
106120
}
107121

0 commit comments

Comments
 (0)