DSOUND: another buffer underrun patch
Jerry Jenkins
Jerry_J_Jenkins at hotmail.com
Sat Apr 5 08:57:58 CST 2003
Align data to IDirectSoundBufferImpl.wfx.nBlockAlign instead of 4 bytes.
If the size of primary buffer is 22050 bytes, the last two bytes won't
be mixed, because 22050 % 4 != 0.
With this patch, another problem of winealsa appears. WINAMP halts when
it try to play another file when a file is played or on demand. The
reason is that WINAMP creates the dsound buffer and setups the callback
function in a thread, but plays the buffer in another one. Although I am
not sure if it is a bug of WINE or ALSA, we can work around it by moving
the code that adds the callback from DSDB_CreateMMAP to
IDsDriverBufferImpl_Play.
Since the winealsa implement a fake HAL support - a callback will
transfer data from primary buffer to sound driver every time it is
called, expect incorrect results in some cases.
ChangeLog:
*dlls/dsound/mixer.c
- Align data to proper size.
-------------- next part --------------
Index: dlls/dsound/mixer.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/mixer.c,v
retrieving revision 1.10
diff -u -r1.10 mixer.c
--- dlls/dsound/mixer.c 17 Mar 2003 21:23:12 -0000 1.10
+++ dlls/dsound/mixer.c 5 Apr 2003 14:29:36 -0000
@@ -316,7 +316,7 @@
static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD fraglen)
{
- INT i, len, ilen, temp, field;
+ INT i, len, ilen, temp, field, nBlockAlign;
INT advance = dsb->dsound->wfx.wBitsPerSample >> 3;
BYTE *buf, *ibuf, *obuf;
INT16 *ibufs, *obufs;
@@ -329,10 +329,11 @@
dsb->nAvgBytesPerSec);
len = (len > temp) ? temp : len;
}
- len &= ~3; /* 4 byte alignment */
+ nBlockAlign = dsb->dsound->wfx.nBlockAlign;
+ len = len / nBlockAlign * nBlockAlign; /* data alignment */
if (len == 0) {
- /* This should only happen if we aren't looping and temp < 4 */
+ /* This should only happen if we aren't looping and temp < nBlockAlign */
return 0;
}
@@ -399,12 +400,13 @@
static void DSOUND_PhaseCancel(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD len)
{
- INT i, ilen, field;
+ INT i, ilen, field, nBlockAlign;
INT advance = dsb->dsound->wfx.wBitsPerSample >> 3;
BYTE *buf, *ibuf, *obuf;
INT16 *ibufs, *obufs;
- len &= ~3; /* 4 byte alignment */
+ nBlockAlign = dsb->dsound->wfx.nBlockAlign;
+ len = len / nBlockAlign * nBlockAlign; /* data alignment */
TRACE("allocating buffer (size = %ld)\n", len);
if ((buf = ibuf = (BYTE *) DSOUND_tmpbuffer(len)) == NULL)
More information about the wine-patches
mailing list