aboutsummaryrefslogtreecommitdiffstats
path: root/alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2022-07-07 22:11:38 -0700
committerChris Robinson <[email protected]>2022-07-07 22:11:38 -0700
commit1ad553b5a913e11c712eb95b7ecc7cbc66f4a274 (patch)
tree6b6a4608d62e38f820eae4840081912347880a70 /alc
parentedadd221ea71b0fd4ba58d231c7aead85af118ec (diff)
Add a config compat option for NFC distance scaling
Currently there's no way for an application to specify the "real world" scale for in-game units. If the game doesn't use one unit to represent what should be perceived as one meter to the user, the NFC filter's effect will be too near or too far sounding. This allows adjusting the unit scale as applied to the NFC filters only, correcting the misalignment. This also removes the influence of EFX's MetersPerUnit from the NFC filters, since many games don't use it, and those that do won't know it also influences the perceived wave curvature along with the air absorption strength.
Diffstat (limited to 'alc')
-rw-r--r--alc/alc.cpp2
-rw-r--r--alc/alu.cpp16
-rw-r--r--alc/alu.h2
3 files changed, 12 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
*