mirror of https://github.com/ericonr/sndio.git
Tolerate clients keeping state across sysex message
This commit is contained in:
parent
4fad29ecb6
commit
fb8bf93f11
|
@ -93,6 +93,7 @@ midi_new(struct midiops *ops, void *arg, int mode)
|
|||
ep->len = 0;
|
||||
ep->idx = 0;
|
||||
ep->st = 0;
|
||||
ep->last_st = 0;
|
||||
ep->txmask = 0;
|
||||
ep->self = 1 << i;
|
||||
ep->tickets = 0;
|
||||
|
@ -306,7 +307,18 @@ midi_in(struct midi *iep, unsigned char *idata, int icount)
|
|||
iep->msg[iep->idx++] = c;
|
||||
iep->ops->imsg(iep->arg, iep->msg, iep->idx);
|
||||
}
|
||||
iep->st = 0;
|
||||
|
||||
/*
|
||||
* There are bogus MIDI sources that keep
|
||||
* state across sysex; Linux virmidi ports fed
|
||||
* by the sequencer is an example. We
|
||||
* workaround this by saving the current
|
||||
* status and restoring it at the end of the
|
||||
* sysex.
|
||||
*/
|
||||
iep->st = iep->last_st;
|
||||
if (iep->st)
|
||||
iep->len = voice_len[(iep->st >> 4) & 7];
|
||||
iep->idx = 0;
|
||||
} else if (c >= 0xf0) {
|
||||
iep->msg[0] = c;
|
||||
|
@ -316,7 +328,7 @@ midi_in(struct midi *iep, unsigned char *idata, int icount)
|
|||
} else if (c >= 0x80) {
|
||||
iep->msg[0] = c;
|
||||
iep->len = voice_len[(c >> 4) & 7];
|
||||
iep->st = c;
|
||||
iep->last_st = iep->st = c;
|
||||
iep->idx = 1;
|
||||
} else if (iep->st) {
|
||||
if (iep->idx == 0 && iep->st != SYSEX_START)
|
||||
|
|
|
@ -68,6 +68,7 @@ struct midi {
|
|||
#define MIDI_MSGMAX 16 /* max size of MIDI msg */
|
||||
unsigned char msg[MIDI_MSGMAX]; /* parsed input message */
|
||||
unsigned int st; /* input MIDI running status */
|
||||
unsigned int last_st; /* backup of st during sysex */
|
||||
unsigned int used; /* bytes used in ``msg'' */
|
||||
unsigned int idx; /* current ``msg'' size */
|
||||
unsigned int len; /* expected ``msg'' length */
|
||||
|
|
Loading…
Reference in New Issue