alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
* XRUN handling
@ 2010-07-06  5:03 melwyn lobo
  2010-07-06  6:29 ` Clemens Ladisch
  2010-07-06 16:16 ` James Courtier-Dutton
  0 siblings, 2 replies; 12+ messages in thread
From: melwyn lobo @ 2010-07-06  5:03 UTC (permalink / raw)
  To: alsa-devel

Hi all,
I have noticed when an Xrun occurs, the bytes between the hw_ptr and
appl_ptr are not copied when both hw and appl pointers are reset in
snd_pcm_prepare().
Consider the following parameters:
  buffer_size  : 22352
  period_size  : 1016
  period_time  : 23038
  tstamp_mode  : NONE
  period_step  : 1
  avail_min    : 1016
  period_event : 0
  start_threshold  : 22352
  stop_threshold   : 22352
  silence_threshold: 0
  silence_size : 0

In case snd_pcm_playback_avail() is less than stop threshold but
greater than 0, then these bytes are missing after Xrun prepare and
start stage.

Is my analysis correct? If so how do we ensure correct behaviour ie
byte accuracy after Xrun.

Thanks,
M.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: XRUN handling
  2010-07-06  5:03 XRUN handling melwyn lobo
@ 2010-07-06  6:29 ` Clemens Ladisch
  2010-07-06 11:05   ` melwyn lobo
  2010-07-06 16:16 ` James Courtier-Dutton
  1 sibling, 1 reply; 12+ messages in thread
From: Clemens Ladisch @ 2010-07-06  6:29 UTC (permalink / raw)
  To: melwyn lobo; +Cc: alsa-devel

melwyn lobo wrote:
> In case snd_pcm_playback_avail() is less than stop threshold but
> greater than 0, then these bytes are missing after Xrun prepare and
> start stage.

Preparing a stream resets it, i.e., any data currently in the buffer
is discarded.

If you want to have data in the buffer after preparing, you have to
write it again.


Regards,
Clemens

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: XRUN handling
  2010-07-06  6:29 ` Clemens Ladisch
@ 2010-07-06 11:05   ` melwyn lobo
  2010-07-06 12:34     ` Clemens Ladisch
  0 siblings, 1 reply; 12+ messages in thread
From: melwyn lobo @ 2010-07-06 11:05 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: alsa-devel

Adding mailing list to copy:

- Hide quoted text -
> melwyn lobo wrote:
>> In case snd_pcm_playback_avail() is less than stop threshold but
>> greater than 0, then these bytes are missing after Xrun prepare and
>> start stage.
>
> Preparing a stream resets it, i.e., any data currently in the buffer
> is discarded.
>
> If you want to have data in the buffer after preparing, you have to
> write it again.
>


Thanks for the confirmation. Our client is working on aplay to test
our driver in which already there is this issue.
Is there any workaround in kernel/driver space that could be done or
it can only be fixed in aplay.

Regards
M.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: XRUN handling
  2010-07-06 11:05   ` melwyn lobo
@ 2010-07-06 12:34     ` Clemens Ladisch
  0 siblings, 0 replies; 12+ messages in thread
From: Clemens Ladisch @ 2010-07-06 12:34 UTC (permalink / raw)
  To: melwyn lobo; +Cc: alsa-devel

melwyn lobo wrote:
>> melwyn lobo wrote:
>>> In case snd_pcm_playback_avail() is less than stop threshold but
>>> greater than 0, then these bytes are missing after Xrun prepare and
>>> start stage.
>>
>> Preparing a stream resets it, i.e., any data currently in the buffer
>> is discarded.
>>
>> If you want to have data in the buffer after preparing, you have to
>> write it again.
> 
> Thanks for the confirmation. Our client is working on aplay to test
> our driver in which already there is this issue.
> Is there any workaround in kernel/driver space that could be done

When the ALSA framework tells the driver to stop, and then resets the
pointers, the driver cannot avoid doing this.


Applications have two choices how xruns are to be handled:
1) Stop the stream; the application must then reset the stream (by
   preparing it).  This mode is selected by using a stop_threshold that
   is lower than the buffer_size.  This is the default mode.
2) Continue playing.  The device will play old data from the ring
   buffer, until the application has caught up and written new data
   to the buffer.  This mode is selected by setting stop_threshold to
   the boundary value.


