[PATCH 3/3] dsound: Mix float natively

Andrew Eikum aeikum at codeweavers.com
Thu May 12 08:43:44 CDT 2016


From: Maarten Lankhorst <wine at mblankhorst.nl>

Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
---
 dlls/dsound/dsound.c         |  1 -
 dlls/dsound/dsound_convert.c | 20 +----------------
 dlls/dsound/dsound_private.h |  4 ++--
 dlls/dsound/mixer.c          | 53 ++++++++++++++++++++++++--------------------
 dlls/dsound/primary.c        | 14 +-----------
 5 files changed, 33 insertions(+), 59 deletions(-)

diff --git a/dlls/dsound/dsound.c b/dlls/dsound/dsound.c
index 2d145a6..0b5c3b4 100644
--- a/dlls/dsound/dsound.c
+++ b/dlls/dsound/dsound.c
@@ -238,7 +238,6 @@ static ULONG DirectSoundDevice_Release(DirectSoundDevice * device)
             IAudioStreamVolume_Release(device->volume);
 
         HeapFree(GetProcessHeap(), 0, device->tmp_buffer);
-        HeapFree(GetProcessHeap(), 0, device->mix_buffer);
         HeapFree(GetProcessHeap(), 0, device->buffer);
         RtlDeleteResource(&device->buffer_list_lock);
         device->mixlock.DebugInfo->Spare[0] = 0;
diff --git a/dlls/dsound/dsound_convert.c b/dlls/dsound/dsound_convert.c
index 5accba6..4ae83ba 100644
--- a/dlls/dsound/dsound_convert.c
+++ b/dlls/dsound/dsound_convert.c
@@ -263,27 +263,9 @@ static void norm32(float *src, INT *dst, unsigned len)
     }
 }
 
-static void normieee32(float *src, float *dst, unsigned len)
-{
-    TRACE("%p - %p %d\n", src, dst, len);
-    len /= 4;
-    while (len--)
-    {
-        if(*src > 1)
-            *dst = 1;
-        else if(*src < -1)
-            *dst = -1;
-        else
-            *dst = *src;
-        ++dst;
-        ++src;
-    }
-}
-
-const normfunc normfunctions[5] = {
+const normfunc normfunctions[4] = {
     (normfunc)norm8,
     (normfunc)norm16,
     (normfunc)norm24,
     (normfunc)norm32,
-    (normfunc)normieee32
 };
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
index 918839e..b980453 100644
--- a/dlls/dsound/dsound_private.h
+++ b/dlls/dsound/dsound_private.h
@@ -49,7 +49,7 @@ extern const bitsgetfunc getbpp[5] DECLSPEC_HIDDEN;
 void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN;
 void mixieee32(float *src, float *dst, unsigned samples) DECLSPEC_HIDDEN;
 typedef void (*normfunc)(const void *, void *, unsigned);
-extern const normfunc normfunctions[5] DECLSPEC_HIDDEN;
+extern const normfunc normfunctions[4] DECLSPEC_HIDDEN;
 
 typedef struct _DSVOLUMEPAN
 {
@@ -87,7 +87,7 @@ struct DirectSoundDevice
     int                         speaker_num[DS_MAX_CHANNELS];
     int                         num_speakers;
     int                         lfe_channel;
-    float *mix_buffer, *tmp_buffer;
+    float *tmp_buffer;
     DWORD                       tmp_buffer_len, mix_buffer_len;
 
     DSVOLUMEPAN                 volpan;
diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c
index 6ac4e3d..dec8ffd 100644
--- a/dlls/dsound/mixer.c
+++ b/dlls/dsound/mixer.c
@@ -468,7 +468,7 @@ static void DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT frames)
  * writepos = position (offset) in device buffer to write at
  * fraglen = number of bytes to mix
  */
-static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD fraglen)
+static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, float *mix_buffer, DWORD writepos, DWORD fraglen)
 {
 	INT len = fraglen;
 	float *ibuf;
@@ -493,7 +493,7 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO
 	/* Apply volume if needed */
 	DSOUND_MixerVol(dsb, frames);
 
-	mixieee32(ibuf, dsb->device->mix_buffer, frames * dsb->device->pwfx->nChannels);
+	mixieee32(ibuf, mix_buffer, frames * dsb->device->pwfx->nChannels);
 
 	/* check for notification positions */
 	if (dsb->dsbd.dwFlags & DSBCAPS_CTRLPOSITIONNOTIFY &&
@@ -517,7 +517,7 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO
  *
  * Returns: the number of bytes beyond the writepos that were mixed.
  */
-static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mixlen)
+static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, float *mix_buffer, DWORD writepos, DWORD mixlen)
 {
 	DWORD primary_done = 0;
 
@@ -544,7 +544,7 @@ static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mi
 	/* First try to mix to the end of the buffer if possible
 	 * Theoretically it would allow for better optimization
 	*/
-	primary_done += DSOUND_MixInBuffer(dsb, writepos, mixlen);
+	primary_done += DSOUND_MixInBuffer(dsb, mix_buffer, writepos, mixlen);
 
 	TRACE("total mixed data=%d\n", primary_done);
 
@@ -559,14 +559,12 @@ static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mi
  * writepos = the current safe-to-write position in the primary buffer
  * mixlen = the maximum amount to mix into the primary buffer
  *          (beyond the current writepos)
- * recover = true if the sound device may have been reset and the write
- *           position in the device buffer changed
  * 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, DWORD writepos, DWORD mixlen, BOOL recover, BOOL *all_stopped)
