[pulseaudio-discuss] [PATCH] alsa: Disable timer-scheduling for PCMs with the BATCH flag

Lars-Peter Clausen lars at metafoo.de
Mon Dec 2 01:57:20 PST 2013


On 12/02/2013 03:54 AM, Raymond Yau wrote:
> 
> 
> 
> 2013/12/1 Lars-Peter Clausen <lars at metafoo.de <mailto:lars at metafoo.de>>
> 
>     PCM Devices which have the BATCH flag set update the PCM pointer only with
>     period size granularity. Using timer based scheduling does not have any
>     advantage in this mode. For one devices which have that flag set usually
>     update
>     the position pointer in software after getting the period interrupt. So
>     disabling the period interrupt is not possible for this kind of devices.
>     Furthermore writing to or reading from the buffer slice for the current
>     period
>     is not possible since the position inside the buffer is not known. On
>     the other
>     hand the tsched algorithm seems to get easily confused for this kind of
>     hardware, which results in garbled audio output. This typically means
>     that timer
>     based scheduling needs to be manually disabled on systems with such devices.
>     Auto disabling tsched in this case allows these systems to run with the
>     default
>     configuration.
> 
> 
> If the playback position is reported in steps instead of monotonic increasing ?
> 
> does this mean that you also need to increase rewind_safeguard to one period
> or modifiy snd_pcm_rewindable ?


Yes that makes sense. The safeguard should probably be 1.5 periods or 1
period + fixed value, since it will always take some time from when the
hardware reaches the next period to when userspace is notified about this.

I'm unfortunately not that familiar with pulseaudio. Maybe there is a better
way to fix this problem then to disable tsched. If anybody wants to recreate
the issue it can easily be emulated by applying the following patch to your
kernel:

--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -328,6 +328,9 @@ static int snd_pcm_update_hw_ptr0(struct
snd_pcm_substream *substream,
     * corrections for hw_ptr position
     */
    pos = substream->ops->pointer(substream);
+   pos /= runtime->period_size;
+   pos *= runtime->period_size;
+
    curr_jiffies = jiffies;
    if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
        snd_pcm_gettime(runtime, (struct timespec *)&curr_tstamp)

- Lars


More information about the pulseaudio-discuss mailing list