Browse Source

Track System Realtime messages

When attempting to read a SysEx message, we need to avoid ending
up reading a continuous flow of System Realtime messages without
realizing that there is no SysEx message to come. We do that by
reading at most 10 consecutive System Realtime messages before
aborting the read.
master
Damien Goutte-Gattat 9 years ago
parent
commit
e6a662d89e
  1. 4
      src/asysex.c
  2. 20
      src/sysex.c

4
src/asysex.c

@ -216,7 +216,7 @@ static void
do_query(midi_io_t *midi, FILE *in, FILE *out, print_midi_fn_t print_midi)
{
unsigned char *query, reply[256];
size_t n;
ssize_t n;
query = NULL;
@ -233,7 +233,7 @@ do_query(midi_io_t *midi, FILE *in, FILE *out, print_midi_fn_t print_midi)
print_midi(out, reply, n);
}
while ( reply[n-1] != 0xF7 );
while ( n > 0 && reply[n-1] != 0xF7 );
fputc('\n', out);
}

20
src/sysex.c

@ -25,17 +25,33 @@
ssize_t
sysex_read(midi_io_t *midi, unsigned char *data, size_t len)
{
int byte, loop, n;
int byte, loop, n, p;
loop = 1;
n = 1;
p = 0;
while ( n < len && loop ) {
if ( (byte = midi_next(midi)) < 0 )
return byte;
if ( byte >= 0xF8 ) /* Ignore System Realtime messages. */
/*
* We're not interested in System Realtime messages and should
* ignore them. However, when using a MIDI device which
* regularly emits such messages, this function can end up
* blocked until the next SysEx message. The workaround here is
* to count System Realtime messages: if we read more than 10
* of them in a row (arbitrary value), it's likely that there
* is no SysEx message in queue, and we can tell the caller
* that we read nothing.
*/
if ( byte >= 0xF8 ) {
if ( ++p >= 10 )
return 0;
continue;
}
else
p = 0;
if ( midi_status(midi) == 0xF0 ) {
if ( byte == 0xF0 && n > 0 ) {

Loading…
Cancel
Save