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