Skip to content

Commit 952b13c

Browse files
committed
ALSA: seq: ump: Optimize conversions from SysEx to UMP
The current conversion from the legacy SysEx event to UMP SysEx packet in the sequencer core has a couple of issues: * The first packet trims the SysEx start byte (0xf0), hence it contains only 5 bytes instead of 6. This isn't wrong, per specification, but it's strange not to fill 6 bytes. * When the SysEx end marker (0xf7) is placed at the first byte of the next packet, it'll end up with an empty data just with the END status. It can be rather folded into the previous packet with the END status. This patch tries to address those issues. The first packet may have 6 bytes even with the SysEx start, and an empty packet with the SysEx end marker is omitted. Fixes: e9e0281 ("ALSA: seq: Automatic conversion of UMP events") Cc: <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 4f61c8f commit 952b13c

File tree

1 file changed

+23
-14
lines changed

1 file changed

+23
-14
lines changed

sound/core/seq/seq_ump_convert.c

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,44 +1192,53 @@ static int cvt_sysex_to_ump(struct snd_seq_client *dest,
11921192
{
11931193
struct snd_seq_ump_event ev_cvt;
11941194
unsigned char status;
1195-
u8 buf[6], *xbuf;
1195+
u8 buf[8], *xbuf;
11961196
int offset = 0;
11971197
int len, err;
1198+
bool finished = false;
11981199

11991200
if (!snd_seq_ev_is_variable(event))
12001201
return 0;
12011202

12021203
setup_ump_event(&ev_cvt, event);
1203-
for (;;) {
1204+
while (!finished) {
12041205
len = snd_seq_expand_var_event_at(event, sizeof(buf), buf, offset);
12051206
if (len <= 0)
12061207
break;
1207-
if (WARN_ON(len > 6))
1208+
if (WARN_ON(len > sizeof(buf)))
12081209
break;
1209-
offset += len;
1210+
12101211
xbuf = buf;
1212+
status = UMP_SYSEX_STATUS_CONTINUE;
1213+
/* truncate the sysex start-marker */
12111214
if (*xbuf == UMP_MIDI1_MSG_SYSEX_START) {
12121215
status = UMP_SYSEX_STATUS_START;
1213-
xbuf++;
12141216
len--;
1215-
if (len > 0 && xbuf[len - 1] == UMP_MIDI1_MSG_SYSEX_END) {
1217+
offset++;
1218+
xbuf++;
1219+
}
1220+
1221+
/* if the last of this packet or the 1st byte of the next packet
1222+
* is the end-marker, finish the transfer with this packet
1223+
*/
1224+
if (len > 0 && len < 8 &&
1225+
xbuf[len - 1] == UMP_MIDI1_MSG_SYSEX_END) {
1226+
if (status == UMP_SYSEX_STATUS_START)
12161227
status = UMP_SYSEX_STATUS_SINGLE;
1217-
len--;
1218-
}
1219-
} else {
1220-
if (xbuf[len - 1] == UMP_MIDI1_MSG_SYSEX_END) {
1228+
else
12211229
status = UMP_SYSEX_STATUS_END;
1222-
len--;
1223-
} else {
1224-
status = UMP_SYSEX_STATUS_CONTINUE;
1225-
}
1230+
len--;
1231+
finished = true;
12261232
}
1233+
1234+
len = min(len, 6);
12271235
fill_sysex7_ump(dest_port, ev_cvt.ump, status, xbuf, len);
12281236
err = __snd_seq_deliver_single_event(dest, dest_port,
12291237
(struct snd_seq_event *)&ev_cvt,
12301238
atomic, hop);
12311239
if (err < 0)
12321240
return err;
1241+
offset += len;
12331242
}
12341243
return 0;
12351244
}

0 commit comments

Comments
 (0)