[Bug 28723] Sound stutter in Rage when emulated windows version is set to "Windows 7" (XAudio2 -> mmdevapi sound output path)

wine-bugs at winehq.org wine-bugs at winehq.org
Fri Nov 11 10:51:30 CST 2011


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

--- Comment #42 from Andrew Eikum <aeikum at codeweavers.com> 2011-11-11 10:51:30 CST ---
(In reply to comment #39)
> Created attachment 37437 [details]
> Proposed patchset, try #2
> 

The first patch gave me tons of underruns (all of the following is without
PulseAudio). I have the following statistics in IAC::Initialize():

trace:alsa:AudioClient_Initialize alsa_period_frames: 470
trace:alsa:AudioClient_Initialize ALSA buffer size: 2352 frames
trace:alsa:AudioClient_Initialize MMDevice period: 0x186a0 * 100ns, 220 frames
trace:alsa:AudioClient_Initialize MMDevice buffer size: 2560 frames

But then I see:
err:alsa:alsa_write_data avail: 1930, held_frames: 2496
trace:alsa:alsa_write_data XRun state, recovering

So it looks like ALSA is reporting an underrun when there isn't enough data in
the ALSA buffer to take a full alsa_period_frames chunk (2352 - 1930 = 422 <
470). So perhaps we need to tweak the write_limit calculation to ensure there's
always at least three mmdev periods _and_ three ALSA periods (three in case we
get the period pattern Wine,Alsa-->Alsa,Wine).

This fixes the problem for me (should clean up the frames-in-alsa-buffer
calculation redundancy, and you'll need to add the alsa_period_frames member):

-    write_limit = This->mmdev_period_frames;
-    /* Make sure ALSA has enough samples to play till next timer event, to get
-       xrun-free behavior we need ALSA to have 2x mmdev_period frames to play.
*/
-    if((This->alsa_bufsize_frames - avail) <= This->mmdev_period_frames)
write_limit += This->mmdev_period_frames;
+    write_limit = 0;
+    while(This->alsa_bufsize_frames - avail + write_limit <
This->mmdev_period_frames * 3 ||
+            This->alsa_bufsize_frames - avail + write_limit <
This->alsa_period_frames * 3)
+        write_limit += This->mmdev_period_frames;

I tested this with a few games with PulseAudio as well, and it worked. Does
this continue to work with RAGE and your other test games?


Some comments on the code in your patches:

-        TRACE("PCM state: %u, avail: %ld, pad: %u\n",
-                snd_pcm_state(This->pcm_handle), avail_frames, *out);
+        *out = This->held_frames;
+        TRACE("pad: %u\n", *out);

I think the snd_pcm_state() value is useful here, if only for debugging the
PulseAudio bug. Unless you have a reason to get rid of it, I'd rather keep it
in.



+#if 0
...
+endif

When you are getting ready to submit the patches, you can just remove this
code.
This patch also creates an unused variable which you can remove,
alsa_period_us.



+    n = max(duration / 10, This->mmdev_period_rt * 3 / 10) ; /* duration
converted to us or 3x our period size */
+    d = 0; 

I know they're taken from my hackish test patch, but please choose a better
variable name than "n" (alsa_buffer_us or something). And you can get rid of
"d" entirely and pass NULL instead.



+    TRACE("n: %u, d: %d\n", n, d);

We trace these values more formally below in that patch, so you can just get
rid of these debug TRACEs.



(In reply to comment #41)
> Changing dsound's primary.c so it don't try to set period size to pre-defined
> value of 50000 seems to fix the problem - no more unexpected xruns, I've got
> only four at expected places after ~5 minutes of RAGE gameplay.

This change is obviously correct, so there should be no problem submitting it.

> specs require to ignore requested period size and use default instead if
> AudioClient is being opened in shared more, which is not the case with the
> current implementation.

This is pretty easy to fix with tests. It's on my list, but feel free to beat
me to it :)

-- 
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