Index: dlls/dsound/primary.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/primary.c,v
retrieving revision 1.21
diff -u -r1.21 primary.c
--- dlls/dsound/primary.c	9 Jan 2004 22:06:54 -0000	1.21
+++ dlls/dsound/primary.c	30 Jan 2004 12:47:35 -0000
@@ -77,7 +77,7 @@
 	DSOUND_RecalcVolPan(&(This->volpan));
 
 	/* are we using waveOut stuff? */
-	if (!This->hwbuf) {
+	if (!This->driver) {
 		LPBYTE newbuf;
 		DWORD buflen;
 		HRESULT merr = DS_OK;
@@ -141,6 +141,23 @@
 			err = mmErr(waveOutSetVolume(This->hwo, vol));
 		}
 	} 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;
+			}
+
+			EnterCriticalSection(&(dsound->mixlock));
+			if (dsound->state == STATE_PLAYING)
+				dsound->state = STATE_STARTING;
+			else if (dsound->state == STATE_STOPPING)
+				dsound->state = STATE_STOPPED;
+			LeaveCriticalSection(&(dsound->mixlock));
+		}
 		err = IDsDriverBuffer_SetVolumePan(This->hwbuf, &(This->volpan));
 	}
 
@@ -161,6 +178,9 @@
 		for (c=0; c<DS_HEL_FRAGS; c++)
 			waveOutUnprepareHeader(This->hwo, This->pwave[c], sizeof(WAVEHDR));
 		This->pwqueue = 0;
+	} else {
+		if (IDsDriverBuffer_Release(This->hwbuf) == 0)
+			This->hwbuf = 0;
 	}
 }
 
@@ -217,9 +237,11 @@
 	TRACE("(%p)\n",This);
 
 	DSOUND_PrimaryClose(This);
-	if (This->hwbuf) {
-		if (IDsDriverBuffer_Release(This->hwbuf) == 0)
-			This->hwbuf = 0;
+	if (This->driver) {
+		if (This->hwbuf) {
+			if (IDsDriverBuffer_Release(This->hwbuf) == 0)
+				This->hwbuf = 0;
+		}
 	} else {
 		unsigned c;
 		for (c=0; c<DS_HEL_FRAGS; c++) {
@@ -329,7 +351,6 @@
 ) {
 	ICOM_THIS(PrimaryBufferImpl,iface);
 	IDirectSoundImpl* dsound = This->dsound;
-	IDirectSoundBufferImpl** dsb;
 	HRESULT err = DS_OK;
 	int			i;
 	TRACE("(%p,%p)\n",This,wfex);
@@ -361,20 +382,6 @@
 	/* **** */
 	RtlAcquireResourceExclusive(&(dsound->lock), TRUE);
 
-	if (dsound->wfx.nSamplesPerSec != wfex->nSamplesPerSec) {
-		dsb = dsound->buffers;
-		for (i = 0; i < dsound->nrofbuffers; i++, dsb++) {
-			/* **** */
-			EnterCriticalSection(&((*dsb)->lock));
-
-			(*dsb)->freqAdjust = ((*dsb)->freq << DSOUND_FREQSHIFT) /
-				wfex->nSamplesPerSec;
-
-			LeaveCriticalSection(&((*dsb)->lock));
-			/* **** */
-		}
-	}
-
 	dsound->wfx.nSamplesPerSec = wfex->nSamplesPerSec;
 	dsound->wfx.nChannels = wfex->nChannels;
 	dsound->wfx.wBitsPerSample = wfex->wBitsPerSample;
@@ -405,8 +412,7 @@
 			RtlReleaseResource(&(dsound->lock));
 			return err;
 		}
-	}
-	if (dsound->hwbuf) {
+	} else if (dsound->hwbuf) {
 		err = IDsDriverBuffer_SetFormat(dsound->hwbuf, &(dsound->wfx));
 		if (err == DSERR_BUFFERLOST) {
 			/* Wine-only: the driver wants us to recreate the HW buffer */
@@ -420,8 +426,10 @@
 				RtlReleaseResource(&(dsound->lock));
 				return err;
 			}
+			EnterCriticalSection(&(dsound->mixlock));
 			if (dsound->state == STATE_PLAYING) dsound->state = STATE_STARTING;
 			else if (dsound->state == STATE_STOPPING) dsound->state = STATE_STOPPED;
+			LeaveCriticalSection(&(dsound->mixlock));
 		} else {
 			WARN("IDsDriverBuffer_SetFormat failed\n");
 			RtlReleaseResource(&(dsound->lock));
@@ -430,6 +438,20 @@
                 /* FIXME: should we set err back to DS_OK in all cases ? */
 	}
 	DSOUND_RecalcPrimary(dsound);
+
+	if (dsound->wfx.nSamplesPerSec != wfex->nSamplesPerSec) {
+		IDirectSoundBufferImpl** dsb = dsound->buffers;
+		for (i = 0; i < dsound->nrofbuffers; i++, dsb++) {
+			/* **** */
+			EnterCriticalSection(&((*dsb)->lock));
+
+			(*dsb)->freqAdjust = ((*dsb)->freq << DSOUND_FREQSHIFT) /
+				wfex->nSamplesPerSec;
+
+			LeaveCriticalSection(&((*dsb)->lock));
+			/* **** */
+		}
+	}
 
 	RtlReleaseResource(&(dsound->lock));
 	/* **** */
