From 5570a1da8e0a5f12c0bb7cdf1576afa9cb762dc9 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Thu, 15 Jan 2009 09:58:45 +0100 Subject: [PATCH] dsound: Don't convert single samples at a time. 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 0ebce3d3734..0a6e474d09d 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_32 (const void *src, void *dst) +static void convert_8_to_24 (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) + { + 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_16_to_8 (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) { - BYTE *dst8 = dst; - *dst8 = (le16(*(const WORD *)src)) / 256; - *dst8 -= 0x80; + 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_16 (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) { - WORD *dest = dst; - *dest = *(const WORD *)src; + 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_24 (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 = le16(*(const WORD *)src); - BYTE *dest24 = dst; + while (count > 0) + { + *(WORD *)dst = *(const WORD *)src; - 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_24 (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) + { + WORD dest = le16(*(const WORD *)src); + BYTE *dest24 = dst; + + 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_24_to_8 (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) { - BYTE *dst8 = dst; - *dst8 = ((const BYTE *)src)[2]; + 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_16 (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) { - WORD *dest16 = dst; - const BYTE *source = src; - *dest16 = le16(source[2] * 256 + source[1]); + 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_24 (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) { - BYTE *dest24 = dst; - const BYTE *src24 = src; + while (count > 0) + { + WORD *dest16 = dst; + const BYTE *source = src; + *dest16 = le16(source[2] * 256 + source[1]); - 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_24 (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) + { + BYTE *dest24 = dst; + const BYTE *src24 = src; + + 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_32_to_8 (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) { - BYTE *dst8 = dst; - *dst8 = (le32(*(const DWORD *)src) / 16777216); - *dst8 -= 0x80; + 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_16 (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) { - WORD *dest16 = dst; - *dest16 = le16(le32(*(const DWORD *)src) / 65536); + 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_24 (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) { - DWORD dest = le32(*(const DWORD *)src); - BYTE *dest24 = dst; + while (count > 0) + { + WORD *dest16 = dst; + *dest16 = le16(le32(*(const DWORD *)src) / 65536); - 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_24 (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 = le32(*(const DWORD *)src); + BYTE *dest24 = dst; + + 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, UINT src_stride, + UINT dst_stride, INT count, UINT freqAcc, UINT adj) +{ + 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 b23e2421f3c..221433f24cb 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 3bcbce02f7d..d014c4b8655 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); - freqAcc &= (1<freqAdjust); } /** Apply volume to the given soundbuffer from (primary) position writepos and length len