diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-03-19 09:47:30 +0100 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-03-19 09:47:30 +0100 |
commit | 0d4a42f6bd298e826620585e766a154ab460617a (patch) | |
tree | 406d8f7778691d858dbe3e48e4bbb10e99c0a58a /sound/usb/pcm.c | |
parent | d62b4892f3d9f7dd2002e5309be10719d6805b0f (diff) | |
parent | a937536b868b8369b98967929045f1df54234323 (diff) |
Merge tag 'v3.9-rc3' into drm-intel-next-queued
Backmerge so that I can merge Imre Deak's coalesced sg entries fixes,
which depend upon the new for_each_sg_page introduce in
commit a321e91b6d73ed011ffceed384c40d2785cf723b
Author: Imre Deak <imre.deak@intel.com>
Date: Wed Feb 27 17:02:56 2013 -0800
lib/scatterlist: add simple page iterator
The merge itself is just two trivial conflicts:
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'sound/usb/pcm.c')
-rw-r--r-- | sound/usb/pcm.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index d82e378d37cb..f94397b42aa5 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -59,7 +59,12 @@ snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs, /* 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; @@ -78,8 +83,7 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream 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); @@ -363,6 +367,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) 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; @@ -1157,6 +1162,10 @@ static void retire_capture_urb(struct snd_usb_substream *subs, 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; @@ -1171,9 +1180,7 @@ static void retire_capture_urb(struct snd_usb_substream *subs, 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); @@ -1190,6 +1197,15 @@ static void retire_capture_urb(struct snd_usb_substream *subs, 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) { |