Add an option for higher quality UHJ filters
This commit is contained in:
parent
250f162496
commit
7e5dd41968
40
alc/alc.cpp
40
alc/alc.cpp
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
##
|
||||
|
@ -12,6 +12,9 @@
|
||||
#include "phase_shifter.h"
|
||||
|
||||
|
||||
size_t UhjQuality{UhjLengthStd};
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
const PhaseShifterT<UhjLengthLq> PShiftLq{};
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user