winealsa: Implement IAudioClock::GetPosition() using snd_pcm_delay.

Joerg-Cyril.Hoehle at Joerg-Cyril.Hoehle at
Fri Dec 9 10:12:54 CST 2011


Here's a version of GetPosition that exhibits the following properties:
- monotonically increasing;
- protection against garbage delay data;
- never using ALSA padding, because that can't be relied upon
  in PulseAudio after an underrun;
- works perfectly with dmix, reasonably well with old Ubuntu Intrepid
  Pulseaudio -- don't dump old Linux distributions!
- after IAC_Stop, freeze to sum_written - mmdevapi_padding.

- Via This->last_pos, provide a means for communication between
  GetPosition and other parts of the code.  What I mean is that future
  fixes to underrun handling in the event callback could bump
  last_pos to maximum, causing subsequent GetPosition to follow.

Please refer to bug #28273. Andrew found a patch like this "passes
all tests" (presumably on top of git, not yet unsubmitted padding
patches).  I found it to work with:
- Ubuntu Intrepid plughw:0, plug:dmix, and more or less Pulse
- Ubuntu Lucid plughw:0, plug:dmix, whereas Pulse completely breaks with Wine
  because of missing underrun handling, independently on this GetPosition patch.

In bug #28273, comment #74, I mentioned bumping position to maximum
when delay becomes smaller than a period.  I've not added that now.
This could be part of a future patch about better underrun handling.
I've seen valid delays < alsa_period_size where ALSA entered XRUN
state with delay < 0 as well as cases where it froze with delay > 0.

Comparison with an enum value in
looks strange, but I don't want to enumerate all XRUN, SUSPEND, DRAINING, PREPARED
and other states. (PREPARED after This->started, but before the first event
writes data, causing ALSA to start).

A note about old (Intrepid) Pulseaudio: my enhanced render.c tests
mostly work, but produce failures because PulseAudio eats data too
fast into its huge 2s buffer.  Old PulseAudio produces much better
results with Andrew's unsubmitted "change drain behaviour" patch.

Valgrind should flag an uninitialized read when tracing: delay may not be written
to when snd_pcm_delay() returns < 0.  That doesn't cause an uninitialized
read when computing the position, but I TRACE the raw values.

	Jörg Höhle
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-winealsa-Implement-IAudioClock-GetPosition-using-snd.patch
Type: application/octet-stream
Size: 3824 bytes
Desc: 0001-winealsa-Implement-IAudioClock-GetPosition-using-snd.patch
URL: <>

More information about the wine-patches mailing list