[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 Dec 2 18:03:54 CST 2011


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

--- Comment #67 from Alexey Loukianov <mooroon2 at mail.ru> 2011-12-02 18:03:54 CST ---
You're welcome. Meanwhile I've been just reported about a real-world bug caused
by "plug" alsa-lib plugin which affects - surprise! - RAGE under Wine with
prefix set to Win7.

Here is my comment in AppDB about it: 
http://appdb.winehq.org/objectManager.php?sClass=version&iId=24512#Comment-73529

What happens is rate plugin not draining samples from the ALSA buffer waiting
for entire period to be pumped into it so the GetCurrentPadding() reported by
winealsa to XA2 remains equal to 896 (i.e. entire "mmdev duration buffer") and
thus XA2 is unable to pump-out more data (buffer is constantly full from it's
point of view) and so it results in no sound produced at all :-). Pretty funny
case IMO.

Concerning your interpretation - hmm, it might be as valid as mine is. How the
things actually are can only be determined by reverse-engineering MS code, but
it is in any case irrelevant for us - we just have to mimic the observed devpos
change behavior in winealsa and nothing more :-).

As for remark about GP vs. adding silence - correct me if I'm wrong but isn't
the only reason to add the silence is to workaround the "pcm is not starting
unless at least one period of data had been pumped out"? I mean, as a part of
XRun recovery process we add up some silence if required to be sure pcm really 
starts, but we are not obliged to reflect these artificially-inserted frames in
the devpos reported to an app. As we had XRun - the stutter had already happed
so adding some silence wouldn't be fatal corruption to and already corrupted
sound output. Taking into account silent frames it the devpos reported to an
app is pretty simple. 

At stream Init():
This->inserted_silent_frames = 0;
This->devpos = 0;

At stream Start() or on Xrun recovery, after inserting N silent frames in order
to force pcm start:
This->devpos = This->written_frames - This->held_frames;
This->inserted_silent_frames = N;

On Stop():
This->devpos = This->written_frames - This->held_frames;

At GetPosition():

if(This->started)
{
    if(delay_frames > 0)
        This->devpos = max(This->written_frames - This->held_frames -
delay_frames - This->inserted_silent_frames, This->devpos);
    else if(pad_frames > 0)
        This->devpos = max(This->written_frames - This->held_frames -
pad_frames - This->inserted_silent_frames, This->devpos);
    else
        This->devpos = max(This->written_frames - This->held_frames -
This->inserted_silent_frames, This->devpos);
}
*pos = This->devpos;

IOW silent frames which we use to force pcm start - they are pretty equivalent
to the artificially added latency and thus should contribute to it. The logic
above it something I had just now quickly scratched and taking into account
that I'm pretty sleepy ATM chances are it's partly or completely wrong. It's a
deep night here so I'm going to take a rest for now and would try to come back
and think more about it tomorrow.

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