dsound: Don't convert single samples at a time.

Henri Verbeet hverbeet at codeweavers.com
Thu Jan 15 02:58:45 CST 2009


This gives a minor performance improvement.
---
 dlls/dsound/dsound_convert.c |  250 +++++++++++++++++++++++++++++++-----------
 dlls/dsound/dsound_private.h |    2 +-
 dlls/dsound/mixer.c          |   34 ++----
 3 files changed, 197 insertions(+), 89 deletions(-)

diff --git a/dlls/dsound/dsound_convert.c b/dlls/dsound/dsound_convert.c
index 0ebce3d..0a6e474 100644
--- a/dlls/dsound/dsound_convert.c
+++ b/dlls/dsound/dsound_convert.c
@@ -58,119 +58,241 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsound);
 #define le32(x) (x)
 #endif
 
-static void convert_8_to_8 (const void *src, void *dst)
+static inline void src_advance(const void **src, UINT stride, INT *count, UINT *freqAcc, UINT adj)
 {
-    BYTE *dest = dst;
-    *dest = *(const BYTE *)src;
+    *freqAcc += adj;
+    if (*freqAcc >= (1 << DSOUND_FREQSHIFT))
+    {
+        ULONG adv = (*freqAcc >> DSOUND_FREQSHIFT);
+        *freqAcc &= (1 << DSOUND_FREQSHIFT) - 1;
+        *(const char **)src += adv * stride;
+        *count -= adv;
+    }
 }
 
-static void convert_8_to_16 (const void *src, void *dst)
+static void convert_8_to_8 (const void *src, void *dst, UINT src_stride,
+        UINT dst_stride, INT count, UINT freqAcc, UINT adj)
 {
-    WORD dest = *(const BYTE *)src, *dest16 = dst;
-    *dest16 = le16(dest * 257 - 32768);
+    while (count > 0)
+    {
+        *(BYTE *)dst = *(const BYTE *)src;
+
+        dst = (char *)dst + dst_stride;
+        src_advance(&src, src_stride, &count, &freqAcc, adj);
+    }
 }
 
-static void convert_8_to_24 (const void *src, void *dst)
+static void convert_8_to_16 (const void *src, void *dst, UINT src_stride,
+        UINT dst_stride, INT count, UINT freqAcc, UINT adj)
 {
-    BYTE dest = *(const BYTE *)src;
-    BYTE *dest24 = dst;
-    dest24[0] = dest;
-    dest24[1] = dest;
-    dest24[2] = dest - 0x80;
+    while (count > 0)
+    {
+        WORD dest = *(const BYTE *)src, *dest16 = dst;
+        *dest16 = le16(dest * 257 - 32768);
+
+        dst = (char *)dst + dst_stride;
+        src_advance(&src, src_stride, &count, &freqAcc, adj);
+    }
+}
+
+static void convert_8_to_24 (const void *src, void *dst, UINT src_stride,
+        UINT dst_stride, INT count, UINT freqAcc, UINT adj)
+{
+    while (count > 0)
+    {
+        BYTE dest = *(const BYTE *)src;
+        BYTE *dest24 = dst;
+        dest24[0] = dest;
+        dest24[1] = dest;
+        dest24[2] = dest - 0x80;
+
+        dst = (char *)dst + dst_stride;
+        src_advance(&src, src_stride, &count, &freqAcc, adj);
+    }
 }
 
-static void convert_8_to_32 (const void *src, void *dst)
+static void convert_8_to_32 (const void *src, void *dst, UINT src_stride,
+        UINT dst_stride, INT count, UINT freqAcc, UINT adj)
 {
-    DWORD dest = *(const BYTE *)src, *dest32 = dst;
-    *dest32 = le32(dest * 16843009 - 2147483648U);
+    while (count > 0)
+    {
+        DWORD dest = *(const BYTE *)src, *dest32 = dst;
+        *dest32 = le32(dest * 16843009 - 2147483648U);
+
+        dst = (char *)dst + dst_stride;
+        src_advance(&src, src_stride, &count, &freqAcc, adj);
+    }
 }
 
-static void convert_16_to_8 (const void *src, void *dst)
+static void convert_16_to_8 (const void *src, void *dst, UINT src_stride,
+        UINT dst_stride, INT count, UINT freqAcc, UINT adj)
 {
-    BYTE *dst8 = dst;
-    *dst8 = (le16(*(const WORD *)src)) / 256;
-    *dst8 -= 0x80;
+    while (count > 0)
+    {
+        BYTE *dst8 = dst;
+        *dst8 = (le16(*(const WORD *)src)) / 256;
+        *dst8 -= 0x80;
+
+        dst = (char *)dst + dst_stride;
+        src_advance(&src, src_stride, &count, &freqAcc, adj);
+    }
 }
 
