Add an option for higher quality UHJ filters

master
Chris Robinson 2022-08-08 03:44:25 -07:00
parent 250f162496
commit 7e5dd41968
6 changed files with 67 additions and 19 deletions

View File

@ -1124,25 +1124,37 @@ void alc_initconfig(void)
if(auto limopt = ConfigValueBool(nullptr, nullptr, "rt-time-limit"))
AllowRTTimeLimit = *limopt;
CompatFlagBitset compatflags{};
auto checkflag = [](const char *envname, const char *optname) -> bool
{
if(auto optval = al::getenv(envname))
CompatFlagBitset compatflags{};
auto checkflag = [](const char *envname, const char *optname) -> bool
{
if(al::strcasecmp(optval->c_str(), "true") == 0
|| strtol(optval->c_str(), nullptr, 0) == 1)
return true;
return false;
}
return GetConfigValueBool(nullptr, "game_compat", optname, false);
};
compatflags.set(CompatFlags::ReverseX, checkflag("__ALSOFT_REVERSE_X", "reverse-x"));
compatflags.set(CompatFlags::ReverseY, checkflag("__ALSOFT_REVERSE_Y", "reverse-y"));
compatflags.set(CompatFlags::ReverseZ, checkflag("__ALSOFT_REVERSE_Z", "reverse-z"));
if(auto optval = al::getenv(envname))
{
if(al::strcasecmp(optval->c_str(), "true") == 0
|| strtol(optval->c_str(), nullptr, 0) == 1)
return true;
return false;
}
return GetConfigValueBool(nullptr, "game_compat", optname, false);
};
compatflags.set(CompatFlags::ReverseX, checkflag("__ALSOFT_REVERSE_X", "reverse-x"));
compatflags.set(CompatFlags::ReverseY, checkflag("__ALSOFT_REVERSE_Y", "reverse-y"));
compatflags.set(CompatFlags::ReverseZ, checkflag("__ALSOFT_REVERSE_Z", "reverse-z"));
aluInit(compatflags, ConfigValueFloat(nullptr, "game_compat", "nfc-scale").value_or(1.0f));
aluInit(compatflags, ConfigValueFloat(nullptr, "game_compat", "nfc-scale").value_or(1.0f));
}
Voice::InitMixer(ConfigValueStr(nullptr, nullptr, "resampler"));
if(auto uhjfiltopt = ConfigValueStr(nullptr, "uhj", "filter-type"))
{
if(al::strcasecmp(uhjfiltopt->c_str(), "fir256") == 0)
UhjQuality = UhjLengthLq;
else if(al::strcasecmp(uhjfiltopt->c_str(), "fir512") == 0)
UhjQuality = UhjLengthHq;
else
WARN("Unsupported uhj/filter-type: %s\n", uhjfiltopt->c_str());
}
auto traperr = al::getenv("ALSOFT_TRAP_ERROR");
if(traperr && (al::strcasecmp(traperr->c_str(), "true") == 0
|| std::strtol(traperr->c_str(), nullptr, 0) == 1))

View File

@ -1093,7 +1093,10 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, al::optional<StereoEncoding
if(stereomode.value_or(StereoEncoding::Default) == StereoEncoding::Uhj)
{
device->mUhjEncoder = std::make_unique<UhjEncoder<UhjLengthStd>>();
if(UhjQuality >= UhjLengthHq)
device->mUhjEncoder = std::make_unique<UhjEncoder<UhjLengthHq>>();
else
device->mUhjEncoder = std::make_unique<UhjEncoder<UhjLengthLq>>();
TRACE("UHJ enabled\n");
InitUhjPanning(device);
device->PostProcess = &ALCdevice::ProcessUhj;

View File

@ -348,6 +348,18 @@
# docs/3D7.1.txt for information about 3D7.1.
#surround3d71 =
##
## UHJ stuff
##
[uhj]
## filter-type: (global)
# Specifies the all-pass filter type for UHJ encoding, decoding, and Super
# Stereo processing. The default is 'fir256', which utilizes a 256-point FIR
# filter. 'fir512' is a 512-point FIR filter, providing higher quality at the
# cost of higher CPU use.
#filter-type = fir256
##
## Reverb effect stuff (includes EAX reverb)
##

View File

@ -12,6 +12,9 @@
#include "phase_shifter.h"
size_t UhjQuality{UhjLengthStd};
namespace {
const PhaseShifterT<UhjLengthLq> PShiftLq{};

View File

@ -13,6 +13,8 @@ static constexpr size_t UhjLengthLq{256};
static constexpr size_t UhjLengthHq{512};
static constexpr size_t UhjLengthStd{UhjLengthLq};
extern size_t UhjQuality;
struct UhjEncoderBase {
virtual ~UhjEncoderBase() = default;

View File

@ -854,13 +854,29 @@ void Voice::prepare(DeviceBase *device)
if(mFmtChannels == FmtSuperStereo)
{
mDecoder = std::make_unique<UhjStereoDecoder<UhjLengthStd>>();
mDecoderPadding = UhjStereoDecoder<UhjLengthStd>::sFilterDelay;
if(UhjQuality >= UhjLengthHq)
{
mDecoder = std::make_unique<UhjStereoDecoder<UhjLengthHq>>();
mDecoderPadding = UhjStereoDecoder<UhjLengthHq>::sFilterDelay;
}
else
{
mDecoder = std::make_unique<UhjStereoDecoder<UhjLengthLq>>();
mDecoderPadding = UhjStereoDecoder<UhjLengthLq>::sFilterDelay;
}
}
else if(IsUHJ(mFmtChannels))
{
mDecoder = std::make_unique<UhjDecoder<UhjLengthStd>>();
mDecoderPadding = UhjDecoder<UhjLengthStd>::sFilterDelay;
if(UhjQuality >= UhjLengthHq)
{
mDecoder = std::make_unique<UhjDecoder<UhjLengthHq>>();
mDecoderPadding = UhjDecoder<UhjLengthHq>::sFilterDelay;
}
else
{
mDecoder = std::make_unique<UhjDecoder<UhjLengthLq>>();
mDecoderPadding = UhjDecoder<UhjLengthLq>::sFilterDelay;
}
}
else
{