Skip to content

Commit

Permalink
ALSA: usb-audio: work around streaming quirk for MacroSilicon MS2109
Browse files Browse the repository at this point in the history
Further investigation of the L-R swap problem on the MS2109 reveals that
the problem isn't that the channels are swapped, but rather that they
are swapped and also out of phase by one sample. In other words, the
issue is actually that the very first frame that comes from the hardware
is a half-frame containing only the right channel, and after that
everything becomes offset.

So introduce a new quirk field to drop the very first 2 bytes that come
in after the format is configured and a capture stream starts. This puts
the channels in phase and in the correct order.

Cc: stable@vger.kernel.org
Signed-off-by: Hector Martin <marcan@marcan.st>
Link: https://lore.kernel.org/r/20200810082400.225858-1-marcan@marcan.st
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
marcan authored and tiwai committed Aug 10, 2020
1 parent 386a653 commit 1b7ecc2
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 0 deletions.
1 change: 1 addition & 0 deletions sound/usb/card.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ struct snd_usb_substream {
unsigned int tx_length_quirk:1; /* add length specifier to transfers */
unsigned int fmt_type; /* USB audio format type (1-3) */
unsigned int pkt_offset_adj; /* Bytes to drop from beginning of packets (for non-compliant devices) */
unsigned int stream_offset_adj; /* Bytes to drop from beginning of stream (for non-compliant devices) */

unsigned int running: 1; /* running status */

Expand Down
6 changes: 6 additions & 0 deletions sound/usb/pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1420,6 +1420,12 @@ static void retire_capture_urb(struct snd_usb_substream *subs,
// continue;
}
bytes = urb->iso_frame_desc[i].actual_length;
if (subs->stream_offset_adj > 0) {
unsigned int adj = min(subs->stream_offset_adj, bytes);
cp += adj;
bytes -= adj;
subs->stream_offset_adj -= adj;
}
frames = bytes / stride;
if (!subs->txfr_quirk)
bytes = frames * stride;
Expand Down
3 changes: 3 additions & 0 deletions sound/usb/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -1495,6 +1495,9 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
case USB_ID(0x2b73, 0x000a): /* Pioneer DJ DJM-900NXS2 */
pioneer_djm_set_format_quirk(subs);
break;
case USB_ID(0x534d, 0x2109): /* MacroSilicon MS2109 */
subs->stream_offset_adj = 2;
break;
}
}

Expand Down
1 change: 1 addition & 0 deletions sound/usb/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
subs->tx_length_quirk = as->chip->tx_length_quirk;
subs->speed = snd_usb_get_speed(subs->dev);
subs->pkt_offset_adj = 0;
subs->stream_offset_adj = 0;

snd_usb_set_pcm_ops(as->pcm, stream);

Expand Down

0 comments on commit 1b7ecc2

Please sign in to comment.