dsound wave format patch

Robert Reif reif at earthlink.net
Tue Aug 17 18:50:18 CDT 2004


Allocate wave format structure dynamically based on format.
Remove format checks to allow driver to decide if format supported.
Code cleanups.
-------------- next part --------------
Index: dlls/dsound/buffer.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/buffer.c,v
retrieving revision 1.30
diff -u -r1.30 buffer.c
--- dlls/dsound/buffer.c	16 Aug 2004 19:59:54 -0000	1.30
+++ dlls/dsound/buffer.c	17 Aug 2004 23:45:41 -0000
@@ -161,7 +161,7 @@
     IDirectSoundNotifyImpl * dsn;
     TRACE("(%p,%p)\n",dsb,pdsn);
 
-    dsn = (IDirectSoundNotifyImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dsn));
+    dsn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dsn));
 
     if (dsn == NULL) {
         WARN("out of memory\n");
@@ -285,7 +285,7 @@
 	}
 
 	if (freq == DSBFREQUENCY_ORIGINAL)
-		freq = This->wfx.nSamplesPerSec;
+		freq = This->pwfx->nSamplesPerSec;
 
 	if ((freq < DSBFREQUENCY_MIN) || (freq > DSBFREQUENCY_MAX)) {
 		WARN("invalid parameter: freq = %ld\n", freq);
@@ -298,8 +298,8 @@
 	oldFreq = This->freq;
 	This->freq = freq;
 	if (freq != oldFreq) {
-		This->freqAdjust = (freq << DSOUND_FREQSHIFT) / This->dsound->wfx.nSamplesPerSec;
-		This->nAvgBytesPerSec = freq * This->wfx.nBlockAlign;
+		This->freqAdjust = (freq << DSOUND_FREQSHIFT) / This->dsound->pwfx->nSamplesPerSec;
+		This->nAvgBytesPerSec = freq * This->pwfx->nBlockAlign;
 		DSOUND_RecalcFormat(This);
 		if (!This->hwbuf)
 			DSOUND_ForceRemix(This);
@@ -432,6 +432,9 @@
 	if (This->notifies != NULL)
 		HeapFree(GetProcessHeap(), 0, This->notifies);
 
+	if (This->pwfx)
+		HeapFree(GetProcessHeap(), 0, This->pwfx);
+
 	HeapFree(GetProcessHeap(),0,This);
 
 	TRACE("(%p) released\n",This);
@@ -469,12 +472,12 @@
 		pmix = 0;
 	}
 	/* divide the offset by its sample size */
-	pmix /= This->dsound->wfx.nBlockAlign;
+	pmix /= This->dsound->pwfx->nBlockAlign;
 	TRACE("primary back-samples=%ld\n",pmix);
 	/* adjust for our frequency */
 	pmix = (pmix * This->freqAdjust) >> DSOUND_FREQSHIFT;
 	/* multiply by our own sample size */
-	pmix *= This->wfx.nBlockAlign;
+	pmix *= This->pwfx->nBlockAlign;
 	TRACE("this back-offset=%ld\n", pmix);
 	/* subtract from our last mixed position */
 	bplay = bmix;
@@ -501,13 +504,11 @@
 		    WARN("IDsDriverBuffer_GetPosition failed\n");
 		    return hres;
 		}
-	}
-	else {
+	} else {
 		if (playpos && (This->state != STATE_PLAYING)) {
 			/* we haven't been merged into the primary buffer (yet) */
 			*playpos = This->buf_mixpos;
-		}
-		else if (playpos) {
+		} else if (playpos) {
 			DWORD pplay, pwrite, lplay, splay, pstate;
 			/* let's get this exact; first, recursively call GetPosition on the primary */
 			EnterCriticalSection(&(This->dsound->mixlock));
@@ -538,21 +539,23 @@
 				/* let's just do what might work for Half-Life */
 				DWORD wp;
 				wp = (This->dsound->pwplay + ds_hel_margin) * This->dsound->fraglen;
-				while (wp >= This->dsound->buflen)
-					wp -= This->dsound->buflen;
+				wp %= This->dsound->buflen;
 				*playpos = DSOUND_CalcPlayPosition(This, pstate, wp, pwrite, lplay, splay);
 			}
 			LeaveCriticalSection(&(This->dsound->mixlock));
 		}
-		if (writepos) *writepos = This->buf_mixpos;
+		if (writepos)
+                    *writepos = This->buf_mixpos;
 	}
 	if (writepos) {
-		if (This->state != STATE_STOPPED)
+		if (This->state != STATE_STOPPED) {
 			/* apply the documented 10ms lead to writepos */
 			*writepos += This->writelead;
-		while (*writepos >= This->buflen) *writepos -= This->buflen;
+		}
+		*writepos %= This->buflen;
 	}
-	if (playpos) This->last_playpos = *playpos;
+	if (playpos)
+            This->last_playpos = *playpos;
 	TRACE("playpos = %ld, writepos = %ld (%p, time=%ld)\n", playpos?*playpos:0, writepos?*writepos:0, This, GetTickCount());
 	return DS_OK;
 }
@@ -581,27 +584,38 @@
 
 
 static HRESULT WINAPI IDirectSoundBufferImpl_GetFormat(
-	LPDIRECTSOUNDBUFFER8 iface,LPWAVEFORMATEX lpwf,DWORD wfsize,LPDWORD wfwritten
-) {
-	ICOM_THIS(IDirectSoundBufferImpl,iface);
-	TRACE("(%p,%p,%ld,%p)\n",This,lpwf,wfsize,wfwritten);
-
-	if (wfsize>sizeof(This->wfx))
-		wfsize = sizeof(This->wfx);
-	if (lpwf) {	/* NULL is valid */
-		memcpy(lpwf,&(This->wfx),wfsize);
-		if (wfwritten)
-			*wfwritten = wfsize;
-	} else {
-		if (wfwritten)
-			*wfwritten = sizeof(This->wfx);
-		else {
-			WARN("invalid parameter: wfwritten == NULL\n");
-			return DSERR_INVALIDPARAM;
-		}
-	}
+    LPDIRECTSOUNDBUFFER8 iface,
+    LPWAVEFORMATEX lpwf,
+    DWORD wfsize,
+    LPDWORD wfwritten)
+{
+    DWORD size;
+    ICOM_THIS(IDirectSoundBufferImpl,iface);
+    TRACE("(%p,%p,%ld,%p)\n",This,lpwf,wfsize,wfwritten);
+
+    size = sizeof(WAVEFORMATEX) + This->pwfx->cbSize;
+
+    if (lpwf) { /* NULL is valid */
+        if (wfsize >= size) {
+            memcpy(lpwf,This->pwfx,size);
+            if (wfwritten)
+                *wfwritten = size;
+        } else {
+            WARN("invalid parameter: wfsize to small\n");
+            if (wfwritten)
+                *wfwritten = 0;
+            return DSERR_INVALIDPARAM;
+        }
+    } else {
+        if (wfwritten)
+            *wfwritten = sizeof(WAVEFORMATEX) + This->pwfx->cbSize;
+        else {
+            WARN("invalid parameter: wfwritten == NULL\n");
+            return DSERR_INVALIDPARAM;
+        }
+    }
 
-	return DS_OK;
+    return DS_OK;
 }
 
 static HRESULT WINAPI IDirectSoundBufferImpl_Lock(
@@ -632,8 +646,7 @@
 		}
 		writecursor += writepos;
 	}
