diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-06-10 07:26:40 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-06-10 07:26:40 +0200 |
commit | eabaf0634a9034f2e487b0be347edc1460c026a4 (patch) | |
tree | e950df1ba10e0a29b25afdd446ac44988381a851 /sound/usb/usbaudio.c | |
parent | 9dea75c70965c240012251dc5845fe0c1a061180 (diff) | |
parent | ae1ec5e1e97f67d41e641a73380129e5905e41cc (diff) |
Merge branch 'topic/pcm-delay' into for-linus
* topic/pcm-delay:
ALSA: usbaudio - Add delay account
ALSA: Add extra delay count in PCM
Diffstat (limited to 'sound/usb/usbaudio.c')
-rw-r--r-- | sound/usb/usbaudio.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index a6b88482637..a8ef2cbcc03 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -627,6 +627,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs, subs->hwptr_done += offs; if (subs->hwptr_done >= runtime->buffer_size) subs->hwptr_done -= runtime->buffer_size; + runtime->delay += offs; spin_unlock_irqrestore(&subs->lock, flags); urb->transfer_buffer_length = offs * stride; if (period_elapsed) @@ -636,12 +637,22 @@ static int prepare_playback_urb(struct snd_usb_substream *subs, /* * process after playback data complete - * - nothing to do + * - decrease the delay count again */ static int retire_playback_urb(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *urb) { + unsigned long flags; + int stride = runtime->frame_bits >> 3; + int processed = urb->transfer_buffer_length / stride; + + spin_lock_irqsave(&subs->lock, flags); + if (processed > runtime->delay) + runtime->delay = 0; + else + runtime->delay -= processed; + spin_unlock_irqrestore(&subs->lock, flags); return 0; } @@ -1520,6 +1531,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) subs->hwptr_done = 0; subs->transfer_done = 0; subs->phase = 0; + runtime->delay = 0; /* clear urbs (to be sure) */ deactivate_urbs(subs, 0, 1); |