http://bugs.winehq.org/show_bug.cgi?id=23079
Jörg Höhle hoehle@users.sourceforge.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |hoehle@users.sourceforge.ne | |t
--- Comment #4 from Jörg Höhle hoehle@users.sourceforge.net 2013-03-01 03:47:44 CST --- Audio misbehaviour after a few days is still relevant, see http://www.winehq.org/pipermail/wine-devel/2013-February/098880.html There's also bug #26968 about foobar2000 stopping audio within 4-7 days.
An overflow can occur within each of Wine's 3 audio layers: mmdevapi, winmm and DSound. Some patches were committed or submitted recently and more are to come.
I distinguish internal from external (i.e. visible at the API) overflow. Some API function may overflow, e.g. GetPosition, yet the driver still produce steady output. Of course, API layering causes one layer's external API overflow (mmdevapi:GetPosition) to possibly break the next API's internal logic (e.g. winmm).
I instrumented the winmm/wave tests to play forever with 3 buffers.
- A w95 machine produced steady output for several days, despite several "missing WOM_DONE notification" (when the HD would resume from sleep?). Actually, I only listened from time to time, thus I don't know if the missed notifications caused a glitch.
- I aborted a Linux ALSA box after 1-2 days to compile more of Wine, audio output was good, no warning.
- After some while, MacOS 10.6.8 output clicked periodically as if playing from a single buffer. Some day later, there was no output at all. There were several "missing WOM_DONE notification". However, the Mac regularly entered suspend/resume cycles and that may have disturbed the tests. That driver needs more work.
This is part of the w95 log: Time is from GetTickCount() (i.e. milliseconds) wave.c:779: Playing 1 second 440Hz tone at 48000x16x2 3 headers 0 loops 192000 bytes WAVE_FORMAT_PCM CALLBACK_EVENT wave.c:519: waveOutGetPosition(0): TIME_MS not supported, returned TIME_SAMPLES wave.c:609: Test failed: At 200608 from -1 to 71940 bytes -- just wave.c:605: Test failed: At 200608 from -1 to 18059 samples-- starting wave.c:596: Test failed: At 200608 time format changed from 1 to 2, value 18131 -- no milliseconds wave.c:609: Test failed: At 22567671 from -47352 to 36724 bytes wave.c:605: Test failed: At 22567671 from 1073729992 to 9181 samples wave.c:605: Test failed: At 22567671 from 1073729996 to 9181 samples wave.c:850: Test failed: missing WOM_DONE notification [9 times] wave.c:609: Test failed: At 45142970 from -47312 to 49428 bytes wave.c:605: Test failed: At 45142970 from 1073729996 to 12357 samples wave.c:605: Test failed: At 45142970 from 1073729996 to 12357 samples wave.c:850: Test failed: missing WOM_DONE notification [many times] wave.c:609: Test failed: At 68401620 from -21908 to 56852 bytes wave.c:605: Test failed: At 68401620 from 1073736347 to 22528 samples wave.c:605: Test failed: At 68401620 from 1073736347 to 22528 samples [...] wave.c:609: Test failed: At 325172108 from -46132 to 25860 bytes wave.c:605: Test failed: At 325172108 from 1073730291 to 14464 samples wave.c:605: Test failed: At 325172108 from 1073730291 to 14464 samples
As you can see, w95 counts in bytes and derives samples from bytes. As the byte counter overflows, the number of samples is reset, never reaching the 32bit limit! Apps playing for several days must consider that.
As the writer of an app playing with some unknown ACM codec, I would not know how far I am when using samples. With bytes, I could add 2^32 when detecting a wrap-around -- or write my code such that wrap-arounds don't cause breaks.
Linux counts differently: wave.c:779: Playing 1 second 440Hz tone at 96000x16x2 3 headers 0 loops 384000 bytes WAVE_FORMAT_PCM CALLBACK_EVENT wave.c:609: Test failed: At 692163206 from -1 to 194048 bytes wave.c:605: Test failed: At 692163206 from -1 to 48512 samples wave.c:601: Test failed: At 692163206 from -1 to 505 ms wave.c:609: Test failed: At 703348338 from -109056 to 13824 bytes wave.c:609: Test failed: At 714533348 from -43520 to 87552 bytes wave.c:609: Test failed: At 725717953 from -100864 to 30208 bytes wave.c:609: Test failed: At 736904392 from -18944 to 103936 bytes wave.c:605: Test failed: At 736904392 from -4736 to 25984 samples wave.c:601: Test failed: At 736904392 from 44739193 to 270 ms - simultaneously wave.c:609: Test failed: At 748089576 from -76288 to 46592 bytes wave.c:609: Test failed: At 759274628 from -10752 to 120320 bytes
You see that Linux counts in samples. Bytes grow 4 times faster and overflow more often. time_ms is derived from samples and reset as samples overflow, never growing beyond 45 million milliseconds despite playing longer.
I want to perform more tests and check whether winmm:wave* GetPosition supports milliseconds at all, even on w7.