Robert Reif wrote:
Make sure buffer sizes are a multiple of the block align size.
Fixed invalid buffer size by rounding up to next multiple of nBlockAlign. Added test to verify buffer rounding behavior.
Index: dlls/dsound/buffer.c =================================================================== RCS file: /home/wine/wine/dlls/dsound/buffer.c,v retrieving revision 1.46 diff -u -p -r1.46 buffer.c --- dlls/dsound/buffer.c 11 Feb 2005 11:49:05 -0000 1.46 +++ dlls/dsound/buffer.c 16 Feb 2005 00:55:58 -0000 @@ -1060,9 +1060,14 @@ HRESULT WINAPI IDirectSoundBufferImpl_Cr
CopyMemory(dsb->pwfx, wfex, cp_size);
- dsb->buflen = dsbd->dwBufferBytes; - dsb->freq = dsbd->lpwfxFormat->nSamplesPerSec; + if (dsbd->dwBufferBytes % dsbd->lpwfxFormat->nBlockAlign) + dsb->buflen = dsbd->dwBufferBytes + + (dsbd->lpwfxFormat->nBlockAlign - + (dsbd->dwBufferBytes % dsbd->lpwfxFormat->nBlockAlign)); + else + dsb->buflen = dsbd->dwBufferBytes;
+ dsb->freq = dsbd->lpwfxFormat->nSamplesPerSec; dsb->notify = NULL; dsb->notifies = NULL; dsb->nrofnotifies = 0; Index: dlls/dsound/tests/ds3d.c =================================================================== RCS file: /home/wine/wine/dlls/dsound/tests/ds3d.c,v retrieving revision 1.19 diff -u -p -r1.19 ds3d.c --- dlls/dsound/tests/ds3d.c 10 Feb 2005 20:26:20 -0000 1.19 +++ dlls/dsound/tests/ds3d.c 16 Feb 2005 00:56:00 -0000 @@ -713,7 +713,8 @@ static HRESULT test_secondary(LPGUID lpG else bufdesc.dwFlags|= (DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN); - bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000; + bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, + wfx.nBlockAlign); bufdesc.lpwfxFormat=&wfx; if (winetest_interactive) { trace(" Testing a %s%ssecondary buffer %s%s%s%sat %ldx%dx%d " Index: dlls/dsound/tests/ds3d8.c =================================================================== RCS file: /home/wine/wine/dlls/dsound/tests/ds3d8.c,v retrieving revision 1.14 diff -u -p -r1.14 ds3d8.c --- dlls/dsound/tests/ds3d8.c 10 Feb 2005 21:21:13 -0000 1.14 +++ dlls/dsound/tests/ds3d8.c 16 Feb 2005 00:56:00 -0000 @@ -615,7 +615,8 @@ static HRESULT test_secondary8(LPGUID lp else bufdesc.dwFlags|= (DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN); - bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000; + bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, + wfx.nBlockAlign); bufdesc.lpwfxFormat=&wfx; if (has_3d) { /* a stereo 3D buffer should fail */ Index: dlls/dsound/tests/dsound.c =================================================================== RCS file: /home/wine/wine/dlls/dsound/tests/dsound.c,v retrieving revision 1.45 diff -u -p -r1.45 dsound.c --- dlls/dsound/tests/dsound.c 10 Feb 2005 20:26:20 -0000 1.45 +++ dlls/dsound/tests/dsound.c 16 Feb 2005 00:56:01 -0000 @@ -305,7 +305,8 @@ static HRESULT test_dsound(LPGUID lpGuid ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D; - bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000; + bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, + wfx.nBlockAlign); bufdesc.lpwfxFormat=&wfx; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DS_OK && secondary!=NULL, @@ -573,7 +574,8 @@ static HRESULT test_primary_secondary(LP ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; - bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000; + bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, + wfx.nBlockAlign); bufdesc.lpwfxFormat=&wfx2; if (winetest_interactive) { trace(" Testing a primary buffer at %ldx%dx%d with a " @@ -672,7 +674,8 @@ static HRESULT test_secondary(LPGUID lpG ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; - bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000; + bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, + wfx.nBlockAlign); rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DSERR_INVALIDPARAM,"IDirectSound_CreateSoundBuffer() " "should have returned DSERR_INVALIDPARAM, returned: %s\n", @@ -684,7 +687,8 @@ static HRESULT test_secondary(LPGUID lpG ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; - bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000; + bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, + wfx.nBlockAlign); bufdesc.lpwfxFormat=&wfx; if (winetest_interactive) { trace(" Testing a secondary buffer at %ldx%dx%d " @@ -727,6 +731,53 @@ EXIT: return rc; }
+static HRESULT test_block_align(LPGUID lpGuid) +{ + HRESULT rc; + LPDIRECTSOUND dso=NULL; + LPDIRECTSOUNDBUFFER secondary=NULL; + DSBUFFERDESC bufdesc; + DSBCAPS dsbcaps; + WAVEFORMATEX wfx; + int ref; + + /* Create the DirectSound object */ + rc=DirectSoundCreate(lpGuid,&dso,NULL); + ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED, + "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc)); + if (rc!=DS_OK) + return rc; + + init_format(&wfx,WAVE_FORMAT_PCM,11025,16,2); + ZeroMemory(&bufdesc, sizeof(bufdesc)); + bufdesc.dwSize=sizeof(bufdesc); + bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; + bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec + 1; + bufdesc.lpwfxFormat=&wfx; + rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); + ok(rc==DS_OK,"IDirectSound_CreateSoundBuffer() " + "should have returned DS_OK, returned: %s\n", + DXGetErrorString8(rc)); + + if (rc==DS_OK && secondary!=NULL) { + rc=IDirectSoundBuffer_GetCaps(secondary,&dsbcaps); + ok(rc==DS_OK,"IDirectSoundBuffer_GetCaps() should have returned DS_OK, " + "returned: %s\n", DXGetErrorString8(rc)); + ok(dsbcaps.dwBufferBytes==(wfx.nAvgBytesPerSec + 4), + "Buffer size not a multiple of nBlockAlign\n"); + ref=IDirectSoundBuffer_Release(secondary); + ok(ref==0,"IDirectSoundBuffer_Release() secondary has %d references, " + "should have 0\n",ref); + } + + ref=IDirectSound_Release(dso); + ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); + if (ref!=0) + return DSERR_GENERIC; + + return rc; +} + static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext) { @@ -738,6 +789,7 @@ static BOOL WINAPI dsenum_callback(LPGUI else if (rc == DSERR_ALLOCATED) trace(" Already In Use\n"); else { + test_block_align(lpGuid); test_primary(lpGuid); test_primary_secondary(lpGuid); test_secondary(lpGuid); Index: dlls/dsound/tests/dsound8.c =================================================================== RCS file: /home/wine/wine/dlls/dsound/tests/dsound8.c,v retrieving revision 1.15 diff -u -p -r1.15 dsound8.c --- dlls/dsound/tests/dsound8.c 10 Feb 2005 20:26:20 -0000 1.15 +++ dlls/dsound/tests/dsound8.c 16 Feb 2005 00:56:02 -0000 @@ -38,6 +38,11 @@
static HRESULT (WINAPI *pDirectSoundCreate8)(LPCGUID,LPDIRECTSOUND8*,LPUNKNOWN)=NULL;
+int align(int length, int align) +{ + return (length / align) * align; +} + static void IDirectSound8_test(LPDIRECTSOUND8 dso, BOOL initialized, LPCGUID lpGuid) { @@ -315,7 +320,8 @@ static HRESULT test_dsound8(LPGUID lpGui ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D; - bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000; + bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, + wfx.nBlockAlign); bufdesc.lpwfxFormat=&wfx; rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DS_OK && secondary!=NULL, @@ -594,7 +600,8 @@ static HRESULT test_primary_secondary8(L ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; - bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000; + bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, + wfx.nBlockAlign); bufdesc.lpwfxFormat=&wfx2; if (winetest_interactive) { trace(" Testing a primary buffer at %ldx%dx%d with a " @@ -693,7 +700,8 @@ static HRESULT test_secondary8(LPGUID lp ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; - bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000; + bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, + wfx.nBlockAlign); rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() " "should have returned DSERR_INVALIDPARAM, returned: %s\n", @@ -705,7 +713,8 @@ static HRESULT test_secondary8(LPGUID lp ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; - bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000; + bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, + wfx.nBlockAlign); bufdesc.lpwfxFormat=&wfx; if (winetest_interactive) { trace(" Testing a secondary buffer at %ldx%dx%d " Index: dlls/dsound/tests/dsound_test.h =================================================================== RCS file: /home/wine/wine/dlls/dsound/tests/dsound_test.h,v retrieving revision 1.6 diff -u -p -r1.6 dsound_test.h --- dlls/dsound/tests/dsound_test.h 13 Dec 2004 21:19:02 -0000 1.6 +++ dlls/dsound/tests/dsound_test.h 16 Feb 2005 00:56:02 -0000 @@ -50,7 +50,6 @@ static const unsigned int formats[][4]={ #define TIME_SLICE 31 #define BUFFER_LEN 400
- extern char* wave_generate_la(WAVEFORMATEX*,double,DWORD*); extern HWND get_hwnd(void); extern void init_format(WAVEFORMATEX*,int,int,int,int); @@ -61,3 +60,4 @@ extern void test_buffer8(LPDIRECTSOUND8, BOOL,BOOL,LONG,BOOL,LONG,BOOL,double,BOOL, LPDIRECTSOUND3DLISTENER,BOOL,BOOL); extern const char * getDSBCAPS(DWORD xmask); +extern int align(int length, int align);