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.
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)