Regards,
Clemens

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: XRUN handling
  2010-07-06  5:03 XRUN handling melwyn lobo
  2010-07-06  6:29 ` Clemens Ladisch
@ 2010-07-06 16:16 ` James Courtier-Dutton
  2010-07-06 17:46   ` melwyn lobo
  1 sibling, 1 reply; 12+ messages in thread
From: James Courtier-Dutton @ 2010-07-06 16:16 UTC (permalink / raw)
  To: melwyn lobo; +Cc: alsa-devel

On 6 July 2010 06:03, melwyn lobo <linux.melwyn@gmail.com> wrote:
> Hi all,
> I have noticed when an Xrun occurs, the bytes between the hw_ptr and
> appl_ptr are not copied when both hw and appl pointers are reset in
> snd_pcm_prepare().
>
> Is my analysis correct? If so how do we ensure correct behaviour ie
> byte accuracy after Xrun.
>

When an Xrun occurs, all bets are off. You should reset the sound card
buffers and start again.
The best thing to do is try to track down why the Xrun occurs in the
first place and stop it happening.
It most likely occurs because some other device is keeping the CPU
from servicing the interrupt correctly.
Normally graphics card drivers, hard disk drivers or file system code
causes this problem.
Look at low latency and real time patches for the Linux kernel.

Kind Regards

James

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: XRUN handling
  2010-07-06 16:16 ` James Courtier-Dutton
@ 2010-07-06 17:46   ` melwyn lobo
  2010-07-06 18:39     ` Jaroslav Kysela
  2010-07-06 19:37     ` James Courtier-Dutton
  0 siblings, 2 replies; 12+ messages in thread
From: melwyn lobo @ 2010-07-06 17:46 UTC (permalink / raw)
  To: James Courtier-Dutton; +Cc: alsa-devel

On Tue, Jul 6, 2010 at 9:46 PM, James Courtier-Dutton
<james.dutton@gmail.com> wrote:
> On 6 July 2010 06:03, melwyn lobo <linux.melwyn@gmail.com> wrote:
>> Hi all,
>> I have noticed when an Xrun occurs, the bytes between the hw_ptr and
>> appl_ptr are not copied when both hw and appl pointers are reset in
>> snd_pcm_prepare().
>>
>> Is my analysis correct? If so how do we ensure correct behaviour ie
>> byte accuracy after Xrun.
>>
>
> When an Xrun occurs, all bets are off. You should reset the sound card
> buffers and start again.
> The best thing to do is try to track down why the Xrun occurs in the
> first place and stop it happening.
> It most likely occurs because some other device is keeping the CPU
> from servicing the interrupt correctly.
> Normally graphics card drivers, hard disk drivers or file system code
> causes this problem.
Thanks James.
We would not like to change the core vanilla kernel available as is
from kernel.org
apart from adding our own platform software of course.
For software robustness, we need to ensure that even after an XRUN
no data is missed.

> Look at low latency and real time patches for the Linux kernel.
>
> Kind Regards
>
> James
>

Thanks Clemens,

>When the ALSA framework tells the driver to stop, and then resets the
>pointers, the driver cannot avoid doing this.
>
>
>Applications have two choices how xruns are to be handled:
>1) Stop the stream; the application must then reset the stream (by
> reparing it).  This mode is selected by using a stop_threshold that
>  is lower than the buffer_size.  This is the default mode.
>2) Continue playing.  The device will play old data from the ring
>  buffer, until the application has caught up and written new data
>  to the buffer.  This mode is selected by setting stop_threshold to
>  the boundary value.
>
>
>Regards,
>Clemens

I have already done the above and issues are as under:
1. Stopping the stream after stop_threshold does ensure that garbage data is not
played, but, as said earlier, the remaining bytes within the buffer
are discarded
by the application. Not acceptable for us (assuming we use only standard aplay)
2. Continuing to run the the ring buffer produces garbage which can be
done away with by using silence_size and silence_threshold. And if the
application still does not get processor time for some reason, the
hw_ptr will overrun the appl_ptr by more than buffer_size and trigger
a bug in snd_pcm_playback_silence().

I am using 2.6.32.8. Are there any patches for xrun handling between
this and the latest versions of the kernel that I could use.

Regards
M.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: XRUN handling
  2010-07-06 17:46   ` melwyn lobo
@ 2010-07-06 18:39     ` Jaroslav Kysela
  2010-07-07  8:11       ` melwyn lobo
  2010-07-06 19:37     ` James Courtier-Dutton
  1 sibling, 1 reply; 12+ messages in thread
From: Jaroslav Kysela @ 2010-07-06 18:39 UTC (permalink / raw)
  To: melwyn lobo; +Cc: alsa-devel, James Courtier-Dutton

On Tue, 6 Jul 2010, melwyn lobo wrote:

> done away with by using silence_size and silence_threshold. And if the
> application still does not get processor time for some reason, the
> hw_ptr will overrun the appl_ptr by more than buffer_size and trigger
> a bug in snd_pcm_playback_silence().

Could you fix (send us a patch) or describe exactly this problem?

 					Jaroslav

-----
Jaroslav Kysela <perex@perex.cz>
Linux Kernel Sound Maintainer
ALSA Project, Red Hat, Inc.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: XRUN handling
  2010-07-06 17:46   ` melwyn lobo
  2010-07-06 18:39     ` Jaroslav Kysela
@ 2010-07-06 19:37     ` James Courtier-Dutton
  1 sibling, 0 replies; 12+ messages in thread
