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.