Andrew Eikum : dsound: Compute mix buffer's size more accurately.

Alexandre Julliard julliard at winehq.org
Tue May 15 12:55:58 CDT 2012


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

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Mon May 14 15:20:02 2012 -0500

dsound: Compute mix buffer's size more accurately.

---

 dlls/dsound/dsound_private.h |    4 +-
 dlls/dsound/mixer.c          |   44 ++++++++---------------------------------
 dlls/dsound/primary.c        |    8 +-----
 3 files changed, 13 insertions(+), 43 deletions(-)

diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
index 375abac..26e59ff 100644
--- a/dlls/dsound/dsound_private.h
+++ b/dlls/dsound/dsound_private.h
@@ -94,7 +94,8 @@ struct DirectSoundDevice
     CRITICAL_SECTION            mixlock;
     IDirectSoundBufferImpl     *primary;
     DWORD                       speaker_config;
-    LPBYTE                      tmp_buffer, mix_buffer;
+    LPBYTE                      tmp_buffer;
+    float *mix_buffer;
     DWORD                       tmp_buffer_len, mix_buffer_len;
 
     DSVOLUMEPAN                 volpan;
@@ -294,7 +295,6 @@ LONG capped_refcount_dec(LONG *ref) DECLSPEC_HIDDEN;
 HRESULT DSOUND_FullDuplexCreate(REFIID riid, LPDIRECTSOUNDFULLDUPLEX* ppDSFD) DECLSPEC_HIDDEN;
 
 /* mixer.c */
-DWORD DSOUND_bufpos_to_mixpos(const DirectSoundDevice* device, DWORD pos) DECLSPEC_HIDDEN;
 void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len) DECLSPEC_HIDDEN;
 void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN;
 void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN;
diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c
index a940a85..9d4b35b 100644
--- a/dlls/dsound/mixer.c
+++ b/dlls/dsound/mixer.c
@@ -96,19 +96,6 @@ void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan)
     TRACE("Vol=%d Pan=%d\n", volpan->lVolume, volpan->lPan);
 }
 
-/** Convert a primary buffer position to a pointer position for device->mix_buffer
- * device: DirectSoundDevice for which to calculate
- * pos: Primary buffer position to converts
- * Returns: Offset for mix_buffer
- */
-DWORD DSOUND_bufpos_to_mixpos(const DirectSoundDevice* device, DWORD pos)
-{
-    DWORD ret = pos * 32 / device->pwfx->wBitsPerSample;
-    if (device->pwfx->wBitsPerSample == 32)
-        ret *= 2;
-    return ret;
-}
-
 /**
  * Recalculate the size for temporary buffer, and new writelead
  * Should be called when one of the following things occur:
@@ -480,7 +467,7 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO
 {
 	INT len = fraglen;
 	BYTE *ibuf, *volbuf;
-	DWORD oldpos, mixbufpos;
+	DWORD oldpos;
 
 	TRACE("sec_mixpos=%d/%d\n", dsb->sec_mixpos, dsb->buflen);
 	TRACE("(%p,%d,%d)\n",dsb,writepos,fraglen);
@@ -502,16 +489,7 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO
 	if (volbuf)
 		ibuf = volbuf;
 
-	mixbufpos = DSOUND_bufpos_to_mixpos(dsb->device, writepos);
-	/* Now mix the temporary buffer into the devices main buffer */
-	if ((writepos + len) <= dsb->device->buflen)
-		dsb->device->mixfunction(ibuf, dsb->device->mix_buffer + mixbufpos, len);
-	else
-	{
-		DWORD todo = dsb->device->buflen - writepos;
-		dsb->device->mixfunction(ibuf, dsb->device->mix_buffer + mixbufpos, todo);
-		dsb->device->mixfunction(ibuf + todo, dsb->device->mix_buffer, len - todo);
-	}
+	dsb->device->mixfunction(ibuf, dsb->device->mix_buffer, len);
 
 	/* check for notification positions */
 	if (dsb->dsbd.dwFlags & DSBCAPS_CTRLPOSITIONNOTIFY &&
@@ -754,7 +732,7 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
 
 	if (device->priolevel != DSSCL_WRITEPRIMARY) {
 		BOOL recover = FALSE, all_stopped = FALSE;
-		DWORD playpos, writepos, writelead, maxq, prebuff_max, prebuff_left, size1, size2, mixplaypos, mixplaypos2;
+		DWORD playpos, writepos, writelead, maxq, prebuff_max, prebuff_left, size1, size2;
 		LPVOID buf1, buf2;
 		int nfiller;
 
@@ -771,9 +749,6 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
 			playpos,writepos,device->playpos,device->mixpos,device->buflen);
 		assert(device->playpos < device->buflen);
 
-		mixplaypos = DSOUND_bufpos_to_mixpos(device, device->playpos);
-		mixplaypos2 = DSOUND_bufpos_to_mixpos(device, playpos);
-
 		/* calc maximum prebuff */
 		prebuff_max = (device->prebuf * device->fraglen);
 
@@ -794,15 +769,12 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
 			/* reset mix position to write position */
 			device->mixpos = writepos;
 
-			ZeroMemory(device->mix_buffer, device->mix_buffer_len);
 			ZeroMemory(device->buffer, device->buflen);
 		} else if (playpos < device->playpos) {
 			buf1 = device->buffer + device->playpos;
 			buf2 = device->buffer;
 			size1 = device->buflen - device->playpos;
 			size2 = playpos;
-			FillMemory(device->mix_buffer + mixplaypos, device->mix_buffer_len - mixplaypos, 0);
-			FillMemory(device->mix_buffer, mixplaypos2, 0);
 			FillMemory(buf1, size1, nfiller);
 			if (playpos && (!buf2 || !size2))
 				FIXME("%d: (%d, %d)=>(%d, %d) There should be an additional buffer here!!\n", __LINE__, device->playpos, device->mixpos, playpos, writepos);
@@ -812,7 +784,6 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
 			buf2 = NULL;
 			size1 = playpos - device->playpos;
 			size2 = 0;
-			FillMemory(device->mix_buffer + mixplaypos, mixplaypos2 - mixplaypos, 0);
 			FillMemory(buf1, size1, nfiller);
 		}
 		device->playpos = playpos;
