Merge pull request #1993 from CookiePLMonster/dsound-improvements-alt

DSound improvements (alternative volume heuristics)
This commit is contained in:
RadWolfie 2020-10-26 17:29:31 -05:00 committed by GitHub
commit f8593e692d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 27 additions and 40 deletions

View File

@ -27,6 +27,7 @@
#pragma once #pragma once
#include <mutex> #include <mutex>
#include <optional>
#include "common/XADPCM.h" #include "common/XADPCM.h"
#include "core/hle/DSOUND/XbDSoundTypes.h" #include "core/hle/DSOUND/XbDSoundTypes.h"
@ -1289,49 +1290,35 @@ static inline HRESULT HybridDirectSoundBuffer_SetMixBinVolumes_8(
{ {
HRESULT hRet = DSERR_INVALIDPARAM; HRESULT hRet = DSERR_INVALIDPARAM;
if (pMixBins != xbox::zeroptr) { if (pMixBins != xbox::zeroptr && pMixBins->lpMixBinVolumePairs != xbox::zeroptr) {
DWORD counter = pMixBins->dwCount, count = pMixBins->dwCount; LONG maxVolume = DSBVOLUME_MIN;
LONG volume = 0; // Let's normalize audio level except for low frequency (subwoofer)
if (pMixBins->lpMixBinVolumePairs != xbox::zeroptr) { for (DWORD i = 0; i < pMixBins->dwCount; i++) {
// Let's normalize audio level except for low frequency (subwoofer) // Update the mixbin volume only, do not reassign volume pair array.
for (DWORD i = 0; i < count; i++) { const auto& it_in = pMixBins->lpMixBinVolumePairs[i];
// Update the mixbin volume only, do not reassign volume pair array. auto it_out = std::find_if(Xb_VoiceProperties.MixBinVolumePairs, Xb_VoiceProperties.MixBinVolumePairs+Xb_VoiceProperties.dwMixBinCount,
for (DWORD i = 0; i < count; i++) { [&it_in](const auto& e) {
const auto& it_in = pMixBins->lpMixBinVolumePairs[i]; return e.dwMixBin == it_in.dwMixBin;
for (DWORD ii = 0; ii < Xb_VoiceProperties.dwMixBinCount; ii++) { });
auto& it_internal = Xb_VoiceProperties.MixBinVolumePairs[ii]; // Once found a match, set the volume.
// NOTE If titles input duplicate with different volume,
// Once found a match, set the volume. // it will override previous value.
// NOTE If titles input duplicate with different volume, if (it_out != Xb_VoiceProperties.MixBinVolumePairs+Xb_VoiceProperties.dwMixBinCount) {
// it will override previous value. it_out->lVolume = it_in.lVolume;
if (it_in.dwMixBin == it_internal.dwMixBin) {
it_internal.lVolume = it_in.lVolume;
}
}
}
#if 0 // This code isn't ideal for DirectSound, since it's not possible to set volume for each speakers.
if (pMixBins->lpMixBinVolumePairs[i].dwMixBin != XDSMIXBIN_LOW_FREQUENCY
// We only want to focus on speaker volumes, nothing else.
&& pMixBins->lpMixBinVolumePairs[i].dwMixBin < XDSMIXBIN_SPEAKERS_MAX) {
#endif
if (pMixBins->lpMixBinVolumePairs[i].dwMixBin == XDSMIXBIN_FRONT_LEFT
// We only want to focus on front speaker volumes, nothing else.
|| pMixBins->lpMixBinVolumePairs[i].dwMixBin == XDSMIXBIN_FRONT_RIGHT) {
volume += pMixBins->lpMixBinVolumePairs[i].lVolume;
} else {
counter--;
}
} }
if (counter > 0) {
Xb_volumeMixBin = volume / (LONG)counter; // Since we cannot set per-channel volumes, we want to pick "dominant" volume
int32_t Xb_volume = Xb_Voice->GetVolume() + Xb_Voice->GetHeadroom(); if (it_in.dwMixBin != XDSMIXBIN_LOW_FREQUENCY && it_in.dwMixBin < XDSMIXBIN_SPEAKERS_MAX) {
hRet = HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, EmuFlags, if (it_in.lVolume > maxVolume) {
Xb_volumeMixBin, Xb_Voice); maxVolume = it_in.lVolume;
} else { }
hRet = DS_OK;
} }
} }
Xb_volumeMixBin = maxVolume;
int32_t Xb_volume = Xb_Voice->GetVolume() + Xb_Voice->GetHeadroom();
hRet = HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, EmuFlags,
Xb_volumeMixBin, Xb_Voice);
} }
return hRet; return hRet;