/* Approximation based on number of samples per USB frame (ms),
some truncation for 44.1 but the estimate is good enough */
- est_delay = subs->last_delay - (frame_diff * rate / 1000);
+ est_delay = frame_diff * rate / 1000;
+ if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
+ est_delay = subs->last_delay - est_delay;
+ else
+ est_delay = subs->last_delay + est_delay;
+
if (est_delay < 0)
est_delay = 0;
return est_delay;
return SNDRV_PCM_POS_XRUN;
spin_lock(&subs->lock);
hwptr_done = subs->hwptr_done;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- substream->runtime->delay = snd_usb_pcm_delay(subs,
+ substream->runtime->delay = snd_usb_pcm_delay(subs,
substream->runtime->rate);
spin_unlock(&subs->lock);
return hwptr_done / (substream->runtime->frame_bits >> 3);
switch (subs->stream->chip->usb_id) {
case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
+ case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */
if (is_playback) {
implicit_fb = 1;
ep = 0x81;
int i, period_elapsed = 0;
unsigned long flags;
unsigned char *cp;
+ int current_frame_number;
+
+ /* read frame number here, update pointer in critical section */
+ current_frame_number = usb_get_current_frame_number(subs->dev);
stride = runtime->frame_bits >> 3;
if (!subs->txfr_quirk)
bytes = frames * stride;
if (bytes % (runtime->sample_bits >> 3) != 0) {
-#ifdef CONFIG_SND_DEBUG_VERBOSE
int oldbytes = bytes;
-#endif
bytes = frames * stride;
snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n",
oldbytes, bytes);
subs->transfer_done -= runtime->period_size;
period_elapsed = 1;
}
+ /* capture delay is by construction limited to one URB,
+ * reset delays here
+ */
+ runtime->delay = subs->last_delay = 0;
+
+ /* realign last_frame_number */
+ subs->last_frame_number = current_frame_number;
+ subs->last_frame_number &= 0xFF; /* keep 8 LSBs */
+
spin_unlock_irqrestore(&subs->lock, flags);
/* copy a data chunk */
if (oldptr + bytes > runtime->buffer_size * stride) {