-	while (writecursor >= This->buflen)
-		writecursor -= This->buflen;
+	writecursor %= This->buflen;
 	if (flags & DSBLOCK_ENTIREBUFFER)
 		writebytes = This->buflen;
 	if (writebytes > This->buflen)
@@ -691,8 +704,7 @@
 				if (This->buf_mixpos > writecursor &&
 				    This->last_playpos < writecursor+writebytes)
 					remix = TRUE;
-			}
-			else {
+			} else {
 				if (This->buf_mixpos > writecursor ||
 				    This->last_playpos < writecursor+writebytes)
 					remix = TRUE;
@@ -718,8 +730,7 @@
 	/* **** */
 	EnterCriticalSection(&(This->lock));
 
-	while (newpos >= This->buflen)
-		newpos -= This->buflen;
+	newpos %= This->buflen;
 	This->buf_mixpos = newpos;
 	if (This->hwbuf) {
 		hres = IDsDriverBuffer_SetPosition(This->hwbuf, This->buf_mixpos);
@@ -803,10 +814,14 @@
 
 	TRACE("(%p,%p,%ld,%p,%ld)\n", This,p1,x1,p2,x2);
 
+	/* **** */
+	EnterCriticalSection(&(This->lock));
+
 	if (!(This->dsound->drvdesc.dwFlags & DSDDESC_DONTNEEDSECONDARYLOCK) && This->hwbuf) {
 		HRESULT hres;
 		hres = IDsDriverBuffer_Unlock(This->hwbuf, p1, x1, p2, x2);
 		if (hres != DS_OK) {
+			LeaveCriticalSection(&(This->lock));
 			WARN("IDsDriverBuffer_Unlock failed\n");
 			return hres;
 		}
@@ -814,8 +829,7 @@
 
 	if (p2) probably_valid_to = (((LPBYTE)p2)-This->buffer->memory) + x2;
 	else probably_valid_to = (((LPBYTE)p1)-This->buffer->memory) + x1;
-	while (probably_valid_to >= This->buflen)
-		probably_valid_to -= This->buflen;
+	probably_valid_to %= This->buflen;
 	if ((probably_valid_to == 0) && ((x1+x2) == This->buflen) &&
 	    ((This->state == STATE_STARTING) ||
 	     (This->state == STATE_PLAYING)))
@@ -823,6 +837,10 @@
 		probably_valid_to = (DWORD)-1;
 	This->probably_valid_to = probably_valid_to;
 
+	LeaveCriticalSection(&(This->lock));
+	/* **** */
+
+	TRACE("probably_valid_to=%ld\n", This->probably_valid_to);
 	return DS_OK;
 }
 
@@ -1052,7 +1070,7 @@
 	LPWAVEFORMATEX wfex = dsbd->lpwfxFormat;
 	HRESULT err = DS_OK;
 	DWORD capf = 0;
-	int use_hw;
+	int use_hw, alloc_size, cp_size;
 	TRACE("(%p,%p,%p)\n",ds,pdsb,dsbd);
 
 	if (dsbd->dwBufferBytes < DSBSIZE_MIN || dsbd->dwBufferBytes > DSBSIZE_MAX) {
@@ -1061,24 +1079,41 @@
 		return DSERR_INVALIDPARAM; /* FIXME: which error? */
 	}
 
-	dsb = (IDirectSoundBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
+	dsb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
 
 	if (dsb == 0) {
 		WARN("out of memory\n");
 		*pdsb = NULL;
 		return DSERR_OUTOFMEMORY;
 	}
+
+	TRACE("Created buffer at %p\n", dsb);
+
 	dsb->ref = 0;
 	dsb->dsb = 0;
 	dsb->dsound = ds;
 	dsb->lpVtbl = &dsbvt;
 	dsb->iks = NULL;
 
-	memcpy(&dsb->dsbd, dsbd, sizeof(*dsbd));
-	if (wfex)
-		memcpy(&dsb->wfx, wfex, sizeof(dsb->wfx));
+	/* size depends on version */
+	memcpy(&dsb->dsbd, dsbd, dsbd->dwSize);
 
-	TRACE("Created buffer at %p\n", dsb);
+	/* variable sized struct so calculate size based on format */
+	if (wfex->wFormatTag == WAVE_FORMAT_PCM) {
+		alloc_size = sizeof(WAVEFORMATEX);
+		cp_size = sizeof(PCMWAVEFORMAT);
+	} else 
+		alloc_size = cp_size = sizeof(WAVEFORMATEX) + wfex->cbSize;
+
+	dsb->pwfx = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,alloc_size);
+	if (dsb->pwfx == NULL) {
+		WARN("out of memory\n");
+		HeapFree(GetProcessHeap(),0,dsb);
+		*pdsb = NULL;
+		return DSERR_OUTOFMEMORY;
+	}
+
+	memcpy(dsb->pwfx, wfex, cp_size);
 
 	dsb->buflen = dsbd->dwBufferBytes;
 	dsb->freq = dsbd->lpwfxFormat->nSamplesPerSec;
@@ -1107,14 +1142,16 @@
 		dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer)));
 		if (dsb->buffer == NULL) {
 			WARN("out of memory\n");
+			HeapFree(GetProcessHeap(),0,dsb->pwfx);
 			HeapFree(GetProcessHeap(),0,dsb);
 			*pdsb = NULL;
 			return DSERR_OUTOFMEMORY;
 		}
 
-		dsb->buffer->memory = (LPBYTE)HeapAlloc(GetProcessHeap(),0,dsb->buflen);
+		dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen);
 		if (dsb->buffer->memory == NULL) {
 			WARN("out of memory\n");
+			HeapFree(GetProcessHeap(),0,dsb->pwfx);
 			HeapFree(GetProcessHeap(),0,dsb->buffer);
 			HeapFree(GetProcessHeap(),0,dsb);
 			*pdsb = NULL;
@@ -1136,15 +1173,17 @@
 				dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer)));
 				if (dsb->buffer == NULL) {
 					WARN("out of memory\n");
+					HeapFree(GetProcessHeap(),0,dsb->pwfx);
 					HeapFree(GetProcessHeap(),0,dsb);
 					*pdsb = NULL;
 					return DSERR_OUTOFMEMORY;
 				}
 