From: James Courtier-Dutton @ 2010-07-06 19:37 UTC (permalink / raw)
  To: melwyn lobo; +Cc: alsa-devel

On 6 July 2010 18:46, melwyn lobo <linux.melwyn@gmail.com> wrote:
> For software robustness, we need to ensure that even after an XRUN
> no data is missed.
>
Not possible. You can recover from the XRUN state but you will never
reach "no data is missed".

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: XRUN handling
  2010-07-06 18:39     ` Jaroslav Kysela
@ 2010-07-07  8:11       ` melwyn lobo
  2010-07-14 10:17         ` melwyn lobo
  0 siblings, 1 reply; 12+ messages in thread
From: melwyn lobo @ 2010-07-07  8:11 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: alsa-devel

On Wed, Jul 7, 2010 at 12:09 AM, Jaroslav Kysela <perex@perex.cz> wrote:
> On Tue, 6 Jul 2010, melwyn lobo wrote:
>
>> done away with by using silence_size and silence_threshold. And if the
>> application still does not get processor time for some reason, the
>> hw_ptr will overrun the appl_ptr by more than buffer_size and trigger
>> a bug in snd_pcm_playback_silence().
>
> Could you fix (send us a patch) or describe exactly this problem?

Yes. It occurs in a loaded system. The hardware runs continously and
eventually underruns (stop_threshold trigger does not
occur because of its large value).
Eventually due to silence_threshold, silence_size setting,
snd_pcm_playback_silence() attempts to continously append
silence.
The function snd_pcm_playback_hw_avail(runtime) returns negative
values. Now consider the code fragment;
noise_dist = snd_pcm_playback_hw_avail(runtime) + runtime->silence_filled;

                if (noise_dist >= (snd_pcm_sframes_t)
runtime->silence_threshold)
                        return;
                frames = runtime->silence_threshold - noise_dist;

which makes at some point frames > runtime->buffer_size and triggers

  if (snd_BUG_ON(frames > runtime->buffer_size))
                return;

This is my analysis as I can see the above statement getting executed.
For this, the solution implemented in the driver, is to eventually
stop the infinite DMA when appl_ptr <= hw_ptr.
>
>                                        Jaroslav
>
> -----
> Jaroslav Kysela <perex@perex.cz>
> Linux Kernel Sound Maintainer
> ALSA Project, Red Hat, Inc.
>
>

Regards,
M.
Regards,
M.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: XRUN handling
  2010-07-07  8:11       ` melwyn lobo
@ 2010-07-14 10:17         ` melwyn lobo
  2010-07-19 14:37           ` Jaroslav Kysela
  0 siblings, 1 reply; 12+ messages in thread
From: melwyn lobo @ 2010-07-14 10:17 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: alsa-devel

Another query, if setting runtime parameters like:
runtime->silence_threshold = runtime->boundary;
runtime->silence_size = runtime->boundary;
runtime->stop_threshold = runtime->boundary;

Also to avoid the bug in snd_pcm_playback_silence()  i.e.,
snd_BUG_ON(frames > runtime->buffer_size),
I have added a tweak in the driver IRQ handler:

              if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK
                                    &&