-static void convert_16_to_16 (const void *src, void *dst)
+static void convert_16_to_16 (const void *src, void *dst, UINT src_stride,
+        UINT dst_stride, INT count, UINT freqAcc, UINT adj)
 {
-    WORD *dest = dst;
-    *dest = *(const WORD *)src;
+    while (count > 0)
+    {
+        *(WORD *)dst = *(const WORD *)src;
+
+        dst = (char *)dst + dst_stride;
+        src_advance(&src, src_stride, &count, &freqAcc, adj);
+    }
 }
 
-static void convert_16_to_24 (const void *src, void *dst)
+static void convert_16_to_24 (const void *src, void *dst, UINT src_stride,
+        UINT dst_stride, INT count, UINT freqAcc, UINT adj)
 {
-    WORD dest = le16(*(const WORD *)src);
-    BYTE *dest24 = dst;
+    while (count > 0)
+    {
+        WORD dest = le16(*(const WORD *)src);
+        BYTE *dest24 = dst;
 
-    dest24[0] = dest / 256;
-    dest24[1] = dest;
-    dest24[2] = dest / 256;
+        dest24[0] = dest / 256;
+        dest24[1] = dest;
+        dest24[2] = dest / 256;
+
+        dst = (char *)dst + dst_stride;
+        src_advance(&src, src_stride, &count, &freqAcc, adj);
+    }
 }
 
-static void convert_16_to_32 (const void *src, void *dst)
+static void convert_16_to_32 (const void *src, void *dst, UINT src_stride,
+        UINT dst_stride, INT count, UINT freqAcc, UINT adj)
 {
-    DWORD dest = *(const WORD *)src, *dest32 = dst;
-    *dest32 = dest * 65537;
+    while (count > 0)
+    {
+        DWORD dest = *(const WORD *)src, *dest32 = dst;
+        *dest32 = dest * 65537;
+
+        dst = (char *)dst + dst_stride;
+        src_advance(&src, src_stride, &count, &freqAcc, adj);
+    }
 }
 
-static void convert_24_to_8 (const void *src, void *dst)
+static void convert_24_to_8 (const void *src, void *dst, UINT src_stride,
+        UINT dst_stride, INT count, UINT freqAcc, UINT adj)
 {
-    BYTE *dst8 = dst;
-    *dst8 = ((const BYTE *)src)[2];
+    while (count > 0)
+    {
+        BYTE *dst8 = dst;
+        *dst8 = ((const BYTE *)src)[2];
+
+        dst = (char *)dst + dst_stride;
+        src_advance(&src, src_stride, &count, &freqAcc, adj);
+    }
 }
 
-static void convert_24_to_16 (const void *src, void *dst)
+static void convert_24_to_16 (const void *src, void *dst, UINT src_stride,
+        UINT dst_stride, INT count, UINT freqAcc, UINT adj)
 {
-    WORD *dest16 = dst;
-    const BYTE *source = src;
-    *dest16 = le16(source[2] * 256 + source[1]);
+    while (count > 0)
+    {
+        WORD *dest16 = dst;
+        const BYTE *source = src;
+        *dest16 = le16(source[2] * 256 + source[1]);
+
+        dst = (char *)dst + dst_stride;
+        src_advance(&src, src_stride, &count, &freqAcc, adj);
+    }
 }
 
-static void convert_24_to_24 (const void *src, void *dst)
+static void convert_24_to_24 (const void *src, void *dst, UINT src_stride,
+        UINT dst_stride, INT count, UINT freqAcc, UINT adj)
 {
-    BYTE *dest24 = dst;
-    const BYTE *src24 = src;
+    while (count > 0)
+    {
+        BYTE *dest24 = dst;
+        const BYTE *src24 = src;
+
+        dest24[0] = src24[0];
+        dest24[1] = src24[1];
+        dest24[2] = src24[2];
 
-    dest24[0] = src24[0];
-    dest24[1] = src24[1];
-    dest24[2] = src24[2];
+        dst = (char *)dst + dst_stride;
+        src_advance(&src, src_stride, &count, &freqAcc, adj);
+    }
 }
 
