diff options
-rw-r--r-- | alc/alc.cpp | 2 | ||||
-rw-r--r-- | alc/alu.cpp | 16 | ||||
-rw-r--r-- | alc/alu.h | 2 | ||||
-rw-r--r-- | alsoftrc.sample | 8 |
4 files changed, 20 insertions, 8 deletions
diff --git a/alc/alc.cpp b/alc/alc.cpp index 6ee6c24a..07c9372c 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -1140,7 +1140,7 @@ void alc_initconfig(void) compatflags.set(CompatFlags::ReverseY, checkflag("__ALSOFT_REVERSE_Y", "reverse-y")); compatflags.set(CompatFlags::ReverseZ, checkflag("__ALSOFT_REVERSE_Z", "reverse-z")); - aluInit(compatflags); + aluInit(compatflags, ConfigValueFloat(nullptr, "game_compat", "nfc-scale").value_or(1.0f)); Voice::InitMixer(ConfigValueStr(nullptr, nullptr, "resampler")); auto traperr = al::getenv("ALSOFT_TRAP_ERROR"); diff --git a/alc/alu.cpp b/alc/alu.cpp index a06d5675..0d7f5156 100644 --- a/alc/alu.cpp +++ b/alc/alu.cpp @@ -135,6 +135,9 @@ float XScale{1.0f}; float YScale{1.0f}; float ZScale{1.0f}; +/* Source distance scale for NFC filters. */ +float NfcScale{1.0f}; + struct ChanMap { Channel channel; @@ -241,12 +244,14 @@ inline ResamplerFunc SelectResampler(Resampler resampler, uint increment) } // namespace -void aluInit(CompatFlagBitset flags) +void aluInit(CompatFlagBitset flags, const float nfcscale) { MixDirectHrtf = SelectHrtfMixer(); XScale = flags.test(CompatFlags::ReverseX) ? -1.0f : 1.0f; YScale = flags.test(CompatFlags::ReverseY) ? -1.0f : 1.0f; ZScale = flags.test(CompatFlags::ReverseZ) ? -1.0f : 1.0f; + + NfcScale = clampf(nfcscale, 0.0001f, 10000.0f); } @@ -787,7 +792,7 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con /* Clamp the distance for really close sources, to prevent * excessive bass. */ - const float mdist{maxf(Distance, Device->AvgSpeakerDist/4.0f)}; + const float mdist{maxf(Distance*NfcScale, Device->AvgSpeakerDist/4.0f)}; const float w0{SpeedOfSoundMetersPerSec / (mdist * Frequency)}; /* Only need to adjust the first channel of a B-Format source. */ @@ -963,7 +968,7 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con /* Get the HRIR coefficients and delays just once, for the given * source direction. */ - GetHrtfCoeffs(Device->mHrtf.get(), ev, az, Distance, Spread, + GetHrtfCoeffs(Device->mHrtf.get(), ev, az, Distance*NfcScale, Spread, voice->mChans[0].mDryParams.Hrtf.Target.Coeffs, voice->mChans[0].mDryParams.Hrtf.Target.Delay); voice->mChans[0].mDryParams.Hrtf.Target.Gain = DryGain.Base; @@ -1041,7 +1046,7 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con /* Clamp the distance for really close sources, to prevent * excessive bass. */ - const float mdist{maxf(Distance, Device->AvgSpeakerDist/4.0f)}; + const float mdist{maxf(Distance*NfcScale, Device->AvgSpeakerDist/4.0f)}; const float w0{SpeedOfSoundMetersPerSec / (mdist * Frequency)}; /* Adjust NFC filters. */ @@ -1513,8 +1518,7 @@ void CalcAttnSourceParams(Voice *voice, const VoiceProps *props, const ContextBa spread = std::asin(props->Radius/Distance) * 2.0f; CalcPanningAndFilters(voice, ToSource[0]*XScale, ToSource[1]*YScale, ToSource[2]*ZScale, - Distance*context->mParams.MetersPerUnit, spread, DryGain, WetGain, SendSlots, props, - context->mParams, Device); + Distance, spread, DryGain, WetGain, SendSlots, props, context->mParams, Device); } void CalcSourceParams(Voice *voice, ContextBase *context, bool force) @@ -24,7 +24,7 @@ enum CompatFlags : uint8_t { }; using CompatFlagBitset = std::bitset<CompatFlags::Count>; -void aluInit(CompatFlagBitset flags); +void aluInit(CompatFlagBitset flags, const float nfcscale); /* aluInitRenderer * diff --git a/alsoftrc.sample b/alsoftrc.sample index 4ea548ce..2dd593a7 100644 --- a/alsoftrc.sample +++ b/alsoftrc.sample @@ -602,6 +602,14 @@ ## [game_compat] +## nfc-scale: (global) +# A meters-per-unit distance scale applied to NFC filters. If a game doesn't +# use real-world meters for in-game units, the filters may create a too-near +# or too-distant effect. For instance, if the game uses 1 foot per unit, a +# value of 0.3048 will correctly adjust the filters. Or if the game uses 1 +# kilometer per unit, a value of 1000 will correctly adjust the filters. +#nfc-scale = 1 + ## reverse-x: (global) # Reverses the local X (left-right) position of 3D sound sources. #reverse-x = false |