Skip to content

Commit 8508fa2

Browse files
artemetiwai
authored andcommitted
ALSA: line6: correct midi status byte when receiving data from podxt
A PODxt device sends 0xb2, 0xc2 or 0xf2 as a status byte for MIDI messages over USB that should otherwise have a 0xb0, 0xc0 or 0xf0 status byte. This is usually corrected by the driver on other OSes. This fixes MIDI sysex messages sent by PODxt. [ tiwai: fixed white spaces ] Signed-off-by: Artem Egorkine <[email protected]> Cc: <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 1b929c0 commit 8508fa2

File tree

5 files changed

+27
-12
lines changed

5 files changed

+27
-12
lines changed

sound/usb/line6/driver.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,8 @@ static void line6_data_received(struct urb *urb)
304304
for (;;) {
305305
done =
306306
line6_midibuf_read(mb, line6->buffer_message,
307-
LINE6_MIDI_MESSAGE_MAXLEN);
307+
LINE6_MIDI_MESSAGE_MAXLEN,
308+
LINE6_MIDIBUF_READ_RX);
308309

309310
if (done <= 0)
310311
break;

sound/usb/line6/midi.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
5656

5757
for (;;) {
5858
done = line6_midibuf_read(mb, chunk,
59-
LINE6_FALLBACK_MAXPACKETSIZE);
59+
LINE6_FALLBACK_MAXPACKETSIZE,
60+
LINE6_MIDIBUF_READ_TX);
6061

6162
if (done == 0)
6263
break;

sound/usb/line6/midibuf.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "midibuf.h"
1111

12+
1213
static int midibuf_message_length(unsigned char code)
1314
{
1415
int message_length;
@@ -20,12 +21,7 @@ static int midibuf_message_length(unsigned char code)
2021

2122
message_length = length[(code >> 4) - 8];
2223
} else {
23-
/*
24-
Note that according to the MIDI specification 0xf2 is
25-
the "Song Position Pointer", but this is used by Line 6
26-
to send sysex messages to the host.
27-
*/
28-
static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
24+
static const int length[] = { -1, 2, 2, 2, -1, -1, 1, 1, 1, -1,
2925
1, 1, 1, -1, 1, 1
3026
};
3127
message_length = length[code & 0x0f];
@@ -125,7 +121,7 @@ int line6_midibuf_write(struct midi_buffer *this, unsigned char *data,
125121
}
126122

127123
int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
128-
int length)
124+
int length, int read_type)
129125
{
130126
int bytes_used;
131127
int length1, length2;
@@ -148,9 +144,22 @@ int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
148144

149145
length1 = this->size - this->pos_read;
150146

151-
/* check MIDI command length */
152147
command = this->buf[this->pos_read];
148+
/*
149+
PODxt always has status byte lower nibble set to 0010,
150+
when it means to send 0000, so we correct if here so
151+
that control/program changes come on channel 1 and
152+
sysex message status byte is correct
153+
*/
154+
if (read_type == LINE6_MIDIBUF_READ_RX) {
155+
if (command == 0xb2 || command == 0xc2 || command == 0xf2) {
156+
unsigned char fixed = command & 0xf0;
157+
this->buf[this->pos_read] = fixed;
158+
command = fixed;
159+
}
160+
}
153161

162+
/* check MIDI command length */
154163
if (command & 0x80) {
155164
midi_length = midibuf_message_length(command);
156165
this->command_prev = command;

sound/usb/line6/midibuf.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#ifndef MIDIBUF_H
99
#define MIDIBUF_H
1010

11+
#define LINE6_MIDIBUF_READ_TX 0
12+
#define LINE6_MIDIBUF_READ_RX 1
13+
1114
struct midi_buffer {
1215
unsigned char *buf;
1316
int size;
@@ -23,7 +26,7 @@ extern void line6_midibuf_destroy(struct midi_buffer *mb);
2326
extern int line6_midibuf_ignore(struct midi_buffer *mb, int length);
2427
extern int line6_midibuf_init(struct midi_buffer *mb, int size, int split);
2528
extern int line6_midibuf_read(struct midi_buffer *mb, unsigned char *data,
26-
int length);
29+
int length, int read_type);
2730
extern void line6_midibuf_reset(struct midi_buffer *mb);
2831
extern int line6_midibuf_write(struct midi_buffer *mb, unsigned char *data,
2932
int length);

sound/usb/line6/pod.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,9 @@ static struct line6_pcm_properties pod_pcm_properties = {
159159
.bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
160160
};
161161

162+
162163
static const char pod_version_header[] = {
163-
0xf2, 0x7e, 0x7f, 0x06, 0x02
164+
0xf0, 0x7e, 0x7f, 0x06, 0x02
164165
};
165166

166167
static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,

0 commit comments

Comments
 (0)