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