[alsa-devel] [PATCH 1/3] ALSA: core: keep track of boundary wrap-around
Takashi Iwai
tiwai at suse.de
Tue Oct 23 16:43:32 CEST 2012
At Mon, 22 Oct 2012 16:42:14 -0500,
Pierre-Louis Bossart wrote:
>
> Keep track of boundary crossing when hw_ptr
> exceeds boundary limit and wraps-around. This
> will help keep track of total number
> of frames played/received at the kernel level
>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
Applied all three patches now. Thanks.
Takashi
> ---
> include/sound/pcm.h | 1 +
> sound/core/pcm_lib.c | 25 ++++++++++++++++++++-----
> 2 files changed, 21 insertions(+), 5 deletions(-)
>
> diff --git a/include/sound/pcm.h b/include/sound/pcm.h
> index 6268a41..28fd9f9 100644
> --- a/include/sound/pcm.h
> +++ b/include/sound/pcm.h
> @@ -281,6 +281,7 @@ struct snd_pcm_runtime {
> unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */
> unsigned long hw_ptr_buffer_jiffies; /* buffer time in jiffies */
> snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */
> + u64 hw_ptr_wrap; /* offset for hw_ptr due to boundary wrap-around */
>
> /* -- HW params -- */
> snd_pcm_access_t access; /* access mode */
> diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
> index f42c10a..3dc029e 100644
> --- a/sound/core/pcm_lib.c
> +++ b/sound/core/pcm_lib.c
> @@ -316,6 +316,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
> unsigned long jdelta;
> unsigned long curr_jiffies;
> struct timespec curr_tstamp;
> + int crossed_boundary = 0;
>
> old_hw_ptr = runtime->status->hw_ptr;
>
> @@ -360,8 +361,10 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
> hdelta = curr_jiffies - runtime->hw_ptr_jiffies;
> if (hdelta > runtime->hw_ptr_buffer_jiffies/2) {
> hw_base += runtime->buffer_size;
> - if (hw_base >= runtime->boundary)
> + if (hw_base >= runtime->boundary) {
> hw_base = 0;
> + crossed_boundary++;
> + }
> new_hw_ptr = hw_base + pos;
> goto __delta;
> }
> @@ -371,8 +374,10 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
> /* pointer crosses the end of the ring buffer */
> if (new_hw_ptr < old_hw_ptr) {
> hw_base += runtime->buffer_size;
> - if (hw_base >= runtime->boundary)
> + if (hw_base >= runtime->boundary) {
> hw_base = 0;
> + crossed_boundary++;
> + }
> new_hw_ptr = hw_base + pos;
> }
> __delta:
> @@ -410,8 +415,10 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
> while (hdelta > xrun_threshold) {
> delta += runtime->buffer_size;
> hw_base += runtime->buffer_size;
> - if (hw_base >= runtime->boundary)
> + if (hw_base >= runtime->boundary) {
> hw_base = 0;
> + crossed_boundary++;
> + }
> new_hw_ptr = hw_base + pos;
> hdelta -= runtime->hw_ptr_buffer_jiffies;
> }
> @@ -456,8 +463,10 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
> /* the delta value is small or zero in most cases */
> while (delta > 0) {
> new_hw_ptr += runtime->period_size;
> - if (new_hw_ptr >= runtime->boundary)
> + if (new_hw_ptr >= runtime->boundary) {
> new_hw_ptr -= runtime->boundary;
> + crossed_boundary--;
> + }
> delta--;
> }
> /* align hw_base to buffer_size */
> @@ -507,6 +516,10 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
> runtime->hw_ptr_base = hw_base;
> runtime->status->hw_ptr = new_hw_ptr;
> runtime->hw_ptr_jiffies = curr_jiffies;
> + if (crossed_boundary) {
> + snd_BUG_ON(crossed_boundary != 1);
> + runtime->hw_ptr_wrap += runtime->boundary;
> + }
> if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
> runtime->status->tstamp = curr_tstamp;
>
> @@ -1661,8 +1674,10 @@ static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream,
> if (snd_pcm_running(substream) &&
> snd_pcm_update_hw_ptr(substream) >= 0)
> runtime->status->hw_ptr %= runtime->buffer_size;
> - else
> + else {
> runtime->status->hw_ptr = 0;
> + runtime->hw_ptr_wrap = 0;
> + }
> snd_pcm_stream_unlock_irqrestore(substream, flags);
> return 0;
> }
> --
> 1.7.9.5
>
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>
More information about the Alsa-devel
mailing list