Maarten Lankhorst : dsound: Get rid of DS_HEL_FRAGS.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Aug 1 05:16:44 CDT 2007


Module: wine
Branch: master
Commit: 60f4db034521c57ce7d418511cd604849d0f72c6
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=60f4db034521c57ce7d418511cd604849d0f72c6

Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date:   Mon Jul 30 16:44:50 2007 +0200

dsound: Get rid of DS_HEL_FRAGS.

---

 dlls/dsound/dsound_private.h |    7 +--
 dlls/dsound/mixer.c          |    8 ++--
 dlls/dsound/primary.c        |  113 ++++++++++++++++++++---------------------
 3 files changed, 61 insertions(+), 67 deletions(-)

diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
index 98575e3..91ac107 100644
--- a/dlls/dsound/dsound_private.h
+++ b/dlls/dsound/dsound_private.h
@@ -23,9 +23,6 @@
 #define DS_TIME_RES 2  /* Resolution of multimedia timer */
 #define DS_TIME_DEL 10  /* Delay of multimedia timer callback, and duration of HEL fragment */
 
-#define DS_HEL_FRAGS 0x10 /* HEL only: number of waveOut fragments in primary buffer
-			 * (changing this won't help you) */
-
 /* direct sound hardware acceleration levels */
 #define DS_HW_ACCEL_FULL        0	/* default on Windows 98 */
 #define DS_HW_ACCEL_STANDARD    1	/* default on Windows 2000 */
@@ -83,8 +80,8 @@ struct DirectSoundDevice
     DWORD                       priolevel;
     PWAVEFORMATEX               pwfx;
     HWAVEOUT                    hwo;
-    LPWAVEHDR                   pwave[DS_HEL_FRAGS];
-    UINT                        timerID, pwplay, pwqueue, prebuf;
+    LPWAVEHDR                   pwave;
+    UINT                        timerID, pwplay, pwqueue, prebuf, helfrags;
     DWORD                       fraglen;
     PIDSDRIVERBUFFER            hwbuf;
     LPBYTE                      buffer;
diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c
index d927df9..6390584 100644
--- a/dlls/dsound/mixer.c
+++ b/dlls/dsound/mixer.c
@@ -753,7 +753,7 @@ static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force)
 	TRACE("(%p)\n", device);
 
 	/* calculate the current wave frag position */
-	wave_fragpos = (device->pwplay + device->pwqueue) % DS_HEL_FRAGS;
+	wave_fragpos = (device->pwplay + device->pwqueue) % device->helfrags;
 
 	/* calculte the current wave write position */
 	wave_writepos = wave_fragpos * device->fraglen;
@@ -787,9 +787,9 @@ static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force)
 	/* queue up the new buffers */
 	for(i=0; i<prebuf_frags; i++){
 		TRACE("queueing wave buffer %i\n", wave_fragpos);
-		waveOutWrite(device->hwo, device->pwave[wave_fragpos], sizeof(WAVEHDR));
+		waveOutWrite(device->hwo, &device->pwave[wave_fragpos], sizeof(WAVEHDR));
 		wave_fragpos++;
-		wave_fragpos %= DS_HEL_FRAGS;
+		wave_fragpos %= device->helfrags;
 	}
 
 	/* **** */
@@ -1030,7 +1030,7 @@ void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, D
 
 		/* update playpos */
 		device->pwplay++;
