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;