dsound: Don't convert single samples at a time.
This gives a minor performance improvement.
This commit is contained in:
parent
44240eff27
commit
5570a1da8e
|
@ -58,119 +58,241 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsound);
|
||||||
#define le32(x) (x)
|
#define le32(x) (x)
|
||||||
#endif
|
#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;
|
*freqAcc += adj;
|
||||||
*dest = *(const BYTE *)src;
|
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;
|
while (count > 0)
|
||||||
*dest16 = le16(dest * 257 - 32768);
|
{
|
||||||
|
*(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;
|
while (count > 0)
|
||||||
BYTE *dest24 = dst;
|
{
|
||||||
dest24[0] = dest;
|
WORD dest = *(const BYTE *)src, *dest16 = dst;
|
||||||
dest24[1] = dest;
|
*dest16 = le16(dest * 257 - 32768);
|
||||||
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_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;
|
while (count > 0)
|
||||||
*dest32 = le32(dest * 16843009 - 2147483648U);
|
{
|
||||||
|
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;
|
while (count > 0)
|
||||||
*dst8 = (le16(*(const WORD *)src)) / 256;
|
{
|
||||||
*dst8 -= 0x80;
|
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;
|
while (count > 0)
|
||||||
*dest = *(const WORD *)src;
|
{
|
||||||
|
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);
|
while (count > 0)
|
||||||
BYTE *dest24 = dst;
|
{
|
||||||
|
*(WORD *)dst = *(const WORD *)src;
|
||||||
|
|
||||||
dest24[0] = dest / 256;
|
dst = (char *)dst + dst_stride;
|
||||||
dest24[1] = dest;
|
src_advance(&src, src_stride, &count, &freqAcc, adj);
|
||||||
dest24[2] = dest / 256;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
while (count > 0)
|
||||||
*dest32 = dest * 65537;
|
{
|
||||||
|
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;
|
while (count > 0)
|
||||||
*dst8 = ((const BYTE *)src)[2];
|
{
|
||||||
|
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;
|
while (count > 0)
|
||||||
const BYTE *source = src;
|
{
|
||||||
*dest16 = le16(source[2] * 256 + source[1]);
|
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;
|
while (count > 0)
|
||||||
const BYTE *src24 = src;
|
{
|
||||||
|
WORD *dest16 = dst;
|
||||||
|
const BYTE *source = src;
|
||||||
|
*dest16 = le16(source[2] * 256 + source[1]);
|
||||||
|
|
||||||
dest24[0] = src24[0];
|
dst = (char *)dst + dst_stride;
|
||||||
dest24[1] = src24[1];
|
src_advance(&src, src_stride, &count, &freqAcc, adj);
|
||||||
dest24[2] = src24[2];
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
while (count > 0)
|
||||||
const BYTE *source = src;
|
{
|
||||||
*dest32 = le32(source[2] * 16777217 + source[1] * 65536 + source[0] * 256);
|
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;
|
while (count > 0)
|
||||||
*dst8 = (le32(*(const DWORD *)src) / 16777216);
|
{
|
||||||
*dst8 -= 0x80;
|
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;
|
while (count > 0)
|
||||||
*dest16 = le16(le32(*(const DWORD *)src) / 65536);
|
{
|
||||||
|
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);
|
while (count > 0)
|
||||||
BYTE *dest24 = dst;
|
{
|
||||||
|
WORD *dest16 = dst;
|
||||||
|
*dest16 = le16(le32(*(const DWORD *)src) / 65536);
|
||||||
|
|
||||||
dest24[0] = dest / 256;
|
dst = (char *)dst + dst_stride;
|
||||||
dest24[1] = dest / 65536;
|
src_advance(&src, src_stride, &count, &freqAcc, adj);
|
||||||
dest24[2] = dest / 16777216;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
while (count > 0)
|
||||||
*dest = *(const DWORD *)src;
|
{
|
||||||
|
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] = {
|
const bitsconvertfunc convertbpp[4][4] = {
|
||||||
|
|
|
@ -69,7 +69,7 @@ typedef struct DirectSoundDevice DirectSoundDevice;
|
||||||
typedef struct DirectSoundCaptureDevice DirectSoundCaptureDevice;
|
typedef struct DirectSoundCaptureDevice DirectSoundCaptureDevice;
|
||||||
|
|
||||||
/* dsound_convert.h */
|
/* 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];
|
extern const bitsconvertfunc convertbpp[4][4];
|
||||||
typedef void (*mixfunc)(const void *, void *, unsigned);
|
typedef void (*mixfunc)(const void *, void *, unsigned);
|
||||||
extern const mixfunc mixfunctions[4];
|
extern const mixfunc mixfunctions[4];
|
||||||
|
|
|
@ -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.
|
* Copy a single frame from the given input buffer to the given output buffer.
|
||||||
* Translate 8 <-> 16 bits and mono <-> stereo
|
* 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;
|
DirectSoundDevice *device = dsb->device;
|
||||||
INT istep = dsb->pwfx->wBitsPerSample / 8, ostep = device->pwfx->wBitsPerSample / 8;
|
INT istep = dsb->pwfx->wBitsPerSample / 8, ostep = device->pwfx->wBitsPerSample / 8;
|
||||||
|
|
||||||
if (device->pwfx->nChannels == dsb->pwfx->nChannels) {
|
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)
|
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)
|
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)
|
if (device->pwfx->nChannels == 2 && dsb->pwfx->nChannels == 1)
|
||||||
{
|
{
|
||||||
dsb->convert(ibuf, obuf);
|
dsb->convert(ibuf, obuf, istride, ostride, count, freqAcc, adj);
|
||||||
dsb->convert(ibuf, obuf + ostep);
|
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)
|
void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD len, BOOL inmixer)
|
||||||
{
|
{
|
||||||
DWORD i;
|
|
||||||
INT size;
|
INT size;
|
||||||
BYTE *ibp, *obp, *obp_begin;
|
BYTE *ibp, *obp, *obp_begin;
|
||||||
INT iAdvance = dsb->pwfx->nBlockAlign;
|
INT iAdvance = dsb->pwfx->nBlockAlign;
|
||||||
|
@ -357,6 +357,7 @@ void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DW
|
||||||
obp_begin = dsb->device->tmp_buffer;
|
obp_begin = dsb->device->tmp_buffer;
|
||||||
|
|
||||||
TRACE("(%p, %p)\n", dsb, ibp);
|
TRACE("(%p, %p)\n", dsb, ibp);
|
||||||
|
size = len / iAdvance;
|
||||||
|
|
||||||
/* Check for same sample rate */
|
/* Check for same sample rate */
|
||||||
if (dsb->freq == dsb->device->pwfx->nSamplesPerSec) {
|
if (dsb->freq == dsb->device->pwfx->nSamplesPerSec) {
|
||||||
|
@ -366,17 +367,12 @@ void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DW
|
||||||
if (!inmixer)
|
if (!inmixer)
|
||||||
obp += writepos/iAdvance*oAdvance;
|
obp += writepos/iAdvance*oAdvance;
|
||||||
|
|
||||||
for (i = 0; i < len; i += iAdvance) {
|
cp_fields(dsb, ibp, obp, iAdvance, oAdvance, size, 0, 1 << DSOUND_FREQSHIFT);
|
||||||
cp_fields(dsb, ibp, obp);
|
|
||||||
ibp += iAdvance;
|
|
||||||
obp += oAdvance;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mix in different sample rates */
|
/* Mix in different sample rates */
|
||||||
TRACE("(%p) Adjusting frequency: %d -> %d\n", dsb, dsb->freq, dsb->device->pwfx->nSamplesPerSec);
|
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);
|
target_writepos = DSOUND_secpos_to_bufpos(dsb, writepos, dsb->sec_mixpos, &freqAcc);
|
||||||
overshot = freqAcc >> DSOUND_FREQSHIFT;
|
overshot = freqAcc >> DSOUND_FREQSHIFT;
|
||||||
|
@ -398,17 +394,7 @@ void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DW
|
||||||
else obp = obp_begin;
|
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 */
|
/* 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, iAdvance, oAdvance, size, freqAcc, dsb->freqAdjust);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Apply volume to the given soundbuffer from (primary) position writepos and length len
|
/** Apply volume to the given soundbuffer from (primary) position writepos and length len
|
||||||
|
|
Loading…
Reference in New Issue