[alsa-devel] On non-rewindability of resamplers

Alexander E. Patrakov patrakov at gmail.com
Mon Apr 28 19:31:56 CEST 2014

28.04.2014 12:57, Raymond Yau wrote:
>  >
>  >> 3) Do pulseaudio keep a copy of client 's buffer ?
>  >>
>  >>  when do pulseauido mix two or more client's buffer ( before write
> to the sound card or after receive data from client )
>  >>
>  >> seem pulse plugin is not rewindable too
>  >
>  >
>  > That's a limitation of the pulse plugin, originating from ioplug
> design. The pulse API does allow rewinds (see the last two parameters of
> pa_stream_write), but ioplug with mmap_rw = 0 essentially ignores ALSA
> rewinds, i.e. it is impossible to know in alsa-plugins/pulse/*.c that a
> rewind has to be processed.
> Once the appl_ptr is rewinded to the nearest position from hw_ptr, it is
> the responbility of the application to write at least one period of
> audio immediately for some card.

Yes, of course, provided that the rewind succeeds.

> http://freedesktop.org/software/pulseaudio/doxygen/streams.html
> Data is routed, converted and mixed from several sources before it is
> passed along to a final output
> ...
> Playback and record streams always have a server-side buffer as part of
> the data flow. The size of this buffer needs to be chosen in a
> compromise between low latency and sensitivity for buffer
> overflows/underruns.
> as pulseaudio only recommend application to use a reasonable size (e.g.
> pulse plugin allow client to select extreme small buffer size which
> sound card cannot support) pulse plugin should increase the constraint
> to a reasonable size which are supported by most sound card
> (e.g. minimum period time of snd-ymfpci is 5ms)

On most sound cards, PulseAudio uses timer-based scheduling and thus is 
not subject to any period-size limitations. As far as I can see, 
snd_ymfpci does not include SNDRV_PCM_INFO_BATCH, and thus will be used 
in this mode. In addition, it has an implementation of 
snd_ymfpci_playback_pointer that seems to look at the hardware, which is 
good. So effective period times less than 5 ms should work on this card.

> ...
> The server-side per-stream playback buffers are indexed by a write and a
> read index. The application writes to the write index and the sound
> device reads from the read index. The read index is increased monotonically,
> How do the sound device reads from the read index ?

read index is just another word for hw_ptr if one talks about the sink 
buffer. When that buffer becomes almost empty, it is refilled by mixing 
all currently playing streams. You can try to follow the code starting 
from pa_sink_render().

> while the write index may be freely controlled by the application.
> Subtracting the read index from the write index will give you the
> current fill level of the buffer.
> look like this buffer still contain the audio in original format sent by
> the client if the difference is the fill level and can be used for per
> stream softvolume
> ...
> Seeking in the Playback Buffer
> A client application may freely seek in the playback buffer.
> PA_SEEK_RELATIVE_ON_READ - seek relative to the current read index. Use
> this to write data to the output buffer that should be played as soon as
> possible
> what is current read index ?

It is the point in the buffer that corresponds to the point in time that 
the hardware currently plays. Or maybe a better (but not equivalent) 
definition would be a point rewinding past which does not make sense 
because of the immediate underrun in the final hardware.

Seeking to 0 samples relatively to the current read index means "I want 
to play this buffer right now instead of whatever junk of unknown length 
that I sent before".

> do the read index mean the place which pulseaudio start to perform
> reasampling, downmixing/upmixing and mixing of all clients ?

No. PulseAudio tries to resample and mix as much as possible in advance, 
in hope that it will be able to undo all that work if needed.

> Does pulseaudio internal resampler support rewind ?

PulseAudio uses libraries such as speex and libsamplerate, and has a 
copy of the ffmpeg resampler as well. None of these libraries support 
rewinds. But PulseAudio has some code to work around that, and does 
achieve an imperfect result of approximately correct length. See 
pa_sink_input_process_rewind() - it resets the resampler, resulting in 
an audible click, if a seek is performed.

Alexander E. Patrakov

More information about the Alsa-devel mailing list