From: Lakulish Antani <lakulisha@valvesoftware.com> If the system's PulseAudio sink is (say) 7.1, and the game has configured the DirectSound buffer to be (say) 5.1, then the format conversion code just copies the first 2 channels of the game's buffer to the first 2 channels of the PulseAudio buffer, leaving the remaining 6 channels of the PulseAudio buffer untouched. This can result in garbage/noise in the output. This change adds explicit handling for quad -> 7.1 and 5.1 -> 7.1 conversion. --- dlls/dsound/dsound_convert.c | 38 ++++++++++++++++++++++++++++++++++++ dlls/dsound/dsound_private.h | 2 ++ dlls/dsound/mixer.c | 10 ++++++++++ 3 files changed, 50 insertions(+) diff --git a/dlls/dsound/dsound_convert.c b/dlls/dsound/dsound_convert.c index bdd62c8e51f..4cd21f628e9 100644 --- a/dlls/dsound/dsound_convert.c +++ b/dlls/dsound/dsound_convert.c @@ -210,6 +210,44 @@ void put_stereo2surround51(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD c } } +void put_quad2surround71(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) +{ + if (channel == 0) { /* Front left */ + dsb->put_aux(dsb, pos, 0, value); /* Front left */ + + dsb->put_aux(dsb, pos, 2, 0.0f); /* Mute front center */ + dsb->put_aux(dsb, pos, 3, 0.0f); /* Mute LFE */ + dsb->put_aux(dsb, pos, 6, 0.0f); /* Mute side left */ + dsb->put_aux(dsb, pos, 7, 0.0f); /* Mute side right */ + } else if (channel == 1) { /* Front right */ + dsb->put_aux(dsb, pos, 1, value); /* Front right */ + } else if (channel == 2) { /* Rear left */ + dsb->put_aux(dsb, pos, 4, value); /* Rear left */ + } else if (channel == 3) { /* Rear right */ + dsb->put_aux(dsb, pos, 5, value); /* Rear right */ + } +} + +void put_surround512surround71(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) +{ + if (channel == 0) { /* Front left */ + dsb->put_aux(dsb, pos, 0, value); /* Front left */ + + dsb->put_aux(dsb, pos, 6, 0.0f); /* Mute side left */ + dsb->put_aux(dsb, pos, 7, 0.0f); /* Mute side right */ + } else if (channel == 1) { /* Front right */ + dsb->put_aux(dsb, pos, 1, value); /* Front right */ + } else if (channel == 2) { /* Front center */ + dsb->put_aux(dsb, pos, 2, value); /* Front center */ + } else if (channel == 3) { /* LFE */ + dsb->put_aux(dsb, pos, 3, value); /* LFE */ + } else if (channel == 4) { /* Rear left */ + dsb->put_aux(dsb, pos, 4, value); /* Rear left */ + } else if (channel == 5) { /* Rear right */ + dsb->put_aux(dsb, pos, 5, value); /* Rear right */ + } +} + void put_surround512stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) { /* based on analyzing a recording of a dsound downmix */ diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index 7e6768a21a8..2b3aa9a9d25 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -182,6 +182,8 @@ void put_stereo2surround51(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD c 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_quad2surround71(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); +void put_surround512surround71(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value); HRESULT secondarybuffer_create(DirectSoundDevice *device, const DSBUFFERDESC *dsbd, IDirectSoundBuffer **buffer); diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index 3b7715e0c69..c37011752b0 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -195,6 +195,16 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) dsb->put = put_quad2stereo; dsb->put_aux = putieee32_sum; } + else if (ichannels == 4 && ochannels == 8) + { + dsb->mix_channels = 4; + dsb->put = put_quad2surround71; + } + else if (ichannels == 6 && ochannels == 8) + { + dsb->mix_channels = 6; + dsb->put = put_surround512surround71; + } else { if (ichannels > 2) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11154