snd_pcm_playback_hw_avail(runtime) == 0) {

                        /* Hardware is continously running so it is
                         * playing silence so that should be OK.
                         * And we played all valid samples, so no data
                         * is lost. Not stopping intentionally
                         */

                          runtime->control->appl_ptr += runtime->period_size;
                        if(runtime->control->appl_ptr >= runtime->boundary)
                                runtime->control->appl_ptr -= runtime->boundary;

                        offset = runtime->control->appl_ptr -
runtime->silence_start;
                        if (offset < 0)
                                offset += runtime->boundary;
                        if ((snd_pcm_uframes_t)offset < runtime->silence_filled)
                                runtime->silence_filled -= offset;
                        else
                                runtime->silence_filled = 0;

                        runtime->silence_start = runtime->control->appl_ptr;

This avoids the bug above, but aplay does not stop after reading all
the samples from the file. It plays silence infinitely.
Should not this condition be detected by the aplay and stop the stream
when EOF on the file happens.

Regards,
M.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: XRUN handling
  2010-07-14 10:17         ` melwyn lobo
@ 2010-07-19 14:37           ` Jaroslav Kysela
  2010-07-19 14:43             ` Jaroslav Kysela
  0 siblings, 1 reply; 12+ messages in thread
From: Jaroslav Kysela @ 2010-07-19 14:37 UTC (permalink / raw)
  To: melwyn lobo; +Cc: alsa-devel

On Wed, 14 Jul 2010, melwyn lobo wrote:

> Another query, if setting runtime parameters like:
> runtime->silence_threshold = runtime->boundary;
> runtime->silence_size = runtime->boundary;
> runtime->stop_threshold = runtime->boundary;
>
> Also to avoid the bug in snd_pcm_playback_silence()  i.e.,
> snd_BUG_ON(frames > runtime->buffer_size),
> I have added a tweak in the driver IRQ handler:

This patch might fix this problem:

diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index bcf95d3..e23e0e7 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -67,6 +67,8 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
  	} else {
  		if (new_hw_ptr == ULONG_MAX) {	/* initialization */
  			snd_pcm_sframes_t avail = snd_pcm_playback_hw_avail(runtime);
+			if (avail > runtime->buffer_size)
+				avail = runtime->buffer_size;
  			runtime->silence_filled = avail > 0 ? avail : 0;
  			runtime->silence_start = (runtime->status->hw_ptr +
  						  runtime->silence_filled) %

But it looks that you do something wrong with hw_ptr or appl_ptr in your 
driver, because this condition would be true only when an large underrun 
occurs immediatelly.

 					Jaroslav

-----
Jaroslav Kysela <perex@perex.cz>
Linux Kernel Sound Maintainer
ALSA Project, Red Hat, Inc.

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: XRUN handling
  2010-07-19 14:37           ` Jaroslav Kysela
@ 2010-07-19 14:43             ` Jaroslav Kysela
  0 siblings, 0 replies; 12+ messages in thread
From: Jaroslav Kysela @ 2010-07-19 14:43 UTC (permalink / raw)
  To: melwyn lobo; +Cc: alsa-devel

On Mon, 19 Jul 2010, Jaroslav Kysela wrote:

> On Wed, 14 Jul 2010, melwyn lobo wrote:
>
>> Another query, if setting runtime parameters like:
>> runtime->silence_threshold = runtime->boundary;
>> runtime->silence_size = runtime->boundary;
>> runtime->stop_threshold = runtime->boundary;
>>
>> Also to avoid the bug in snd_pcm_playback_silence()  i.e.,
>> snd_BUG_ON(frames > runtime->buffer_size),
>> I have added a tweak in the driver IRQ handler:
>
> This patch might fix this problem:
>
> diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
> index bcf95d3..e23e0e7 100644
> --- a/sound/core/pcm_lib.c
> +++ b/sound/core/pcm_lib.c
> @@ -67,6 +67,8 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
>  	} else {
>  		if (new_hw_ptr == ULONG_MAX) {	/* initialization */
>  			snd_pcm_sframes_t avail = snd_pcm_playback_hw_avail(runtime);
> +			if (avail > runtime->buffer_size)
> +				avail = runtime->buffer_size;
>  			runtime->silence_filled = avail > 0 ? avail : 0;
>  			runtime->silence_start = (runtime->status->hw_ptr +
>  						  runtime->silence_filled) %
>
> But it looks that you do something wrong with hw_ptr or appl_ptr in your
> driver, because this condition would be true only when an large underrun
> occurs immediatelly.

Not underrun but overfill (but this should not occur - the PCM core 
functions check for this). Could you print appl_ptr, hw_ptr and 
buffer_size before you call snd_pcm_elapsed()?

 						Jaroslav

-----
Jaroslav Kysela <perex@perex.cz>
Linux Kernel Sound Maintainer
ALSA Project, Red Hat, Inc.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2010-07-19 14:43 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-06  5:03 XRUN handling melwyn lobo
2010-07-06  6:29 ` Clemens Ladisch
2010-07-06 11:05   ` melwyn lobo
2010-07-06 12:34     ` Clemens Ladisch
2010-07-06 16:16 ` James Courtier-Dutton
2010-07-06 17:46   ` melwyn lobo
2010-07-06 18:39     ` Jaroslav Kysela
2010-07-07  8:11       ` melwyn lobo
2010-07-14 10:17         ` melwyn lobo
2010-07-19 14:37           ` Jaroslav Kysela
2010-07-19 14:43             ` Jaroslav Kysela
2010-07-06 19:37     ` James Courtier-Dutton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).