-				dsb->buffer->memory = (LPBYTE)HeapAlloc(GetProcessHeap(),0,dsb->buflen);
+				dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen);
 				if (dsb->buffer->memory == NULL) {
 					WARN("out of memory\n");
 					HeapFree(GetProcessHeap(),0,dsb->buffer);
+					HeapFree(GetProcessHeap(),0,dsb->pwfx);
 					HeapFree(GetProcessHeap(),0,dsb);
 					*pdsb = NULL;
 					return DSERR_OUTOFMEMORY;
@@ -1164,7 +1203,7 @@
 	dsb->state = STATE_STOPPED;
 
 	dsb->freqAdjust = (dsb->freq << DSOUND_FREQSHIFT) /
-		ds->wfx.nSamplesPerSec;
+		ds->pwfx->nSamplesPerSec;
 	dsb->nAvgBytesPerSec = dsb->freq *
 		dsbd->lpwfxFormat->nBlockAlign;
 
@@ -1199,9 +1238,9 @@
 	if (!(dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER)) {
 		IDirectSoundBufferImpl **newbuffers;
 		if (ds->buffers)
-			newbuffers = (IDirectSoundBufferImpl**)HeapReAlloc(GetProcessHeap(),0,ds->buffers,sizeof(IDirectSoundBufferImpl*)*(ds->nrofbuffers+1));
+			newbuffers = HeapReAlloc(GetProcessHeap(),0,ds->buffers,sizeof(IDirectSoundBufferImpl*)*(ds->nrofbuffers+1));
 		else
-			newbuffers = (IDirectSoundBufferImpl**)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBufferImpl*)*(ds->nrofbuffers+1));
+			newbuffers = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBufferImpl*)*(ds->nrofbuffers+1));
 
 		if (newbuffers) {
 			ds->buffers = newbuffers;
@@ -1216,6 +1255,7 @@
 				HeapFree(GetProcessHeap(),0,dsb->buffer);
 			DeleteCriticalSection(&(dsb->lock));
 			RtlReleaseResource(&(ds->lock));
+			HeapFree(GetProcessHeap(),0,dsb->pwfx);
 			HeapFree(GetProcessHeap(),0,dsb);
 			*pdsb = NULL;
 			return DSERR_OUTOFMEMORY;
@@ -1545,7 +1585,7 @@
 	SecondaryBufferImpl *sb;
 	TRACE("(%p,%p)\n",dsb,psb);
 
-	sb = (SecondaryBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*sb));
+	sb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*sb));
 
 	if (sb == 0) {
 		WARN("out of memory\n");
Index: dlls/dsound/capture.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/capture.c,v
retrieving revision 1.27
diff -u -r1.27 capture.c
--- dlls/dsound/capture.c	16 Aug 2004 19:59:37 -0000	1.27
+++ dlls/dsound/capture.c	17 Aug 2004 23:45:42 -0000
@@ -134,7 +134,7 @@
     if ( !lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL) ) 
 	lpcGUID = &DSDEVID_DefaultCapture;
 
-    *ippDSC = (IDirectSoundCaptureImpl*)HeapAlloc(GetProcessHeap(),
+    *ippDSC = HeapAlloc(GetProcessHeap(),
         HEAP_ZERO_MEMORY, sizeof(IDirectSoundCaptureImpl));
 
     if (*ippDSC == NULL) {
@@ -769,9 +769,9 @@
 	    buflen = lpcDSCBufferDesc->dwBufferBytes;
             TRACE("desired buflen=%ld, old buffer=%p\n", buflen, ipDSC->buffer);
 	    if (ipDSC->buffer)
-                newbuf = (LPBYTE)HeapReAlloc(GetProcessHeap(),0,ipDSC->buffer,buflen);
+                newbuf = HeapReAlloc(GetProcessHeap(),0,ipDSC->buffer,buflen);
 	    else
-		newbuf = (LPBYTE)HeapAlloc(GetProcessHeap(),0,buflen);	    
+		newbuf = HeapAlloc(GetProcessHeap(),0,buflen);	    
             if (newbuf == NULL) {
                 WARN("failed to allocate capture buffer\n");
                 err = DSERR_OUTOFMEMORY;
@@ -905,7 +905,7 @@
     IDirectSoundCaptureNotifyImpl * dscn;
     TRACE("(%p,%p)\n",dscb,pdscn);
 
-    dscn = (IDirectSoundCaptureNotifyImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dscn));
+    dscn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dscn));
 
     if (dscn == NULL) {
 	WARN("out of memory\n");
@@ -1736,7 +1736,7 @@
         return DSERR_NOAGGREGATION;
     }
 
-    *ippDSFD = (IDirectSoundFullDuplexImpl*)HeapAlloc(GetProcessHeap(),
+    *ippDSFD = HeapAlloc(GetProcessHeap(),
 	HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
 
     if (*ippDSFD == NULL) {
Index: dlls/dsound/dsound.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/dsound.c,v
retrieving revision 1.13
diff -u -r1.13 dsound.c
--- dlls/dsound/dsound.c	12 Aug 2004 23:00:58 -0000	1.13
+++ dlls/dsound/dsound.c	17 Aug 2004 23:45:43 -0000
@@ -467,6 +467,7 @@
     IDirectSoundBufferImpl* pdsb;
     IDirectSoundBufferImpl* dsb;
     HRESULT hres = DS_OK;
+    int size;
     ICOM_THIS(IDirectSoundImpl,iface);
 
     TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
@@ -553,7 +554,21 @@
     dsb->ds3db = NULL;
     dsb->iks = NULL; /* FIXME? */
     dsb->dsb = NULL;
-    memcpy(&(dsb->wfx), &(pdsb->wfx), sizeof(dsb->wfx));
+
+    /* variable sized struct so calculate size based on format */
+    size = sizeof(WAVEFORMATEX) + pdsb->pwfx->cbSize;
+
+    dsb->pwfx = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size);
+    if (dsb->pwfx == NULL) {
+            WARN("out of memory\n");
+            HeapFree(GetProcessHeap(),0,dsb->buffer);
+            HeapFree(GetProcessHeap(),0,dsb);
+            *ppdsb = NULL;
+            return DSERR_OUTOFMEMORY;
+    }
+
+    memcpy(dsb->pwfx, pdsb->pwfx, size);
+
     InitializeCriticalSection(&(dsb->lock));
     dsb->lock.DebugInfo->Spare[1] = (DWORD)"DSOUNDBUFFER_lock";
     /* register buffer */
@@ -575,6 +590,8 @@
             IDirectSoundBuffer8_Release(psb);
             DeleteCriticalSection(&(dsb->lock));
             RtlReleaseResource(&(This->lock));
+            HeapFree(GetProcessHeap(),0,dsb->buffer);
+            HeapFree(GetProcessHeap(),0,dsb->pwfx);
             HeapFree(GetProcessHeap(),0,dsb);
             *ppdsb = 0;
             return DSERR_OUTOFMEMORY;
@@ -821,9 +838,9 @@
         err = IDsDriver_GetDriverDesc(drv,&(pDS->drvdesc));
         if (err != DS_OK) {
             WARN("IDsDriver_GetDriverDesc failed\n");
-                 HeapFree(GetProcessHeap(),0,pDS);
-                 *ppDS = NULL;
-                 return err;
+            HeapFree(GetProcessHeap(),0,pDS);
+            *ppDS = NULL;
+            return err;
         }
     } else {
         /* if no DirectSound interface available, use WINMM API instead */
@@ -833,17 +850,25 @@
     pDS->drvdesc.dnDevNode = wod;
 
     /* Set default wave format (may need it for waveOutOpen) */
-    pDS->wfx.wFormatTag = WAVE_FORMAT_PCM;
+    pDS->pwfx = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEFORMATEX));
+    if (pDS->pwfx == NULL) {
+        WARN("out of memory\n");
+        HeapFree(GetProcessHeap(),0,pDS);
+        *ppDS = NULL;
+        return DSERR_OUTOFMEMORY;
+    }
+
+    pDS->pwfx->wFormatTag = WAVE_FORMAT_PCM;
     /* We rely on the sound driver to return the actual sound format of
      * the device if it does not support 22050x8x2 and is given the
      * WAVE_DIRECTSOUND flag.
      */
