[Bug 30118] New: Sound occasionally stalls past underrun, bypassing our lead-in writer
wine-bugs at winehq.org
wine-bugs at winehq.org
Fri Mar 9 07:03:59 CST 2012
http://bugs.winehq.org/show_bug.cgi?id=30118
Bug #: 30118
Summary: Sound occasionally stalls past underrun, bypassing our
lead-in writer
Product: Wine
Version: 1.4-rc5
Platform: x86
OS/Version: Linux
Status: NEW
Severity: normal
Priority: P2
Component: winealsa.drv
AssignedTo: wine-bugs at winehq.org
ReportedBy: hoehle at users.sourceforge.net
Classification: Unclassified
Attachment #39217 to bug #29294 contains a log where Civilization 5 audio
stalls after an underrun.
99% of the time, an underrun happens while the mmdevapi render callback sleeps.
snd_pcm_avail is then the first to detect it, recovers, writes the lead-in and
audio is running again. This happened 266 times in the log:
62.063:alsa_write_data XRun state avail 12689, recovering
In rare cases, the underrun did not yet occur when snd_pcm_avail was called
rather than a few µs later in snd_pcm_write.
62.190:alsa_write_data pad: 4245
62.190:alsa_write_best_effort writei failed, recovering: -32 (Broken pipe)
ALSA lib pcm.c:7316:(snd_pcm_recover) underrun occurred
Following that, ALSA has a little data
62.201:alsa_write_data pad: 512
62.211:alsa:alsa_write_data pad: 5120
but somehow DSound stops feeding it.
Now bug #29294 involves Jack whose precise behaviour I don't know, but here's
what would happen when using plain plug:dmix or hw:0: Our lead-in writer does
not trigger because it sits before snd_pcm_write. The key issue is that ALSA
has less than one period of data, so it doesn't start! That is known behaviour
from both dmix and hw:x,y devices.
23.054:AudioClient_Initialize ALSA period: 5512 frames
23.055:AudioClient_Initialize ALSA buffer: 16537 frames
23.055:AudioClient_Initialize MMDevice period: 441 frames
23.055:AudioClient_Initialize MMDevice buffer: 5120 frames
As a result, position does not increase. The little data prevents writing the
lead-in upon subsequent callback invocations. Unfortunately, DSound is
presumably waiting for a particular position to be reached to continue feeding
data.
Position would increase and bump to max = release_frames - held_frames if it
would hit another underun -- if ALSA had managed to start.
So this is partly a bug in DSound which I've already blamed for using
GetPosition instead of GetCurrentPadding when feeding data, witness comment
#21, bug #29472, comment #17 or bug #29497, comment #1. However the subject of
this bug report shall be winealsa's incomplete underrun recovery.
Also note another issue here: mmdevapi's buffer of 5120 frames is smaller than
ALSA's period! Thanks to the lead-in, that nevertheless works at start.
Perhaps DSound would not have stalled had that buffer been larger; it might
have written more frames.
Months ago I conducted many tests with different buffer and period sizes in
exclusive mode but have not finalized that work about the minimum and maximum
buffer sizes and when to return E_INVALID_DEVICE_PERIOD or
AUDCLNT_E_BUFFER_SIZE_ERROR etc. That's still a TODO on my list. That work
has been very revealing about the relationship between mmdevapi and alsa buffer
and period sizes. Presumably, mmdevapi must create a buffer at least as large
as ALSA's period.
--
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