mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-28 13:22:57 +00:00
ALSA: line6: correct midi status byte when receiving data from podxt
commit 8508fa2e74
upstream.
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 <arteme@gmail.com>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20221225105728.1153989-1-arteme@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
414bacd8f3
commit
c8b3f17c13
5 changed files with 27 additions and 12 deletions
|
@ -311,7 +311,8 @@ static void line6_data_received(struct urb *urb)
|
||||||
for (;;) {
|
for (;;) {
|
||||||
done =
|
done =
|
||||||
line6_midibuf_read(mb, line6->buffer_message,
|
line6_midibuf_read(mb, line6->buffer_message,
|
||||||
LINE6_MIDI_MESSAGE_MAXLEN);
|
LINE6_MIDI_MESSAGE_MAXLEN,
|
||||||
|
LINE6_MIDIBUF_READ_RX);
|
||||||
|
|
||||||
if (done <= 0)
|
if (done <= 0)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -60,7 +60,8 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
done = line6_midibuf_read(mb, chunk,
|
done = line6_midibuf_read(mb, chunk,
|
||||||
LINE6_FALLBACK_MAXPACKETSIZE);
|
LINE6_FALLBACK_MAXPACKETSIZE,
|
||||||
|
LINE6_MIDIBUF_READ_TX);
|
||||||
|
|
||||||
if (done == 0)
|
if (done == 0)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "midibuf.h"
|
#include "midibuf.h"
|
||||||
|
|
||||||
|
|
||||||
static int midibuf_message_length(unsigned char code)
|
static int midibuf_message_length(unsigned char code)
|
||||||
{
|
{
|
||||||
int message_length;
|
int message_length;
|
||||||
|
@ -24,12 +25,7 @@ static int midibuf_message_length(unsigned char code)
|
||||||
|
|
||||||
message_length = length[(code >> 4) - 8];
|
message_length = length[(code >> 4) - 8];
|
||||||
} else {
|
} else {
|
||||||
/*
|
static const int length[] = { -1, 2, 2, 2, -1, -1, 1, 1, 1, -1,
|
||||||
Note that according to the MIDI specification 0xf2 is
|
|
||||||
the "Song Position Pointer", but this is used by Line 6
|
|
||||||
to send sysex messages to the host.
|
|
||||||
*/
|
|
||||||
static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, -1, 1, 1
|
1, 1, 1, -1, 1, 1
|
||||||
};
|
};
|
||||||
message_length = length[code & 0x0f];
|
message_length = length[code & 0x0f];
|
||||||
|
@ -129,7 +125,7 @@ int line6_midibuf_write(struct midi_buffer *this, unsigned char *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
|
int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
|
||||||
int length)
|
int length, int read_type)
|
||||||
{
|
{
|
||||||
int bytes_used;
|
int bytes_used;
|
||||||
int length1, length2;
|
int length1, length2;
|
||||||
|
@ -152,9 +148,22 @@ int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
|
||||||
|
|
||||||
length1 = this->size - this->pos_read;
|
length1 = this->size - this->pos_read;
|
||||||
|
|
||||||
/* check MIDI command length */
|
|
||||||
command = this->buf[this->pos_read];
|
command = this->buf[this->pos_read];
|
||||||
|
/*
|
||||||
|
PODxt always has status byte lower nibble set to 0010,
|
||||||
|
when it means to send 0000, so we correct if here so
|
||||||
|
that control/program changes come on channel 1 and
|
||||||
|
sysex message status byte is correct
|
||||||
|
*/
|
||||||
|
if (read_type == LINE6_MIDIBUF_READ_RX) {
|
||||||
|
if (command == 0xb2 || command == 0xc2 || command == 0xf2) {
|
||||||
|
unsigned char fixed = command & 0xf0;
|
||||||
|
this->buf[this->pos_read] = fixed;
|
||||||
|
command = fixed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check MIDI command length */
|
||||||
if (command & 0x80) {
|
if (command & 0x80) {
|
||||||
midi_length = midibuf_message_length(command);
|
midi_length = midibuf_message_length(command);
|
||||||
this->command_prev = command;
|
this->command_prev = command;
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
#ifndef MIDIBUF_H
|
#ifndef MIDIBUF_H
|
||||||
#define MIDIBUF_H
|
#define MIDIBUF_H
|
||||||
|
|
||||||
|
#define LINE6_MIDIBUF_READ_TX 0
|
||||||
|
#define LINE6_MIDIBUF_READ_RX 1
|
||||||
|
|
||||||
struct midi_buffer {
|
struct midi_buffer {
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
int size;
|
int size;
|
||||||
|
@ -27,7 +30,7 @@ extern void line6_midibuf_destroy(struct midi_buffer *mb);
|
||||||
extern int line6_midibuf_ignore(struct midi_buffer *mb, int length);
|
extern int line6_midibuf_ignore(struct midi_buffer *mb, int length);
|
||||||
extern int line6_midibuf_init(struct midi_buffer *mb, int size, int split);
|
extern int line6_midibuf_init(struct midi_buffer *mb, int size, int split);
|
||||||
extern int line6_midibuf_read(struct midi_buffer *mb, unsigned char *data,
|
extern int line6_midibuf_read(struct midi_buffer *mb, unsigned char *data,
|
||||||
int length);
|
int length, int read_type);
|
||||||
extern void line6_midibuf_reset(struct midi_buffer *mb);
|
extern void line6_midibuf_reset(struct midi_buffer *mb);
|
||||||
extern int line6_midibuf_write(struct midi_buffer *mb, unsigned char *data,
|
extern int line6_midibuf_write(struct midi_buffer *mb, unsigned char *data,
|
||||||
int length);
|
int length);
|
||||||
|
|
|
@ -169,8 +169,9 @@ static struct line6_pcm_properties pod_pcm_properties = {
|
||||||
.bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
|
.bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const char pod_version_header[] = {
|
static const char pod_version_header[] = {
|
||||||
0xf2, 0x7e, 0x7f, 0x06, 0x02
|
0xf0, 0x7e, 0x7f, 0x06, 0x02
|
||||||
};
|
};
|
||||||
|
|
||||||
/* forward declarations: */
|
/* forward declarations: */
|
||||||
|
|
Loading…
Reference in a new issue