-static void convert_24_to_32 (const void *src, void *dst)
+static void convert_24_to_32 (const void *src, void *dst, UINT src_stride,
+        UINT dst_stride, INT count, UINT freqAcc, UINT adj)
 {
-    DWORD *dest32 = dst;
-    const BYTE *source = src;
-    *dest32 = le32(source[2] * 16777217 + source[1] * 65536 + source[0] * 256);
+    while (count > 0)
+    {
+        DWORD *dest32 = dst;
+        const BYTE *source = src;
+        *dest32 = le32(source[2] * 16777217 + source[1] * 65536 + source[0] * 256);
+
+        dst = (char *)dst + dst_stride;
+        src_advance(&src, src_stride, &count, &freqAcc, adj);
+    }
 }
 
-static void convert_32_to_8 (const void *src, void *dst)
+static void convert_32_to_8 (const void *src, void *dst, UINT src_stride,
+        UINT dst_stride, INT count, UINT freqAcc, UINT adj)
 {
-    BYTE *dst8 = dst;
-    *dst8 = (le32(*(const DWORD *)src) / 16777216);
-    *dst8 -= 0x80;
+    while (count > 0)
+    {
+        BYTE *dst8 = dst;
+        *dst8 = (le32(*(const DWORD *)src) / 16777216);
+        *dst8 -= 0x80;
+
+        dst = (char *)dst + dst_stride;
+        src_advance(&src, src_stride, &count, &freqAcc, adj);
+    }
 }
 
-static void convert_32_to_16 (const void *src, void *dst)
+static void convert_32_to_16 (const void *src, void *dst, UINT src_stride,
+        UINT dst_stride, INT count, UINT freqAcc, UINT adj)
 {
-    WORD *dest16 = dst;
-    *dest16 = le16(le32(*(const DWORD *)src) / 65536);
+    while (count > 0)
+    {
+        WORD *dest16 = dst;
+        *dest16 = le16(le32(*(const DWORD *)src) / 65536);
+
+        dst = (char *)dst + dst_stride;
+        src_advance(&src, src_stride, &count, &freqAcc, adj);
+    }
 }
 
-static void convert_32_to_24 (const void *src, void *dst)
+static void convert_32_to_24 (const void *src, void *dst, UINT src_stride,
+        UINT dst_stride, INT count, UINT freqAcc, UINT adj)
 {
-    DWORD dest = le32(*(const DWORD *)src);
-    BYTE *dest24 = dst;
+    while (count > 0)
+    {
+        DWORD dest = le32(*(const DWORD *)src);
+        BYTE *dest24 = dst;
+
+        dest24[0] = dest / 256;
+        dest24[1] = dest / 65536;
+        dest24[2] = dest / 16777216;
 
-    dest24[0] = dest / 256;
-    dest24[1] = dest / 65536;
-    dest24[2] = dest / 16777216;
+        dst = (char *)dst + dst_stride;
+        src_advance(&src, src_stride, &count, &freqAcc, adj);
+    }
 }
 