+static void DSOUND_MixToPrimary(const DirectSoundDevice *device, float *mix_buffer, DWORD writepos, DWORD mixlen, BOOL *all_stopped)
 {
 	INT i;
 	IDirectSoundBufferImpl	*dsb;
@@ -574,7 +572,7 @@ static void DSOUND_MixToPrimary(const DirectSoundDevice *device, DWORD writepos,
 	/* unless we find a running buffer, all have stopped */
 	*all_stopped = TRUE;
 
-	TRACE("(%d,%d,%d)\n", writepos, mixlen, recover);
+	TRACE("(%d,%d)\n", writepos, mixlen);
 	for (i = 0; i < device->nrofbuffers; i++) {
 		dsb = device->buffers[i];
 
@@ -594,7 +592,7 @@ static void DSOUND_MixToPrimary(const DirectSoundDevice *device, DWORD writepos,
 					dsb->state = STATE_PLAYING;
 
 				/* mix next buffer into the main buffer */
-				DSOUND_MixOne(dsb, writepos, mixlen);
+				DSOUND_MixOne(dsb, mix_buffer, writepos, mixlen);
 
 				*all_stopped = FALSE;
 			}
@@ -646,8 +644,7 @@ done:
  * secondary->buffer (secondary format)
  *   =[Resample]=> device->tmp_buffer (float format)
  *   =[Volume]=> device->tmp_buffer (float format)
- *   =[Mix]=> device->mix_buffer (float format)
- *   =[Reformat]=> device->buffer (device format)
+ *   =[Reformat]=> device->buffer (device format, skipped on float)
  */
 static void DSOUND_PerformMix(DirectSoundDevice *device)
 {
@@ -686,7 +683,7 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
 	if (device->priolevel != DSSCL_WRITEPRIMARY) {
 		BOOL all_stopped = FALSE;
 		int nfiller;
-		DWORD bpp = device->pwfx->wBitsPerSample>>3;
+		void *buffer = NULL;
 
 		/* the sound of silence */
 		nfiller = device->pwfx->wBitsPerSample == 8 ? 128 : 0;
@@ -700,24 +697,32 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
 			TRACE("Buffer restarting\n");
 		}
 
-		memset(device->mix_buffer, nfiller, maxq);
+		hr = IAudioRenderClient_GetBuffer(device->render, maxq / block, (void*)&buffer);
+		if(FAILED(hr)){
+			WARN("GetBuffer failed: %08x\n", hr);
+			LeaveCriticalSection(&device->mixlock);
+			return;
+		}
 
-		/* do the mixing */
-		DSOUND_MixToPrimary(device, writepos, maxq, TRUE, &all_stopped);
+		memset(buffer, nfiller, maxq);
 
-		if (maxq + writepos > device->buflen) {
-			DWORD todo = device->buflen - writepos;
+		if (!device->normfunction)
+			DSOUND_MixToPrimary(device, buffer, writepos, maxq, &all_stopped);
+		else {
+			memset(device->buffer, nfiller, device->buflen);
 
-			device->normfunction(device->mix_buffer, device->buffer + writepos, todo);
-			DSOUND_WaveQueue(device, device->buffer + writepos, todo);
+			/* do the mixing */
+			DSOUND_MixToPrimary(device, (float*)device->buffer, writepos, maxq, &all_stopped);
 
-			device->normfunction(device->mix_buffer + todo / bpp, device->buffer, (maxq - todo));
-			DSOUND_WaveQueue(device, device->buffer, maxq - todo);
-		} else {
-			device->normfunction(device->mix_buffer, device->buffer + writepos, maxq);
-			DSOUND_WaveQueue(device, device->buffer + writepos, maxq);
+			device->normfunction(device->buffer, buffer, maxq);
 		}
 
+		hr = IAudioRenderClient_ReleaseBuffer(device->render, maxq / block, 0);
+		if(FAILED(hr))
+			ERR("ReleaseBuffer failed: %08x\n", hr);
+
+		device->pad += maxq;
+
 		if (maxq) {
 			if (device->state == STATE_STARTING ||
 			    device->state == STATE_STOPPED) {
diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c
index bdab0ee..1925d0c 100644
--- a/dlls/dsound/primary.c
+++ b/dlls/dsound/primary.c
@@ -338,11 +338,7 @@ HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
 		device->buflen = ds_hel_buflen;
 	device->buflen -= device->buflen % device->pwfx->nBlockAlign;
 
-	HeapFree(GetProcessHeap(), 0, device->mix_buffer);
 	device->mix_buffer_len = (device->buflen / (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;
 
 	if (device->state == STATE_PLAYING) device->state = STATE_STARTING;
 	else if (device->state == STATE_STOPPING) device->state = STATE_STOPPED;
@@ -370,21 +366,13 @@ HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
             (device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
              IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat,
                  &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)))
-        device->normfunction = normfunctions[4];
+        device->normfunction = NULL;
     else
         device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
 
     FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
-    FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
     device->playpos = 0;
 
-    if (device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
-	 (device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
-	  IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)))
-        device->normfunction = normfunctions[4];
-    else
-        device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
-
     for (i = 0; i < device->nrofbuffers; i++) {
         RtlAcquireResourceExclusive(&dsb[i]->lock, TRUE);
         DSOUND_RecalcFormat(dsb[i]);
-- 
2.8.2




More information about the wine-patches mailing list