[PATCH 0/5] MR11082: dsound: Speed up resampling, part 7
From: Anton Baskanov <baskanov@gmail.com> --- dlls/dsound/dsound_private.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index 7e6768a21a8..3c0ed73340d 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -43,13 +43,13 @@ typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl; typedef struct DirectSoundDevice DirectSoundDevice; /* dsound_convert.h */ -typedef float (*bitsgetfunc)(const IDirectSoundBufferImpl *, BYTE *, DWORD); -typedef void (*bitsputfunc)(const IDirectSoundBufferImpl *, DWORD, DWORD, float); +typedef float (*bitsgetfunc)(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel); +typedef void (*bitsputfunc)(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); extern const bitsgetfunc getbpp[5]; void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); void putieee32_sum(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); void mixieee32(float *src, float *dst, unsigned samples); -typedef void (*normfunc)(const void *, void *, unsigned); +typedef void (*normfunc)(const void *src, void *dst, unsigned samples); extern const normfunc normfunctions[4]; typedef struct _DSVOLUMEPAN -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11082
From: Anton Baskanov <baskanov@gmail.com> --- dlls/dsound/dsound_convert.c | 121 ++++++++++++++++------------------- dlls/dsound/dsound_private.h | 3 +- dlls/dsound/mixer.c | 9 +-- 3 files changed, 60 insertions(+), 73 deletions(-) diff --git a/dlls/dsound/dsound_convert.c b/dlls/dsound/dsound_convert.c index bdd62c8e51f..ac52df6cc64 100644 --- a/dlls/dsound/dsound_convert.c +++ b/dlls/dsound/dsound_convert.c @@ -154,91 +154,90 @@ void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, floa *fbuf = value; } -void putieee32_sum(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) -{ - BYTE *buf = (BYTE *)dsb->device->tmp_buffer; - float *fbuf = (float*)(buf + pos + sizeof(float) * channel); - *fbuf += value; -} - void put_mono2stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) { - dsb->put_aux(dsb, pos, 0, value); - dsb->put_aux(dsb, pos, 1, value); + float *dst = (float *)((BYTE *)dsb->device->tmp_buffer + pos); + + dst[0] = value; + dst[1] = value; } void put_mono2quad(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) { - dsb->put_aux(dsb, pos, 0, value); - dsb->put_aux(dsb, pos, 1, value); - dsb->put_aux(dsb, pos, 2, value); - dsb->put_aux(dsb, pos, 3, value); + float *dst = (float *)((BYTE *)dsb->device->tmp_buffer + pos); + + dst[0] = value; + dst[1] = value; + dst[2] = value; + dst[3] = value; } void put_stereo2quad(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) { + float *dst = (float *)((BYTE *)dsb->device->tmp_buffer + pos); + if (channel == 0) { /* Left */ - dsb->put_aux(dsb, pos, 0, value); /* Front left */ - dsb->put_aux(dsb, pos, 2, value); /* Back left */ + dst[0] = value; /* Front left */ + dst[2] = value; /* Back left */ } else if (channel == 1) { /* Right */ - dsb->put_aux(dsb, pos, 1, value); /* Front right */ - dsb->put_aux(dsb, pos, 3, value); /* Back right */ + dst[1] = value; /* Front right */ + dst[3] = value; /* Back right */ } } void put_mono2surround51(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) { - dsb->put_aux(dsb, pos, 0, value); - dsb->put_aux(dsb, pos, 1, value); - dsb->put_aux(dsb, pos, 2, value); - dsb->put_aux(dsb, pos, 3, value); - dsb->put_aux(dsb, pos, 4, value); - dsb->put_aux(dsb, pos, 5, value); + float *dst = (float *)((BYTE *)dsb->device->tmp_buffer + pos); + + dst[0] = value; + dst[1] = value; + dst[2] = value; + dst[3] = value; + dst[4] = value; + dst[5] = value; } void put_stereo2surround51(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) { + float *dst = (float *)((BYTE *)dsb->device->tmp_buffer + pos); + if (channel == 0) { /* Left */ - dsb->put_aux(dsb, pos, 0, value); /* Front left */ - dsb->put_aux(dsb, pos, 4, value); /* Back left */ + dst[0] = value; /* Front left */ + dst[4] = value; /* Back left */ - dsb->put_aux(dsb, pos, 2, 0.0f); /* Mute front centre */ - dsb->put_aux(dsb, pos, 3, 0.0f); /* Mute LFE */ + dst[2] = 0.0f; /* Mute front centre */ + dst[3] = 0.0f; /* Mute LFE */ } else if (channel == 1) { /* Right */ - dsb->put_aux(dsb, pos, 1, value); /* Front right */ - dsb->put_aux(dsb, pos, 5, value); /* Back right */ + dst[1] = value; /* Front right */ + dst[5] = value; /* Back right */ } } void put_surround512stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) { + float *dst = (float *)((BYTE *)dsb->device->tmp_buffer + pos); + /* based on analyzing a recording of a dsound downmix */ switch(channel){ case 4: /* surround left */ - value *= 0.24f; - dsb->put_aux(dsb, pos, 0, value); + dst[0] += value * 0.24f; break; case 0: /* front left */ - value *= 1.0f; - dsb->put_aux(dsb, pos, 0, value); + dst[0] += value; break; case 5: /* surround right */ - value *= 0.24f; - dsb->put_aux(dsb, pos, 1, value); - break; + dst[1] += value * 0.24f; case 1: /* front right */ - value *= 1.0f; - dsb->put_aux(dsb, pos, 1, value); + dst[1] += value; break; case 2: /* centre */ - value *= 0.7; - dsb->put_aux(dsb, pos, 0, value); - dsb->put_aux(dsb, pos, 1, value); + dst[0] += value * 0.7f; + dst[1] += value * 0.7f; break; case 3: @@ -249,43 +248,37 @@ void put_surround512stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD c void put_surround712stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) { + float *dst = (float *)((BYTE *)dsb->device->tmp_buffer + pos); + /* based on analyzing a recording of a dsound downmix */ switch(channel){ case 6: /* back left */ - value *= 0.24f; - dsb->put_aux(dsb, pos, 0, value); + dst[0] += value * 0.24f; break; case 4: /* surround left */ - value *= 0.24f; - dsb->put_aux(dsb, pos, 0, value); + dst[0] += value * 0.24f; break; case 0: /* front left */ - value *= 1.0f; - dsb->put_aux(dsb, pos, 0, value); + dst[0] += value; break; case 7: /* back right */ - value *= 0.24f; - dsb->put_aux(dsb, pos, 1, value); + dst[1] += value * 0.24f; break; case 5: /* surround right */ - value *= 0.24f; - dsb->put_aux(dsb, pos, 1, value); - break; + dst[1] += value * 0.24f; case 1: /* front right */ - value *= 1.0f; - dsb->put_aux(dsb, pos, 1, value); + dst[1] += value; break; case 2: /* centre */ - value *= 0.7; - dsb->put_aux(dsb, pos, 0, value); - dsb->put_aux(dsb, pos, 1, value); + dst[0] += value * 0.7f; + dst[1] += value * 0.7f; break; case 3: @@ -296,27 +289,25 @@ void put_surround712stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD c void put_quad2stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) { + float *dst = (float *)((BYTE *)dsb->device->tmp_buffer + pos); + /* based on pulseaudio's downmix algorithm */ switch(channel){ case 2: /* back left */ - value *= 0.1f; /* (1/9) / (sum of left volumes) */ - dsb->put_aux(dsb, pos, 0, value); + dst[0] += value * 0.1f; /* (1/9) / (sum of left volumes) */ break; case 0: /* front left */ - value *= 0.9f; /* 1 / (sum of left volumes) */ - dsb->put_aux(dsb, pos, 0, value); + dst[0] += value * 0.9f; /* 1 / (sum of left volumes) */ break; case 3: /* back right */ - value *= 0.1f; /* (1/9) / (sum of right volumes) */ - dsb->put_aux(dsb, pos, 1, value); + dst[1] += value * 0.1f; /* (1/9) / (sum of right volumes) */ break; case 1: /* front right */ - value *= 0.9f; /* 1 / (sum of right volumes) */ - dsb->put_aux(dsb, pos, 1, value); + dst[1] += value * 0.9f; /* 1 / (sum of right volumes) */ break; } } diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index 3c0ed73340d..875f111ac4f 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -47,7 +47,6 @@ typedef float (*bitsgetfunc)(const IDirectSoundBufferImpl *dsb, BYTE *base, DWOR typedef void (*bitsputfunc)(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); extern const bitsgetfunc getbpp[5]; void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); -void putieee32_sum(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); void mixieee32(float *src, float *dst, unsigned samples); typedef void (*normfunc)(const void *src, void *dst, unsigned samples); extern const normfunc normfunctions[4]; @@ -166,7 +165,7 @@ struct IDirectSoundBufferImpl /* Used for bit depth conversion */ int mix_channels; bitsgetfunc get, get_aux; - bitsputfunc put, put_aux; + bitsputfunc put; int num_filters; DSFilter* filters; diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index 3b7715e0c69..9afb7651796 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -138,10 +138,9 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) oldFreqAdjustDen / 2) / oldFreqAdjustDen; dsb->get_aux = ieee ? getbpp[4] : getbpp[dsb->pwfx->wBitsPerSample/8 - 1]; - dsb->put_aux = putieee32; dsb->get = dsb->get_aux; - dsb->put = dsb->put_aux; + dsb->put = putieee32; if (ichannels == ochannels) { @@ -181,19 +180,16 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) { dsb->mix_channels = 6; dsb->put = put_surround512stereo; - dsb->put_aux = putieee32_sum; } else if (ichannels == 8 && ochannels == 2) { dsb->mix_channels = 8; dsb->put = put_surround712stereo; - dsb->put_aux = putieee32_sum; } else if (ichannels == 4 && ochannels == 2) { dsb->mix_channels = 4; dsb->put = put_quad2stereo; - dsb->put_aux = putieee32_sum; } else { @@ -687,7 +683,8 @@ static void DSOUND_MixToTemporary(IDirectSoundBufferImpl *dsb, DWORD frames) dsb->device->tmp_buffer_len = size_bytes; dsb->device->tmp_buffer = realloc(dsb->device->tmp_buffer, size_bytes); } - if(dsb->put_aux == putieee32_sum) + if(dsb->put == put_surround512stereo || dsb->put == put_surround712stereo || + dsb->put == put_quad2stereo) memset(dsb->device->tmp_buffer, 0, dsb->device->tmp_buffer_len); cp_fields(dsb, frames, &dsb->freqAccNum); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11082
From: Anton Baskanov <baskanov@gmail.com> --- dlls/dsound/dsound_convert.c | 78 ++++++++++++++++++++++++++++++++++-- dlls/dsound/dsound_private.h | 4 +- dlls/dsound/mixer.c | 6 +-- 3 files changed, 79 insertions(+), 9 deletions(-) diff --git a/dlls/dsound/dsound_convert.c b/dlls/dsound/dsound_convert.c index ac52df6cc64..8bc3eb38203 100644 --- a/dlls/dsound/dsound_convert.c +++ b/dlls/dsound/dsound_convert.c @@ -99,18 +99,90 @@ static float getieee32(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD chan const bitsgetfunc getbpp[5] = {get8, get16, get24, get32, getieee32}; -float get_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel) +static float get8_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel) { DWORD channels = dsb->pwfx->nChannels; DWORD c; float val = 0; /* XXX: does Windows include LFE into the mix? */ - for (c = 0; c < channels; c++) - val += dsb->get_aux(dsb, base, c); + for (c = 0; c < channels; c++) { + const BYTE *buf = base + c; + val += (buf[0] - 0x80) / (float)0x80; + } + val /= channels; + return val; +} + +static float get16_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel) +{ + DWORD channels = dsb->pwfx->nChannels; + DWORD c; + float val = 0; + /* XXX: does Windows include LFE into the mix? */ + for (c = 0; c < channels; c++) { + const BYTE *buf = base + 2 * c; + const SHORT *sbuf = (const SHORT*)(buf); + SHORT sample = (SHORT)le16(*sbuf); + val += sample / (float)0x8000; + } + val /= channels; + return val; +} + +static float get24_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel) +{ + DWORD channels = dsb->pwfx->nChannels; + DWORD c; + float val = 0; + /* XXX: does Windows include LFE into the mix? */ + for (c = 0; c < channels; c++) { + LONG sample; + const BYTE *buf = base + 3 * c; + + /* The next expression deliberately has an overflow for buf[2] >= 0x80, + this is how negative values are made. + */ + sample = (buf[0] << 8) | (buf[1] << 16) | (buf[2] << 24); + val += sample / (float)0x80000000U; + } val /= channels; return val; } +static float get32_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel) +{ + DWORD channels = dsb->pwfx->nChannels; + DWORD c; + float val = 0; + /* XXX: does Windows include LFE into the mix? */ + for (c = 0; c < channels; c++) { + const BYTE *buf = base + 4 * c; + const LONG *sbuf = (const LONG*)(buf); + LONG sample = le32(*sbuf); + val += sample / (float)0x80000000U; + } + val /= channels; + return val; +} + +static float getieee32_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel) +{ + DWORD channels = dsb->pwfx->nChannels; + DWORD c; + float val = 0; + /* XXX: does Windows include LFE into the mix? */ + for (c = 0; c < channels; c++) { + const BYTE *buf = base + 4 * c; + const float *sbuf = (const float*)(buf); + /* The value will be clipped later, when put into some non-float buffer */ + val += *sbuf; + } + val /= channels; + return val; +} + +const bitsgetfunc getbpp_mono[5] = {get8_mono, get16_mono, get24_mono, get32_mono, getieee32_mono}; + static inline unsigned char f_to_8(float value) { if(value <= -1.f) diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index 875f111ac4f..8753410b18b 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -46,6 +46,7 @@ typedef struct DirectSoundDevice DirectSoundDevice; typedef float (*bitsgetfunc)(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel); typedef void (*bitsputfunc)(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); extern const bitsgetfunc getbpp[5]; +extern const bitsgetfunc getbpp_mono[5]; void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); void mixieee32(float *src, float *dst, unsigned samples); typedef void (*normfunc)(const void *src, void *dst, unsigned samples); @@ -164,7 +165,7 @@ struct IDirectSoundBufferImpl BOOL ds3db_need_recalc; /* Used for bit depth conversion */ int mix_channels; - bitsgetfunc get, get_aux; + bitsgetfunc get; bitsputfunc put; int num_filters; DSFilter* filters; @@ -172,7 +173,6 @@ struct IDirectSoundBufferImpl struct list entry; }; -float get_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel); void put_mono2stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); void put_mono2quad(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); void put_stereo2quad(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index 9afb7651796..fd532408999 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -137,9 +137,7 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) dsb->freqAccNum = (dsb->freqAccNum * (LONG64)dsb->freqAdjustDen + oldFreqAdjustDen / 2) / oldFreqAdjustDen; - dsb->get_aux = ieee ? getbpp[4] : getbpp[dsb->pwfx->wBitsPerSample/8 - 1]; - - dsb->get = dsb->get_aux; + dsb->get = ieee ? getbpp[4] : getbpp[dsb->pwfx->wBitsPerSample/8 - 1]; dsb->put = putieee32; if (ichannels == ochannels) @@ -164,7 +162,7 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) else if (ochannels == 1) { dsb->mix_channels = 1; - dsb->get = get_mono; + dsb->get = ieee ? getbpp_mono[4] : getbpp_mono[dsb->pwfx->wBitsPerSample/8 - 1]; } else if (ichannels == 2 && ochannels == 4) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11082
From: Anton Baskanov <baskanov@gmail.com> Inspired by a patch by Matteo Bruni. --- dlls/dsound/dsound_convert.c | 178 ++++++++++++++++++++++------------- dlls/dsound/dsound_private.h | 20 ++-- dlls/dsound/mixer.c | 40 +++++--- 3 files changed, 152 insertions(+), 86 deletions(-) diff --git a/dlls/dsound/dsound_convert.c b/dlls/dsound/dsound_convert.c index 8bc3eb38203..296c1b16e96 100644 --- a/dlls/dsound/dsound_convert.c +++ b/dlls/dsound/dsound_convert.c @@ -219,97 +219,134 @@ static inline LONG f_to_32(float value) return le32(lrintf(value * 0x80000000U)); } -void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) +void putieee32(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel) { - BYTE *buf = (BYTE *)dsb->device->tmp_buffer; - float *fbuf = (float*)(buf + pos + sizeof(float) * channel); - *fbuf = value; + DWORD channels = dsb->device->pwfx->nChannels; + float *dst = dsb->device->tmp_buffer; + int i; + + for (i = 0; i < samples; ++i) + dst[i * channels + channel] = src[i]; } -void put_mono2stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) +void put_mono2stereo(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel) { - float *dst = (float *)((BYTE *)dsb->device->tmp_buffer + pos); + float *dst = dsb->device->tmp_buffer; + int i; - dst[0] = value; - dst[1] = value; + for (i = 0; i < samples; ++i) { + float value = src[i]; + dst[i * 2 + 0] = value; + dst[i * 2 + 1] = value; + } } -void put_mono2quad(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) +void put_mono2quad(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel) { - float *dst = (float *)((BYTE *)dsb->device->tmp_buffer + pos); - - dst[0] = value; - dst[1] = value; - dst[2] = value; - dst[3] = value; + float *dst = dsb->device->tmp_buffer; + int i; + + for (i = 0; i < samples; ++i) { + float value = src[i]; + dst[i * 4 + 0] = value; + dst[i * 4 + 1] = value; + dst[i * 4 + 2] = value; + dst[i * 4 + 3] = value; + } } -void put_stereo2quad(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) +void put_stereo2quad(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel) { - float *dst = (float *)((BYTE *)dsb->device->tmp_buffer + pos); + float *dst = dsb->device->tmp_buffer; + int i; if (channel == 0) { /* Left */ - dst[0] = value; /* Front left */ - dst[2] = value; /* Back left */ + for (i = 0; i < samples; ++i) { + float value = src[i]; + dst[i * 4 + 0] = value; /* Front left */ + dst[i * 4 + 2] = value; /* Back left */ + } } else if (channel == 1) { /* Right */ - dst[1] = value; /* Front right */ - dst[3] = value; /* Back right */ + for (i = 0; i < samples; ++i) { + float value = src[i]; + dst[i * 4 + 1] = value; /* Front right */ + dst[i * 4 + 3] = value; /* Back right */ + } } } -void put_mono2surround51(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) +void put_mono2surround51(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel) { - float *dst = (float *)((BYTE *)dsb->device->tmp_buffer + pos); - - dst[0] = value; - dst[1] = value; - dst[2] = value; - dst[3] = value; - dst[4] = value; - dst[5] = value; + float *dst = dsb->device->tmp_buffer; + int i; + + for (i = 0; i < samples; ++i) { + float value = src[i]; + dst[i * 6 + 0] = value; + dst[i * 6 + 1] = value; + dst[i * 6 + 2] = value; + dst[i * 6 + 3] = value; + dst[i * 6 + 4] = value; + dst[i * 6 + 5] = value; + } } -void put_stereo2surround51(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) +void put_stereo2surround51(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel) { - float *dst = (float *)((BYTE *)dsb->device->tmp_buffer + pos); + float *dst = dsb->device->tmp_buffer; + int i; if (channel == 0) { /* Left */ - dst[0] = value; /* Front left */ - dst[4] = value; /* Back left */ - - dst[2] = 0.0f; /* Mute front centre */ - dst[3] = 0.0f; /* Mute LFE */ + for (i = 0; i < samples; ++i) { + float value = src[i]; + dst[i * 6 + 0] = value; /* Front left */ + dst[i * 6 + 4] = value; /* Back left */ + + dst[i * 6 + 2] = 0.0f; /* Mute front centre */ + dst[i * 6 + 3] = 0.0f; /* Mute LFE */ + } } else if (channel == 1) { /* Right */ - dst[1] = value; /* Front right */ - dst[5] = value; /* Back right */ + for (i = 0; i < samples; ++i) { + float value = src[i]; + dst[i * 6 + 1] = value; /* Front right */ + dst[i * 6 + 5] = value; /* Back right */ + } } } -void put_surround512stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) +void put_surround512stereo(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel) { - float *dst = (float *)((BYTE *)dsb->device->tmp_buffer + pos); + float *dst = dsb->device->tmp_buffer; + int i; /* based on analyzing a recording of a dsound downmix */ switch(channel){ case 4: /* surround left */ - dst[0] += value * 0.24f; + for (i = 0; i < samples; ++i) + dst[i * 2 + 0] += src[i] * 0.24f; break; case 0: /* front left */ - dst[0] += value; + for (i = 0; i < samples; ++i) + dst[i * 2 + 0] += src[i]; break; case 5: /* surround right */ - dst[1] += value * 0.24f; + for (i = 0; i < samples; ++i) + dst[i * 2 + 1] += src[i] * 0.24f; case 1: /* front right */ - dst[1] += value; + for (i = 0; i < samples; ++i) + dst[i * 2 + 1] += src[i]; break; case 2: /* centre */ - dst[0] += value * 0.7f; - dst[1] += value * 0.7f; + for (i = 0; i < samples; ++i) { + float value = src[i] * 0.7f; + dst[i * 2 + 0] += value; + dst[i * 2 + 1] += value; + } break; case 3: @@ -318,39 +355,49 @@ void put_surround512stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD c } } -void put_surround712stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) +void put_surround712stereo(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel) { - float *dst = (float *)((BYTE *)dsb->device->tmp_buffer + pos); + float *dst = dsb->device->tmp_buffer; + int i; /* based on analyzing a recording of a dsound downmix */ switch(channel){ case 6: /* back left */ - dst[0] += value * 0.24f; + for (i = 0; i < samples; ++i) + dst[i * 2 + 0] += src[i] * 0.24f; break; case 4: /* surround left */ - dst[0] += value * 0.24f; + for (i = 0; i < samples; ++i) + dst[i * 2 + 0] += src[i] * 0.24f; break; case 0: /* front left */ - dst[0] += value; + for (i = 0; i < samples; ++i) + dst[i * 2 + 0] += src[i]; break; case 7: /* back right */ - dst[1] += value * 0.24f; + for (i = 0; i < samples; ++i) + dst[i * 2 + 1] += src[i] * 0.24f; break; case 5: /* surround right */ - dst[1] += value * 0.24f; + for (i = 0; i < samples; ++i) + dst[i * 2 + 1] += src[i] * 0.24f; case 1: /* front right */ - dst[1] += value; + for (i = 0; i < samples; ++i) + dst[i * 2 + 1] += src[i]; break; case 2: /* centre */ - dst[0] += value * 0.7f; - dst[1] += value * 0.7f; + for (i = 0; i < samples; ++i) { + float value = src[i] * 0.7f; + dst[i * 2 + 0] += value; + dst[i * 2 + 1] += value; + } break; case 3: @@ -359,27 +406,32 @@ void put_surround712stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD c } } -void put_quad2stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) +void put_quad2stereo(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel) { - float *dst = (float *)((BYTE *)dsb->device->tmp_buffer + pos); + float *dst = dsb->device->tmp_buffer; + int i; /* based on pulseaudio's downmix algorithm */ switch(channel){ case 2: /* back left */ - dst[0] += value * 0.1f; /* (1/9) / (sum of left volumes) */ + for (i = 0; i < samples; ++i) + dst[i * 2 + 0] += src[i] * 0.1f; /* (1/9) / (sum of left volumes) */ break; case 0: /* front left */ - dst[0] += value * 0.9f; /* 1 / (sum of left volumes) */ + for (i = 0; i < samples; ++i) + dst[i * 2 + 0] += src[i] * 0.9f; /* 1 / (sum of left volumes) */ break; case 3: /* back right */ - dst[1] += value * 0.1f; /* (1/9) / (sum of right volumes) */ + for (i = 0; i < samples; ++i) + dst[i * 2 + 1] += src[i] * 0.1f; /* (1/9) / (sum of right volumes) */ break; case 1: /* front right */ - dst[1] += value * 0.9f; /* 1 / (sum of right volumes) */ + for (i = 0; i < samples; ++i) + dst[i * 2 + 1] += src[i] * 0.9f; /* 1 / (sum of right volumes) */ break; } } diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index 8753410b18b..b1443bf49ad 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -44,10 +44,10 @@ typedef struct DirectSoundDevice DirectSoundDevice; /* dsound_convert.h */ typedef float (*bitsgetfunc)(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel); -typedef void (*bitsputfunc)(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); +typedef void (*bitsputfunc)(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel); extern const bitsgetfunc getbpp[5]; extern const bitsgetfunc getbpp_mono[5]; -void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); +void putieee32(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel); void mixieee32(float *src, float *dst, unsigned samples); typedef void (*normfunc)(const void *src, void *dst, unsigned samples); extern const normfunc normfunctions[4]; @@ -173,14 +173,14 @@ struct IDirectSoundBufferImpl struct list entry; }; -void put_mono2stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); -void put_mono2quad(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); -void put_stereo2quad(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); -void put_mono2surround51(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); -void put_stereo2surround51(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); -void put_surround512stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); -void put_surround712stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); -void put_quad2stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); +void put_mono2stereo(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel); +void put_mono2quad(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel); +void put_stereo2quad(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel); +void put_mono2surround51(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel); +void put_stereo2surround51(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel); +void put_surround512stereo(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel); +void put_surround712stereo(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel); +void put_quad2stereo(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel); HRESULT secondarybuffer_create(DirectSoundDevice *device, const DSBUFFERDESC *dsbd, IDirectSoundBuffer **buffer); diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index fd532408999..7c2d99d65f1 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -519,7 +519,6 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, DWORD *f { UINT i, channel; UINT istride = dsb->pwfx->nBlockAlign; - UINT ostride = dsb->device->pwfx->nChannels * sizeof(float); UINT committed_samples = 0; LONG64 freqAcc_start = *freqAccNum; @@ -579,9 +578,8 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, DWORD *f required_input, count, intermediate + channel * required_input, output + channel * (FIR_WIDTH - 1 + count)); - for(i = 0; i < count; ++i) - for (channel = 0; channel < channels; channel++) - dsb->put(dsb, i * ostride, channel, output[channel * (FIR_WIDTH - 1 + count) + i]); + for (channel = 0; channel < channels; channel++) + dsb->put(dsb, output + channel * (FIR_WIDTH - 1 + count), count, channel); return max_ipos; } @@ -589,27 +587,43 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, DWORD *f static UINT cp_fields_noresample(IDirectSoundBufferImpl *dsb, UINT count) { UINT istride = dsb->pwfx->nBlockAlign; - UINT ostride = dsb->device->pwfx->nChannels * sizeof(float); + float *intermediate, *itmp; UINT committed_samples = 0; DWORD channel, i; + DWORD len = count * dsb->mix_channels; + len *= sizeof(float); + if (!secondarybuffer_is_audible(dsb)) return count; + if (!dsb->device->cp_buffer) { + dsb->device->cp_buffer = malloc(len); + dsb->device->cp_buffer_len = len; + } else if (len > dsb->device->cp_buffer_len) { + dsb->device->cp_buffer = realloc(dsb->device->cp_buffer, len); + dsb->device->cp_buffer_len = len; + } + + intermediate = dsb->device->cp_buffer; + if(dsb->use_committed) { committed_samples = (dsb->writelead - dsb->committed_mixpos) / istride; committed_samples = committed_samples <= count ? committed_samples : count; } - for (i = 0; i < committed_samples; i++) - for (channel = 0; channel < dsb->mix_channels; channel++) - dsb->put(dsb, i * ostride, channel, get_current_sample(dsb, dsb->committedbuff, - dsb->writelead, dsb->committed_mixpos + i * istride, channel)); + itmp = intermediate; + for (channel = 0; channel < dsb->mix_channels; channel++) { + for (i = 0; i < committed_samples; i++) + *(itmp++) = get_current_sample(dsb, dsb->committedbuff, + dsb->writelead, dsb->committed_mixpos + i * istride, channel); + for (; i < count; i++) + *(itmp++) = get_current_sample(dsb, dsb->buffer->memory, + dsb->buflen, dsb->sec_mixpos + i * istride, channel); + } - for (; i < count; i++) - for (channel = 0; channel < dsb->mix_channels; channel++) - dsb->put(dsb, i * ostride, channel, get_current_sample(dsb, dsb->buffer->memory, - dsb->buflen, dsb->sec_mixpos + i * istride, channel)); + for (channel = 0; channel < dsb->mix_channels; channel++) + dsb->put(dsb, intermediate + channel * count, count, channel); return count; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11082
From: Anton Baskanov <baskanov@gmail.com> Inspired by a patch by Matteo Bruni, which was in turn inspired by a patch by Giovanni Mascellani. --- dlls/dsound/dsound_convert.c | 184 ++++++++++++++++++++++------------- dlls/dsound/dsound_private.h | 2 +- dlls/dsound/mixer.c | 68 ++++++++----- 3 files changed, 160 insertions(+), 94 deletions(-) diff --git a/dlls/dsound/dsound_convert.c b/dlls/dsound/dsound_convert.c index 296c1b16e96..c72ee7e5e07 100644 --- a/dlls/dsound/dsound_convert.c +++ b/dlls/dsound/dsound_convert.c @@ -55,130 +55,176 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsound); #define le32(x) (x) #endif -static float get8(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel) +static void get8(const IDirectSoundBufferImpl *dsb, BYTE *base, float *dst, unsigned samples, DWORD channel) { + DWORD channels = dsb->pwfx->nChannels; const BYTE *buf = base + channel; - return (buf[0] - 0x80) / (float)0x80; + int i; + + for (i = 0; i < samples; ++i) + dst[i] = (buf[i * channels] - 0x80) / (float)0x80; } -static float get16(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel) +static void get16(const IDirectSoundBufferImpl *dsb, BYTE *base, float *dst, unsigned samples, DWORD channel) { + DWORD channels = dsb->pwfx->nChannels; const BYTE *buf = base + 2 * channel; const SHORT *sbuf = (const SHORT*)(buf); - SHORT sample = (SHORT)le16(*sbuf); - return sample / (float)0x8000; + int i; + + for (i = 0; i < samples; ++i) { + SHORT sample = (SHORT)le16(sbuf[i * channels]); + dst[i] = sample / (float)0x8000; + } } -static float get24(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel) +static void get24(const IDirectSoundBufferImpl *dsb, BYTE *base, float *dst, unsigned samples, DWORD channel) { - LONG sample; + DWORD channels = dsb->pwfx->nChannels; const BYTE *buf = base + 3 * channel; + int i; - /* The next expression deliberately has an overflow for buf[2] >= 0x80, - this is how negative values are made. - */ - sample = (buf[0] << 8) | (buf[1] << 16) | (buf[2] << 24); - return sample / (float)0x80000000U; + for (i = 0; i < samples; ++i) { + /* The next expression deliberately has an overflow for buf[2] >= 0x80, + this is how negative values are made. + */ + LONG sample = + (buf[i * channels * 3 + 0] << 8) | + (buf[i * channels * 3 + 1] << 16) | + (buf[i * channels * 3 + 2] << 24); + dst[i] = sample / (float)0x80000000U; + } } -static float get32(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel) +static void get32(const IDirectSoundBufferImpl *dsb, BYTE *base, float *dst, unsigned samples, DWORD channel) { + DWORD channels = dsb->pwfx->nChannels; const BYTE *buf = base + 4 * channel; const LONG *sbuf = (const LONG*)(buf); - LONG sample = le32(*sbuf); - return sample / (float)0x80000000U; + int i; + + for (i = 0; i < samples; ++i) { + LONG sample = le32(sbuf[i * channels]); + dst[i] = sample / (float)0x80000000U; + } } -static float getieee32(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel) +static void getieee32(const IDirectSoundBufferImpl *dsb, BYTE *base, float *dst, unsigned samples, DWORD channel) { + DWORD channels = dsb->pwfx->nChannels; const BYTE *buf = base + 4 * channel; const float *sbuf = (const float*)(buf); - /* The value will be clipped later, when put into some non-float buffer */ - return *sbuf; + int i; + + for (i = 0; i < samples; ++i) + /* The value will be clipped later, when put into some non-float buffer */ + dst[i] = sbuf[i * channels]; } const bitsgetfunc getbpp[5] = {get8, get16, get24, get32, getieee32}; -static float get8_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel) +static void get8_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, float *dst, unsigned samples, DWORD channel) { DWORD channels = dsb->pwfx->nChannels; DWORD c; - float val = 0; - /* XXX: does Windows include LFE into the mix? */ - for (c = 0; c < channels; c++) { - const BYTE *buf = base + c; - val += (buf[0] - 0x80) / (float)0x80; + int i; + + for (i = 0; i < samples; ++i) { + float val = 0; + /* XXX: does Windows include LFE into the mix? */ + for (c = 0; c < channels; c++) { + const BYTE *buf = base + c; + val += (buf[i * channels] - 0x80) / (float)0x80; + } + val /= channels; + dst[i] = val; } - val /= channels; - return val; } -static float get16_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel) +static void get16_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, float *dst, unsigned samples, DWORD channel) { DWORD channels = dsb->pwfx->nChannels; DWORD c; - float val = 0; - /* XXX: does Windows include LFE into the mix? */ - for (c = 0; c < channels; c++) { - const BYTE *buf = base + 2 * c; - const SHORT *sbuf = (const SHORT*)(buf); - SHORT sample = (SHORT)le16(*sbuf); - val += sample / (float)0x8000; + int i; + + for (i = 0; i < samples; ++i) { + float val = 0; + /* XXX: does Windows include LFE into the mix? */ + for (c = 0; c < channels; c++) { + const BYTE *buf = base + 2 * c; + const SHORT *sbuf = (const SHORT*)(buf); + SHORT sample = (SHORT)le16(sbuf[i * channels]); + val += sample / (float)0x8000; + } + val /= channels; + dst[i] = val; } - val /= channels; - return val; } -static float get24_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel) +static void get24_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, float *dst, unsigned samples, DWORD channel) { DWORD channels = dsb->pwfx->nChannels; DWORD c; - float val = 0; - /* XXX: does Windows include LFE into the mix? */ - for (c = 0; c < channels; c++) { - LONG sample; - const BYTE *buf = base + 3 * c; + int i; - /* The next expression deliberately has an overflow for buf[2] >= 0x80, - this is how negative values are made. - */ - sample = (buf[0] << 8) | (buf[1] << 16) | (buf[2] << 24); - val += sample / (float)0x80000000U; + for (i = 0; i < samples; ++i) { + float val = 0; + /* XXX: does Windows include LFE into the mix? */ + for (c = 0; c < channels; c++) { + LONG sample; + const BYTE *buf = base + 3 * c; + + /* The next expression deliberately has an overflow for buf[2] >= 0x80, + this is how negative values are made. + */ + sample = (buf[i * channels * 3 + 0] << 8) | + (buf[i * channels * 3 + 1] << 16) | + (buf[i * channels * 3 + 2] << 24); + val += sample / (float)0x80000000U; + } + val /= channels; + dst[i] = val; } - val /= channels; - return val; } -static float get32_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel) +static void get32_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, float *dst, unsigned samples, DWORD channel) { DWORD channels = dsb->pwfx->nChannels; DWORD c; - float val = 0; - /* XXX: does Windows include LFE into the mix? */ - for (c = 0; c < channels; c++) { - const BYTE *buf = base + 4 * c; - const LONG *sbuf = (const LONG*)(buf); - LONG sample = le32(*sbuf); - val += sample / (float)0x80000000U; + int i; + + for (i = 0; i < samples; ++i) { + float val = 0; + /* XXX: does Windows include LFE into the mix? */ + for (c = 0; c < channels; c++) { + const BYTE *buf = base + 4 * c; + const LONG *sbuf = (const LONG*)(buf); + LONG sample = le32(sbuf[i * channels]); + val += sample / (float)0x80000000U; + } + val /= channels; + dst[i] = val; } - val /= channels; - return val; } -static float getieee32_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel) +static void getieee32_mono(const IDirectSoundBufferImpl *dsb, BYTE *base, float *dst, unsigned samples, DWORD channel) { DWORD channels = dsb->pwfx->nChannels; DWORD c; - float val = 0; - /* XXX: does Windows include LFE into the mix? */ - for (c = 0; c < channels; c++) { - const BYTE *buf = base + 4 * c; - const float *sbuf = (const float*)(buf); - /* The value will be clipped later, when put into some non-float buffer */ - val += *sbuf; + int i; + + for (i = 0; i < samples; ++i) { + float val = 0; + /* XXX: does Windows include LFE into the mix? */ + for (c = 0; c < channels; c++) { + const BYTE *buf = base + 4 * c; + const float *sbuf = (const float*)(buf); + /* The value will be clipped later, when put into some non-float buffer */ + val += sbuf[i * channels]; + } + val /= channels; + dst[i] = val; } - val /= channels; - return val; } const bitsgetfunc getbpp_mono[5] = {get8_mono, get16_mono, get24_mono, get32_mono, getieee32_mono}; diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index b1443bf49ad..569ffc7c234 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -43,7 +43,7 @@ typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl; typedef struct DirectSoundDevice DirectSoundDevice; /* dsound_convert.h */ -typedef float (*bitsgetfunc)(const IDirectSoundBufferImpl *dsb, BYTE *base, DWORD channel); +typedef void (*bitsgetfunc)(const IDirectSoundBufferImpl *dsb, BYTE *base, float *dst, unsigned samples, DWORD channel); typedef void (*bitsputfunc)(const IDirectSoundBufferImpl *dsb, float *src, unsigned samples, DWORD channel); extern const bitsgetfunc getbpp[5]; extern const bitsgetfunc getbpp_mono[5]; diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index 7c2d99d65f1..01f1b139c32 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -273,12 +273,32 @@ void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len } } -static inline float get_current_sample(const IDirectSoundBufferImpl *dsb, - BYTE *buffer, DWORD buflen, DWORD mixpos, DWORD channel) +static inline void get_samples(const IDirectSoundBufferImpl *dsb, BYTE *buffer, DWORD buflen, + DWORD mixpos, DWORD channel, DWORD count, float *dst) { - if (mixpos >= buflen && !(dsb->playflags & DSBPLAY_LOOPING)) - return 0.0f; - return dsb->get(dsb, buffer + (mixpos % buflen), channel); + UINT istride = dsb->pwfx->nBlockAlign; + DWORD advance; + DWORD pos; + + if (!(dsb->playflags & DSBPLAY_LOOPING)) { + if (mixpos >= buflen) { + memset(dst, 0, count * sizeof(float)); + return; + } + advance = min((buflen - mixpos) / istride, count); + dsb->get(dsb, buffer + mixpos, dst, advance, channel); + memset(dst + advance, 0, (count - advance) * sizeof(float)); + return; + } + + advance = min((buflen - mixpos % buflen) / istride, count); + dsb->get(dsb, buffer + mixpos % buflen, dst, advance, channel); + pos = advance; + while (pos < count) { + advance = min(buflen / istride, count - pos); + dsb->get(dsb, buffer, dst + pos, advance, channel); + pos += advance; + } } #ifdef __SSE__ @@ -517,7 +537,7 @@ static void resample(DWORD freq_adjust_num, DWORD freq_adjust_den, DWORD freq_ac static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, DWORD *freqAccNum) { - UINT i, channel; + UINT channel; UINT istride = dsb->pwfx->nBlockAlign; UINT committed_samples = 0; @@ -529,7 +549,7 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, DWORD *f UINT required_input = max( (freqAcc_start + (count - 1) * dsb->freqAdjustNum) / dsb->freqAdjustDen + FIR_WIDTH, (freqAcc_start + (count - 1 + FIR_WIDTH) * dsb->freqAdjustNum) / dsb->freqAdjustDen); - float *intermediate, *output, *itmp; + float *intermediate, *output; DWORD len = required_input * channels; /* Allocate an output buffer for each channel with padding on both ends as @@ -563,14 +583,14 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, DWORD *f * if you want -msse3 to have any effect. * This is good for CPU cache effects, too. */ - itmp = intermediate; for (channel = 0; channel < channels; channel++) { - for (i = 0; i < committed_samples; i++) - *(itmp++) = get_current_sample(dsb, dsb->committedbuff, - dsb->writelead, dsb->committed_mixpos + i * istride, channel); - for (; i < required_input; i++) - *(itmp++) = get_current_sample(dsb, dsb->buffer->memory, - dsb->buflen, dsb->sec_mixpos + i * istride, channel); + get_samples(dsb, dsb->committedbuff, dsb->writelead, dsb->committed_mixpos, channel, + committed_samples, intermediate + channel * required_input); + if (required_input > committed_samples) + get_samples(dsb, dsb->buffer->memory, dsb->buflen, + dsb->sec_mixpos + committed_samples * istride, channel, + required_input - committed_samples, + intermediate + channel * required_input + committed_samples); } for (channel = 0; channel < channels; channel++) @@ -587,9 +607,9 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, DWORD *f static UINT cp_fields_noresample(IDirectSoundBufferImpl *dsb, UINT count) { UINT istride = dsb->pwfx->nBlockAlign; - float *intermediate, *itmp; UINT committed_samples = 0; - DWORD channel, i; + float *intermediate; + DWORD channel; DWORD len = count * dsb->mix_channels; len *= sizeof(float); @@ -612,14 +632,14 @@ static UINT cp_fields_noresample(IDirectSoundBufferImpl *dsb, UINT count) committed_samples = committed_samples <= count ? committed_samples : count; } - itmp = intermediate; - for (channel = 0; channel < dsb->mix_channels; channel++) { - for (i = 0; i < committed_samples; i++) - *(itmp++) = get_current_sample(dsb, dsb->committedbuff, - dsb->writelead, dsb->committed_mixpos + i * istride, channel); - for (; i < count; i++) - *(itmp++) = get_current_sample(dsb, dsb->buffer->memory, - dsb->buflen, dsb->sec_mixpos + i * istride, channel); + for (channel = 0; channel < dsb->mix_channels; channel++) + { + get_samples(dsb, dsb->committedbuff, dsb->writelead, dsb->committed_mixpos, channel, + committed_samples, intermediate + channel * count); + if (count > committed_samples) + get_samples(dsb, dsb->buffer->memory, dsb->buflen, + dsb->sec_mixpos + committed_samples * istride, channel, + count - committed_samples, intermediate + channel * count + committed_samples); } for (channel = 0; channel < dsb->mix_channels; channel++) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11082
participants (2)
-
Anton Baskanov -
Anton Baskanov (@baskanov)