[PATCH 2/4] dsound: Use frame rather than byte counts to clarify the mixing.

Huw Davies huw at codeweavers.com
Wed Mar 1 04:19:43 CST 2017


Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/dsound/dsound_private.h |  2 +-
 dlls/dsound/mixer.c          | 93 ++++++++++++++++++++------------------------
 dlls/dsound/primary.c        |  8 ++--
 3 files changed, 47 insertions(+), 56 deletions(-)

diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
index 63d1226..b15189e 100644
--- a/dlls/dsound/dsound_private.h
+++ b/dlls/dsound/dsound_private.h
@@ -77,7 +77,7 @@ struct DirectSoundDevice
     DWORD                       priolevel, sleeptime;
     PWAVEFORMATEX               pwfx, primary_pwfx;
     LPBYTE                      buffer;
-    DWORD                       writelead, buflen, aclen, fraglen, playpos, pad, stopped;
+    DWORD                       writelead, buflen, ac_frames, frag_frames, playpos, pad, stopped;
     int                         nrofbuffers;
     IDirectSoundBufferImpl**    buffers;
     RTL_RWLOCK                  buffer_list_lock;
diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c
index 174d56c..9e68304 100644
--- a/dlls/dsound/mixer.c
+++ b/dlls/dsound/mixer.c
@@ -489,21 +489,13 @@ static void DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT frames)
  * dsb  = the secondary buffer to mix from
  * fraglen = number of bytes to mix
  */
-static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, float *mix_buffer, DWORD fraglen)
+static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, float *mix_buffer, DWORD frames)
 {
-	INT len = fraglen;
 	float *ibuf;
 	DWORD oldpos;
-	UINT frames = fraglen / dsb->device->pwfx->nBlockAlign;
 
 	TRACE("sec_mixpos=%d/%d\n", dsb->sec_mixpos, dsb->buflen);
-	TRACE("(%p,%d)\n",dsb,fraglen);
-
-	if (len % dsb->device->pwfx->nBlockAlign) {
-		INT nBlockAlign = dsb->device->pwfx->nBlockAlign;
-		ERR("length not a multiple of block size, len = %d, block size = %d\n", len, nBlockAlign);
-		len -= len % nBlockAlign; /* data alignment */
-	}
+	TRACE("(%p, frames=%d)\n",dsb,frames);
 
 	/* Resample buffer to temporary buffer specifically allocated for this purpose, if needed */
 	oldpos = dsb->sec_mixpos;
@@ -522,7 +514,7 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, float *mix_buffer,
 		DSOUND_CheckEvent(dsb, oldpos, ilen);
 	}
 
-	return len;
+	return frames;
 }
 
 /**
@@ -531,37 +523,37 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, float *mix_buffer,
  *
  * dsb = the secondary buffer
  * playpos = the current play position in the device buffer (primary buffer)
- * mixlen = the maximum number of bytes in the primary buffer to mix, from the
+ * frames = the maximum number of frames in the primary buffer to mix, from the
  *          current writepos.
  *
- * Returns: the number of bytes beyond the writepos that were mixed.
+ * Returns: the number of frames beyond the writepos that were mixed.
  */
