[Bug 29472] Regen: locks up/crashes on audio output

wine-bugs at winehq.org wine-bugs at winehq.org
Tue Jan 3 12:18:06 CST 2012


http://bugs.winehq.org/show_bug.cgi?id=29472

--- Comment #9 from Jörg Höhle <hoehle at users.sourceforge.net> 2012-01-03 12:18:06 CST ---
>It's how dsound has worked since before [...]
Yet another instance of a double bug that makes it so hard to change something
in the fragile equilibrium that Wine's audio was/is.  In the past, position was
locked to buffer avail so the bug was not noticeable.

See how mmdevapi's periodic filler operates with GetCurrentPadding only. 
DSound should do exactly the same.  It wants to fill a buffer, not perform lip
synch'ing.
Look up the DONTS about avail_update and delay in Poettering's blog:
http://0pointer.de/blog/projects/guide-to-sound-apis.html

In my vision, when DSound is called by mmdevapi's periodic event, it should
- query GetCurrentPadding to see how much it can mix;
- mix that much data and Release it.
Perhaps it also wants to perform rate limiting such that apps can still add a
secondary buffer that plays almost immediately, without DSound playing "I've
already queued 2s of data, your request will have to wait until after that".

GetPosition does not qualify as a play position for DSound because it could be
that late that it doesn't even fit into DSound's tiny buffer; we don't control
it; for the sake of bug #28723 we introduced latency, mmdevapi's and ALSA's
buffer all add up.  Instead, I believe we should treat DSound + mmdevapi + ALSA
as what it really is: a chain of filters, adding up their latency, each with
their own buffering constraints.  DSound's primary buffer contents should be
fed to mmdevapi piece by piece.  IOW, DSound's read pointer follows mmdevapi's
write pointer.  Perhaps we could add GetStreamLatency to come a little closer
to the actual speaker position.

OTOH you may argue that dsound:GetCurrentPosition appears to be the only
function that apps can use for synchronisation purposes (requiring GetPosition
& snd_pcm_delay).  Alas it is expressed in terms of buffer positions, which is
not that surprising given that D means Direct, i.e. a HW buffer model.  Hence
Wine must find a consistent way to map speaker positions onto the buffer(s). 
Clearly, here mmdevapi has the better separation of concerns.

MS seems to realize this, see DSBCAPS_TRUEPLAYPOSITION
http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.dsbcaps%28v=vs.85%29.aspx

The dilemma is: For the sake of bug #28723, we've increased latency in
mmdevapi, still having GetPosition return a true speaker position for the
purpose of lip synchronization, while DSound's buffer model and following lack
of distinction between frontmost buffer position and true speaker position does
not fit well with mmdevapi's streaming.  DSound is much like ALSA's hw:0:
there, snd_pcm_delay + avail_update == buffer_size, i.e. what leaves the buffer
is immediately heard, according to ALSA, there's no other latency.

So Wine's DSound jobs are:
a) Have GetCurrentPosition provide values suitable for lip-sync'ing
   -- see MSDN about DSBCAPS_GETCURRENTPOSITION2
b) Have buffers large enough that a) can work;
c) Have buffers small enough that the illusion of direct HW access can be
maintained;
d) Have latency as small as possible (fast audio feedback);
Great fun!


What I don't know is: does DSound's primary buffer "materialize" (via a data
pointer) when using secondary buffers, or is it then inaccessible to apps?  In
the latter case, mmdevapi's buffer could serve as primary (mixing like
described above), eliminating a bit of latency for the sake of Wine gamers that
want short audio response times.
When the app requests WRITEPRIMARY, this shortcut is not possible, and
primary's contents must be copied into mmdevapi, because the two buffer
behaviours are incompatible on paper (one is fixed circular, the other
dynamic).  It is conceivable that native avoids that by having a fixed mmdevapi
buffer with only rare auxiliary ones in case of wrap-around (like winealsa,
unlike winecoreaudio), the output of my tests seems to back this up, but it's
undocumented.  I wonder whether/when we'll hit the first bug like DSound bug
#28748, comment #1, that some apps touches mmdevapi's buffer outside of the
Get/ReleaseBuffer pair.  That might crash winecoreaudio.

-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.


More information about the wine-bugs mailing list