The sad state of audio GetPosition
m.b.lankhorst at gmail.com
Mon Aug 22 07:29:05 CDT 2011
On 08/22/2011 02:13 PM, Joerg-Cyril.Hoehle at t-systems.com wrote:
> 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).
> Jörg Höhle
More information about the wine-devel