http://bugs.winehq.org/show_bug.cgi?id=29585
Bug #: 29585 Summary: wineoss.drv audio renderer not on par with others Product: Wine Version: 1.3.36 Platform: x86 URL: http://www.winehq.org/pipermail/wine-devel/2012-Januar y/093721.html OS/Version: Linux Status: NEW Severity: normal Priority: P2 Component: mmdevapi AssignedTo: wine-bugs@winehq.org ReportedBy: hoehle@users.sourceforge.net CC: aeikum@codeweavers.com Classification: Unclassified
The OSS4 mmdevapi audio renderer is not yet on par with developments in the two other ones in Wine.
Specific issues are: 1. handling underrun(?) 2. handling incomplete last (initial?) period 3. correct GetPosition 4. non-blocking mode or not needed? i.e. what's mostly covered by my renderer tests attached to bug #27937. Some of it was discussed in bug #28056.
This bug is *not* about mixer related issues, or failure to recognize an audio device at all, or recording. If your Linux or BSD system has such issues with Wine, please file another bug.
Andre Eikum proposed a patch to GetPosition in: http://www.winehq.org/pipermail/wine-devel/2012-January/093721.html It has two flaws: + *pos = 0; this should be at least the position of the last Start (I highly recommend This->last_pos_frames).
+ stopped/running/etc. state is not checked, yet GETODELAY can only be invoked while running (witness IIRC the logs attached to bug #28056).
The current ALSA driver is not the best, but here is how I believe several issues could be solved: - Decouple OSS buffer from mmdevapi buffer, a bit like winealsa;
- Hide at least one OSS period in that buffer, i.e. GetCurrentPadding yields 0 while OSPACE < oss_period and 1 with period+1. This will help with bug #28723.
That way, unreliable OSS padding < period won't bother GetCurrentPadding.
My preference goes to something like attached to bug #28723, comment #105, except it should try to hide less than the 3 periods winealsa hides in 1.3.35, i.e. somewhat of a breed of that attachment and Andrew's initial wine 1.3.25 code.
- At callback time, complete a partial mmdevapi period by adding trailing silence. We need to do that with ALSA too to ensure short sounds get played, as well as trailing samples on period-driven devices like dmix. This is the major ALSA bug #26878. Here I'd like to know how OSS behaves.
- Introduce This->last_pos_frames like I did with ALSA;
...Underrun GetPosition() must return `size'
Not immediately, according to bug #28723, comment #65. But if underrun can be defined as OSPACE < oss_period (not sure, presumably then 2 OSS periods need be hidden from GCP), then we can bump last_pos_frames.
Regarding non-blocking mode, I simply don't know whether OSS may block in open(), waiting for another process. While playing, now that GETOSPACE is used, blocking may be prevented (I've some doubts since I saw ALSA return EAGAIN with nearly full buffers in non-blocking mode).
For now, I believe it would be enough to behave like an exclusive-mode renderer and not bother with decrementing padding in mmdevapi-period-size chunks -- I still don't know how to best do that.
http://bugs.winehq.org/show_bug.cgi?id=29585
Jörg Höhle hoehle@users.sourceforge.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|--- |1.4.0
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #1 from Andrew Eikum aeikum@codeweavers.com 2012-01-20 14:12:08 CST --- Created attachment 38468 --> http://bugs.winehq.org/attachment.cgi?id=38468 BROKEN: Patchset to improve wineoss
Here's two patches that improve the OSS driver, similar to how you suggested. The first patch fixes GetPosition (it's basically the same patch as on the mail you link, but with your bugs fixed). The second patch duplicates winealsa's buffering behavior. Even though it passes your extended render tests, it's not quite correct.
I'm going bonkers trying to figure this out, so I'm posting it here for now.
The strategy is to limit the amount of data that we actually send to OSS, since OSS has no mechanism to pause playback. So, we try to keep no more than 4 periods' worth of data in the OSS buffer, and retain the rest in the MMDevAPI object. This is just like winealsa. BUT we can't actually get a reading on how much data is in the OSS buffer, because of the following annoyance.
The GETOSPACE call seems like it should work. It gives us the fragment count (bi.fragstotal), the fragment size (bi.fragsize), and the amount of space available to write (bi.bytes). So (bi.fragstotal * bi.fragsize - bi.bytes) should give us the amount of data residing in the OSS buffer. But of course it's broken. After creation (i.e. without write()ing anything), on my computer, I found that bi.fragstotal * bi.fragsize > bi.bytes, so that calculation yields data sitting in the OSS buffer, even though we haven't written anything. Wonderful.
There is another call, CURRENT_OPTR, which explicitly returns "the number of samples currently buffered in the device level FIFO." But, it never succeeds for me. I always get EINVAL, which is usually interpreted as "invalid ioctl command." The support for this call appears to be ifdef'd out if the "long long" type isn't supported. Even though "long long" is supported, I removed those ifdefs, recompiled, and it still fails with EINVAL. So I have no clue why that call isn't working. Again, wonderful.
So I'm just going to leave this here for now and come back to it later. Argh.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #2 from Jörg Höhle hoehle@users.sourceforge.net 2012-01-21 08:36:53 CST --- Well, without an OSS4 machine it's tough for me to suggest anything, but here it goes http://manuals.opensound.com/developer/SNDCTL_DSP_GETOSPACE.html "The maximum amount of data the application can ever write is (fragments-1)*fragsize bytes." Is bi.bytes == (fragments-1)*fragsize initially ?
I suggest to try out the alternate design sketched in bug #28723. Drawback: - GetCurrentPadding does not decreases by period size stepts. That will cause failures with my render tests. BTW do you always use at least WINETEST_DEBUG=2? wineoss doesn't do it now either and nobody complained, so perhaps that's not the most important behaviour to mimic from native.
0. Write from the callback only, not ReleaseBuffer. 1. Switch to non-blocking mode -- even though OSS recommends against it. 2. limit the buffer to 4 mmdevapi periods s.t. Stop won't loose much. 3. Never care about GETOSPACE. Write as much as possible into that max 4 periods space. write() should return a smaller number of bytes written than submitted, or EAGAIN. Work with that. 4. Have GetCurrentPadding (GCP) ignore what's in the OSS buffer and report only frames in the mmdevapi buffer.
5. Any issues with GetPosition? 6. Does OSS4 care about underrun and need a restart like ALSA? If yes, how to detect it? 7. Presumably OSS will need trailing silence like ALSA in order to play the last few frames. I've no solution to that yet (that's an area where GETOSPACE would be useful). 8. Ideally, manage to start OSS only when THRESHHOLD = one oss period whatever that is + one mmdevapi period + a little safety like 5ms frames have been written.
Later improvements to the design would be to reduce latency by having GCP take into account a fraction of what's in the OSS buffer (more precisely, only if there's more than THRESHOLD in the OSS buffer) -- but that requires a working GETOSPACE.
The final improvement is to have GCP virtually decrement by mmdevapi steps, taking into account corner cases like the mmdevapi buffer filling up but not being a multiple of the period size. That's what I want for winealsa.
Advantages of the design: - Decouple latency from OSS/ALSA buffer size; - Amenable to a blocking design, using poll(fd,period) instead of CreateTimerQueue; - Decouple OSS/ALSA period from mmdevapi one; - Designed to support the Rage/XAudio2 worst-case low-latency scenario (given point 8.) -- as long as Linux' scheduler doesn't delay our or the app's audio thread for too long, since we can't tell it "this is a Pro Audio high priority task".
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #3 from Jörg Höhle hoehle@users.sourceforge.net 2012-01-23 04:35:05 CST --- The next improvement to winealsa and wineoss design: 9. Split use of the critical section This->lock a) One prevents several app threads from calling the API concurrently. b) The second one shall prevent the internal callback from operating on the slots that Get/ReleaseBuffer modify concurrently.
It is not good that bombarding the API with ReleaseBuffer(0) or GetCurrentPadding blocks the audio callback. Instead of an internal lock, we should investigate the opportunity for a lock-less design. Then, the kernel would never put the callback to sleep in EnterCriticalSection. What kernel expert knows how much later a thread recovers from such a sleep?
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #4 from Andrew Eikum aeikum@codeweavers.com 2012-01-23 10:28:01 CST --- (In reply to comment #2)
Well, without an OSS4 machine it's tough for me to suggest anything, but here it goes http://manuals.opensound.com/developer/SNDCTL_DSP_GETOSPACE.html "The maximum amount of data the application can ever write is (fragments-1)*fragsize bytes." Is bi.bytes == (fragments-1)*fragsize initially ?
There's two cases I've found, neither of which match that documentation. When I use the Test Sound button in winecfg (44.1 kHz, 1 channel, 16 bits), it gives me:
bi.fragstotal = 32 bi.fragsize = 2048 bi.bytes = 65536 = 32 * 2048
In Lemmix (7092 Hz, 1 channel, 8 bits), I get:
bi.fragstotal = 32 bi.fragsize = 151 bi.bytes = 4096 = 128 * 32 = 151 * 27.125...
So it seems like a bug related to rate conversion. However, (151/128) != (8000/7092) so it's not obvious where the bug comes from.
- limit the buffer to 4 mmdevapi periods s.t. Stop won't loose much.
- Never care about GETOSPACE. Write as much as possible into that max 4
periods space. write() should return a smaller number of bytes written than submitted, or EAGAIN. Work with that.
Of course the trouble here is OSS can't guarantee that behavior: "It's important to understand that this call just sets the size hint. There is no guarantee that the requested size gets used. For example some devices always use fixed buffer size and there is no way to affect this." http://manuals.opensound.com/developer/SNDCTL_DSP_SETFRAGMENT.html
So the trouble remains, how can we limit the data we write to OSS?
- Does OSS4 care about underrun and need a restart like ALSA? If yes, how to
detect it?
I haven't tested this thoroughly, but it seems like OSS behaves like MMDevAPI. That is, it just stops playing when it hits underrun, and resumes when you begin feeding it data again. The documentation on the HALT ioctl command agrees with that implicitly: http://manuals.opensound.com/developer/SNDCTL_DSP_HALT.html
- Presumably OSS will need trailing silence like ALSA in order to play the
last few frames. I've no solution to that yet (that's an area where GETOSPACE would be useful).
I'm actually not sure if OSS shares this issue. Needs more testing.
- Amenable to a blocking design, using poll(fd,period) instead of
CreateTimerQueue;
Looking forward to doing this after 1.4. That will be a very nice improvement, I think.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #5 from Jörg Höhle hoehle@users.sourceforge.net 2012-01-23 12:18:33 CST --- Looks like what we know from ALSA/dmix. Let's suppose OSS remixes to 48000. A 1024 fragments buffer at 48000 lasts 21.333ms, a period we now know well from HDA. What's the fragment size for something at 7092 samples per second? 7092 * 21.333ms -> 151.3
So the trouble remains, how can we limit the data we write to OSS?
Surprising answer? We won't! Write as much as possible in non-blocking mode.
As far as GetCurrentPadding is concerned, I believe it is not important whether bi.bytes ever matches fragstotal * fragsize. What matters is consistency of the results over time *and* that we find a formula, based on bi.* values of how much to add from OSS' buffer to This->held_frames.
Let's suppose the initial bi.bytes (4096 with Lemmix) is the maximum you ever see, then use osspadding = bi_initial.bytes - bi.bytes. Then compute GCP as threshold = ossperiod + mmdevapiperiod + safety; if osspadding < 0 then bad formula... if osspadding > threshold return GCP = osspadding - threshold + This->held_frames; else return This->held_frames;
Alternatively, osspadding = (fragstotal-1) * fragsize - bi.bytes may work just as well. The key point here is that the sub-fragment noise vanishes below the threshold value. Initially introduced to guarantee a glitch-free worst-case(=Rage/XAudio2) scenario, we may increase upto threshold to 2*ossperiod + mmdevapiperiod + safety;
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #6 from Andrew Eikum aeikum@codeweavers.com 2012-01-23 12:46:06 CST --- (In reply to comment #5)
Looks like what we know from ALSA/dmix. Let's suppose OSS remixes to 48000. A 1024 fragments buffer at 48000 lasts 21.333ms, a period we now know well from HDA. What's the fragment size for something at 7092 samples per second? 7092 * 21.333ms -> 151.3
Nice!
So the trouble remains, how can we limit the data we write to OSS?
Surprising answer? We won't! Write as much as possible in non-blocking mode.
How do we implement Stop() then?
Here's a complicated plan. Maintain a read pointer in the MMDevAPI buffer, which we advance when writing _only_after_ the first write. During Stop(), we use DSP_HALT to empty the OSS buffer, and then in Start() fill the OSS buffer from that read pointer. So, we have three pointers into the MMDevAPI buffer: one which emulates the OSS device position within the buffer, one which points to valid data not yet written to OSS, and one where the client application writes to.
Sound sane?
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #7 from Jörg Höhle hoehle@users.sourceforge.net 2012-01-23 15:45:00 CST ---
if osspadding < 0 then bad formula...
if(osspadding<0)then { This->oss_buffer_size aka. bi_initial.bytes = bi.bytes; warn("buffer size increase now %u\n", bi.bytes); } The design doesn't care about the exact size, consistency is important. PA's bug where avail grows and grows would defeat this.
How do we implement Stop() then? [plan:]During Stop(), we use DSP_HALT
IAC_Stop is conceptually pause in shared mode. I don't know whether that best maps to a) letting OSS enter underrun, b) SNDCTL_DSP_SILENCE or c) SNDCTL_DSP_HALT. GetPosition is the sole judge. 1. GetPosition must eventually reach the total Release'd frames. 2. IAC_Stop+_Start must behave w.r.t. GetPosition as if no stop ever occurred. 3. As an approximation, even GCP should nearly freeze. But I don't think that's important. After all, there are no guarantees when audio resumes after IAC_Start, hence a decrease of padding is not objectionable. Note that padding jumps in exclusive mode. Here you'll notice that unless cached, my design will see GCP continue to decrease past Stop. Actually, I recommend a cache or rather updating the data for GCP within the callback only. If that can be done only when running, GCP will appear frozen when stopped. My first approximation would be Stop with _SILENCE or underrun (I prefer underrun so the data is heard once), Start with SNDCTL_DSP_SKIP in shared mode. _HALT may be ok in exclusive mode, but most apps experience shared mode.
I don't consider stopping audible output as fast as possible important. Let it play some remaining frames and best fade out. However, IAC_Reset is important, as shown by bug #28413. playSound should use waveOutReset which must invoke IAC_Reset which should kill audio ASAP, i.e. use SNDCTL_DSP_HALT, not _SKIP and not simply set held_frames to 0. BTW http://manuals.opensound.com/developer/callorder.html says SKIP has no effect when not running, yet IAC_Reset currently uses that.
Here's a complicated plan.
If I understand you right, this would require enlarging mmdevapi's buffer so as to ensure Getbuffer(GetBufferSize-GetCurrentPadding) always works. Gettings this right sounds more complicated than entering underrun -- until there comes the day where an OSS back-end eats 2s of data like PA.
_only_after_ the first write
Why is a single write important? If you want to replay N frames, you need to buffer them. If each callback only writes period size frames, would you buffer one period only? That's not enough to worry about. Really, the problem would appear only with backends that buffer >1s like PA.
The issue I see is: we whould tell OSS that we're interested in a buffer ~50-500ms, not 10, not 1000, despite all the caveats in SNDCTL_DSP_SETFRAGMENT manpage.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #8 from Andrew Eikum aeikum@codeweavers.com 2012-01-24 10:47:36 CST --- Created attachment 38531 --> http://bugs.winehq.org/attachment.cgi?id=38531 OSS playground (C source)
Here's a simple test program I put together to test how OSS behaves.
I found the following:
1 kHz -> SKIP -> 200 Hz The rest of the 1 kHz buffer plays out, then the 200 Hz tone starts. No silence at all. This seems no different if the SKIP is omitted.
1 kHz -> HALT -> 200 Hz The 1 kHz tone stops immediately, then the 200 Hz tone starts. No silence at all.
1 kHz -> SILENCE -> 200 Hz The 1 kHz tone stops immediately, then silence for the length of the buffer, then the 200 Hz tone starts.
1 kHz -> sleep(2) -> 200 Hz The 1kHz tone stops during the sleep, then some silence, then the 200 Hz tone plays with no delay.
At no point did I observe the buffer to "wrap" and re-play old frames. As the last test above shows, OSS4 handles underrun in the same was as MMDevAPI; it just stops the device and restarts it immediately when data is written. No recovery is required.
So I believe HALT is the only interesting command (SKIP appears to do nothing at all, and we probably have no interest in inserting a buffer's length of SILENCE).
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #9 from Andrew Eikum aeikum@codeweavers.com 2012-01-24 11:13:07 CST --- (In reply to comment #7)
Gettings this right sounds more complicated than entering underrun -- until there comes the day where an OSS back-end eats 2s of data like PA.
I'm just afraid that these exist already. My experience with audio hardware so far has been "if the API doesn't explicitly disallow it (or even if it does), some hardware probably does it." I hesitate to make our driver depend on the assumption that buffers are always no more than half a second or so.
On the other hand, I'm running out of other ideas. This wouldn't be all that hard if we could just get an accurate reading of how much data is in the buffer. I'm just going to try adapting the cached buffer size value to my "write no more than 3 periods of data" approach and see what happens.
http://bugs.winehq.org/show_bug.cgi?id=29585
Andrew Eikum aeikum@codeweavers.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Attachment #38468|0 |1 is obsolete| |
--- Comment #10 from Andrew Eikum aeikum@codeweavers.com 2012-01-24 14:39:39 CST --- Created attachment 38536 --> http://bugs.winehq.org/attachment.cgi?id=38536 OSS improvements patchset
So here's a patchset which works for me. I used your suggestion of just caching the largest bi.bytes value as the max buffer size, and calculating the amount of data in the OSS buffer based off of that. It works in the handful of cases that I've tried, and passes your extended render tests (with WINETEST_DEBUG=2) just fine. Now it works basically the same as the ALSA driver (writing in period-sized chunks, no more than 4 periods in the OSS buffer, no writing in ReleaseBuffer, etc).
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #11 from Jörg Höhle hoehle@users.sourceforge.net 2012-01-25 09:31:57 CST ---
Now it works basically the same as the ALSA driver [...]
Good for 1.4. Congratulations! BTW, the other day I ran a diff between winealsa and wineoss and made a note that a patch is needed one day to eliminate gratuitous differences between the three drivers. Beside that, it also revealed one error in wineoss (bad pointer/offset update), but I forgot where. Maybe you'll spot that and fix it too.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #12 from Andrew Eikum aeikum@codeweavers.com 2012-01-25 11:15:25 CST --- (In reply to comment #11)
Now it works basically the same as the ALSA driver [...]
Good for 1.4. Congratulations! BTW, the other day I ran a diff between winealsa and wineoss and made a note that a patch is needed one day to eliminate gratuitous differences between the three drivers. Beside that, it also revealed one error in wineoss (bad pointer/offset update), but I forgot where. Maybe you'll spot that and fix it too.
Yep, found it:
memcpy(This->tmp_buffer, This->local_buffer + offs_bytes, chunk_bytes); - memcpy(This->tmp_buffer, This->local_buffer, + memcpy(This->tmp_buffer + chunk_bytes, This->local_buffer, frames_bytes - chunk_bytes);
Patches are sent.
http://bugs.winehq.org/show_bug.cgi?id=29585
Alex Masterov amasterov@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |amasterov@gmail.com
http://bugs.winehq.org/show_bug.cgi?id=29585
Mateusz Stachowski mateusz.stachowski@wp.pl changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |mateusz.stachowski@wp.pl
--- Comment #13 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-02-01 10:47:54 CST --- It's great that you two are working on Open Sound System support for Wine, but this changes broke some games for me. I can't get sound from atleast three games that have been working with wine-1.3.37. Here is the list:
Anomaly Warzone Earth Sanctum Defense Grid: The Awakening
I'm on Ubuntu 11.10 32-bit with OSS-v4.2-build2005 compiled from mercurial repository.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #14 from Andrew Eikum aeikum@codeweavers.com 2012-02-01 14:00:26 CST --- I'm able to reproduce this (all three of those games have demos on Steam, and all three work fine in ALSA and OSS before the decouple patch), but I'm really confused. I see the audio playing correctly (or it looks correct) from the levels widgets in ossxmix. But, I don't hear anything through the speakers. It's getting the audio data, but not playing it.
I tried dumping O_NONBLOCK to no effect. Calling SETTRIGGER to enable output did nothing. As far as I can tell, the output device isn't opened twice while writing, so it seems like that shouldn't be a problem.
So, why won't it play our data through the speakers?
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #15 from Andrew Eikum aeikum@codeweavers.com 2012-02-01 14:30:01 CST --- Created attachment 38649 --> http://bugs.winehq.org/attachment.cgi?id=38649 wineoss.drv: Don't call GETOSPACE immediately after device initialization
Hmm, removing the GETOSPACE call in IAudioClient::Initialize and hard-coding the same result makes it work. I tried writing some silence before that call, but that didn't work.
The GETOSPACE docs say, "This ioctl must in no case be called before the device setup is finished." But we set channels, rate, and format before making the GETOSPACE call, so it seems like this is a valid call (see http://manuals.opensound.com/developer/callorder.html). Even more annoyingly, the call works fine in some games, but not in other games.
I think we can get away with initializing the oss_buffersize_bytes variable to 0, since we detect new maximums anyway before actually using it. See attached patch.
Why does GETOSPACE break the device in this strange way? Maybe the device needs a few milliseconds to settle, and calling GETOSPACE before that breaks the device? This seems plausible. I think we make the exact same order of calls with and without this patch (SETFMT, CHANNELS, SPEED, GETOSPACE), but with this patch, we only make the GETOSPACE call during the first write() callback after IAC::Start(), not immediately after initialization.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #16 from Andrew Eikum aeikum@codeweavers.com 2012-02-02 13:55:09 CST --- Well, after spending the better part of a day on this, I'm no further to understanding why that call breaks the OSS device.
While it seems like this ought to be a read-only call (i.e. no modifications to the device), diving into the OSS source reveals that it isn't:
static int get_ospace (adev_p adev, dmap_p dmap, ioctl_arg arg) { ... if (!(dmap->flags & DMAP_PREPARED)) { setup_fragments (adev, dmap, OPEN_WRITE); prepare_output (adev, dmap); } ...
Notice setup_fragments() and prepare_output(), both of which make changes to dmap's and adev's members.
I was also wrong in the last comment. The call order is: (open, engineinfo, setfmt, channels, speed, [getospace,] getodelay, getospace, write), the one in brackets is our problematic call. Looking through the source for GETODELAY, I see no modifications to the device (there is a driver call in there that I didn't investigate).
Going to see if I can figure out how to build OSS and get it to output stuff.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #17 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-02-05 04:15:22 CST --- Unfortunately I can't help in the matter of programming. I just hope that you find the problem and solve it.
In the meantime I've found even more games that doesn't produce sound on wine-1.4-rc2. You can also install them from Steam:
EDGE Demo Dungeon Siege III Demo Titan Quest Demo
You should also check out Dungeon Defenders Demo, because it always (even before 1.4-rc1) produced sound only partialy. I mean that you could hear it in the intro videos, but as soon as you get to the menu there is only silence.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #18 from Andrew Eikum aeikum@codeweavers.com 2012-02-06 09:16:10 CST --- Yes, those three games have the same problem and are solved by this patch. The Dungeon Defenders problem sounds like Bug 28840 which should be fixed now, although the voice tracks skipped a little bit when I was testing.
I'll probably go ahead and submit that patch soon.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #19 from Jörg Höhle hoehle@users.sourceforge.net 2012-02-06 09:32:33 CST --- One extra idea may be to make a max. write the first time (after all, NONBLOCK is set), such that GETOSPACE always follows the first write.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #20 from Andrew Eikum aeikum@codeweavers.com 2012-02-06 15:22:27 CST --- That patch is in Wine as bb1ca5811458f59297f1b82205f563e0c07b5ece. I couldn't think of a worthwhile comment to add about the unexpectedly broken functionality. ("Don't insert this call here because it might break stuff" with no further explanation? Eh...)
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #21 from hash HASH.DuOrden@gmail.com 2012-02-08 07:57:45 CST --- Created attachment 38743 --> http://bugs.winehq.org/attachment.cgi?id=38743 logs runned with different OSS4 setups from WINETEST_INTERACTIVE=1 WINETEST_DEBUG=2 WINETEST_PLATFORM=wine wine mmdevapi_test.exe.so capture
I was contacted by Jörg Höhle and asked for to run some tests with and without vmix enabled so here it is: capture_novmix.log - OSS4 without vmix support. capture_vmix.log - OSS4 with vmix enabled and attached, winecfg in audio tab all set to Default. capture_SB_Audigy_main.log - OSS4 with vmix enabled and attached, winecfg in audio tab all set to "SB Audigy main". capture_SB_Audigy_main_vmix.log - OSS4 with vmix enabled and attached, winecfg in audio tab all set to "SB Audigy main (vmix)".
wine-1.4-rc2-61-g93ed8a0
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #22 from hash HASH.DuOrden@gmail.com 2012-02-08 07:59:23 CST --- Created attachment 38744 --> http://bugs.winehq.org/attachment.cgi?id=38744 logs runned with different OSS4 setups from WINETEST_INTERACTIVE=1 WINETEST_DEBUG=2 WINETEST_PLATFORM=wine wine mmdevapi_test.exe.so render
And the render part: render_novmix.log - OSS4 without vmix support. render_vmix.log - OSS4 with vmix enabled and attached, winecfg in audio tab all set to Default. render_SB_Audigy_main.log - OSS4 with vmix enabled and attached, winecfg in audio tab all set to "SB Audigy main". render_SB_Audigy_main_vmix.log - OSS4 with vmix enabled and attached, winecfg in audio tab all set to "SB Audigy main (vmix)".
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #23 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-02-08 13:12:31 CST --- I've tested today apps that I reported and sound is working. Unfortunately quality of it has regresed severly (it was much better with wine-1.3.37, not ideal). I've got constant clicks and loops of audio fragments. The worst results gives me Anomaly and Defence Grid.
I've tested it on Wine compiled from git (wine-1.4-rc2-61-g93ed8a0) and the newest version of Open Sound System compiled from mercurial repository.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #24 from Andrew Eikum aeikum@codeweavers.com 2012-02-09 10:02:08 CST --- Mateusz: The demos for both those games are working fine on my computer. Can you attach a log with the channels from http://wiki.winehq.org/Sound?
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #25 from Jörg Höhle hoehle@users.sourceforge.net 2012-02-10 04:34:42 CST --- Mateusz, Andrew, please use WINETEST_INTERACTIVE=1 and describe what you hear. Hash's logs show: render.c:1631: Released 1920=2x960 -1920 frames at 48000 worth 0ms in 7737ms (nothing was played!) and plenty of crashes, so wineoss is sererely broken for him.
I recommend you use the render tests from today's testbot job #16901, which will hopefully hit git tonight. Please mention which version of Wine (1.4-rc2 or latest git) you've been using. See bug #28723, comment #128 for various forms of audio output that you may hear.
Unfortunately, you probably can't run my newest tests with older versions of Wine such as wine-1.3.37. But what you can do with old versions when compiling yourself is to take the newest test tests/render.c, comment out everything except test_audioclient() and test_worst_case(), then run that against 1.3.37 with WINETEST_INTERACTIVE=1.
Hash, render_novmix.log was the only one that didn't crash. render.c:410: Test failed: Initialize(shared, 96000x16x2) returns 00000000 render.c:463: Test failed: Initialize failed: 88890008 Odd. [crash follows.] Perhaps some process was still running when you ran the subsequent tests? Could you please investigate that? Probably Andrew will need a WINEDEBUG=+xyz log to analyse this.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #26 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-02-11 06:42:26 CST --- Created attachment 38796 --> http://bugs.winehq.org/attachment.cgi?id=38796 Anomaly Warzone Earth log WINEDEBUG=+tid,+mmdevapi,+winmm,+driver,+midi,+dsound,+dmusic,+mci,+oss
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #27 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-02-11 06:43:39 CST --- Created attachment 38797 --> http://bugs.winehq.org/attachment.cgi?id=38797 Defense Grid log WINEDEBUG=+tid,+mmdevapi,+winmm,+driver,+midi,+dsound,+dmusic,+mci,+oss
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #28 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-02-11 06:54:58 CST --- I've added logs from the two games that output a very bad sound. I was using wine-1.4-rc2-61-g93ed8a0 in those tests.
I have also found another game that quality of sound regresed Toki Tori.
Jörg I will probably add the logs that you requested later. I have to update my wine-git installation first.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #29 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-02-11 13:28:08 CST --- Created attachment 38806 --> http://bugs.winehq.org/attachment.cgi?id=38806 mmdevapi tests on wine-git WINETEST_INTERACTIVE=1 WINETEST_DEBUG=5 /media/Ubuntu/wine/wine mmdevapi_test.exe.so
I've compiled the latest wine from git ($ git describe wine-1.4-rc2-96-gb0bc037) and runned the mmdevapi tests (render and capture). During the testing I didn't hear anything (absolute silence).
I have wine-git repository cloned to /media/Ubuntu/wine directory and I've runned that on testing. I made a script for that purpose:
#!/bin/sh cd /media/Ubuntu/wine/dlls/mmdevapi/tests WINETEST_INTERACTIVE=1 WINETEST_DEBUG=5 /media/Ubuntu/wine/wine mmdevapi_test.exe.so render 2>&1 | tee /media/Ubuntu/render_vmix.log
I wonder does that is the appropriate way of doing your tests Jörg.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #30 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-02-12 08:38:19 CST --- Created attachment 38820 --> http://bugs.winehq.org/attachment.cgi?id=38820 mmdevapi tests on wine-1.3.37 WINETEST_INTERACTIVE=1 WINETEST_DEBUG=5 /media/Wolne/wine-1.3.37/wine mmdevapi_test.exe.so
I've added tests results for wine-1.3.37. I hope that I did them properly. I've copied render.c from wine-git and removed everything beetwen test_audioclient() and test_worst_case(), then compiled wine.
I've used this script:
#!/bin/sh cd /media/Wolne/wine-1.3.37/dlls/mmdevapi/tests WINETEST_INTERACTIVE=1 WINETEST_DEBUG=5 /media/Wolne/wine-1.3.37/wine mmdevapi_test.exe.so render 2>&1 | tee /media/Wolne/render_vmix.log
In case of this tests I also didn't hear anything from my headphones.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #31 from Jörg Höhle hoehle@users.sourceforge.net 2012-02-13 05:38:38 CST --- render.c:198: bits: 16 You hear nothing because I've implemented audio output for FLOAT only, not 16bit ints. Your OSS4 does not support floating point formats? wineoss.drv:mmdevdrv.c checks #ifdef AFMT_FLOAT This is an issue that IMHO Wine must address: MS mentions here and there that the mixer uses floats, so until now we are lucky that there's no bugzilla issue about an app crashing because Wine's GetMixFormat returns an integer format.
render.c:1697: Test failed: Wait gave 102 [a hundred times] render.c:1729: Released 960=1x960 -1920 frames in 7764ms Something is definitely wrong. a) SetEvent was never delivered in time. b) Padding never decreased so as to write more frames.
Compare that to your wine-1.3.37 log: render.c:1729: Released 84480=88x960 -960 frames worth 1740ms in 2026ms That looks acceptable. Time for git bisect wine-1.4rc3 wine-1.3.37 -- dlls/wineoss.drv/mmdevdrv.c
err:ntdll:RtlpWaitForCriticalSection section Maybe that's a hint?
worth 4294967276ms in 7764ms That's a minor bug in my test. Work-around: use WINETEST_DEBUG at most 2.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #32 from Andrew Eikum aeikum@codeweavers.com 2012-02-14 11:12:20 CST --- I wonder if this is another timer skew problem, caused by CreateTimerQueueTimer not being as accurate as we need.
I ran the tests with WINETEST_INTERACTIVE=1 and found I got two different behaviors. About 75% of the time, all tests would pass without fail, although I didn't hear any audio. The other 25% of the time, I'd get similar results to comment 30, where the Wait() call fails continually. Eventually it would crash.
I changed the OSS timer interval to be:
if(!CreateTimerQueueTimer(&This->timer, g_timer_q, - oss_period_callback, This, 0, This->period_us / 1000, + oss_period_callback, This, 0, This->period_us / 1000 * 0.75, WT_EXECUTEINTIMERTHREAD))
and it stopped failing entirely.
Mateusz, could you try this little hack and see if Anomaly's behavior improves, or if that test failure goes away?
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #33 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-02-14 16:18:39 CST --- Andrew I have compiled the latest wine-git ($ git describe wine-1.4-rc3-22-g2e90188) with that line changed in mmdevdrv.c file. Unfortunately it didn't solve problems with sound in Anomaly Warzone Earth. I think that it even got worse (but it's quite subjective feeling).
Jörg my OSSv4 most likely supports floating point formats, because that's what it defaults to when building on Linux: http://www.opensound.com/wiki/index.php/Building_OSSv4_from_source#Notable_c...
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #34 from Andrew Eikum aeikum@codeweavers.com 2012-02-15 10:26:32 CST --- Created attachment 38889 --> http://bugs.winehq.org/attachment.cgi?id=38889 OSS debugging traces
Calling SNDCTL_ENGINEINFO reports oss_audioinfo.oformats = 0x5010 = (AFMT_FLOAT | AFMT_S32_LE | AFMT_S16_LE). Calling SNDCTL_PCM_SETFMT with AFMT_FLOAT gives AFMT_S16_LE in return, implying that AFMT_FLOAT isn't supported. I sent a mail to OSS's development mailing list, so we'll see if that gets anywhere...
Seems like this is a race problem. If I add more TRACEing to wineoss, the test failures go away entirely. Using WINEDEBUG=-all brings them back again.
I've attached a little patch here which just adds logging. Can you run the failing render tests again with this applied and all the usual channels, Mateusz?
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #35 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-02-15 14:56:34 CST --- Created attachment 38895 --> http://bugs.winehq.org/attachment.cgi?id=38895 mmdevapi tests on wine-git patched (OSS debugging traces)
I've compiled the latest wine-git ($ git describe wine-1.4-rc3-51-g0352a70) with your patch and run the tests again.
I've used this script:
#!/bin/sh cd /media/Ubuntu/wine-clean/dlls/mmdevapi/tests WINETEST_INTERACTIVE=1 WINETEST_DEBUG=2 WINEDEBUG=+tid,+mmdevapi,+winmm,+driver,+midi,+dsound,+dmusic,+mci,+oss /media/Ubuntu/wine-clean/wine mmdevapi_test.exe.so render 2>&1 | tee /media/Ubuntu/render_vmix.log
I've tried to contact with Open Sound System devs through the mailing list (in different matter, custom mixer) and it's four days since my question was accepted, but so far no answers. Hannu and other devs probably don't have time to look at that (so you will have to wait quite some time for the answer).
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #36 from Jörg Höhle hoehle@users.sourceforge.net 2012-02-16 03:18:57 CST --- WINEDEBUG=+timestamp is useful to see what happens when. Please repeat. I've disabled FLOAT in wineALSA and produced audible 16bit sine samples. There was no crash or abnormal behaviour. So all blame is on [wine]OSS.
http://bugs.winehq.org/show_bug.cgi?id=29585
Mateusz Stachowski mateusz.stachowski@wp.pl changed:
What |Removed |Added ---------------------------------------------------------------------------- Attachment #38895|0 |1 is obsolete| |
--- Comment #37 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-02-16 13:49:10 CST --- Created attachment 38912 --> http://bugs.winehq.org/attachment.cgi?id=38912 mmdevapi tests on wine-git patched (OSS debugging traces) WINEDEBUG=+timestamp
I've added +timestamp to the debugging channels in my script and run the tests again with updated wine-git ($ git describe wine-1.4-rc3-65-g98f0be8).
Hannu has answered to your question on opensound-devel mailing list and the patch is in the mercurial repository.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #38 from Andrew Eikum aeikum@codeweavers.com 2012-02-17 10:41:21 CST --- Here's a 4-patch sequence. The first patch is the same as the debugging traces patch from comment 34.
The second patch is the OSS counterpart to winealsa's 8db18a893b3769d482f22bd2e2b545b82a31574f (winealsa: Avoid deadlock in AudioClient_Stop.). This fixes the "Wait returned 102" error. With this applied, wineoss behaves the same as winealsa in the mmdevapi render tests on my machine, modulo format problems.
The final two patches are quick hacks. The third patch tweaks the mmdevapi tests to always use int16_t format, instead of always using float. The last patch is just the hack from comment 32. This makes the audio heard on my machine continuous, instead of with underruns from the clock skew (this same hack fixes winealsa's underruns).
I guess I don't know if I expect these patches to fix Mateusz's problem. The second patch is definitely correct, and I'll send it off to wine-patches shortly. But I'm not convinced that's the problem Mateusz is experiencing. Regardless, I'm interested to know if applying 3 or all 4 of these patches helps anything.
http://bugs.winehq.org/show_bug.cgi?id=29585
Andrew Eikum aeikum@codeweavers.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Attachment #38889|0 |1 is obsolete| |
--- Comment #39 from Andrew Eikum aeikum@codeweavers.com 2012-02-17 10:42:00 CST --- Created attachment 38927 --> http://bugs.winehq.org/attachment.cgi?id=38927 Some more attempts at improvements
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #40 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-02-19 10:18:17 CST --- The results were to big so here is an alternative link: http://ubuntuone.com/7k2SMByx5aK6BuanZveLeP [tests on wine-1.4-rc4 (with 4 patches) mmdevapi render and games]
Next round of tests this time on wine-1.4-rc4 with patches by Andrew Eikum. I've first tried how it will go when using only patches (without HACKS), but there still was very bad sound quality in games. Then I've compiled Wine again with HACKS. Unfortunately the sound quality didn't improve at all. I've also found more games affected by this problem:
Q.U.B.E. Demo (it's on Steam, but it needs .NET 4.0 which can be installed with the newest winetricks from svn) Mass Effect 3 Demo (it's on Origin)
I've also upgraded my OSSv4 to the newest version (with commit "Fixed reporting of AFMT_FLOAT as a supported format").
Running mmdeavapi render tests produces audible sine waves, but when the vmix is disabled the output often becomes not clear.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #41 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-02-26 15:52:56 CST --- I've tested the newest wine-1.4-rc5 without any additional patches and sound output with OSSv4 is still broken.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #42 from Jörg Höhle hoehle@users.sourceforge.net 2012-03-04 01:33:06 CST --- A patch to stabilize CreateTimerQueueTimer to avoid underruns is in bug #30071.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #43 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-03-05 12:46:45 CST --- I've compiled wine-1.4-rc6 with patch to stabilize CreateTimerQueueTimer, but it didn't solve the problem. I've tested Anomaly and Sanctum and underruns still occur.
Jörg does that patch need to be applied with some other patches.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #44 from Jörg Höhle hoehle@users.sourceforge.net 2012-03-06 03:54:35 CST ---
does that patch need to be applied with some other patches.
No. You can add the one about audible 16bit sine in the render test.
Please summarize your current situation. - Crackling with render tests? with/without vmix? - What do the apps you name use? DSound? XAudio2? Winmm? Other?
DSound suffers from other issues and can cause crackling in scenarios with small buffer sizes because it does not sync well with mmdevapi. That's why it's important to distinguish crackling from DSound vs. w7/XAudio2 apps. One good news is that DSound doesn't care about missing floating point in mmdevapi because DSound apps typically use 8 or 16bit output.
underruns still occur.
Please be more precise. Occasional or continuous?
The patch is no protection against clock skew. I expect occasional underruns in the XAudio2 scenario should the audio device consume frames faster that the system's clock idea of 48000fps. This should be visible in the logs as a slow decrease of *average* padding in the buffer.
Running mmdeavapi render tests produces audible sine waves, but when the vmix is disabled the output often becomes not clear.
My beliefs about your situation are: - with vmix: render & XAudio & winmm app sound is ok, without crackling; - w/o vmix: "output not clear" - origin unknown - DSound apps can suffer from crackling (several per second). What's right and what is wrong?
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #45 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-03-06 16:04:02 CST --- I don't know what those games use. I don't know how to check it. I have them from Steam and the bundled DirectX libraries include XAudio and X3DAudio. Anomaly Warzone Earth required setting DirectSound HardwareAcceleration to emulation in earlier versions of Wine.
I have ran mmdevapi tests and the winmm wave test, but the output is too large to create attachment so I uploaded them elsewhere: http://ubuntuone.com/1nlGSqvxwZkrhQTYluauaR
In the archive you will find no_vmix.wav file which is exactly what i hear during mmdevapi test without vmix. That record is very quiet, but audible.
Winmm test didn't go without problems. There were times that I couldn't hear anything.
http://bugs.winehq.org/show_bug.cgi?id=29585
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|1.4.0 |1.6.0
--- Comment #46 from Austin English austinenglish@gmail.com 2012-03-07 13:27:14 CST --- Moving milestone to 1.6.
http://bugs.winehq.org/show_bug.cgi?id=29585
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|1.6.0 |1.4.0
--- Comment #47 from Austin English austinenglish@gmail.com 2012-03-07 13:34:26 CST --- My mistake, 1.6 criteria are not set yet, so these need to stay in 1.4.
Sorry for the noise.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #48 from Chris Purnell cjp@lost.org.uk 2012-04-06 14:14:20 CDT --- I've found what was causing me crackling with dsound playback.
I was watching the "padding" in the logging and noticed that I was getting the crackling every time it hit 0. This padding value is the held_frames. For me this was hovering around 1024 and always a multiple of 512 and never more than 2048. So it didn't take much for it to hit 0.
Now 512 was what dsound had chosen as a fragment size in frames based upon the sample rate which in this case was 44100. My sound device was defaulting to a fragment size of 1024 frames.
Dsound was tying to keep the sound device filled with 10 of its fragments and wineoss.drv was trying to keep 3 whole device fragments buffered in the sound device. So yeah, 10*512(from dsound) = 3*1024(written) + 2048(held).
The condition under which I was getting crackling (frames_held==0) is one that occurs more often with larger device fragment sizes.
The crackling was not the result of any underrun. In fact it existed in the data that was being written.
What dsound was doing was instead of adding 1 or 2 of its fragments it was buffering all 10. It was doing this because the value from GetPosition was jumping ahead to exactly 10 dsound fragments beyond the dsound's saved value.
AudioClock_GetPosition in wineoss.drv has a check for !This->held_frames and if so does not subtract the value it gets from SNDCTL_DSP_GETODELAY. This delay was hovering around a little under 3-4 device fragments. That is about 7 dsound fragments.
What I'm guessing is that dsound does not have the data for that far ahead and is mixing in 0s. It probably should not be doing that but then wineoss.drv should definitely not be reporting the position of an underrun event that has not happened yet.
Removing the "|| !This->held_frames" from AudioClock_GetPosition got rid of the crackling for me.
Looking at the corresponding ALSA code there does not appear to be an equivalent test.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #49 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-04-10 13:38:33 CDT --- Chris you have shed a light of hope for me as this problem (crackling sound on OSSv4) is already been here for couple of Wine releases.
I'm not sure what exactly should I delete and in what file. I assume that it should be in mmdevdrv.c and is it this line || !This->held_frames || (there are other This->held_frames). Could you provide more specific instructions. Maybe even diff file.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #50 from Chris Purnell cjp@lost.org.uk 2012-04-13 00:49:31 CDT --- Created attachment 39783 --> http://bugs.winehq.org/attachment.cgi?id=39783 Use odelay even when no held frames.
Uploading a diff because Mateusz asked for one.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #51 from Jörg Höhle hoehle@users.sourceforge.net 2012-04-13 03:10:45 CDT --- Chris, I don't understand parts of what you wrote. Could you please elaborate?
In fact it existed in the data that was being written. It was doing this because the value from GetPosition was jumping ahead to exactly 10 dsound fragments beyond the dsound's saved value
??
wineoss.drv should definitely not be reporting the position of an underrun event that has not happened yet.
Definitely. But where/how do you diagnose this in wineoss? Part of what I don't understand about what you write is what DSound is doing wrong and what mmdevapi is doing wrong.
What I want: 1. Have mmdevapi produce sound values. Here you patch is incorrect, because GetPosition should a priori not bump to maximum when held_frames is zero. That point is debatable and debated[*].
2. Have DSound deal with huge latencies.
This delay was hovering around a little under 3-4 device fragments. That is about 7 dsound fragments.
What you write sounds to me as if DSound does not work well when the latency is almost as large as its buffer. I think this is a known bug in Wine's DSound, that has become apparent since the switch to mmdevapi. Former code used to lie about latency. Is what you mean point L in my list: http://www.winehq.org/pipermail/wine-devel/2012-January/093982.html
[*] I forgot where I wrote about this. Basically: Contra: There could be 2 seconds worth of samples buffered within OSS, USB or the remote desktop, they should drain slowly and normally. We need some tests on native with such a setup. Pro: The native mixer ticks every 10ms and its GetCurrentPadding slowly decreases by deltas of 10ms. All test results so far shows that GetPosition is not far (less than ~40ms) behind GetCurrentPadding. Therefore, when padding decreases and reaches zero, position soon reaches max. One bug is that Wine's GetCurrentPadding does not behave that regularly. IIRC there was a bug report where we observed and discussed GetPosition jumps to maximum, but I can't find it now. Bug #29472, comment #9 and bug #29531 are related.
http://bugs.winehq.org/show_bug.cgi?id=29585
Chris Purnell cjp@lost.org.uk changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |cjp@lost.org.uk
--- Comment #52 from Chris Purnell cjp@lost.org.uk 2012-04-13 23:40:59 CDT --- (In reply to comment #51)
Chris, I don't understand parts of what you wrote. Could you please elaborate?
In fact it existed in the data that was being written.
I added some debugging code to write a copy the audio data to a file and on playing that file I heard the exact same crackling.
It was doing this because the value from GetPosition was jumping ahead to exactly 10 dsound fragments beyond the dsound's saved value
??
The way wine's dsound currently works is it initially gives mmdevapi 10 fragments. Then is sends more fragments as the mmdevapi GetPosition increases.
When held_frames is zero, the oss mmdevapi GetPosition jumps to maximum.
Dsound sees this and sends 10 more fragments.
wineoss.drv should definitely not be reporting the position of an underrun event that has not happened yet.
Definitely. But where/how do you diagnose this in wineoss?
By looking at the value from GetPosition over time and seeing it suddenly jump to a value that corresponds to all the data passed to mmdevapi thus far.
Part of what I don't understand about what you write is what DSound is doing wrong and what mmdevapi is doing wrong.
I don't know what, if anything, dsound is doing wrong. I've not looked at dsound beyound its interaction with mmdevapi.
What I want:
- Have mmdevapi produce sound values.
Here you patch is incorrect, because GetPosition should a priori not bump to maximum when held_frames is zero. That point is debatable and debated[*].
What you said there is kind of confusing, even after I looked up "priori".
The thing is GetPosition should not suddenly jump ahead. I was seeing it jump forward by as much as 90ms.
Also, don't confuse held_frames with GetCurrentPadding. GetCurrentPadding may currently return held_frames but that may not be the correct thing to do.
But dsound is currently using GetPosition and not GetCurrentPadding so I don't care about GetCurrentPadding.
- Have DSound deal with huge latencies.
This delay was hovering around a little under 3-4 device fragments. That is about 7 dsound fragments.
What you write sounds to me as if DSound does not work well when the latency is almost as large as its buffer. I think this is a known bug in Wine's DSound, that has become apparent since the switch to mmdevapi. Former code used to lie about latency. Is what you mean point L in my list: http://www.winehq.org/pipermail/wine-devel/2012-January/093982.html
Latency does not appear to be a problem.
For example, one thing I tried was "max_period = This->period_frames" and ignoring bi.fragsize there. This ment that less was written to the device so held_frames never hit 0 and avoided the problem.
Another thing I tired was removing the SNDCTL_DSP_GETODELAY from GetPosition entirely. This adds a lot of latency to dsound playback but other than that is seemed to work fine.
It just seems to be a simple case of inconsistant values of GetPosition depening upon whether held_frames is 0 or not. Something the other mmdevdrvs don't do.
That said they may be other problems with wine's dsound if you really do have unavoidably large audio latancies.
There are some things I don't get: Why not write as much as possible to the device? Why no SNDCTL_DSP_SETFRAGMENT?
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #53 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-04-16 16:45:13 CDT --- I've tested some games with wine-1.5.2 vanilla and with deleted !This->held_frames and results are mixed. This definitely doesn't solve the problem but I wasn't actually expecting that.
There is atleast one game that gets good sound with modified wine-1.5.2 and it's Rayman Origins Demo (it's available on Steam). The other games that I've tested had only slightly better sound output with modified Wine.
I've uploaded the logs for Rayman and Legend of Grimrock Hardware Test: http://ubuntuone.com/6exafJErg0Hk6ID2hp74iG (modified are for wine-1.5.2 without !This->held_frames)
You can download the Hardware Test for Legend of Grimrock at this locations:
http://www.playerattack.com/file/16019/Legend-of-Grimrock-v1.0.4-Beta-Build/ http://www.atomicgamer.com/files/95753/legend-of-grimrock-hardware-test-v1-0...
it needs atleast wine-1.5.1 to run and needs dll overrides:
winetricks xact_jun2010 d3dx9_36
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #54 from Andrew Eikum aeikum@codeweavers.com 2012-04-17 09:30:40 CDT --- Are all of the games that have problems dsound games? For example, is winecfg's Test Sound button broken?
(In reply to comment #52)
But dsound is currently using GetPosition and not GetCurrentPadding so I don't care about GetCurrentPadding.
I have a patchset to fix this, and several other dsound issues. It may fix this problem if dsound is the only bad audio path.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #55 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-04-17 13:52:11 CDT --- Test Sound in winecfg works (no problems with that).
I think that all of these games use XAudio2. When looking at winetricks from it's GUI into installed DLLs all of them have xact or xact_jun2010 or both (every game in a separate Wineprefix).
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #56 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-04-23 13:54:13 CDT --- Andrew could you post your patches here or point me into the place where I can download them. I hoped that they appear in the git repository (past week) but there wasn't anything from you and even anything audio related.
I would really like to solve sound problems with OSSv4 and I know how to apply patch and compile Wine.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #57 from Andrew Eikum aeikum@codeweavers.com 2012-04-26 14:44:47 CDT --- Created attachment 39931 --> http://bugs.winehq.org/attachment.cgi?id=39931 (NEEDS WORK) Dsound resampler and cleanup patchset
Mateusz: Here is the dsound patchset. It contains both Alexander's improved resampler from Bug 14717, as well as some cleanup afterwards to improve how dsound operates and how it uses MMDevAPI. It will only affect games that use dsound.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #58 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-05-02 14:44:31 CDT --- I'm sorry that I didn't respond for so long. It's upgrade time on Ubuntu and with 12.04 I've moved to 64bit and Wine compilation isn't as straight forward as it was on 32bit (I've still didn't get it).
I've downloaded wine-1.5.3 from the ibiblio.org and then applied the patches one by one. Unfortunately not all of them applied cleanly.
I've noticed that Alexander's patches are now in git repository so yours will probably follow (for now I will try compiling git).
http://bugs.winehq.org/show_bug.cgi?id=29585
Andrew Eikum aeikum@codeweavers.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Attachment #39931|0 |1 is obsolete| |
--- Comment #59 from Andrew Eikum aeikum@codeweavers.com 2012-05-03 09:05:20 CDT --- Created attachment 40012 --> http://bugs.winehq.org/attachment.cgi?id=40012 (NEEDS WORK, rebased) Dsound resampler and cleanup patchset
Yeah, things are kind of in flux as they're being sent to Wine this week. Here's another patchset. This should apply cleanly on top of 9c19ba63a84f0024e3bb0e4febc6da484b47d3e5.
http://bugs.winehq.org/show_bug.cgi?id=29585
Mateusz Stachowski mateusz.stachowski@wp.pl changed:
What |Removed |Added ---------------------------------------------------------------------------- Attachment #38796|0 |1 is obsolete| | Attachment #38797|0 |1 is obsolete| | Attachment #38806|0 |1 is obsolete| | Attachment #38820|0 |1 is obsolete| | Attachment #38912|0 |1 is obsolete| |
--- Comment #60 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-05-06 15:34:41 CDT --- Created attachment 40066 --> http://bugs.winehq.org/attachment.cgi?id=40066 Trine 2 in Unity 3D WINEDEBUG=+timestamp,+mmdevapi,+winmm,+driver,+dsound,+dmusic,+oss
I've finally compiled Wine on Ubuntu 12.04 in chroot environment so I could get the 32bit version. It's impossible to get it normal way without huge amount of tinkering and hacks on the 64bit Precise.
I've compiled the newest version of Wine from git (wine-1.5.3-164-gdec3d50) it's newer than the commit you mention. This time all of the patches applied cleanly. After applying them I've used ./tools/make_requests.
I'm very happy to report that this patches fixed the sound issues in all of the games that I tested. Atleast it is truth for Unity 2D and Razor-qt. I've discovered that running games in Unity 3D still produces some sound problems in several games. Those are very little problems aside from one game (Trine 2) which is definitely most demanding. When I run it in Unity 3D the sound is pretty bad, but in Unity 2D and Razor-qt it's all good. I've attached log of Trine 2 on Unity.
List of tested games:
SOLVED Titan Quest Demo Dungeon Siege III Demo Mass Effect 3 Demo Rayman Origins Demo
Much better, but still some minor problems when running in Unity 3D EDGE Demo Legend of Grimrock Defense Grid: The Awakening Anomaly Warzone Earth Q.U.B.E. Demo
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #61 from Andrew Eikum aeikum@codeweavers.com 2012-05-07 08:44:22 CDT --- (In reply to comment #60)
I'm very happy to report that this patches fixed the sound issues in all of the games that I tested.
Great! The last patch for Bug 14717 is currently working its way in. I'll get the rest of the cleanup patches in over the next week or two. We can probably close this bug after they're in.
Much better, but still some minor problems when running in Unity 3D
I'm not sure what you mean by "running in Unity 3D." I grabbed the EDGE demo and it worked well for me. Is there a way to change the engine that the game runs in?
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #62 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-05-07 13:38:33 CDT --- I didn't mean Unity Engine but Unity the new shell of Ubuntu (desktop environment). http://en.wikipedia.org/wiki/Unity_(user_interface)
You could try running Trine 2 Demo it's on Steam. Here are my test results for the full version of Trine 2: http://appdb.winehq.org/objectManager.php?sClass=version&iId=24961&i...
Unfortunately there is also another game that gives me bad sound in Unity 3D (in the Unity 2D it's all good). This game is Legend of Grimrock it doesn't have demo version but there was a Hardware Test release which is also affected.
http://www.atomicgamer.com/files/95753/legend-of-grimrock-hardware-test-v1-0... http://www.playerattack.com/file/16019/Legend-of-Grimrock-v1.0.4-Beta-Build/
You will need to install dll's: winetricks d3dx9_36 xact_jun2010 (clean wineprefix)
The problems with sound only occur in Unity 3D (and those two games) on other tested DE's (Unity 2D, Razor-qt and Gnome Shell) I have good sound quality.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #63 from Andrew Eikum aeikum@codeweavers.com 2012-05-16 14:31:12 CDT --- Mateusz: All of those patches are in Wine now. Can you retest and confirm it's working.
Any objection to closing this bug? Any thoughts Jörg?
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #64 from Mateusz Stachowski mateusz.stachowski@wp.pl 2012-05-20 14:41:55 CDT --- Andrew besides the issues I'm experiencing in the Unity user interface it's all good. I've tested the latest Wine from git. I'm still wondering why it's like that, sure Unity is using Compiz and is heavy on the resources but why it has impact on the sound output.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #65 from Jörg Höhle hoehle@users.sourceforge.net 2012-05-22 04:12:25 CDT --- In my original report, I intended a formal meaning of "not on par": winealsa had received a couple of improvements, wineoss not. I haven't looked recently at the diff among the two drivers. If there's no diff[*], the bug can be closed. Or ... you interpret "not on par" at the feature level: perhaps some apps produce bad output with wineoss but work find with winealsa? That should not be.
Is GetPosition working reliably?
Is wineoss working equally well with and without vmix? If not, that deserves its own bug report. [*] ignoring that wineoss has no lead-in.
http://bugs.winehq.org/show_bug.cgi?id=29585
--- Comment #66 from Andrew Eikum aeikum@codeweavers.com 2012-05-22 11:23:25 CDT --- (In reply to comment #65)
In my original report, I intended a formal meaning of "not on par": winealsa had received a couple of improvements, wineoss not. I haven't looked recently at the diff among the two drivers. If there's no diff[*], the bug can be closed. [*] ignoring that wineoss has no lead-in.
Looks like the diff is mostly on the Capture side. The conversion for getbuf_last was never done for OSS's capture implementation. There's also a few minor things to straighten out (one or two instances of using GetCurrentPadding instead of synonymous This->held_frames).
Is GetPosition working reliably?
I think so. It's monotonically increasing, and uses SNDCTL_DSP_GETODELAY. In fact, I think the improved GetPosition behavior was the cause of Mateusz's dsound problems, since dsound was using GetPosition instead of GetCurrentPadding.
Is wineoss working equally well with and without vmix? If not, that deserves its own bug report.
Bug 28790 seems to be the most relevant. Worth retesting at some point.
https://bugs.winehq.org/show_bug.cgi?id=29585
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution|--- |FIXED
--- Comment #67 from Austin English austinenglish@gmail.com --- Fixed, any remaining issues should be reported in their own bugs.
https://bugs.winehq.org/show_bug.cgi?id=29585
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #68 from Alexandre Julliard julliard@winehq.org --- Closing bugs fixed in 1.7.26.