The sad state of audio GetPosition

Maarten Lankhorst m.b.lankhorst at
Mon Aug 22 07:29:05 CDT 2011

On 08/22/2011 02:13 PM, Joerg-Cyril.Hoehle at wrote:
> Hi,
> These exclusive mode test failures look like nothing:
> render.c:1086: Test failed: GetCurrentPadding returned 576, should be 0
> render.c:1092: Test failed: Position 90720 at end vs. 91296 played frames
> but they made me completely rework my model of how mmdevapi works.
> 91296 = 90720 + 576 remainder
>         90720 = 720 * 126
>                 720 = 15ms period at 48000 frames/s
> It looks like only a multiple of period_size frames are rendered.
> There are also test runs which end with GCP > period_size despite underrun
> Only Vista and w2k8 present these 2 errors.  w2k8R2 and w7 only
> present the second one.  In shared mode, GetCurrentPadding (GCP)
> returns 0 and GetPosition returns all submitted ("played") frames.
> What happened?
> Possible explanations:
> Vista + w2k8 exclusive mode:
> a) Bug in native that forgets to account for sub-period_size data. Or
> b) Play only multiples of period size.  Wait until period_size data
>    accumulates before sending the next packet.
Have to go with this one, exclusive mode wants you to fill the entire buffer at the same time..
> c) other...
> w2k8R2 + w7 exclusive mode:
> a) Bug in native that sets GCP to 0 (like in shared mode). Or
> b) At each period tick, only play data if a full period is available.
>    Drop partially filled buffers (explains padding = 0) instead of
>    playing them much later when the buffer fills up (no ghost sounds).
> c) Bug in native that forgets to increment Position yet plays data.
> d) other...
If I look at msdn, exclusive mode wants you to fill the entire buffer in 1 go, doing partial data doesn't make sense, and it wouldn't surprise me if that's why it drops things..
> shared mode:
> a) At each 10ms period tick, mix a period_size of all streams that
>    provided a full period of data.  Ignore other streams yet always
>    decrement GetCurrentPadding and sum played/ignored frames.
> b) At each 10ms period tick, mix all streams.  Handle streams with
>    padding < period_size as follows:
>    - if previous frame was full, mix at beginning of buffer (trailer)
>    - otherwise mix at end (expect beginning of next sound)
> c) At each 10ms period tick, mix all streams, padding streams with
>    less than period_size frames with silence (i.e. mix at beginning).
> d) other...
> If I were MS, I'd implement heuristic b).
> This is all unlike what Wine does...
I'm inclined to believe it's C
> I'll probably write audible audio tests in the next few weeks to be
> able to test what native does (e.g. emit a short beep < period size
> every few ms and listen to what happens).
> Regards,
> 	Jörg Höhle

More information about the wine-devel mailing list