aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/usbmidi.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2007-08-16 02:44:51 -0400
committerJaroslav Kysela <perex@perex.cz>2007-10-16 09:59:01 -0400
commit61870aed229519e7cd7f1899a19e4e7c8ba915e4 (patch)
treeeef415e298e6eb51b1c944819102e711794150f3 /sound/usb/usbmidi.c
parent20a45e8644ef4f5e7dfd727859301c4c581e9489 (diff)
[ALSA] usb-audio: fix parsing of SysEx messages from CME keyboards
When CME keyboards send a SysEx message (e.g. master volume), the USB packet uses a format different from the standard format. Parsing this packet according to the specification corrupts the SysEx message itself and can cause the following MIDI messages to be misinterpreted, too. This patch adds a workaround for this case. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/usb/usbmidi.c')
-rw-r--r--sound/usb/usbmidi.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 99295f9b7691..2bb1834a8c22 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -407,6 +407,20 @@ static void snd_usbmidi_maudio_broken_running_status_input(
407} 407}
408 408
409/* 409/*
410 * CME protocol: like the standard protocol, but SysEx commands are sent as a
411 * single USB packet preceded by a 0x0F byte.
412 */
413static void snd_usbmidi_cme_input(struct snd_usb_midi_in_endpoint *ep,
414 uint8_t *buffer, int buffer_length)
415{
416 if (buffer_length < 2 || (buffer[0] & 0x0f) != 0x0f)
417 snd_usbmidi_standard_input(ep, buffer, buffer_length);
418 else
419 snd_usbmidi_input_data(ep, buffer[0] >> 4,
420 &buffer[1], buffer_length - 1);
421}
422
423/*
410 * Adds one USB MIDI packet to the output buffer. 424 * Adds one USB MIDI packet to the output buffer.
411 */ 425 */
412static void snd_usbmidi_output_standard_packet(struct urb* urb, uint8_t p0, 426static void snd_usbmidi_output_standard_packet(struct urb* urb, uint8_t p0,
@@ -572,6 +586,12 @@ static struct usb_protocol_ops snd_usbmidi_maudio_broken_running_status_ops = {
572 .output_packet = snd_usbmidi_output_standard_packet, 586 .output_packet = snd_usbmidi_output_standard_packet,
573}; 587};
574 588
589static struct usb_protocol_ops snd_usbmidi_cme_ops = {
590 .input = snd_usbmidi_cme_input,
591 .output = snd_usbmidi_standard_output,
592 .output_packet = snd_usbmidi_output_standard_packet,
593};
594
575/* 595/*
576 * Novation USB MIDI protocol: number of data bytes is in the first byte 596 * Novation USB MIDI protocol: number of data bytes is in the first byte
577 * (when receiving) (+1!) or in the second byte (when sending); data begins 597 * (when receiving) (+1!) or in the second byte (when sending); data begins
@@ -1690,6 +1710,7 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
1690 err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1); 1710 err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
1691 break; 1711 break;
1692 case QUIRK_MIDI_CME: 1712 case QUIRK_MIDI_CME:
1713 umidi->usb_protocol_ops = &snd_usbmidi_cme_ops;
1693 err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); 1714 err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
1694 break; 1715 break;
1695 default: 1716 default: