ALSA: snd-usb: use ep->stride from urb callbacks

For normal PCM transfer, this change has no effect, as the endpoint's
stride is always frame_bits/8. For DSD DOP streams, however, which is
added later, the hardware stride differs from the software stride, and
the endpoint has the correct information in these cases.

Signed-off-by: Daniel Mack <zonque@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Daniel Mack 2013-04-17 00:01:37 +08:00 committed by Takashi Iwai
parent ef7a4f979b
commit 8a2a74d2b7

View file

@ -1236,8 +1236,8 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
counts = snd_usb_endpoint_next_packet_size(ep); counts = snd_usb_endpoint_next_packet_size(ep);
/* set up descriptor */ /* set up descriptor */
urb->iso_frame_desc[i].offset = frames * stride; urb->iso_frame_desc[i].offset = frames * ep->stride;
urb->iso_frame_desc[i].length = counts * stride; urb->iso_frame_desc[i].length = counts * ep->stride;
frames += counts; frames += counts;
urb->number_of_packets++; urb->number_of_packets++;
subs->transfer_done += counts; subs->transfer_done += counts;
@ -1251,14 +1251,14 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
frames -= subs->transfer_done; frames -= subs->transfer_done;
counts -= subs->transfer_done; counts -= subs->transfer_done;
urb->iso_frame_desc[i].length = urb->iso_frame_desc[i].length =
counts * stride; counts * ep->stride;
subs->transfer_done = 0; subs->transfer_done = 0;
} }
i++; i++;
if (i < ctx->packets) { if (i < ctx->packets) {
/* add a transfer delimiter */ /* add a transfer delimiter */
urb->iso_frame_desc[i].offset = urb->iso_frame_desc[i].offset =
frames * stride; frames * ep->stride;
urb->iso_frame_desc[i].length = 0; urb->iso_frame_desc[i].length = 0;
urb->number_of_packets++; urb->number_of_packets++;
} }
@ -1269,7 +1269,7 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
!snd_usb_endpoint_implicit_feedback_sink(subs->data_endpoint)) /* finish at the period boundary */ !snd_usb_endpoint_implicit_feedback_sink(subs->data_endpoint)) /* finish at the period boundary */
break; break;
} }
bytes = frames * stride; bytes = frames * ep->stride;
if (subs->hwptr_done + bytes > runtime->buffer_size * stride) { if (subs->hwptr_done + bytes > runtime->buffer_size * stride) {
/* err, the transferred area goes over buffer boundary. */ /* err, the transferred area goes over buffer boundary. */
unsigned int bytes1 = unsigned int bytes1 =
@ -1310,8 +1310,8 @@ static void retire_playback_urb(struct snd_usb_substream *subs,
{ {
unsigned long flags; unsigned long flags;
struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
int stride = runtime->frame_bits >> 3; struct snd_usb_endpoint *ep = subs->data_endpoint;
int processed = urb->transfer_buffer_length / stride; int processed = urb->transfer_buffer_length / ep->stride;
int est_delay; int est_delay;
/* ignore the delay accounting when procssed=0 is given, i.e. /* ignore the delay accounting when procssed=0 is given, i.e.