[alsa-devel] [PATCH] ALSA: pcm - introduce soc_delay

Takashi Iwai tiwai at suse.de
Mon Jul 23 12:27:10 CEST 2012


At Mon, 23 Jul 2012 15:36:37 +0530,
Vinod Koul wrote:
> 
> In many modern SoCs the audio DSP can buffer the PCM ring buffer data. Today we
> have no means to represent this buffering and ALSA wrongly detects an overrun
> when hw_ptr reaches app_ptr value, though DSP may still have some buffered data.
> 
> This patch tries to add a new field "soc_delay" to represent buffering done in
> DSPs. This value is also used for the xrun calculations in ALSA.
> 
> Signed-off-by: Vinod Koul <vinod.koul at linux.intel.com>
> 
> --
> Once we are okay with this approach, I will send a follow up patch which adds
> this notion in ASoC and uses this to compute cpu_dai delay. The codec_dai delay
> along with FIFO delay from cpu_dai should be added and reresented by today's
> notion of delay.

Hmm, it's confusing to have both delay and soc_delay fields.

And, if the XRUN detection is the only problem, we can provide a flag
to correct avail with runtime->delay.


> ---
>  include/sound/pcm.h     |    1 +
>  sound/core/pcm_lib.c    |   14 +++++++++++---
>  sound/core/pcm_native.c |    6 +++---
>  3 files changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/include/sound/pcm.h b/include/sound/pcm.h
> index a55d5db..405deb7 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 */
> +	snd_pcm_sframes_t soc_delay;	/* extra delay; typically delay incurred in soc */
>  
>  	/* -- HW params -- */
>  	snd_pcm_access_t access;	/* access mode */
> diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
> index 8f312fa..4977012 100644
> --- a/sound/core/pcm_lib.c
> +++ b/sound/core/pcm_lib.c
> @@ -292,7 +292,15 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream,
>  			return -EPIPE;
>  		}
>  	} else {
> -		if (avail >= runtime->stop_threshold) {
> +		snd_pcm_uframes_t actual_avail;
> +		if (avail < runtime->soc_delay)
> +			actual_avail = avail;
> +		else
> +			actual_avail = avail - runtime->soc_delay;
> +		if (actual_avail  >= runtime->stop_threshold) {
> +			snd_printd(KERN_ERR  "avail > stop_threshold!!\n");
> +			snd_printd(KERN_ERR  "actual_avail %ld, avail %ld, soc_delay %ld!!\n",
> +					actual_avail, avail,  runtime->soc_delay);

Don't add debug prints here.  This is no kernel error, and XRUN is
already informed in xrun() function.


thanks,

Takashi

>  			xrun(substream);
>  			return -EPIPE;
>  		}
> @@ -440,9 +448,9 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
>  	if (runtime->hw.info & SNDRV_PCM_INFO_BATCH)
>  		goto no_jiffies_check;
>  	hdelta = delta;
> -	if (hdelta < runtime->delay)
> +	if (hdelta < (runtime->delay + runtime->soc_delay))
>  		goto no_jiffies_check;
> -	hdelta -= runtime->delay;
> +	hdelta -= (runtime->delay + runtime->soc_delay);
>  	jdelta = curr_jiffies - runtime->hw_ptr_jiffies;
>  	if (((hdelta * HZ) / runtime->rate) > jdelta + HZ/100) {
>  		delta = jdelta /
> diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
> index 53b5ada..fc2d664 100644
> --- a/sound/core/pcm_native.c
> +++ b/sound/core/pcm_native.c
> @@ -606,13 +606,13 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
>  		if (runtime->status->state == SNDRV_PCM_STATE_RUNNING ||
>  		    runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
>  			status->delay = runtime->buffer_size - status->avail;
> -			status->delay += runtime->delay;
> +			status->delay += runtime->delay + runtime->soc_delay;
>  		} else
>  			status->delay = 0;
>  	} else {
>  		status->avail = snd_pcm_capture_avail(runtime);
>  		if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
> -			status->delay = status->avail + runtime->delay;
> +			status->delay = status->avail + runtime->delay + runtime->soc_delay;
>  		else
>  			status->delay = 0;
>  	}
> @@ -2442,7 +2442,7 @@ static int snd_pcm_delay(struct snd_pcm_substream *substream,
>  			n = snd_pcm_playback_hw_avail(runtime);
>  		else
>  			n = snd_pcm_capture_avail(runtime);
> -		n += runtime->delay;
> +		n += runtime->delay + runtime->soc_delay;
>  		break;
>  	case SNDRV_PCM_STATE_XRUN:
>  		err = -EPIPE;
> -- 
> 1.7.0.4
> 


More information about the Alsa-devel mailing list