http://bugs.winehq.org/show_bug.cgi?id=28413
Summary: Sound play in games and programs causes brief "pauses" Product: Wine Version: 1.3.25 Platform: x86-64 OS/Version: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: -unknown AssignedTo: wine-bugs@winehq.org ReportedBy: turbolad995@hotmail.co.uk
When playing games such as 3D Pinball Space Cadet, Lemmix etc., every time a sound plays, the game briefly "pauses" at the same time. I'm sure this has occurred since Wine version 1.3.25 was installed and it has been a problem ever since.
This is also discussed with technical info from Raymond, in comment #46: http://bugs.winehq.org/show_bug.cgi?id=22880#c46. Also explained here in comment #6 onwards: http://bugs.winehq.org/show_bug.cgi?id=28060#c6
I'm not sure if this bug report has been filed already (I did search) or if this bug report contains enough information?
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #1 from Austin English austinenglish@gmail.com 2011-09-19 13:18:33 CDT --- Please attach a +tid,+mmdevapi,+winmm,+dsound,+oss,+alsa,+coreaudio trace.
Is this a regression (did it occur before 1.3.25)?
http://bugs.winehq.org/show_bug.cgi?id=28413
Andrew Eikum aeikum@codeweavers.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |aeikum@codeweavers.com
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #2 from David turbolad995@hotmail.co.uk 2011-09-20 18:38:19 CDT --- (In reply to comment #1)
Please attach a +tid,+mmdevapi,+winmm,+dsound,+oss,+alsa,+coreaudio trace.
Is this a regression (did it occur before 1.3.25)?
It does seem to be a regression yes - I don't remember this problem happening before version 1.3.25 - but since that version, more sounds are working in games.
I don't know how to make the "trace" you require. Try playing a game in Wine, such as lemmix (a lemmings clone) and I'll tell you how I discovered this bug: http://www.ericenzwaan.nl/eric/lemmings/lemmix.htm
To hear the problem, release the lemmings at 99 and when they walk into the "home", a sound is played each time - but there's a brief pause each time too.
http://bugs.winehq.org/show_bug.cgi?id=28413
Raymond superquad.vortex2@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |superquad.vortex2@gmail.com
--- Comment #3 from Raymond superquad.vortex2@gmail.com 2011-09-24 03:02:36 CDT --- You can change Remix=1 to Remix=2 and GoodWavePos=0 to GoodWavePos=1 in wavemix.inf
; Remix=1 = ResetRemix() ; Remix=2 = NoResetRemix() ; default=1 Remix=2
; GoodWavePos=0 = uses timeGetTime() (default) ; GoodWavePos=1 = uses waveOutGetPosition() GoodWavePos=1
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #4 from Raymond superquad.vortex2@gmail.com 2011-09-24 03:10:20 CDT --- (In reply to comment #2)
(In reply to comment #1)
Is this a regression (did it occur before 1.3.25)?
It does seem to be a regression yes - I don't remember this problem happening before version 1.3.25 - but since that version, more sounds are working in games.
pinball 's sounds work fine in 1.3.24 , so this is a regression
There is another bug ( no music(
trace:mci:mciSendCommandA (00000000, MCI_OPEN, 00002002, 0102500c) trace:mci:mciSendCommandW (00000000, MCI_OPEN, 00002002, 00140fe4) trace:mci:MCI_Open (00002002, 0x140fe4) trace:mci:MCI_Open devType=L"pinball.mid" ! trace:mci:MCI_LoadMciDriver wDevID=0001 fixme:mci:MCI_LoadMciDriver Couldn't load driver for type L"PINBALL.MID". trace:mci:mciSendCommandW => 00000132 trace:mci:MCI_Close (ffffffff, 00000002, (nil))
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #5 from David turbolad995@hotmail.co.uk 2011-09-30 07:47:03 CDT --- Since getting Wine version 1.3.29 with my Ubuntu updates today, I can definitely say this problem has improved, but it's still there. When playing 3D Pinball Space Cadet (for XP), the brief pauses still occur, but they don't slow down the game as much now. If you listen carefully, you will hear some slight crackling when the sounds in the game are played.
I've also tested Lemmix and again, the problem has been improved, but the time still pauses in levels when the lemmings are closest together and walk into the "home".
Sorry I can't do much else, as I'm an end-user of Wine without the advanced knowledge to help. I do test programs with each new update of Wine and let you know what happens.
http://bugs.winehq.org/show_bug.cgi?id=28413
Raymond superquad.vortex2@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |hoehle@users.sourceforge.ne | |t
http://bugs.winehq.org/show_bug.cgi?id=28413
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|--- |1.4.0
--- Comment #6 from Austin English austinenglish@gmail.com 2011-10-09 15:23:14 CDT --- Sound bug => 1.4 milestone.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #7 from Andrew Eikum aeikum@codeweavers.com 2011-10-27 12:59:24 CDT --- Created attachment 37156 --> http://bugs.winehq.org/attachment.cgi?id=37156 Patchset to fix
Here's a short patchset that fixes this issue.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #8 from Andrew Eikum aeikum@codeweavers.com 2011-10-27 13:16:09 CDT --- So the problem was that PlaySound(), in this circumstance, is supposed to cancel all other sounds that had previously been played with PlaySound() before playing the requested sound (in this case, lemmings saying Yippee). Since PlaySound() is asynchronous, it spins off its own thread which feeds up to two buffers to waveOutWrite(), waiting for the previous buffer to finish before refilling it and writing again.
The cancelling mechanism works by setting a flag, which the feeder thread checks between waveOutWrite() calls. The trouble was that the buffer size used (one third of a second) was too long. Since the feeder thread waits for the previous buffer to complete playing before checking this flag, it waits up to 1/3 of a second before the effect can be cancelled and the newly requested sound can be played. So the patch I attached above drops the buffer size down to 1/25 of a second, which reduces the delay to be basically unnoticeable.
There's probably a better way to fix this, which is to rewrite PlaySound() to handle its asynchrony better. Specifically, we should be able to cancel the feeder thread without having to wait for the current buffer to be returned. But it's a real mess in there, and I hesitate to do a significant rework if this is an acceptable solution anyway.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #9 from Jörg Höhle hoehle@users.sourceforge.net 2011-10-28 02:37:53 CDT --- If you look through git history, you'll notice that I once basically reverted a patch that called waveOutReset from another thread. Witness bug #9026, comment #22. waveOutReset had the obvious benefit to cancel fast, but there were issues caused by calling winmm:waveOutReset simultaneously with winmm:waveOutClose from another thread. I don't think your recent rewrite of parts of winmm has improved things in that area, does it? IOW, I believe it's still unsafe in Wine to call winmm:wave* or midi*, e.g. GetPosition or Reset on a handle that's being closed (or may be closed anytime) by another thread.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #10 from Jörg Höhle hoehle@users.sourceforge.net 2011-10-28 02:44:37 CDT --- There's something weird here. The 333ms delay has existed for half a year, see bug #9026, yet the trouble with Lemmix became apparent only with mmdevapi in 1.3.25. IOW, there's something else that changed since mmdevapi, not the 333ms. What piece of puzzle is missing?
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #11 from Andrew Eikum aeikum@codeweavers.com 2011-10-28 09:20:54 CDT --- Created attachment 37169 --> http://bugs.winehq.org/attachment.cgi?id=37169 Revert "Revert "winmm: Fix PlaySound so it doesn't block when another sound is already playing."."
(In reply to comment #9)
If you look through git history, you'll notice that I once basically reverted a patch that called waveOutReset from another thread. Witness bug #9026, comment #22. waveOutReset had the obvious benefit to cancel fast, but there were issues caused by calling winmm:waveOutReset simultaneously with winmm:waveOutClose from another thread. I don't think your recent rewrite of parts of winmm has improved things in that area, does it?
I would expect this to work. I wrote it with the intention of being threadsafe. What makes you think it shouldn't?
I think the only practical difference between execution orders is whether waveOutReset() returns buffers or not, since waveOutClose() doesn't return buffers (Should it? I don't see tests for this). It's possible that waveOutReset()'s buffer returning callbacks occur _after_ waveOutClose() has finished, or even after the WOM_CLOSE message, so any WinMM calls within the callbacks would fail. But I think that's fine and matches Windows.
In fact, I went and reverted your revert ("git revert 15ad749eced53e0c33454970bfc2bdb58b64f92b"), resolved a handful of conflicts (patch attached), and the Lemmings behavior was fixed. I grabbed a copy of Spider Solitaire off my WinXP VM and clicked like crazy on a card and wasn't able to cause a crash like Bug 9026 reported.
What do you think about this solution?
(In reply to comment #10)
There's something weird here. The 333ms delay has existed for half a year, see bug #9026, yet the trouble with Lemmix became apparent only with mmdevapi in 1.3.25. IOW, there's something else that changed since mmdevapi, not the 333ms. What piece of puzzle is missing?
Well, the behavior that we're seeing _now_ makes complete sense to me. WinMM doesn't return a buffer until it has completely finished playing, which is why we see the required 333ms delay between PlaySound() calls. I don't know why the old backends didn't have this problem.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #12 from Jörg Höhle hoehle@users.sourceforge.net 2011-10-28 10:15:12 CDT ---
waveOutClose() doesn't return buffers (Should it?)
No, there's WAVERR_STILLPLAYING.
so any WinMM calls within the callbacks would fail
It's not external calls that fail, it's winmm internally which got corrupt, as one call had already progressed past the "fetch object if handle ok" check in winmm then got preempted, then another thread closed the device. => crash when the first thread resumes.
I'll have to carefully review the current winmm code, but I can't remember seeing protections like InterlockedIncrement around winmm calls which I see as a means to verify that no other thread is currently using a given handle, so I have some doubts it's safe now. Is there any other means? IIRC, CreateTimer uses this technique to tell whether a timer callback is still executing.
clicked like crazy
You want to configure windows/win.ini, see bug #21277 comment #3 to use PlaySound via my MCI shell: sound default sound systemasterisk notify sound systemexclamation notify [copy&paste a dozen of these lines from an editor to a wine console]
we see the required 333ms delay between PlaySound() calls
Perhaps previously, when queued fast, the player was aborted even before submitting the first header. If that's not the case anymore, one needs to understand where the change in behaviour comes from.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #13 from Andrew Eikum aeikum@codeweavers.com 2011-10-28 10:42:05 CDT --- (In reply to comment #12)
so any WinMM calls within the callbacks would fail
It's not external calls that fail, it's winmm internally which got corrupt, as one call had already progressed past the "fetch object if handle ok" check in winmm then got preempted, then another thread closed the device. => crash when the first thread resumes.
I'll have to carefully review the current winmm code, but I can't remember seeing protections like InterlockedIncrement around winmm calls which I see as a means to verify that no other thread is currently using a given handle, so I have some doubts it's safe now. Is there any other means?
Well, every time a device object is accessed, the thread doing the accessing holds the device's mutex. And every time a mutex is obtained, the device's validity is checked, usually by ValidateAndLock(), but also sometimes by things like "device->device," which will be non-NULL iff the device is open. I guess these checks could be made consistent (always check device->open, or eliminate device->open and check something else like device->device).
I would welcome your own analysis, though.
clicked like crazy
You want to configure windows/win.ini, see bug #21277 comment #3 to use PlaySound via my MCI shell: sound default sound systemasterisk notify sound systemexclamation notify [copy&paste a dozen of these lines from an editor to a wine console]
Did this test a few dozen times with the patch applied and saw no failures.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #14 from Jörg Höhle hoehle@users.sourceforge.net 2011-11-08 15:19:36 CST ---
I can't remember seeing protections
My memory failed me. Winmm looks much much better since the rewrite.
But that doesn't prevent concurrency troubles whenever an app needs transactions above the winmm level. Consider the following scenario:
1. PlaySound thread finishes, calls waveOutClose(hwave=0x8000) but is preempted before reaching PlaySound_Free. 2. Another thread calls waveOutOpen. It obtains the next free handle, e.g. 0x8000, which happens to be the same number as above and starts doing stuff. 3. Yet another thread calls PlaySound, thus attempts to enter WINMM_cs to abort playsound 1. Should waveOutReset be called now, it would disturb thread 2!
The MCI presents similar concurrency challenges...
Would moving waveOutReset into the section protected by WINMM_cs help? WINMM_cs is a very big lock so it may have other side effects. Introducing fine grained locks needs careful thinking to prevent dead locks. I wish I had a theorem prover ready to generally answer such questions.
Note that these days, one can consider moving waveOutClose after PlaySound_Free. That was not an option at the time Wine's winmm had to be careful not to have a device opened twice, because that was not supported by all backends (well, even now non-default devices like plughw:N may not support that).
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #15 from Raymond superquad.vortex2@gmail.com 2011-11-08 16:57:29 CST --- (In reply to comment #14) That was not an option at the time Wine's winmm had to be
careful not to have a device opened twice, because that was not supported by all backends (well, even now non-default devices like plughw:N may not support that).
it is a bug of rewrite when wine's mmdev does not check whether the device can be open more then once using shared mode and exclusive mode
e.g spdif with ac3 passthrough cannot be open twice
The main problem of current implementation is
dxdiag cannot test sound card
which is normal in win 7 but abnormal in xp
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #16 from Jörg Höhle hoehle@users.sourceforge.net 2011-11-11 06:28:30 CST --- There's a decades old debate whether small ints like UNIX file descriptors or FILE* pointers are good design. Unlike pointers, small ints are easy to check for validity but can be reused inadvertently, exactly like my 0x8000 example.
Raymond Chen describes that MS mixes both approaches and uses the upper 16 bits to store a unique number, while the lower 16 bits are still an array index. http://blogs.msdn.com/b/oldnewthing/archive/2007/07/17/3903614.aspx
The late waveOutReset(0x8000) from thread 1 would be returned INVALHANDLE and no more disturb the new handle 0xABCD8000 from thread 2.
Wine should do something like that too (e.g. via a counter or random number generator). In WINMM_GetDeviceFromHWAVE if(junk != 0x1) becomes (junk && junk != device->cookie) return NULL; For completeness, upper 16 bits = 0000 must be a pass-through for 16bit apps.
It is currently very unfortunate that handle numbers may be reused immediately in Wine. Think about how UNIX systems avoid reusing process numbers all too soon. It's the same issue.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #17 from Andrew Eikum aeikum@codeweavers.com 2011-11-21 13:08:13 CST --- Created attachment 37564 --> http://bugs.winehq.org/attachment.cgi?id=37564 winmm: Make new device handles unique
Working towards a fix here, what do you think about this patch, Jörg?
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #18 from Andrew Eikum aeikum@codeweavers.com 2011-11-21 13:16:05 CST --- Actually I just ran a test on Windows 7 and it seems to reuse device handles like Wine does. I think unique device handles aren't necessarily the solution for the problem in Comment 14.
Test snippet: mr = waveOutOpen(&hwave, 0, &fmt, 0, 0, CALLBACK_NULL); ok(mr == MMSYSERR_NOERROR, "waveOutOpen failed\n"); waveOutClose(hwave);
mr = waveOutOpen(&hwave2, 0, &fmt, 0, 0, CALLBACK_NULL); ok(mr == MMSYSERR_NOERROR, "waveOutOpen failed\n");
ok(0, "hwave: %p, hwave2: %p\n", hwave, hwave2);
Result on Windows 7 VM: wave.c:1487: Test failed: hwave: 002D54E0, hwave2: 002D54E0 wave: 4 tests executed (0 marked as todo, 1 failure), 0 skipped.
Am I missing something?
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #19 from Jörg Höhle hoehle@users.sourceforge.net 2011-11-22 04:19:42 CST --- My tests on an older system showed that - CreateWindow handles feature this 16bit counter (more precisely, it looks like every 16 low bits handle has its own 16 high bits counter). - HMIDIOUT handles don't.
Your test shows that HWAVEOUT doesn't either. Indeed, R. Chen talks about window handles in the blog entry. Although it would be good to add this protection to winmm handles, it's possible that AJ objects based on the "100% bug compatible" argument.
Your patch looks good, except the one junk bit is not checked anymore to detect bogus handles.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #20 from Andrew Eikum aeikum@codeweavers.com 2011-11-22 09:57:01 CST --- Yeah, I'm not going to submit it since Windows doesn't do that. We really just need someone to think about and clean up PlaySound().
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #21 from David turbolad995@hotmail.co.uk 2012-01-05 07:21:20 CST --- Going through my bug list, I see that this bug is still "unconfirmed".
This problem still occurs in the Lemmix game (a clone of the classic Lemmings game) when the release rate is set at 99. The game "pauses" briefly each time - when the lemmings are closest to each other - and go into the "home".
In contrast, the Pinball XP game from Windows XP (3D Pinball Space Cadet) does not have the same sound problems during normal gameplay when used in Wine.
I will occasionally post back my findings, as I'm an end-user of Wine and don't know the technical stuff.
http://bugs.winehq.org/show_bug.cgi?id=28413
Andrew Eikum aeikum@codeweavers.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Attachment #37156|0 |1 is obsolete| | Attachment #37169|0 |1 is obsolete| |
--- Comment #22 from Andrew Eikum aeikum@codeweavers.com 2012-02-08 10:13:04 CST --- Created attachment 38749 --> http://bugs.winehq.org/attachment.cgi?id=38749 winmm: Allow new sounds to interrupt previous PlaySound invocations
So here's a cleanup patch which I'm happy with. It removes the notion of a list of playsound invocations, instead only tracking the very last one. A review by a second pair of eyes would be helpful.
I'm still deciding about sending this for 1.4. It's not a trivial change, but it's not huge either and I feel like it's a fairly important bug to fix. Although it would be very nice to have some tests for PlaySound() too, so maybe I'll work on that and submit after 1.4 instead.
http://bugs.winehq.org/show_bug.cgi?id=28413
Jörg Höhle hoehle@users.sourceforge.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Component|-unknown |winmm&mci
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #23 from Jörg Höhle hoehle@users.sourceforge.net 2012-02-09 06:31:02 CST --- Your change to PlaySound_Free is incorrect. There are error paths that go there with last_playsound == wps.
EnterCriticalSection(&WINMM_cs);
Every time I see a critical section, my reviews are delayed by at least one hour because I must visit and think about all users and uses of the CS. Even more when it's a big lock.
I recommend you look into Interlocked* instead, where applicable.
if(last_playsound == wps) last_playsound = NULL; InterlockedCompareExchangePointer
EnterCriticalSection(&WINMM_cs); if (waveOutOpen(&wps->hWave, ...
You should not hold such a big lock for an operation like waveOutOpen that can take ages loading all msacm codecs.
Instead the pattern is: . verify preconditions hold . start an operation locally . before changing global state, check whether preconditions still hold . if not, either abort or retry transaction -- With playsound you'll abort, not retry: if (...) /* are we still owners */ if(waveOutOpen(&hwave, ... if (...) /* are we still owners */ wps->hWave = hwave; else /* superseded by another PlaySound */ waveOutClose(hwave) + goto CleanUp;
Well, that's concurrency theory. With winmm, you'll prefer to serialize calls so as to avoid ERROR_DEVICE_IN_USE in the superseding PlaySound. How to serialize? That's tough without the psLastEvent that you removed.
Can we get rid of critical sections entirely? No, because waveOutReset depends on mutual exclusion. The aborting player must be sure that the other player is still running and not amid waveOutClose.
Your waveOutReset patch part is correct. My paranoia would make me cache last_playsound (and use InterlockedExchange): EnterCS; if ((running = last_playsound) != NULL) { running->bPlaySoundStop = TRUE; if (running->hwave) waveOutReset(running->hwave); } or if ((running = last_playsound) != NULL && !running->bPlaySoundStop) { running->bPlaySoundStop = TRUE; if (running->hwave) waveOutReset(running->hwave); } last_playsound = wps; LeaveCS;
What must the other side do? CleanUp: hwave = wps->hwave; EnterCS; wps->hwave = 0; /* tell others to keep off */ if (last_playsound == wps) { last_playsound = NULL; } LeaveCS; if (hwave) waveOutClose(hwave);
It appears that the CS we need is a pure local one. Hijacking WINMM_cs may have unforeseen effects.
Do we need a CS when starting up? I don't think so, but you'll have to use InterLockedExchange() above and be careful about the condition after waveOutOpen. A short CS after waveOutOpen may be easier to reason about until you get acquainted to Interlocked*. Please give them a try. I find the Interlocked* functions easier to reason about than critical sections, esp. when it comes to liveness properties in concurency.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #24 from Jörg Höhle hoehle@users.sourceforge.net 2012-02-16 07:07:17 CST --- Patch submitted, using psLastEvent to serialize access to waveOutOpen. http://www.winehq.org/pipermail/wine-patches/2012-February/111619.html
http://bugs.winehq.org/show_bug.cgi?id=28413
Jörg Höhle hoehle@users.sourceforge.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Resolution| |FIXED
--- Comment #25 from Jörg Höhle hoehle@users.sourceforge.net 2012-02-16 14:46:56 CST --- Fixed by commit 197607db2e06f28b666da9ce88b69c9994c1bb65
http://bugs.winehq.org/show_bug.cgi?id=28413
Jörg Höhle hoehle@users.sourceforge.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Attachment #38749|0 |1 is obsolete| |
http://bugs.winehq.org/show_bug.cgi?id=28413
Andrew Eikum aeikum@codeweavers.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Fixed by SHA1| |197607db2e06f28b666da9ce88b | |69c9994c1bb65
http://bugs.winehq.org/show_bug.cgi?id=28413
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #26 from Alexandre Julliard julliard@winehq.org 2012-02-17 13:50:58 CST --- Closing bugs fixed in 1.4-rc4.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #27 from David turbolad995@hotmail.co.uk 2012-08-16 07:20:19 CDT --- Wine version 1.4.1 stable.
This bug exists on PC-BSD 9 (FreeBSD) when you play Lemmix and set the lemmings release rate to 99. When the lemmings are very close together and go into the "home", the game briefly pauses each time.
Please re-open this bug for the PC-BSD (FreeBSD?) version of Wine 1.4.1 stable. I'm unable to get the "development" release of Wine for PC-BSD.
http://bugs.winehq.org/show_bug.cgi?id=28413
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|CLOSED |REOPENED Resolution|FIXED | Ever Confirmed|0 |1
--- Comment #28 from Austin English austinenglish@gmail.com 2012-08-20 23:54:39 CDT --- (In reply to comment #27)
Wine version 1.4.1 stable.
This bug exists on PC-BSD 9 (FreeBSD) when you play Lemmix and set the lemmings release rate to 99. When the lemmings are very close together and go into the "home", the game briefly pauses each time.
Please re-open this bug for the PC-BSD (FreeBSD?) version of Wine 1.4.1 stable. I'm unable to get the "development" release of Wine for PC-BSD.
Reopening.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #29 from Andrew Eikum aeikum@codeweavers.com 2012-08-21 07:37:14 CDT --- David, can you gather a log with the channels from http://wiki.winehq.org/Sound?
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #30 from Jörg Höhle hoehle@users.sourceforge.net 2012-08-21 09:45:53 CDT --- As long as Lemmings works without pauses on the old/initial system, this bug should not be reopened. FreeBSD is a very different system, wineoss could be involved this time -- or simply OSS4 open/close times on a BSD system. So IMHO it should get its own bug report.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #31 from David turbolad995@hotmail.co.uk 2012-08-23 18:47:04 CDT --- I discovered this bug on PC-BSD 9 64-bit by chance (PC-BSD is a "user friendly" FreeBSD). This bug behaviour is exactly the same as it was in Ubuntu, before it was fixed in the Linux version of Wine. I don't know the technical info, but I knew I had to report the problem here. I felt it was the right thing to do.
If anyone can make all development releases of Wine available for PC-BSD via its AppCafe, I would be happy to have every latest development release of Wine, issued with the updates on PC-BSD.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #32 from Andrew Eikum aeikum@codeweavers.com 2012-08-24 08:47:57 CDT --- It's fine. If we need to split this off into a different bug, we can do that later. But first let's confirm what's going on, since I would still expect this to work for you. Is it possible for you to gather a log with the channels from http://wiki.winehq.org/Sound?
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #33 from David turbolad995@hotmail.co.uk 2012-08-25 12:25:48 CDT --- I keep trying, but I get the message "Invalid null command" every time.
I'm still a newbie to PC-BSD and I don't know much about FreeBSD itself.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #34 from David turbolad995@hotmail.co.uk 2012-08-28 08:46:42 CDT --- Created attachment 41514 --> http://bugs.winehq.org/attachment.cgi?id=41514 Lemmix in PC-BSD/FreeBSD
I can't get Wine to output anything from the Terminal in PC-BSD, using GNOME 2.
To reproduce this bug using Lemmix in PC-BSD (FreeBSD): get the lemmings closest together - release rate 99, as shown in the screenshot (level 1, rating "tricky"). Watch how the game itself and the time in the bottom-right briefly "pauses" each time the lemmings go into the "home".
To download Lemmix (it's for Windows, *not* DOS), visit: http://ericenzwaan.nl/eric/lemmings/lemmix.htm
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #35 from David turbolad995@hotmail.co.uk 2012-12-24 10:43:10 CST --- This problem still occurs in Wine 1.5.19 and PC-BSD 9.1 when testing Lemmix.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #36 from Andrew Eikum aeikum@codeweavers.com 2012-12-27 14:47:03 CST --- Thanks, David. I installed PC-BSD 9.1 into a VirtualBox VM and am able to reproduce this.
Looks like the problem is it takes a long time to cancel previously playing sounds when a new sound asks to be played:
17.594:0009:trace:winmm:MULTIMEDIA_PlaySound pszSound='0x153278' hmod=0x400000 fdwSound=00000005 ... 17.688:0009:err:winmm:MULTIMEDIA_PlaySound returning control
That's nearly a full tenth of a second between invoking and returning from PlaySound.
Jörg did work in this area recently. The code is still pretty messy, so there might be further improvements. For example, maybe we can avoid waiting for the other sounds to stop playing if SND_ASYNC is given.
(By the way, the "Invalid null command" is because PC-BSD uses csh as its shell by default. You can run "bash" first and then the debugging command to generate a log.)
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #37 from David turbolad995@hotmail.co.uk 2013-01-02 17:26:09 CST --- (In reply to comment #36)
Thanks, David. I installed PC-BSD 9.1 into a VirtualBox VM and am able to reproduce this.
Looks like the problem is it takes a long time to cancel previously playing sounds when a new sound asks to be played:
17.594:0009:trace:winmm:MULTIMEDIA_PlaySound pszSound='0x153278' hmod=0x400000 fdwSound=00000005 ... 17.688:0009:err:winmm:MULTIMEDIA_PlaySound returning control
That's nearly a full tenth of a second between invoking and returning from PlaySound.
Jörg did work in this area recently. The code is still pretty messy, so there might be further improvements. For example, maybe we can avoid waiting for the other sounds to stop playing if SND_ASYNC is given.
(By the way, the "Invalid null command" is because PC-BSD uses csh as its shell by default. You can run "bash" first and then the debugging command to generate a log.)
I'm glad someone else can reproduce this bug. I'm sure there are other apps besides lemmix/lemmings which will highlight this sound bug.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #38 from Jörg Höhle hoehle@users.sourceforge.net 2013-01-04 05:20:22 CST ---
That's nearly a full tenth of a second between invoking and returning from PlaySound.
Please investigate further whether it's PlaySound, winmm/wave or mmdevapi that causes such delays. PlaySound uses waveOutReset+Wait so it already does its best at trying to abort a currently playing sound. As the bug appears to be limited to *BSD and they all use wineoss, it's presumably long-lasting calls into OSS that leak from wineoss to mmdevapi to winmm:wave* to PlaySound.
A tenth of a second doesn' look like much to me, but Lemmix shows that native behaves differently. We need some timing tests to find out whether the winmm:wave* functions return very fast, so PlaySound does it too or whether wave* may introduce delays that PlaySound hides.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #39 from David turbolad995@hotmail.co.uk 2013-01-07 18:25:59 CST --- Created attachment 43114 --> http://bugs.winehq.org/attachment.cgi?id=43114 Lemmix level in PC-BSD (FreeBSD) exposing this sound bug.
Another problem has appeared too...
We know that when the lemmings are so close together and going "home", it exposes this sound bug, but it also makes the "+" cursor in the game flicker slightly!
Note that the screenshot is not showing the "+" cursor in the game. I uploaded the screenshot to show what triggers the sound "pauses", which is most noticeable when you look at the time in the level as this happens; the time pauses on every sound play.
I don't know if this extra problem ("+" cursor flicker) is caused by THIS sound bug, but it appears to be?
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #40 from Andrew Eikum aeikum@codeweavers.com 2013-01-15 14:56:26 CST --- Created attachment 43183 --> http://bugs.winehq.org/attachment.cgi?id=43183 winmm: Don't wait for device to be closed before allowing next sound to play
(In reply to comment #38)
That's nearly a full tenth of a second between invoking and returning from PlaySound.
Please investigate further whether it's PlaySound, winmm/wave or mmdevapi that causes such delays.
I looked closer and it's the close(fd) call in AudioClient_Release. I've seen it take over 0.125 seconds according to +timestamp.
So, here's a patch to signal the next sound to play before the waveOutClose() call occurs. It fixes the issue in my VM. What do you think Jörg?
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #41 from Jörg Höhle hoehle@users.sourceforge.net 2013-01-17 04:24:15 CST --- I have not looked at the patch yet. I'm afraid of a can of worms. Not serializing calls to waveOutOpen/Close means concurrent audio connections, which were a cause of trouble in the past (IIRC winealsa did not implement them). Nowadays we're not in a much better shape, because there's no central mixing in Wine for all audio output, only DSound mixes. So Wine still depends on the backend to be able to open multiple connections, e.g. pulse or dmix, but not plughw! (and I've heard people mention that the surround devices cannot be opened multiply either).
We need to think more about timing. E.g. my current thread-instead-of-timer-queue winealsa patch patiently waits until the end of the period sleep (10ms) within IAC_Release, hence each waveOutClose costs on average 5ms. That way the feeder thread can use usleep() instead of poll/select(), not waiting for the rare termination event to occur. I have not tested it with Lemmix.
Now if only OSS takes a lot of time to close() but always supports multiple connections, maybe we can put something into wineoss (not dlls/winmm) to accelerate IAC_Release? Or ask some OSS mailing list why it takes so long.
http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #42 from Jörg Höhle hoehle@users.sourceforge.net 2013-01-18 09:18:10 CST --- That quote scheds interesting light, yet it is about MIDI http://web.tiscalinet.it/giordy/midi-tech/share.htm "There is one thing that I've noticed about some drivers. They allow an application to quickly return from a call to midiOutClose() or midiInClose(), but the driver then goes on to do some "cleanup" in the background. The driver may not yet be ready to allow someone else to do a midiInOpen() or midiOutOpen()[corr.] during that time, and may return a "Device is busy" error."
http://bugs.winehq.org/show_bug.cgi?id=28413
Johan Gardhage johan.gardhage@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |johan.gardhage@gmail.com
https://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #43 from Austin English austinenglish@gmail.com --- This is your friendly reminder that there has been no bug activity for 1 year. Is this still an issue in current (1.7.31 or newer) wine? If so, please attach the terminal output in 1.7.31 (see http://wiki.winehq.org/FAQ#get_log).
https://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #44 from Austin English austinenglish@gmail.com --- Over 2 years with no reply, marking abandoned.
https://bugs.winehq.org/show_bug.cgi?id=28413
Gijs Vermeulen gijsvrm@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|REOPENED |RESOLVED Resolution|--- |ABANDONED
--- Comment #45 from Gijs Vermeulen gijsvrm@gmail.com --- Resolving.
https://bugs.winehq.org/show_bug.cgi?id=28413
André H. nerv@dawncrow.de changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |nerv@dawncrow.de Status|RESOLVED |CLOSED
--- Comment #46 from André H. nerv@dawncrow.de --- closing abandoned