aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--alc/alc.cpp2
-rw-r--r--alc/alu.cpp16
-rw-r--r--alc/alu.h2
-rw-r--r--alsoftrc.sample8
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)
diff --git a/alc/alu.h b/alc/alu.h
index f3796a89..67fd09e5 100644
--- a/alc/alu.h
+++ b/alc/alu.h
@@ -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