http://bugs.winehq.org/show_bug.cgi?id=28723
--- Comment #128 from Jörg Höhle hoehle@users.sourceforge.net 2012-02-04 02:45:08 CST --- Well, I've a simple explanation for the crackling sound that my audible worst_case/Xaudio2 test attached to bug #27937 produces. I always thought it would explain stuttering (as in the subject line of this bug) but I perceive it as crackling instead (as in the subject line of bug #28856).
If my test_worst case really replicates XAudio2 behaviour, that would explain crackling in all apps that use XAudio2 (i.e. w7 xact audio insead of xp DSound).
Case 1: render.c:Released 48000=100x480 -480 frames at 48000 worth 990ms in 1196ms Here CreateEventTimer delivers events every 12ms -- always late. As test_worst_case never writes more than one (10ms) period, audio hits an underrun every few periods. This cause a crackling sound partly covering the sine tone. Crackling is almost continuous.
Case 2: render.c:Released 48000=100x480 -480 frames at 48000 worth 990ms in 1009ms On this machine, CreateEventTimer delivers events every 10ms like we asked. However, because event delivery is not synchronized to the audio clock, there may be times where GetCurrentPadding is larger than one period. Every such time, test_worst_case won't write data. There will be a hole, resulting in an underrun and crackling some timer later.
Case 3: render.c:Released 40320=84x480 -960 frames at 48000 worth 820ms in 789ms Here I cheated on the 12ms timer machine, using CreateTimerQueue(period_ms -3), resulting in timer callbacks 8ms apart. In that case, not writing a period full of samples was not harmful, as it would likely be written at the next timer event. That's why only 84 periods were written in that case, despite receiving 100 events. The result is a continuous sine, without crackling.
I consider the algorithm "write one period if padding is less or equal to one period" to be stupid, because it doesn' take clock skew into account. Or it hints that native's doesn't deliver events like we do.