-    pDS->wfx.nSamplesPerSec = 22050;
-    pDS->wfx.wBitsPerSample = 8;
-    pDS->wfx.nChannels = 2;
-    pDS->wfx.nBlockAlign = pDS->wfx.wBitsPerSample * pDS->wfx.nChannels / 8;
-    pDS->wfx.nAvgBytesPerSec = pDS->wfx.nSamplesPerSec * pDS->wfx.nBlockAlign;
-    pDS->wfx.cbSize = 0;
+    pDS->pwfx->nSamplesPerSec = 22050;
+    pDS->pwfx->wBitsPerSample = 8;
+    pDS->pwfx->nChannels = 2;
+    pDS->pwfx->nBlockAlign = pDS->pwfx->wBitsPerSample * pDS->pwfx->nChannels / 8;
+    pDS->pwfx->nAvgBytesPerSec = pDS->pwfx->nSamplesPerSec * pDS->pwfx->nBlockAlign;
+    pDS->pwfx->cbSize = 0;
 
     /* If the driver requests being opened through MMSYSTEM
      * (which is recommended by the DDK), it is supposed to happen
@@ -857,7 +882,7 @@
             flags |= WAVE_DIRECTSOUND;
 
         err = mmErr(waveOutOpen(&(pDS->hwo),
-                                pDS->drvdesc.dnDevNode, &(pDS->wfx),
+                                pDS->drvdesc.dnDevNode, pDS->pwfx,
                                 (DWORD)DSOUND_callback, (DWORD)pDS,
                                 flags));
         if (err != DS_OK) {
Index: dlls/dsound/dsound_private.h
===================================================================
RCS file: /home/wine/wine/dlls/dsound/dsound_private.h,v
retrieving revision 1.21
diff -u -r1.21 dsound_private.h
--- dlls/dsound/dsound_private.h	12 Aug 2004 19:52:51 -0000	1.21
+++ dlls/dsound/dsound_private.h	17 Aug 2004 23:45:44 -0000
@@ -78,7 +78,7 @@
     DSDRIVERDESC                drvdesc;
     DSDRIVERCAPS                drvcaps;
     DWORD                       priolevel;
-    WAVEFORMATEX                wfx; /* current main waveformat */
+    PWAVEFORMATEX               pwfx;
     HWAVEOUT                    hwo;
     LPWAVEHDR                   pwave[DS_HEL_FRAGS];
     UINT                        timerID, pwplay, pwwrite, pwqueue, prebuf, precount;
@@ -197,7 +197,7 @@
     IDirectSoundImpl*           dsound;
     CRITICAL_SECTION            lock;
     PIDSDRIVERBUFFER            hwbuf;
-    WAVEFORMATEX                wfx;
+    PWAVEFORMATEX               pwfx;
     BufferMemory*               buffer;
     DWORD                       playflags,state,leadin;
     DWORD                       playpos,startpos,writelead,buflen;
Index: dlls/dsound/mixer.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/mixer.c,v
retrieving revision 1.23
diff -u -r1.23 mixer.c
--- dlls/dsound/mixer.c	12 Aug 2004 20:01:32 -0000	1.23
+++ dlls/dsound/mixer.c	17 Aug 2004 23:45:44 -0000
@@ -106,7 +106,7 @@
 	DWORD sw;
 	TRACE("(%p)\n",dsb);
 
-	sw = dsb->wfx.nChannels * (dsb->wfx.wBitsPerSample / 8);
+	sw = dsb->pwfx->nChannels * (dsb->pwfx->wBitsPerSample / 8);
 	/* calculate the 10ms write lead */
 	dsb->writelead = (dsb->freq / 100) * sw;
 }