-static void convert_32_to_32 (const void *src, void *dst)
+static void convert_32_to_32 (const void *src, void *dst, UINT src_stride,
+        UINT dst_stride, INT count, UINT freqAcc, UINT adj)
 {
-    DWORD *dest = dst;
-    *dest = *(const DWORD *)src;
+    while (count > 0)
+    {
+        DWORD *dest = dst;
+        *dest = *(const DWORD *)src;
+
+        dst = (char *)dst + dst_stride;
+        src_advance(&src, src_stride, &count, &freqAcc, adj);
+    }
 }
 
 const bitsconvertfunc convertbpp[4][4] = {
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
index b23e242..221433f 100644
--- a/dlls/dsound/dsound_private.h
+++ b/dlls/dsound/dsound_private.h
@@ -69,7 +69,7 @@ typedef struct DirectSoundDevice             DirectSoundDevice;
 typedef struct DirectSoundCaptureDevice      DirectSoundCaptureDevice;
 
 /* dsound_convert.h */
-typedef void (*bitsconvertfunc)(const void *, void *);
+typedef void (*bitsconvertfunc)(const void *, void *, UINT, UINT, INT, UINT, UINT);
 extern const bitsconvertfunc convertbpp[4][4];
 typedef void (*mixfunc)(const void *, void *, unsigned);
 extern const mixfunc mixfunctions[4];
diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c
index 3bcbce0..d014c4b 100644
--- a/dlls/dsound/mixer.c
+++ b/dlls/dsound/mixer.c
@@ -271,26 +271,27 @@ void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len
  * Copy a single frame from the given input buffer to the given output buffer.
  * Translate 8 <-> 16 bits and mono <-> stereo
  */
-static inline void cp_fields(const IDirectSoundBufferImpl *dsb, const BYTE *ibuf, BYTE *obuf )
+static inline void cp_fields(const IDirectSoundBufferImpl *dsb, const BYTE *ibuf, BYTE *obuf,
+        UINT istride, UINT ostride, UINT count, UINT freqAcc, UINT adj)
 {
     DirectSoundDevice *device = dsb->device;
     INT istep = dsb->pwfx->wBitsPerSample / 8, ostep = device->pwfx->wBitsPerSample / 8;
 
     if (device->pwfx->nChannels == dsb->pwfx->nChannels) {
-        dsb->convert(ibuf, obuf);
+        dsb->convert(ibuf, obuf, istride, ostride, count, freqAcc, adj);
         if (device->pwfx->nChannels == 2)
-            dsb->convert(ibuf + istep, obuf + ostep);
+            dsb->convert(ibuf + istep, obuf + ostep, istride, ostride, count, freqAcc, adj);
     }
 
     if (device->pwfx->nChannels == 1 && dsb->pwfx->nChannels == 2)
     {
-        dsb->convert(ibuf, obuf);
+        dsb->convert(ibuf, obuf, istride, ostride, count, freqAcc, adj);
     }
 
     if (device->pwfx->nChannels == 2 && dsb->pwfx->nChannels == 1)
     {
-        dsb->convert(ibuf, obuf);
-        dsb->convert(ibuf, obuf + ostep);
+        dsb->convert(ibuf, obuf, istride, ostride, count, freqAcc, adj);
+        dsb->convert(ibuf, obuf + ostep, istride, ostride, count, freqAcc, adj);
     }
 }
 
@@ -324,7 +325,6 @@ static inline DWORD DSOUND_BufPtrDiff(DWORD buflen, DWORD ptr1, DWORD ptr2)
  */
 void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD len, BOOL inmixer)
 {
-	DWORD	i;
 	INT	size;
 	BYTE	*ibp, *obp, *obp_begin;
 	INT	iAdvance = dsb->pwfx->nBlockAlign;
@@ -357,6 +357,7 @@ void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DW
 		obp_begin = dsb->device->tmp_buffer;
 
 	TRACE("(%p, %p)\n", dsb, ibp);
+	size = len / iAdvance;
 
 	/* Check for same sample rate */
 	if (dsb->freq == dsb->device->pwfx->nSamplesPerSec) {
@@ -366,17 +367,12 @@ void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DW
 		if (!inmixer)
 			 obp += writepos/iAdvance*oAdvance;
 
-		for (i = 0; i < len; i += iAdvance) {
-			cp_fields(dsb, ibp, obp);
-			ibp += iAdvance;
-			obp += oAdvance;
-		}
+		cp_fields(dsb, ibp, obp, iAdvance, oAdvance, size, 0, 1 << DSOUND_FREQSHIFT);
 		return;
 	}
 
 	/* Mix in different sample rates */
 	TRACE("(%p) Adjusting frequency: %d -> %d\n", dsb, dsb->freq, dsb->device->pwfx->nSamplesPerSec);
-	size = len / iAdvance;
 
 	target_writepos = DSOUND_secpos_to_bufpos(dsb, writepos, dsb->sec_mixpos, &freqAcc);
 	overshot = freqAcc >> DSOUND_FREQSHIFT;
@@ -398,17 +394,7 @@ void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DW
 	else obp = obp_begin;
 
 	/* FIXME: Small problem here when we're overwriting buf_mixpos, it then STILL uses old freqAcc, not sure if it matters or not */
-	while (size > 0) {
-		cp_fields(dsb, ibp, obp);
-		obp += oAdvance;
-		freqAcc += dsb->freqAdjust;
-		if (freqAcc >= (1<<DSOUND_FREQSHIFT)) {
-			ULONG adv = (freqAcc>>DSOUND_FREQSHIFT);
-			freqAcc &= (1<<DSOUND_FREQSHIFT)-1;
-			ibp += adv * iAdvance;
-			size -= adv;
-		}
-	}
+	cp_fields(dsb, ibp, obp, iAdvance, oAdvance, size, freqAcc, dsb->freqAdjust);
 }
 
 /** Apply volume to the given soundbuffer from (primary) position writepos and length len
-- 
1.6.0.6



--------------090905050006070802050704--



More information about the wine-patches mailing list