-		device->pwplay %= DS_HEL_FRAGS;
+		device->pwplay %= device->helfrags;
 
 		/* sanity */
 		if(device->pwqueue == 0){
diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c
index dfcf107..0b7986f 100644
--- a/dlls/dsound/primary.c
+++ b/dlls/dsound/primary.c
@@ -39,31 +39,32 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsound);
 static void DSOUND_RecalcPrimary(DirectSoundDevice *device)
 {
 	DWORD nBlockAlign;
+	DWORD fraglen;
 	TRACE("(%p)\n", device);
 
 	nBlockAlign = device->pwfx->nBlockAlign;
-	if (device->hwbuf) {
-		DWORD fraglen;
-		/* Alsa doesn't have continuous buffers, instead it has buffers with power of 2,
-		 * If DS_TIME_DEL is about 10 ms, 512 * nBlockAlign is roughly correct */
-		fraglen = 512 * nBlockAlign;
-
-		/* Compensate for only being roughly accurate */
-		if (device->pwfx->nSamplesPerSec <= 26000)
-			fraglen /= 2;
-
-		if (device->pwfx->nSamplesPerSec <= 12000)
-			fraglen /= 2;
-
-		if (device->pwfx->nSamplesPerSec >= 80000)
-			fraglen *= 2;
-
-		/* reduce fragment size until an integer number of them fits in the buffer */
-		/* (FIXME: this may or may not be a good idea) */
-		while (device->buflen % fraglen) fraglen -= nBlockAlign;
-		device->fraglen = fraglen;
-		TRACE("fraglen=%d\n", device->fraglen);
-	}
+	/* Alsa doesn't have continuous buffers, instead it has buffers with power of 2,
+	 * If DS_TIME_DEL is about 10 ms, 512 * nBlockAlign is roughly correct */
+	fraglen = 512 * nBlockAlign;
+
+	/* Compensate for only being roughly accurate */
+	if (device->pwfx->nSamplesPerSec <= 26000)
+		fraglen /= 2;
+
+	if (device->pwfx->nSamplesPerSec <= 12000)
+		fraglen /= 2;
+
+	if (device->pwfx->nSamplesPerSec >= 80000)
+		fraglen *= 2;
+
+	/* If in emulation mode, reduce fragment size until an integer number of them fits in the buffer */
+	if (!device->driver)
+		while (device->buflen % fraglen)
+			fraglen -= nBlockAlign;
+	device->fraglen = fraglen;
+	device->helfrags = device->buflen / fraglen;
+	TRACE("fraglen=%d helfrags=%d\n", device->fraglen, device->helfrags);
+
 	if (device->hwbuf && device->drvdesc.dwFlags & DSDDESC_DONTNEEDWRITELEAD)
 		device->writelead = 0;
 	else
@@ -79,6 +80,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
 	/* are we using waveOut stuff? */
 	if (!device->driver) {
 		LPBYTE newbuf;
+		LPWAVEHDR headers = NULL;
 		DWORD buflen;
 		HRESULT merr = DS_OK;
 		/* Start in pause mode, to allow buffers to get filled */
@@ -89,6 +91,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
 		/* on original windows, the buffer it set to a fixed size, no matter what the settings are.
 		   on windows this size is always fixed (tested on win-xp) */
 		buflen = ds_hel_buflen;
+		buflen -= ds_hel_buflen % device->pwfx->nBlockAlign;
 
 		TRACE("desired buflen=%d, old buffer=%p\n", buflen, device->buffer);
 
@@ -98,6 +101,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
 		else
 			newbuf = HeapAlloc(GetProcessHeap(),0,buflen);
 
+
 		if (newbuf == NULL) {
 			ERR("failed to allocate primary buffer\n");
 			merr = DSERR_OUTOFMEMORY;
@@ -108,27 +112,38 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
 			device->buffer = newbuf;
 			device->buflen = buflen;
 		}
-		if (device->buffer) {
+
+		DSOUND_RecalcPrimary(device);
+		if (device->pwave)
+			headers = HeapReAlloc(GetProcessHeap(),0,device->pwave, device->helfrags * sizeof(WAVEHDR));
+		else
+			headers = HeapAlloc(GetProcessHeap(),0,device->helfrags * sizeof(WAVEHDR));
+
+		if (!headers) {
+			ERR("failed to allocate wave headers\n");
+			merr = DSERR_OUTOFMEMORY;
+		}
+		else if (device->buffer) {
 			unsigned c;
 
-			device->fraglen = device->buflen / DS_HEL_FRAGS;
+			device->pwave = headers;
 
 			/* sanity */
-			if(device->buflen % DS_HEL_FRAGS){
-				ERR("Bad DS_HEL_FRAGS resolution\n");
+			if(device->buflen % device->helfrags){
+				ERR("Bad helfrags resolution\n");
 			}
 
 			/* prepare fragment headers */
-			for (c=0; c<DS_HEL_FRAGS; c++) {
-				device->pwave[c]->lpData = (char*)device->buffer + c*device->fraglen;
-				device->pwave[c]->dwBufferLength = device->fraglen;
-				device->pwave[c]->dwUser = (DWORD)device;
-				device->pwave[c]->dwFlags = 0;
-				device->pwave[c]->dwLoops = 0;
-				err = mmErr(waveOutPrepareHeader(device->hwo,device->pwave[c],sizeof(WAVEHDR)));
+			for (c=0; c<device->helfrags; c++) {
+				device->pwave[c].lpData = (char*)device->buffer + c*device->fraglen;
+				device->pwave[c].dwBufferLength = device->fraglen;
+				device->pwave[c].dwUser = (DWORD)device;
+				device->pwave[c].dwFlags = 0;
+				device->pwave[c].dwLoops = 0;
+				err = mmErr(waveOutPrepareHeader(device->hwo,&device->pwave[c],sizeof(WAVEHDR)));
 				if (err != DS_OK) {
 					while (c--)
-						waveOutUnprepareHeader(device->hwo,device->pwave[c],sizeof(WAVEHDR));
+						waveOutUnprepareHeader(device->hwo,&device->pwave[c],sizeof(WAVEHDR));
 					break;
 				}
 			}
@@ -160,6 +175,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
 		device->mixpos = 0;
 		FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
 	}
+	DSOUND_RecalcPrimary(device);
 
 	return err;
 }
@@ -178,8 +194,8 @@ static void DSOUND_PrimaryClose(DirectSoundDevice *device)
 		/* **** */
 		device->pwqueue = (DWORD)-1; /* resetting queues */
 		waveOutReset(device->hwo);
-		for (c=0; c<DS_HEL_FRAGS; c++)
-			waveOutUnprepareHeader(device->hwo, device->pwave[c], sizeof(WAVEHDR));
+		for (c=0; c<device->helfrags; c++)
+			waveOutUnprepareHeader(device->hwo, &device->pwave[c], sizeof(WAVEHDR));
 		/* **** */
 		EnterCriticalSection(&(device->mixlock));
 
@@ -212,21 +228,6 @@ HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device)
 			return err;
 		}
 	}
-	if (!device->hwbuf) {
-		/* Allocate memory for HEL buffer headers */
-		unsigned c;
-		for (c=0; c<DS_HEL_FRAGS; c++) {
-			device->pwave[c] = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEHDR));
-			if (!device->pwave[c]) {
-				/* Argh, out of memory */
-				while (c--) {
-					HeapFree(GetProcessHeap(),0,device->pwave[c]);
-				}
-				WARN("out of memory\n");
-				return DSERR_OUTOFMEMORY;
-			}
-		}
-	}
 
 	err = DSOUND_PrimaryOpen(device);
 
@@ -235,8 +236,6 @@ HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device)
 		return err;
 	}
 
-	/* calculate fragment size and write lead */
-	DSOUND_RecalcPrimary(device);
 	device->state = STATE_STOPPED;
 	return DS_OK;
 }
@@ -255,10 +254,8 @@ HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device)
 				device->hwbuf = 0;
 		}
 	} else {
-		unsigned c;
-		for (c=0; c<DS_HEL_FRAGS; c++) {
-			HeapFree(GetProcessHeap(),0,device->pwave[c]);
-		}
+		if (device->pwave)
+			HeapFree(GetProcessHeap(),0,device->pwave);
 	}
         HeapFree(GetProcessHeap(),0,device->pwfx);
         device->pwfx=NULL;
@@ -459,8 +456,8 @@ HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex)
 			goto done;
 		}
                 /* FIXME: should we set err back to DS_OK in all cases ? */
+		DSOUND_RecalcPrimary(device);
 	}
-	DSOUND_RecalcPrimary(device);
 
 	if (nSamplesPerSec != device->pwfx->nSamplesPerSec) {
 		IDirectSoundBufferImpl** dsb = device->buffers;




More information about the wine-cvs mailing list