[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