http://bugs.winehq.org/show_bug.cgi?id=14717
--- Comment #153 from Raymond superquad.vortex2@gmail.com 2011-02-22 19:54:19 CST --- (In reply to comment #151)
DSound may be not designed for playing high-quality music, but even the highest-quality resampler in the patch easily fits the latency budget that you imply by saying "dsound has to use small period size (I guess is 10ms) and try to mix the new sound effect and play them out as soon as possible".
As for the acceptable tradeoffs in terms of CPU/latency/quality, I think they need to be discussed, otherwise someone will be able to say "mixing must be as fast as possible, so let's convert anything to 8 bits for performance reasons" (and that's in the same realm of strawman arguments as your suggestion to use a zero-order-hold resampler). My viewpoint is that wine either must provide the same resampling quality & latency as Windows does for DirectSound apps, or use the system's mixer/resampler and thus have the same characteristics as linux sound apps.
The main problem is dsound did not correctly caclulated the number of period , period size and buffer size
You can see the above examples, some sound cards have 128K byte , 64K bytes or 32 Kbytes Buffer,
when winealsa.drv try to set a buffer time of 0.5 seconds for 44100 S16 stereo, it will get 371ms buffer for those sound cards with 64K Bytes buffer , but when you will get a different buffer times when the application select a different rate or U8 or mono
since oss use a power of two frag size, wineoss.drv is usually better than winealsa.drv when using emulation
bug#8668
if you search wine-developer mailing list archive, you will find many wine developer had said they will fix this issue
http://www.intel.com/support/motherboards/desktop/sb/cs-020642.htm#multistre...
you can also use dsound in foobar2000 to play audio to the front panel headphone if your hda-intel codec have the extra DAC for multistream playback
Take a look at dsound/primary.c
DWORD DSOUND_fraglen(DWORD nSamplesPerSec, DWORD nBlockAlign) { /* Given a timer delay of 10ms, the fragment size is approximately: * fraglen = (nSamplesPerSec * 10 / 1000) * nBlockAlign * ==> fraglen = (nSamplesPerSec / 100) * nBlockSize * * ALSA uses buffers that are powers of 2. Because of this, fraglen * is rounded up to the nearest power of 2: */
if (nSamplesPerSec <= 12800) return 128 * nBlockAlign;
if (nSamplesPerSec <= 25600) return 256 * nBlockAlign;
if (nSamplesPerSec <= 51200) return 512 * nBlockAlign;
return 1024 * nBlockAlign; }
static void DSOUND_RecalcPrimary(DirectSoundDevice *device) { TRACE("(%p)\n", device);
device->helfrags = device->buflen / device->fraglen; TRACE("fraglen=%d helfrags=%d\n", device->fraglen, device->helfrags);
if (device->hwbuf && device->drvdesc.dwFlags & DSDDESC_DONTNEEDWRITELEAD) device->writelead = 0; else /* calculate the 10ms write lead */ device->writelead = (device->pwfx->nSamplesPerSec / 100) * device->pwfx->nBlockAlign; }