[DSOUND] block align buffer sizes (revised)

Robert Reif reif at earthlink.net
Tue Feb 15 19:02:25 CST 2005


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.
-------------- next part --------------
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);


More information about the wine-patches mailing list