[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
Mon Dec 19 16:39:28 CST 2011


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

--- Comment #102 from Jörg Höhle <hoehle at users.sourceforge.net> 2011-12-19 16:39:28 CST ---
Well, I came to the conclusion that Alexey's is really 2 patches and should be
split: one to have GCP implement delta increments and be updated only when
write happens at event ticks, the other to limit the writes.
As I said in comment #83, I don't like the alsa_write rate limiting part.
Furthermore, I think that part would be strictly superfluous if
set_hw_periods(3) or (4) gives good results.

To summarize
set_period_near(mmdevapi_period)
set_periods(4)

if(some_test) return INVALID_PERIOD_SIZE (excl.) or CREATE_ENDPOINT_FAILED
(shared).
if(other_test) FIXME("period size doesn't match, expect trouble").

To recap:


Why do we need a not too large buffer? a) Because PA appears to work better and
b) because snd_pcm_drop upon Stop is bogus, so my next patch is going to drop
it and let Stop enter XRUN state. So it's essential that ALSA didn't buffer too
much, otherwise ALSA would continue to play for too long after Stop.
After Stop In shared mode mmdevapi must hold:
sum written = GetPosition + GetCurrentPadding


Can the driver deal with an ALSA period < 10ms? We'll feed it only every 10ms,
hence we need a buffer large enough to hold more periods. This conflicts with
the above set_periods(4), e.g. imagine ALSA period were 1ms. I've not yet
tested how set_buffer_min(2xmmdevapi_period) + set_periods(4) play together.
Perhaps:
alsa_period = mmdevapi_period;
set_period_near(alsa_period) // that's an in+out variable!
if(alsa_period>=mmdevapi_period)
  set_periods(4);
else
  set_buffer_size_near(4xmmdevapi_period);
This supposes that set_period_near immediately returns a period, i.e. before
set_hw_params().


Can the driver bear an ALSA period > 10ms? IMHO only with a silence lead-in
patch.
The worst-case scenario is: app writes 10ms at every event, but unlike Rage2
doesn't even prefill with 10ms. This is a slight variation of Alexey's test
case from comment #55. I claim that this would work in native without
underruns.
Imagine a 50ms period. Only the silence lead-in gives enough freedom in
streaming mode such that after 5x10ms have been sent, ALSA won't XRUN just
before the next 5x10ms have been collected and sent.
Currently I'm not sure whether a 10ms lead-in is enough, or a 40-50ms one
required.


Furthermore, because of the bug in comment #69 that ALSA won't play a trailing
chunk less than period size, we also need to write trailing silence...
A trailing silence doesn't make the lead-in superfluous. I'd believe native can
get away with a lead-in because its mixer (behaves as if it) is constantly
running, but it still needs trailing silence to eventually have the HW play the
final bits.  Wine needs the lead-in because its mixer is not running and
sending a continuous audio stream.
So it's not so funny that we're back at the original wine-1.3.25 mmdevapi
design which used to add silence, except that we now know better
- that GetPosition must filter out our silence additions and
- that it's incorrect to add more than mmdevapi 10ms silence at each event,
even with ALSA period size 50ms.

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