-static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, float *mix_buffer, DWORD mixlen)
+static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, float *mix_buffer, DWORD frames)
 {
 	DWORD primary_done = 0;
 
-	TRACE("(%p,%d)\n",dsb,mixlen);
+	TRACE("(%p, frames=%d)\n",dsb,frames);
 	TRACE("looping=%d, leadin=%d\n", dsb->playflags, dsb->leadin);
 
 	/* If leading in, only mix about 20 ms, and 'skip' mixing the rest, for more fluid pointer advancement */
 	/* FIXME: Is this needed? */
 	if (dsb->leadin && dsb->state == STATE_STARTING) {
-		if (mixlen > 2 * dsb->device->fraglen) {
-			primary_done = mixlen - 2 * dsb->device->fraglen;
-			mixlen = 2 * dsb->device->fraglen;
-			dsb->sec_mixpos += (primary_done / dsb->device->pwfx->nBlockAlign) *
+		if (frames > 2 * dsb->device->frag_frames) {
+			primary_done = frames - 2 * dsb->device->frag_frames;
+			frames = 2 * dsb->device->frag_frames;
+			dsb->sec_mixpos += primary_done *
 				dsb->pwfx->nBlockAlign * dsb->freqAdjustNum / dsb->freqAdjustDen;
 		}
 	}
 
 	dsb->leadin = FALSE;
 
-	TRACE("mixlen (primary) = %i\n", mixlen);
+	TRACE("frames (primary) = %i\n", frames);
 
 	/* First try to mix to the end of the buffer if possible
 	 * Theoretically it would allow for better optimization
 	*/
-	primary_done += DSOUND_MixInBuffer(dsb, mix_buffer, mixlen);
+	primary_done += DSOUND_MixInBuffer(dsb, mix_buffer, frames);
 
 	TRACE("total mixed data=%d\n", primary_done);
 
@@ -573,14 +565,13 @@ static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, float *mix_buffer, DWORD
  * For a DirectSoundDevice, go through all the currently playing buffers and
  * mix them in to the device buffer.
  *
- * mixlen = the maximum amount to mix into the primary buffer
- *          (beyond the current writepos)
+ * frames = the maximum amount to mix into the primary buffer
  * all_stopped = reports back if all buffers have stopped
  *
  * Returns:  the length beyond the writepos that was mixed to.
  */
 
-static void DSOUND_MixToPrimary(const DirectSoundDevice *device, float *mix_buffer, DWORD mixlen, BOOL *all_stopped)
+static void DSOUND_MixToPrimary(const DirectSoundDevice *device, float *mix_buffer, DWORD frames, BOOL *all_stopped)
 {
 	INT i;
 	IDirectSoundBufferImpl	*dsb;
@@ -588,14 +579,14 @@ static void DSOUND_MixToPrimary(const DirectSoundDevice *device, float *mix_buff
 	/* unless we find a running buffer, all have stopped */
 	*all_stopped = TRUE;
 
-	TRACE("(%d)\n", mixlen);
+	TRACE("(frames %d)\n", frames);
 	for (i = 0; i < device->nrofbuffers; i++) {
 		dsb = device->buffers[i];
 
 		TRACE("MixToPrimary for %p, state=%d\n", dsb, dsb->state);
 
 		if (dsb->buflen && dsb->state) {
-			TRACE("Checking %p, mixlen=%d\n", dsb, mixlen);
+			TRACE("Checking %p, frames=%d\n", dsb, frames);
 			RtlAcquireResourceShared(&dsb->lock, TRUE);
 			/* if buffer is stopping it is stopped now */
 			if (dsb->state == STATE_STOPPING) {
@@ -608,7 +599,7 @@ static void DSOUND_MixToPrimary(const DirectSoundDevice *device, float *mix_buff
 					dsb->state = STATE_PLAYING;
 
 				/* mix next buffer into the main buffer */
-				DSOUND_MixOne(dsb, mix_buffer, mixlen);
+				DSOUND_MixOne(dsb, mix_buffer, frames);
 
 				*all_stopped = FALSE;
 			}
@@ -666,8 +657,7 @@ static void DSOUND_WaveQueue(DirectSoundDevice *device, LPBYTE pos, DWORD bytes)
  */
 static void DSOUND_PerformMix(DirectSoundDevice *device)
 {
-	UINT32 pad, maxq;
-	DWORD block;
+        DWORD block, pad_frames, pad_bytes, frames;;
 	HRESULT hr;
 
 	TRACE("(%p)\n", device);
@@ -675,26 +665,26 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
 	/* **** */
 	EnterCriticalSection(&device->mixlock);
 
-	hr = IAudioClient_GetCurrentPadding(device->client, &pad);
+	hr = IAudioClient_GetCurrentPadding(device->client, &pad_frames);
 	if(FAILED(hr)){
 		WARN("GetCurrentPadding failed: %08x\n", hr);
 		LeaveCriticalSection(&device->mixlock);
 		return;
 	}
 	block = device->pwfx->nBlockAlign;
-	pad *= block;
-	device->playpos += device->pad - pad;
+	pad_bytes = pad_frames * block;
+	device->playpos += device->pad - pad_bytes;
 	device->playpos %= device->buflen;
-	device->pad = pad;
+	device->pad = pad_bytes;
 
-	maxq = device->aclen - pad;
-	if(!maxq){
+	frames = device->ac_frames - pad_frames;
+	if(!frames){
 		/* nothing to do! */
 		LeaveCriticalSection(&device->mixlock);
 		return;
 	}
-	if (maxq > device->fraglen * 3)
-		maxq = device->fraglen * 3;
+	if (frames > device->frag_frames * 3)
+		frames = device->frag_frames * 3;
 
 	if (device->priolevel != DSSCL_WRITEPRIMARY) {
 		BOOL all_stopped = FALSE;
@@ -706,44 +696,45 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
 
 		/* check for underrun. underrun occurs when the write position passes the mix position
 		 * also wipe out just-played sound data */
-		if (!pad)
+		if (!pad_frames)
 			WARN("Probable buffer underrun\n");
 
-		hr = IAudioRenderClient_GetBuffer(device->render, maxq / block, (void*)&buffer);
+		hr = IAudioRenderClient_GetBuffer(device->render, frames, (void*)&buffer);
 		if(FAILED(hr)){
 			WARN("GetBuffer failed: %08x\n", hr);
 			LeaveCriticalSection(&device->mixlock);
 			return;
 		}
 
-		memset(buffer, nfiller, maxq);
+		memset(buffer, nfiller, frames * block);
 
 		if (!device->normfunction)
-			DSOUND_MixToPrimary(device, buffer, maxq, &all_stopped);
+			DSOUND_MixToPrimary(device, buffer, frames, &all_stopped);
 		else {
 			memset(device->buffer, nfiller, device->buflen);
 
 			/* do the mixing */
-			DSOUND_MixToPrimary(device, (float*)device->buffer, maxq, &all_stopped);
+			DSOUND_MixToPrimary(device, (float*)device->buffer, frames, &all_stopped);
 
-			device->normfunction(device->buffer, buffer, maxq);
+			device->normfunction(device->buffer, buffer, frames * block);
 		}
 
-		hr = IAudioRenderClient_ReleaseBuffer(device->render, maxq / block, 0);
+		hr = IAudioRenderClient_ReleaseBuffer(device->render, frames, 0);
 		if(FAILED(hr))
 			ERR("ReleaseBuffer failed: %08x\n", hr);
 
-		device->pad += maxq;
+		device->pad += frames * block;
 	} else if (!device->stopped) {
-                DWORD writepos = (device->playpos + pad) % device->buflen;
+                DWORD writepos = (device->playpos + pad_bytes) % device->buflen;
+                DWORD bytes = frames * block;
 
-		if (maxq > device->buflen)
-			maxq = device->buflen;
-		if (writepos + maxq > device->buflen) {
+		if (bytes > device->buflen)
+			bytes = device->buflen;
+		if (writepos + bytes > device->buflen) {
 			DSOUND_WaveQueue(device, device->buffer + writepos, device->buflen - writepos);
-			DSOUND_WaveQueue(device, device->buffer, writepos + maxq - device->buflen);
+			DSOUND_WaveQueue(device, device->buffer, writepos + bytes - device->buflen);
 		} else
-			DSOUND_WaveQueue(device, device->buffer + writepos, maxq);
+			DSOUND_WaveQueue(device, device->buffer + writepos, bytes);
 	}
 
 	LeaveCriticalSection(&(device->mixlock));
diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c
index 87b7e8e..6eb5a98 100644
--- a/dlls/dsound/primary.c
+++ b/dlls/dsound/primary.c
@@ -264,7 +264,7 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device, WAVEFORMATEX *wfx,
 
     device->writelead = (wfx->nSamplesPerSec / 100) * wfx->nBlockAlign;
 
-    TRACE("buflen: %u, fraglen: %u\n", device->buflen, device->fraglen);
+    TRACE("buflen: %u, frames %u\n", device->buflen, frames);
 
     if (!mixfloat)
         device->normfunction = normfunctions[wfx->wBitsPerSample/8 - 1];
@@ -351,7 +351,7 @@ HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
 
     aclen_frames = min(acbuf_frames, 3 * frag_frames);
 
-    TRACE("period %u ms fraglen %u buflen %u\n", period_ms, frag_frames * wfx->nBlockAlign, aclen_frames * wfx->nBlockAlign);
+    TRACE("period %u ms frag_frames %u buf_frames %u\n", period_ms, frag_frames, aclen_frames);
 
     hres = DSOUND_PrimaryOpen(device, wfx, aclen_frames, forcewave);
     if(FAILED(hres))
@@ -361,8 +361,8 @@ HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
     device->client = client;
     device->render = render;
     device->volume = volume;
-    device->fraglen = frag_frames * wfx->nBlockAlign;
-    device->aclen = aclen_frames * wfx->nBlockAlign;
+    device->frag_frames = frag_frames;
+    device->ac_frames = aclen_frames;
 
     if (period_ms < 3)
         device->sleeptime = 5;
-- 
2.10.2




More information about the wine-patches mailing list