[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-devel
Subject:    alsa and audioio testing needed for dsound patch
From:       Robert Reif <reif () earthlink ! net>
Date:       2004-01-30 13:24:37
Message-ID: 401A5B14.2AB6F810 () earthlink ! net
[Download RAW message or body]

This patch insures that the hardware primary buffer
is deleted and recreated properly when changing
the primary format.  It also makes sure the proper
frequency adjust is calculated for the actual format
used rather than the requested one.

This should only affect oss, alsa, and audioio and I
have tested oss already.  Please test it with the dsound
tests in the interactive mode so sounds are actually played.
Make sure "HardwareAcceleration" in the config file is
not set to 'Emulation" so the dsound HAL driver is used.

Thanks,

Bob.

["dsound.diff" (application/x-unknown-content-type-diff_auto_file)]

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


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic