diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-10-12 21:08:53 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-05-05 08:47:21 -0400 |
commit | ae1ec5e1e97f67d41e641a73380129e5905e41cc (patch) | |
tree | d6366e64044c20570724decdf2d6d10f1e476c97 /sound/usb | |
parent | 4bbe1ddf89a5ba3ec30fe5980912d8bda3a3cbb2 (diff) |
ALSA: usbaudio - Add delay account
Manage the PCM delay account based on the queued URBs.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb')
-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 823296d7d578..6c25fa23f702 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, | |||
627 | subs->hwptr_done += offs; | 627 | subs->hwptr_done += offs; |
628 | if (subs->hwptr_done >= runtime->buffer_size) | 628 | if (subs->hwptr_done >= runtime->buffer_size) |
629 | subs->hwptr_done -= runtime->buffer_size; | 629 | subs->hwptr_done -= runtime->buffer_size; |
630 | runtime->delay += offs; | ||
630 | spin_unlock_irqrestore(&subs->lock, flags); | 631 | spin_unlock_irqrestore(&subs->lock, flags); |
631 | urb->transfer_buffer_length = offs * stride; | 632 | urb->transfer_buffer_length = offs * stride; |
632 | if (period_elapsed) | 633 | if (period_elapsed) |
@@ -636,12 +637,22 @@ static int prepare_playback_urb(struct snd_usb_substream *subs, | |||
636 | 637 | ||
637 | /* | 638 | /* |
638 | * process after playback data complete | 639 | * process after playback data complete |
639 | * - nothing to do | 640 | * - decrease the delay count again |
640 | */ | 641 | */ |
641 | static int retire_playback_urb(struct snd_usb_substream *subs, | 642 | static int retire_playback_urb(struct snd_usb_substream *subs, |
642 | struct snd_pcm_runtime *runtime, | 643 | struct snd_pcm_runtime *runtime, |
643 | struct urb *urb) | 644 | struct urb *urb) |
644 | { | 645 | { |
646 | unsigned long flags; | ||
647 | int stride = runtime->frame_bits >> 3; | ||
648 | int processed = urb->transfer_buffer_length / stride; | ||
649 | |||
650 | spin_lock_irqsave(&subs->lock, flags); | ||
651 | if (processed > runtime->delay) | ||
652 | runtime->delay = 0; | ||
653 | else | ||
654 | runtime->delay -= processed; | ||
655 | spin_unlock_irqrestore(&subs->lock, flags); | ||
645 | return 0; | 656 | return 0; |
646 | } | 657 | } |
647 | 658 | ||
@@ -1520,6 +1531,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) | |||
1520 | subs->hwptr_done = 0; | 1531 | subs->hwptr_done = 0; |
1521 | subs->transfer_done = 0; | 1532 | subs->transfer_done = 0; |
1522 | subs->phase = 0; | 1533 | subs->phase = 0; |
1534 | runtime->delay = 0; | ||
1523 | 1535 | ||
1524 | /* clear urbs (to be sure) */ | 1536 | /* clear urbs (to be sure) */ |
1525 | deactivate_urbs(subs, 0, 1); | 1537 | deactivate_urbs(subs, 0, 1); |