@@ -180,41 +180,41 @@
 {
         INT fl,fr;
 
-        if (dsb->wfx.wBitsPerSample == 8)  {
-                if (dsb->dsound->wfx.wBitsPerSample == 8 &&
-                    dsb->dsound->wfx.nChannels == dsb->wfx.nChannels) {
+        if (dsb->pwfx->wBitsPerSample == 8)  {
+                if (dsb->dsound->pwfx->wBitsPerSample == 8 &&
+                    dsb->dsound->pwfx->nChannels == dsb->pwfx->nChannels) {
                         /* avoid needless 8->16->8 conversion */
                         *obuf=*ibuf;
-                        if (dsb->wfx.nChannels==2)
+                        if (dsb->pwfx->nChannels==2)
                                 *(obuf+1)=*(ibuf+1);
                         return;
                 }
                 fl = cvtU8toS16(*ibuf);
-                fr = (dsb->wfx.nChannels==2 ? cvtU8toS16(*(ibuf + 1)) : fl);
+                fr = (dsb->pwfx->nChannels==2 ? cvtU8toS16(*(ibuf + 1)) : fl);
         } else {
                 fl = *((INT16 *)ibuf);
-                fr = (dsb->wfx.nChannels==2 ? *(((INT16 *)ibuf) + 1)  : fl);
+                fr = (dsb->pwfx->nChannels==2 ? *(((INT16 *)ibuf) + 1)  : fl);
         }
 
-        if (dsb->dsound->wfx.nChannels == 2) {
-                if (dsb->dsound->wfx.wBitsPerSample == 8) {
+        if (dsb->dsound->pwfx->nChannels == 2) {
+                if (dsb->dsound->pwfx->wBitsPerSample == 8) {
                         *obuf = cvtS16toU8(fl);
                         *(obuf + 1) = cvtS16toU8(fr);
                         return;
                 }
-                if (dsb->dsound->wfx.wBitsPerSample == 16) {
+                if (dsb->dsound->pwfx->wBitsPerSample == 16) {
                         *((INT16 *)obuf) = fl;
                         *(((INT16 *)obuf) + 1) = fr;
                         return;
                 }
         }
-        if (dsb->dsound->wfx.nChannels == 1) {
+        if (dsb->dsound->pwfx->nChannels == 1) {
                 fl = (fl + fr) >> 1;
-                if (dsb->dsound->wfx.wBitsPerSample == 8) {
+                if (dsb->dsound->pwfx->wBitsPerSample == 8) {
                         *obuf = cvtS16toU8(fl);
                         return;
                 }
-                if (dsb->dsound->wfx.wBitsPerSample == 16) {
+                if (dsb->dsound->pwfx->wBitsPerSample == 16) {
                         *((INT16 *)obuf) = fl;
                         return;
                 }
@@ -226,17 +226,17 @@
 {
 	INT	i, size, ipos, ilen;
 	BYTE	*ibp, *obp;
-	INT	iAdvance = dsb->wfx.nBlockAlign;
-	INT	oAdvance = dsb->dsound->wfx.nBlockAlign;
+	INT	iAdvance = dsb->pwfx->nBlockAlign;
+	INT	oAdvance = dsb->dsound->pwfx->nBlockAlign;
 
 	ibp = dsb->buffer->memory + dsb->buf_mixpos;
 	obp = buf;
 
 	TRACE("(%p, %p, %p), buf_mixpos=%ld\n", dsb, ibp, obp, dsb->buf_mixpos);
 	/* Check for the best case */
-	if ((dsb->freq == dsb->dsound->wfx.nSamplesPerSec) &&
-	    (dsb->wfx.wBitsPerSample == dsb->dsound->wfx.wBitsPerSample) &&
-	    (dsb->wfx.nChannels == dsb->dsound->wfx.nChannels)) {
+	if ((dsb->freq == dsb->dsound->pwfx->nSamplesPerSec) &&
+	    (dsb->pwfx->wBitsPerSample == dsb->dsound->pwfx->wBitsPerSample) &&
+	    (dsb->pwfx->nChannels == dsb->dsound->pwfx->nChannels)) {
 	        DWORD bytesleft = dsb->buflen - dsb->buf_mixpos;
 		TRACE("(%p) Best case\n", dsb);
 	    	if (len <= bytesleft )
@@ -249,9 +249,9 @@
 	}
 
 	/* Check for same sample rate */
-	if (dsb->freq == dsb->dsound->wfx.nSamplesPerSec) {
+	if (dsb->freq == dsb->dsound->pwfx->nSamplesPerSec) {
 		TRACE("(%p) Same sample rate %ld = primary %ld\n", dsb,
-			dsb->freq, dsb->dsound->wfx.nSamplesPerSec);
+			dsb->freq, dsb->dsound->pwfx->nSamplesPerSec);
 		ilen = 0;
 		for (i = 0; i < len; i += oAdvance) {
 			cp_fields(dsb, ibp, obp );
@@ -273,7 +273,7 @@
 	 * TransGaming Technologies Inc. */
 
 	/* FIXME("(%p) Adjusting frequency: %ld -> %ld (need optimization)\n",
-	   dsb, dsb->freq, dsb->dsound->wfx.nSamplesPerSec); */
+	   dsb, dsb->freq, dsb->dsound->pwfx->nSamplesPerSec); */
 
 	size = len / oAdvance;
 	ilen = 0;
@@ -286,8 +286,7 @@
 			ULONG adv = (dsb->freqAcc>>DSOUND_FREQSHIFT) * iAdvance;
 			dsb->freqAcc &= (1<<DSOUND_FREQSHIFT)-1;
 			ipos += adv; ilen += adv;
-			while (ipos >= dsb->buflen)
-				ipos -= dsb->buflen;
+			ipos %= dsb->buflen;
 		}
 	}
 	return ilen;
@@ -312,11 +311,11 @@
 	/* with a mono primary buffer, it could sound very weird using */
 	/* this method. Oh well, tough patooties. */
 
-	switch (dsb->dsound->wfx.wBitsPerSample) {
+	switch (dsb->dsound->pwfx->wBitsPerSample) {
 	case 8:
 		/* 8-bit WAV is unsigned, but we need to operate */
 		/* on signed data for this to work properly */
-		switch (dsb->dsound->wfx.nChannels) {
+		switch (dsb->dsound->pwfx->nChannels) {
 		case 1:
 			for (i = 0; i < len; i++) {
 				INT val = *bpc - 128;
@@ -337,13 +336,13 @@
 			}
 			break;
 		default:
-			FIXME("doesn't support %d channels\n", dsb->dsound->wfx.nChannels);
+			FIXME("doesn't support %d channels\n", dsb->dsound->pwfx->nChannels);
 			break;
 		}
 		break;
 	case 16:
 		/* 16-bit WAV is signed -- much better */
-		switch (dsb->dsound->wfx.nChannels) {
+		switch (dsb->dsound->pwfx->nChannels) {
 		case 1:
 			for (i = 0; i < len; i += 2) {
 				*bps = (*bps * dsb->cvolpan.dwTotalLeftAmpFactor) >> 16;
@@ -359,12 +358,12 @@
 			}
 			break;
 		default:
-			FIXME("doesn't support %d channels\n", dsb->dsound->wfx.nChannels);
+			FIXME("doesn't support %d channels\n", dsb->dsound->pwfx->nChannels);
 			break;
 		}
 		break;
 	default:
-		FIXME("doesn't support %d bit samples\n", dsb->dsound->wfx.wBitsPerSample);
+		FIXME("doesn't support %d bit samples\n", dsb->dsound->pwfx->wBitsPerSample);
 		break;
 	}
 }
@@ -394,13 +393,13 @@
 
 	len = fraglen;
 	if (!(dsb->playflags & DSBPLAY_LOOPING)) {
-		temp = MulDiv(dsb->dsound->wfx.nAvgBytesPerSec, dsb->buflen,
+		temp = MulDiv(dsb->dsound->pwfx->nAvgBytesPerSec, dsb->buflen,
 			dsb->nAvgBytesPerSec) -
-		       MulDiv(dsb->dsound->wfx.nAvgBytesPerSec, dsb->buf_mixpos,
+		       MulDiv(dsb->dsound->pwfx->nAvgBytesPerSec, dsb->buf_mixpos,
 			dsb->nAvgBytesPerSec);
 		len = (len > temp) ? temp : len;
 	}
-	nBlockAlign = dsb->dsound->wfx.nBlockAlign;
+	nBlockAlign = dsb->dsound->pwfx->nBlockAlign;
 	len = len / nBlockAlign * nBlockAlign;	/* data alignment */
 
 	if (len == 0) {
@@ -421,7 +420,7 @@
 	    (dsb->dsbd.dwFlags & DSBCAPS_CTRL3D))
 		DSOUND_MixerVol(dsb, ibuf, len);
 
-	if (dsb->dsound->wfx.wBitsPerSample == 8) {
+	if (dsb->dsound->pwfx->wBitsPerSample == 8) {
 		BYTE	*obuf = dsb->dsound->buffer + writepos;
 
 		if ((writepos + len) <= dsb->dsound->buflen)
@@ -499,8 +498,7 @@
 	if (dsb->buf_mixpos >= dsb->buflen) {
 		if (dsb->playflags & DSBPLAY_LOOPING) {
 			/* wrap */
-			while (dsb->buf_mixpos >= dsb->buflen)
-				dsb->buf_mixpos -= dsb->buflen;
+			dsb->buf_mixpos %= dsb->buflen;
 			if (dsb->leadin && (dsb->startpos <= dsb->buf_mixpos))
 				dsb->leadin = FALSE; /* HACK: see above */
 		}
@@ -516,7 +514,7 @@
 
 	TRACE("(%p,%ld,%ld)\n",dsb,writepos,len);
 
-	nBlockAlign = dsb->dsound->wfx.nBlockAlign;
+	nBlockAlign = dsb->dsound->pwfx->nBlockAlign;
 	len = len / nBlockAlign * nBlockAlign;  /* data alignment */
 
 	TRACE("allocating buffer (size = %ld)\n", len);
@@ -532,7 +530,7 @@
 		DSOUND_MixerVol(dsb, ibuf, len);
 
 	/* subtract instead of add, to phase out premixed data */
-	if (dsb->dsound->wfx.wBitsPerSample == 8) {
+	if (dsb->dsound->pwfx->wBitsPerSample == 8) {
 		BYTE	*obuf = dsb->dsound->buffer + writepos;
 
 		if ((writepos + len) <= dsb->dsound->buflen)
@@ -601,8 +599,8 @@
 static void DSOUND_MixCancel(IDirectSoundBufferImpl *dsb, DWORD writepos, BOOL cancel)
 {
 	DWORD   size, flen, len, npos, nlen;
-	INT	iAdvance = dsb->wfx.nBlockAlign;
-	INT	oAdvance = dsb->dsound->wfx.nBlockAlign;
+	INT	iAdvance = dsb->pwfx->nBlockAlign;
+	INT	oAdvance = dsb->dsound->pwfx->nBlockAlign;
 	/* determine amount of premixed data to cancel */
 	DWORD primary_done =
 		((dsb->primary_mixpos < writepos) ? dsb->dsound->buflen : 0) +
@@ -628,9 +626,9 @@
 		len = ((dsb->buf_mixpos < npos) ? dsb->buflen : 0) +
 			dsb->buf_mixpos - npos;
 		flen = dsb->freqAcc;
-		nlen = len / dsb->wfx.nBlockAlign;
+		nlen = len / dsb->pwfx->nBlockAlign;
 		nlen = ((nlen << DSOUND_FREQSHIFT) + flen) / dsb->freqAdjust;
-		nlen *= dsb->dsound->wfx.nBlockAlign;
+		nlen *= dsb->dsound->pwfx->nBlockAlign;
 		writepos =
 			((dsb->primary_mixpos < nlen) ? dsb->dsound->buflen : 0) +
 			dsb->primary_mixpos - nlen;
@@ -650,8 +648,8 @@
 {
 #if 0
 	DWORD   i, size, flen, len, npos, nlen;
-	INT	iAdvance = dsb->wfx.nBlockAlign;
-	INT	oAdvance = dsb->dsound->wfx.nBlockAlign;
+	INT	iAdvance = dsb->pwfx->nBlockAlign;
+	INT	oAdvance = dsb->dsound->pwfx->nBlockAlign;
 	/* determine amount of premixed data to cancel */
 	DWORD buf_done =
 		((dsb->buf_mixpos < buf_writepos) ? dsb->buflen : 0) +
@@ -761,8 +759,8 @@
 			/* adjust for our frequency and our sample size */
 			probably_valid_left = MulDiv(probably_valid_left,
 						     1 << DSOUND_FREQSHIFT,
-						     dsb->wfx.nBlockAlign * dsb->freqAdjust) *
-				              dsb->dsound->wfx.nBlockAlign;
+						     dsb->pwfx->nBlockAlign * dsb->freqAdjust) *
+				              dsb->dsound->pwfx->nBlockAlign;
 			/* check whether to clip mix_len */
 			if (probably_valid_left < mixlen) {
 				TRACE("clipping to probably_valid_left=%ld\n", probably_valid_left);
@@ -800,8 +798,7 @@
 			still_behind = FALSE;
 
 		dsb->primary_mixpos += slen; len -= slen;
-		while (dsb->primary_mixpos >= dsb->dsound->buflen)
-			dsb->primary_mixpos -= dsb->dsound->buflen;
+		dsb->primary_mixpos %= dsb->dsound->buflen;
 
 		if ((dsb->state == STATE_STOPPED) || !slen) break;
 	}
@@ -885,7 +882,7 @@
 	TRACE("(%ld)\n", writepos);
 
 	/* the sound of silence */
-	nfiller = dsound->wfx.wBitsPerSample == 8 ? 128 : 0;
+	nfiller = dsound->pwfx->wBitsPerSample == 8 ? 128 : 0;
 
 	/* reset all buffer mix positions */
 	for (i = dsound->nrofbuffers - 1; i >= 0; i--) {
@@ -966,7 +963,7 @@
 	TRACE("()\n");
 
 	/* the sound of silence */
-	nfiller = dsound->wfx.wBitsPerSample == 8 ? 128 : 0;
+	nfiller = dsound->pwfx->wBitsPerSample == 8 ? 128 : 0;
 
 	/* whether the primary is forced to play even without secondary buffers */
 	forced = ((dsound->state == STATE_PLAYING) || (dsound->state == STATE_STARTING));
@@ -986,16 +983,14 @@
 			/* rather add our safety margin to the writepos, if we're playing */
 			if (!paused) {
 				writepos += dsound->writelead;
-				while (writepos >= dsound->buflen)
-					writepos -= dsound->buflen;
+				writepos %= dsound->buflen;
 			} else writepos = playpos;
 		} else {
  			playpos = dsound->pwplay * dsound->fraglen;
  			writepos = playpos;
  			if (!paused) {
 	 			writepos += ds_hel_margin * dsound->fraglen;
-	 			while (writepos >= dsound->buflen)
- 					writepos -= dsound->buflen;
+ 				writepos %= dsound->buflen;
 	 		}
 		}
 		TRACE("primary playpos=%ld, writepos=%ld, clrpos=%ld, mixpos=%ld, buflen=%ld\n",
@@ -1086,8 +1081,7 @@
 		frag = DSOUND_MixToPrimary(dsound, playpos, writepos, maxq, paused);
 		if (forced) frag = maxq - inq;
 		dsound->mixpos += frag;
-		while (dsound->mixpos >= dsound->buflen)
-			dsound->mixpos -= dsound->buflen;
+		dsound->mixpos %= dsound->buflen;
 
 		if (frag) {
 			/* buffers have been filled, restart playback */
Index: dlls/dsound/primary.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/primary.c,v
retrieving revision 1.29
diff -u -r1.29 primary.c
--- dlls/dsound/primary.c	12 Aug 2004 23:00:57 -0000	1.29
+++ dlls/dsound/primary.c	17 Aug 2004 23:45:45 -0000
@@ -54,11 +54,11 @@
 	DWORD sw;
 	TRACE("(%p)\n",This);
 
-	sw = This->wfx.nChannels * (This->wfx.wBitsPerSample / 8);
+	sw = This->pwfx->nChannels * (This->pwfx->wBitsPerSample / 8);
 	if (This->hwbuf) {
 		DWORD fraglen;
 		/* let fragment size approximate the timer delay */
-		fraglen = (This->wfx.nSamplesPerSec * DS_TIME_DEL / 1000) * sw;
+		fraglen = (This->pwfx->nSamplesPerSec * DS_TIME_DEL / 1000) * sw;
 		/* reduce fragment size until an integer number of them fits in the buffer */
 		/* (FIXME: this may or may not be a good idea) */
 		while (This->buflen % fraglen) fraglen -= sw;
@@ -66,7 +66,7 @@
 		TRACE("fraglen=%ld\n", This->fraglen);
 	}
 	/* calculate the 10ms write lead */
-	This->writelead = (This->wfx.nSamplesPerSec / 100) * sw;
+	This->writelead = (This->pwfx->nSamplesPerSec / 100) * sw;
 }
 
 static HRESULT DSOUND_PrimaryOpen(IDirectSoundImpl *This)
@@ -85,14 +85,14 @@
 		else if (This->state == STATE_STOPPING) This->state = STATE_STOPPED;
 		/* use fragments of 10ms (1/100s) each (which should get us within
 		 * the documented write cursor lead of 10-15ms) */
-		buflen = ((This->wfx.nAvgBytesPerSec / 100) & ~3) * DS_HEL_FRAGS;
+		buflen = ((This->pwfx->nAvgBytesPerSec / 100) & ~3) * DS_HEL_FRAGS;
 		TRACE("desired buflen=%ld, old buffer=%p\n", buflen, This->buffer);
 		/* reallocate emulated primary buffer */
 
 		if (This->buffer)
-			newbuf = (LPBYTE)HeapReAlloc(GetProcessHeap(),0,This->buffer,buflen);
+			newbuf = HeapReAlloc(GetProcessHeap(),0,This->buffer,buflen);
 		else
-			newbuf = (LPBYTE)HeapAlloc(GetProcessHeap(),0,buflen);
+			newbuf = HeapAlloc(GetProcessHeap(),0,buflen);
 
 		if (newbuf == NULL) {
 			ERR("failed to allocate primary buffer\n");
@@ -127,26 +127,24 @@
 			This->pwqueue = 0;
 			This->playpos = 0;
 			This->mixpos = 0;
-			memset(This->buffer, (This->wfx.wBitsPerSample == 16) ? 0 : 128, This->buflen);
+			memset(This->buffer, (This->pwfx->wBitsPerSample == 16) ? 0 : 128, This->buflen);
 			TRACE("fraglen=%ld\n", This->fraglen);
 			DSOUND_WaveQueue(This, (DWORD)-1);
 		}
 		if ((err == DS_OK) && (merr != DS_OK))
 			err = merr;
-	} else {
-		if (!This->hwbuf) {
-			err = IDsDriver_CreateSoundBuffer(This->driver,&(This->wfx),
-							  DSBCAPS_PRIMARYBUFFER,0,
-							  &(This->buflen),&(This->buffer),
-							  (LPVOID*)&(This->hwbuf));
-			if (err != DS_OK) {
-				WARN("IDsDriver_CreateSoundBuffer failed\n");
-				return err;
-			}
-
-			if (dsound->state == STATE_PLAYING) dsound->state = STATE_STARTING;
-			else if (dsound->state == STATE_STOPPING) dsound->state = STATE_STOPPED;
+	} else if (!This->hwbuf) {
+		err = IDsDriver_CreateSoundBuffer(This->driver,This->pwfx,
+						  DSBCAPS_PRIMARYBUFFER,0,
+						  &(This->buflen),&(This->buffer),
+						  (LPVOID*)&(This->hwbuf));
+		if (err != DS_OK) {
+			WARN("IDsDriver_CreateSoundBuffer failed\n");
+			return err;
 		}
+
+		if (dsound->state == STATE_PLAYING) dsound->state = STATE_STARTING;
+		else if (dsound->state == STATE_STOPPING) dsound->state = STATE_STOPPED;
 	}
 
 	return err;
@@ -177,12 +175,12 @@
 	HRESULT err = DS_OK;
 	TRACE("(%p)\n",This);
 
-	This->buflen = This->wfx.nAvgBytesPerSec;
+	This->buflen = This->pwfx->nAvgBytesPerSec;
 
 	/* FIXME: verify that hardware capabilities (DSCAPS_PRIMARY flags) match */
 
 	if (This->driver) {
-		err = IDsDriver_CreateSoundBuffer(This->driver,&(This->wfx),
+		err = IDsDriver_CreateSoundBuffer(This->driver,This->pwfx,
 						  DSBCAPS_PRIMARYBUFFER,0,
 						  &(This->buflen),&(This->buffer),
 						  (LPVOID*)&(This->hwbuf));
@@ -236,6 +234,10 @@
 			HeapFree(GetProcessHeap(),0,This->pwave[c]);
 		}
 	}
+	if (This->pwfx) {
+		HeapFree(GetProcessHeap(),0,This->pwfx);
+		This->pwfx=NULL;
+	}
 	return DS_OK;
 }
 
@@ -274,10 +276,10 @@
 			waveOutClose(This->hwo);
 			This->hwo = 0;
 			err = mmErr(waveOutOpen(&(This->hwo), This->drvdesc.dnDevNode,
-						&(This->wfx), (DWORD)DSOUND_callback, (DWORD)This,
+						This->pwfx, (DWORD)DSOUND_callback, (DWORD)This,
 						flags));
 			if (err == DS_OK) {
-				err = IDsDriver_CreateSoundBuffer(This->driver,&(This->wfx),
+				err = IDsDriver_CreateSoundBuffer(This->driver,This->pwfx,
 								  DSBCAPS_PRIMARYBUFFER,0,
 								  &(This->buflen),&(This->buffer),
 								  (LPVOID)&(This->hwbuf));
@@ -307,8 +309,7 @@
 			WARN("IDsDriverBuffer_GetPosition failed\n");
 			return err;
 		}
-	}
-	else {
+	} else {
 		if (playpos) {
 			MMTIME mtime;
 			mtime.wType = TIME_BYTES;
@@ -328,7 +329,6 @@
 	return DS_OK;
 }
 
-
 /*******************************************************************************
  *		PrimaryBuffer
  */
@@ -340,8 +340,8 @@
 	ICOM_THIS(PrimaryBufferImpl,iface);
 	IDirectSoundImpl* dsound = This->dsound;
 	HRESULT err = DS_OK;
-	int i;
-	DWORD nSamplesPerSec; 
+	int i, alloc_size, cp_size;
+	DWORD nSamplesPerSec;
 	TRACE("(%p,%p)\n",This,wfex);
 
 	if (This->dsound->priolevel == DSSCL_NORMAL) {
@@ -360,24 +360,20 @@
 	      wfex->nAvgBytesPerSec, wfex->nBlockAlign,
 	      wfex->wBitsPerSample, wfex->cbSize);
 
-	if ((wfex->wFormatTag != WAVE_FORMAT_PCM) ||
-	    (wfex->nChannels < 1) || (wfex->nChannels > 2) ||
-	    (wfex->nSamplesPerSec < 1) ||
-	    ((wfex->wBitsPerSample != 8) && (wfex->wBitsPerSample != 16))) {
-		WARN("invalid paramemer: unsupported format!\n");
-		return DSERR_INVALIDPARAM;
-	}
-
 	/* **** */
 	RtlAcquireResourceExclusive(&(dsound->lock), TRUE);
 
-	nSamplesPerSec = dsound->wfx.nSamplesPerSec;
-	dsound->wfx.nSamplesPerSec = wfex->nSamplesPerSec;
-	dsound->wfx.nChannels = wfex->nChannels;
-	dsound->wfx.wBitsPerSample = wfex->wBitsPerSample;
-	dsound->wfx.nBlockAlign = dsound->wfx.wBitsPerSample / 8 * dsound->wfx.nChannels;
-	dsound->wfx.nAvgBytesPerSec =
-		dsound->wfx.nSamplesPerSec * dsound->wfx.nBlockAlign;
+	if (wfex->wFormatTag == WAVE_FORMAT_PCM) {
+            alloc_size = sizeof(WAVEFORMATEX);
+            cp_size = sizeof(PCMWAVEFORMAT);
+        } else
+            alloc_size = cp_size = sizeof(WAVEFORMATEX) + wfex->cbSize;
+
+        dsound->pwfx = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dsound->pwfx,alloc_size);
+
+	nSamplesPerSec = dsound->pwfx->nSamplesPerSec;
+
+        memcpy(dsound->pwfx, wfex, cp_size);
 
 	if (dsound->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMSETFORMAT) {
 		DWORD flags = CALLBACK_FUNCTION;
@@ -388,7 +384,7 @@
 		waveOutClose(dsound->hwo);
 		dsound->hwo = 0;
                 err = mmErr(waveOutOpen(&(dsound->hwo), dsound->drvdesc.dnDevNode,
-                                        &(dsound->wfx), (DWORD)DSOUND_callback, (DWORD)dsound,
+                                        dsound->pwfx, (DWORD)DSOUND_callback, (DWORD)dsound,
                                         flags));
                 if (err == DS_OK) {
                     err = DSOUND_PrimaryOpen(dsound);
@@ -403,11 +399,11 @@
 			return err;
 		}
 	} else if (dsound->hwbuf) {
-		err = IDsDriverBuffer_SetFormat(dsound->hwbuf, &(dsound->wfx));
+		err = IDsDriverBuffer_SetFormat(dsound->hwbuf, dsound->pwfx);
 		if (err == DSERR_BUFFERLOST) {
 			/* Wine-only: the driver wants us to recreate the HW buffer */
 			IDsDriverBuffer_Release(dsound->hwbuf);
-			err = IDsDriver_CreateSoundBuffer(dsound->driver,&(dsound->wfx),
+			err = IDsDriver_CreateSoundBuffer(dsound->driver,dsound->pwfx,
 							  DSBCAPS_PRIMARYBUFFER,0,
 							  &(dsound->buflen),&(dsound->buffer),
 							  (LPVOID)&(dsound->hwbuf));
@@ -427,7 +423,7 @@
 	}
 	DSOUND_RecalcPrimary(dsound);
 
-	if (nSamplesPerSec != dsound->wfx.nSamplesPerSec) {
+	if (nSamplesPerSec != dsound->pwfx->nSamplesPerSec) {
 		IDirectSoundBufferImpl** dsb = dsound->buffers;
 		for (i = 0; i < dsound->nrofbuffers; i++, dsb++) {
 			/* **** */
@@ -656,27 +652,38 @@
 
 
 static HRESULT WINAPI PrimaryBufferImpl_GetFormat(
-	LPDIRECTSOUNDBUFFER8 iface,LPWAVEFORMATEX lpwf,DWORD wfsize,LPDWORD wfwritten
-) {
-	ICOM_THIS(PrimaryBufferImpl,iface);
-	TRACE("(%p,%p,%ld,%p)\n",This,lpwf,wfsize,wfwritten);
-
-	if (wfsize>sizeof(This->dsound->wfx))
-		wfsize = sizeof(This->dsound->wfx);
-	if (lpwf) {	/* NULL is valid */
-		memcpy(lpwf,&(This->dsound->wfx),wfsize);
-		if (wfwritten)
-			*wfwritten = wfsize;
-	} else {
-		if (wfwritten)
-			*wfwritten = sizeof(This->dsound->wfx);
-		else {
-			WARN("invalid parameter: wfwritten == NULL\n");
-			return DSERR_INVALIDPARAM;
-		}
-	}
+    LPDIRECTSOUNDBUFFER8 iface,
+    LPWAVEFORMATEX lpwf,
+    DWORD wfsize,
+    LPDWORD wfwritten)
+{
+    DWORD size;
+    ICOM_THIS(PrimaryBufferImpl,iface);
+    TRACE("(%p,%p,%ld,%p)\n",This,lpwf,wfsize,wfwritten);
+
+    size = sizeof(WAVEFORMATEX) + This->dsound->pwfx->cbSize;
+
+    if (lpwf) {	/* NULL is valid */
+        if (wfsize >= size) {
+            memcpy(lpwf,This->dsound->pwfx,size);
+            if (wfwritten)
+                *wfwritten = size;
+        } else {
+            WARN("invalid parameter: wfsize to small\n");
+            if (wfwritten)
+                *wfwritten = 0;
+            return DSERR_INVALIDPARAM;
+        }
+    } else {
+        if (wfwritten)
+            *wfwritten = sizeof(WAVEFORMATEX) + This->dsound->pwfx->cbSize;
+        else {
+            WARN("invalid parameter: wfwritten == NULL\n");
+            return DSERR_INVALIDPARAM;
+        }
+    }
 
-	return DS_OK;
+    return DS_OK;
 }
 
 static HRESULT WINAPI PrimaryBufferImpl_Lock(
@@ -891,7 +898,7 @@
 		return DSERR_CONTROLUNAVAIL;
 	}
 
-	*freq = This->dsound->wfx.nSamplesPerSec;
+	*freq = This->dsound->pwfx->nSamplesPerSec;
 	TRACE("-> %ld\n", *freq);
 
 	return DS_OK;
@@ -993,7 +1000,7 @@
 
 	*ppobj = NULL;	/* assume failure */
 
-	if ( IsEqualGUID(riid, &IID_IUnknown) || 
+	if ( IsEqualGUID(riid, &IID_IUnknown) ||
 	     IsEqualGUID(riid, &IID_IDirectSoundBuffer) ) {
 		IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)This);
 		*ppobj = This;
@@ -1084,7 +1091,7 @@
 		return DSERR_INVALIDPARAM;
 	}
 
-	dsb = (PrimaryBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
+	dsb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
 
 	if (dsb == NULL) {
 		WARN("out of memory\n");
@@ -1101,9 +1108,9 @@
 	TRACE("Created primary buffer at %p\n", dsb);
 	TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld,"
 		"bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
-		ds->wfx.wFormatTag, ds->wfx.nChannels, ds->wfx.nSamplesPerSec,
-		ds->wfx.nAvgBytesPerSec, ds->wfx.nBlockAlign,
-		ds->wfx.wBitsPerSample, ds->wfx.cbSize);
+		ds->pwfx->wFormatTag, ds->pwfx->nChannels, ds->pwfx->nSamplesPerSec,
+		ds->pwfx->nAvgBytesPerSec, ds->pwfx->nBlockAlign,
+		ds->pwfx->wBitsPerSample, ds->pwfx->cbSize);
 
 	*pdsb = dsb;
 	return S_OK;
Index: dlls/dsound/propset.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/propset.c,v
retrieving revision 1.19
diff -u -r1.19 propset.c
--- dlls/dsound/propset.c	12 Aug 2004 23:00:57 -0000	1.19
+++ dlls/dsound/propset.c	17 Aug 2004 23:45:46 -0000
@@ -208,7 +208,7 @@
     IKsBufferPropertySetImpl *iks;
     TRACE("(%p,%p)\n",dsb,piks);
 
-    iks = (IKsBufferPropertySetImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*iks));
+    iks = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*iks));
     iks->ref = 0;
     iks->dsb = dsb;
     dsb->iks = iks;
@@ -1140,7 +1140,7 @@
 {
     IKsPrivatePropertySetImpl *iks;
 
-    iks = (IKsPrivatePropertySetImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
+    iks = HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
     iks->ref = 0;
     iks->lpVtbl = &ikspvt;
 
Index: dlls/dsound/sound3d.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/sound3d.c,v
retrieving revision 1.31
diff -u -r1.31 sound3d.c
--- dlls/dsound/sound3d.c	12 Aug 2004 23:00:57 -0000	1.31
+++ dlls/dsound/sound3d.c	17 Aug 2004 23:45:47 -0000
@@ -733,7 +733,7 @@
 	IDirectSound3DBufferImpl *ds3db;
 	TRACE("(%p,%p)\n",dsb,pds3db);
 
-	ds3db = (IDirectSound3DBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*ds3db));
+	ds3db = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*ds3db));
 
 	if (ds3db == NULL) {
 		WARN("out of memory\n");
@@ -1111,7 +1111,7 @@
 	IDirectSound3DListenerImpl *dsl;
 	TRACE("(%p,%p)\n",This,pdsl);
 
-	dsl = (IDirectSound3DListenerImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsl));
+	dsl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsl));
 
 	if (dsl == NULL) {
 		WARN("out of memory\n");


More information about the wine-patches mailing list