Loading include/sound/pcm.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -270,6 +270,7 @@ struct snd_pcm_runtime { snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */ snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */ snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */ snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */ unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */ unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */ snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */ /* -- HW params -- */ /* -- HW params -- */ snd_pcm_access_t access; /* access mode */ snd_pcm_access_t access; /* access mode */ Loading sound/core/pcm_native.c +5 −3 Original line number Original line Diff line number Diff line Loading @@ -587,14 +587,15 @@ int snd_pcm_status(struct snd_pcm_substream *substream, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { status->avail = snd_pcm_playback_avail(runtime); status->avail = snd_pcm_playback_avail(runtime); if (runtime->status->state == SNDRV_PCM_STATE_RUNNING || if (runtime->status->state == SNDRV_PCM_STATE_RUNNING || runtime->status->state == SNDRV_PCM_STATE_DRAINING) runtime->status->state == SNDRV_PCM_STATE_DRAINING) { status->delay = runtime->buffer_size - status->avail; status->delay = runtime->buffer_size - status->avail; else status->delay += runtime->delay; } else status->delay = 0; status->delay = 0; } else { } else { status->avail = snd_pcm_capture_avail(runtime); status->avail = snd_pcm_capture_avail(runtime); if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) status->delay = status->avail; status->delay = status->avail + runtime->delay; else else status->delay = 0; status->delay = 0; } } Loading Loading @@ -2410,6 +2411,7 @@ static int snd_pcm_delay(struct snd_pcm_substream *substream, n = snd_pcm_playback_hw_avail(runtime); n = snd_pcm_playback_hw_avail(runtime); else else n = snd_pcm_capture_avail(runtime); n = snd_pcm_capture_avail(runtime); n += runtime->delay; break; break; case SNDRV_PCM_STATE_XRUN: case SNDRV_PCM_STATE_XRUN: err = -EPIPE; err = -EPIPE; Loading sound/usb/usbaudio.c +13 −1 Original line number Original line Diff line number Diff line Loading @@ -627,6 +627,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs, subs->hwptr_done += offs; subs->hwptr_done += offs; if (subs->hwptr_done >= runtime->buffer_size) if (subs->hwptr_done >= runtime->buffer_size) subs->hwptr_done -= runtime->buffer_size; subs->hwptr_done -= runtime->buffer_size; runtime->delay += offs; spin_unlock_irqrestore(&subs->lock, flags); spin_unlock_irqrestore(&subs->lock, flags); urb->transfer_buffer_length = offs * stride; urb->transfer_buffer_length = offs * stride; if (period_elapsed) if (period_elapsed) Loading @@ -636,12 +637,22 @@ static int prepare_playback_urb(struct snd_usb_substream *subs, /* /* * process after playback data complete * process after playback data complete * - nothing to do * - decrease the delay count again */ */ static int retire_playback_urb(struct snd_usb_substream *subs, static int retire_playback_urb(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct snd_pcm_runtime *runtime, struct urb *urb) 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; return 0; } } Loading Loading @@ -1520,6 +1531,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) subs->hwptr_done = 0; subs->hwptr_done = 0; subs->transfer_done = 0; subs->transfer_done = 0; subs->phase = 0; subs->phase = 0; runtime->delay = 0; /* clear urbs (to be sure) */ /* clear urbs (to be sure) */ deactivate_urbs(subs, 0, 1); deactivate_urbs(subs, 0, 1); Loading Loading
include/sound/pcm.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -270,6 +270,7 @@ struct snd_pcm_runtime { snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */ snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */ snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */ snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */ unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */ unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */ snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */ /* -- HW params -- */ /* -- HW params -- */ snd_pcm_access_t access; /* access mode */ snd_pcm_access_t access; /* access mode */ Loading
sound/core/pcm_native.c +5 −3 Original line number Original line Diff line number Diff line Loading @@ -587,14 +587,15 @@ int snd_pcm_status(struct snd_pcm_substream *substream, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { status->avail = snd_pcm_playback_avail(runtime); status->avail = snd_pcm_playback_avail(runtime); if (runtime->status->state == SNDRV_PCM_STATE_RUNNING || if (runtime->status->state == SNDRV_PCM_STATE_RUNNING || runtime->status->state == SNDRV_PCM_STATE_DRAINING) runtime->status->state == SNDRV_PCM_STATE_DRAINING) { status->delay = runtime->buffer_size - status->avail; status->delay = runtime->buffer_size - status->avail; else status->delay += runtime->delay; } else status->delay = 0; status->delay = 0; } else { } else { status->avail = snd_pcm_capture_avail(runtime); status->avail = snd_pcm_capture_avail(runtime); if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) status->delay = status->avail; status->delay = status->avail + runtime->delay; else else status->delay = 0; status->delay = 0; } } Loading Loading @@ -2410,6 +2411,7 @@ static int snd_pcm_delay(struct snd_pcm_substream *substream, n = snd_pcm_playback_hw_avail(runtime); n = snd_pcm_playback_hw_avail(runtime); else else n = snd_pcm_capture_avail(runtime); n = snd_pcm_capture_avail(runtime); n += runtime->delay; break; break; case SNDRV_PCM_STATE_XRUN: case SNDRV_PCM_STATE_XRUN: err = -EPIPE; err = -EPIPE; Loading
sound/usb/usbaudio.c +13 −1 Original line number Original line Diff line number Diff line Loading @@ -627,6 +627,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs, subs->hwptr_done += offs; subs->hwptr_done += offs; if (subs->hwptr_done >= runtime->buffer_size) if (subs->hwptr_done >= runtime->buffer_size) subs->hwptr_done -= runtime->buffer_size; subs->hwptr_done -= runtime->buffer_size; runtime->delay += offs; spin_unlock_irqrestore(&subs->lock, flags); spin_unlock_irqrestore(&subs->lock, flags); urb->transfer_buffer_length = offs * stride; urb->transfer_buffer_length = offs * stride; if (period_elapsed) if (period_elapsed) Loading @@ -636,12 +637,22 @@ static int prepare_playback_urb(struct snd_usb_substream *subs, /* /* * process after playback data complete * process after playback data complete * - nothing to do * - decrease the delay count again */ */ static int retire_playback_urb(struct snd_usb_substream *subs, static int retire_playback_urb(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct snd_pcm_runtime *runtime, struct urb *urb) 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; return 0; } } Loading Loading @@ -1520,6 +1531,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) subs->hwptr_done = 0; subs->hwptr_done = 0; subs->transfer_done = 0; subs->transfer_done = 0; subs->phase = 0; subs->phase = 0; runtime->delay = 0; /* clear urbs (to be sure) */ /* clear urbs (to be sure) */ deactivate_urbs(subs, 0, 1); deactivate_urbs(subs, 0, 1); Loading