@@ -823,17 +794,20 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
 		TRACE("prebuff_left = %d, prebuff_max = %dx%d=%d, writelead=%d\n",
 			prebuff_left, device->prebuf, device->fraglen, prebuff_max, writelead);
 
+		ZeroMemory(device->mix_buffer, device->mix_buffer_len);
+
 		/* do the mixing */
 		DSOUND_MixToPrimary(device, writepos, maxq, recover, &all_stopped);
 
 		if (maxq + writepos > device->buflen)
 		{
 			DWORD todo = device->buflen - writepos;
-			device->normfunction(device->mix_buffer + DSOUND_bufpos_to_mixpos(device, writepos), device->buffer + writepos, todo);
-			device->normfunction(device->mix_buffer, device->buffer, maxq - todo);
+			DWORD offs_float = (todo / device->pwfx->nBlockAlign) * device->pwfx->nChannels;
+			device->normfunction(device->mix_buffer, device->buffer + writepos, todo);
+			device->normfunction(device->mix_buffer + offs_float, device->buffer, maxq - todo);
 		}
 		else
-			device->normfunction(device->mix_buffer + DSOUND_bufpos_to_mixpos(device, writepos), device->buffer + writepos, maxq);
+			device->normfunction(device->mix_buffer, device->buffer + writepos, maxq);
 
 		/* update the mix position, taking wrap-around into account */
 		device->mixpos = writepos + maxq;
diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c
index ff79a70..6633124 100644
--- a/dlls/dsound/primary.c
+++ b/dlls/dsound/primary.c
@@ -159,8 +159,8 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
 
 	device->helfrags = device->buflen / device->fraglen;
 
-	device->mix_buffer_len = DSOUND_bufpos_to_mixpos(device, device->buflen);
-	device->mix_buffer = HeapAlloc(GetProcessHeap(), 0, device->mix_buffer_len);
+	device->mix_buffer_len = ((device->prebuf * device->fraglen) / (device->pwfx->wBitsPerSample / 8)) * sizeof(float);
+	device->mix_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, device->mix_buffer_len);
 	if (!device->mix_buffer)
 		return DSERR_OUTOFMEMORY;
 
@@ -512,10 +512,6 @@ opened:
 			WARN("DSOUND_PrimaryOpen(2) failed: %08x\n", err);
 	}
 
-	device->mix_buffer_len = DSOUND_bufpos_to_mixpos(device, device->buflen);
-	device->mix_buffer = HeapReAlloc(GetProcessHeap(), 0, device->mix_buffer, device->mix_buffer_len);
-	FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
-
 	if(device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
 			(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
 			 IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat,




More information about the wine-cvs mailing list