aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--alc/alc.cpp1
-rw-r--r--alc/panning.cpp4
-rw-r--r--core/device.h9
-rw-r--r--core/filters/nfc.cpp108
-rw-r--r--core/voice.cpp11
5 files changed, 61 insertions, 72 deletions
diff --git a/alc/alc.cpp b/alc/alc.cpp
index df38b22b..9f2abc13 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -1755,6 +1755,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
return ALC_NO_ERROR;
device->AvgSpeakerDist = 0.0f;
+ device->mNFCtrlFilter = NfcFilter{};
device->mUhjEncoder = nullptr;
device->AmbiDecoder = nullptr;
device->Bs2b = nullptr;
diff --git a/alc/panning.cpp b/alc/panning.cpp
index d686de1d..eefcc867 100644
--- a/alc/panning.cpp
+++ b/alc/panning.cpp
@@ -218,6 +218,10 @@ void InitNearFieldCtrl(ALCdevice *device, float ctrl_dist, uint order, bool is3d
device->AvgSpeakerDist = clampf(ctrl_dist, 0.1f, 10.0f);
TRACE("Using near-field reference distance: %.2f meters\n", device->AvgSpeakerDist);
+ const float w1{SpeedOfSoundMetersPerSec /
+ (device->AvgSpeakerDist * static_cast<float>(device->Frequency))};
+ device->mNFCtrlFilter.init(w1);
+
auto iter = std::copy_n(is3d ? chans_per_order3d : chans_per_order2d, order+1u,
std::begin(device->NumChannelsPerOrder));
std::fill(iter, std::end(device->NumChannelsPerOrder), 0u);
diff --git a/core/device.h b/core/device.h
index 194901a2..111e26ce 100644
--- a/core/device.h
+++ b/core/device.h
@@ -15,8 +15,9 @@
#include "alspan.h"
#include "ambidefs.h"
#include "atomic.h"
-#include "core/bufferline.h"
+#include "bufferline.h"
#include "devformat.h"
+#include "filters/nfc.h"
#include "intrusive_ptr.h"
#include "mixer/hrtfdefs.h"
#include "opthelpers.h"
@@ -30,7 +31,6 @@ struct Compressor;
struct ContextBase;
struct DirectHrtfState;
struct HrtfStore;
-struct UhjEncoder;
using uint = unsigned int;
@@ -171,6 +171,11 @@ struct DeviceBase {
*/
float AvgSpeakerDist{0.0f};
+ /* The default NFC filter. Not used directly, but is pre-initialized with
+ * the control distance from AvgSpeakerDist.
+ */
+ NfcFilter mNFCtrlFilter{};
+
uint SamplesDone{0u};
std::chrono::nanoseconds ClockBase{0};
std::chrono::nanoseconds FixedLatency{0};
diff --git a/core/filters/nfc.cpp b/core/filters/nfc.cpp
index 9a28517c..aa64c613 100644
--- a/core/filters/nfc.cpp
+++ b/core/filters/nfc.cpp
@@ -62,25 +62,21 @@ NfcFilter1 NfcFilterCreate1(const float w0, const float w1) noexcept
float b_00, g_0;
float r;
- nfc.base_gain = 1.0f;
- nfc.gain = 1.0f;
-
- /* Calculate bass-boost coefficients. */
- r = 0.5f * w0;
+ /* Calculate bass-cut coefficients. */
+ r = 0.5f * w1;
b_00 = B[1][0] * r;
g_0 = 1.0f + b_00;
- nfc.gain *= g_0;
- nfc.b1 = 2.0f * b_00 / g_0;
+ nfc.base_gain = 1.0f / g_0;
+ nfc.a1 = 2.0f * b_00 / g_0;
- /* Calculate bass-cut coefficients. */
- r = 0.5f * w1;
+ /* Calculate bass-boost coefficients. */
+ r = 0.5f * w0;
b_00 = B[1][0] * r;
g_0 = 1.0f + b_00;
- nfc.base_gain /= g_0;
- nfc.gain /= g_0;
- nfc.a1 = 2.0f * b_00 / g_0;
+ nfc.gain = nfc.base_gain * g_0;
+ nfc.b1 = 2.0f * b_00 / g_0;
return nfc;
}
@@ -102,29 +98,25 @@ NfcFilter2 NfcFilterCreate2(const float w0, const float w1) noexcept
float b_10, b_11, g_1;
float r;
- nfc.base_gain = 1.0f;
- nfc.gain = 1.0f;
-
- /* Calculate bass-boost coefficients. */
- r = 0.5f * w0;
+ /* Calculate bass-cut coefficients. */
+ r = 0.5f * w1;
b_10 = B[2][0] * r;
b_11 = B[2][1] * r * r;
g_1 = 1.0f + b_10 + b_11;
- nfc.gain *= g_1;
- nfc.b1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
- nfc.b2 = 4.0f * b_11 / g_1;
+ nfc.base_gain = 1.0f / g_1;
+ nfc.a1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
+ nfc.a2 = 4.0f * b_11 / g_1;
- /* Calculate bass-cut coefficients. */
- r = 0.5f * w1;
+ /* Calculate bass-boost coefficients. */
+ r = 0.5f * w0;
b_10 = B[2][0] * r;
b_11 = B[2][1] * r * r;
g_1 = 1.0f + b_10 + b_11;
- nfc.base_gain /= g_1;
- nfc.gain /= g_1;
- nfc.a1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
- nfc.a2 = 4.0f * b_11 / g_1;
+ nfc.gain = nfc.base_gain * g_1;
+ nfc.b1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
+ nfc.b2 = 4.0f * b_11 / g_1;
return nfc;
}
@@ -149,35 +141,31 @@ NfcFilter3 NfcFilterCreate3(const float w0, const float w1) noexcept
float b_00, g_0;
float r;
- nfc.base_gain = 1.0f;
- nfc.gain = 1.0f;
-
- /* Calculate bass-boost coefficients. */
- r = 0.5f * w0;
+ /* Calculate bass-cut coefficients. */
+ r = 0.5f * w1;
b_10 = B[3][0] * r;
b_11 = B[3][1] * r * r;
b_00 = B[3][2] * r;
g_1 = 1.0f + b_10 + b_11;
g_0 = 1.0f + b_00;
- nfc.gain *= g_1 * g_0;
- nfc.b1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
- nfc.b2 = 4.0f * b_11 / g_1;
- nfc.b3 = 2.0f * b_00 / g_0;
+ nfc.base_gain = 1.0f / (g_1 * g_0);
+ nfc.a1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
+ nfc.a2 = 4.0f * b_11 / g_1;
+ nfc.a3 = 2.0f * b_00 / g_0;
- /* Calculate bass-cut coefficients. */
- r = 0.5f * w1;
+ /* Calculate bass-boost coefficients. */
+ r = 0.5f * w0;
b_10 = B[3][0] * r;
b_11 = B[3][1] * r * r;
b_00 = B[3][2] * r;
g_1 = 1.0f + b_10 + b_11;
g_0 = 1.0f + b_00;
- nfc.base_gain /= g_1 * g_0;
- nfc.gain /= g_1 * g_0;
- nfc.a1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
- nfc.a2 = 4.0f * b_11 / g_1;
- nfc.a3 = 2.0f * b_00 / g_0;
+ nfc.gain = nfc.base_gain * (g_1 * g_0);
+ nfc.b1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
+ nfc.b2 = 4.0f * b_11 / g_1;
+ nfc.b3 = 2.0f * b_00 / g_0;
return nfc;
}
@@ -191,7 +179,7 @@ void NfcFilterAdjust3(NfcFilter3 *nfc, const float w0) noexcept
const float g_1{1.0f + b_10 + b_11};
const float g_0{1.0f + b_00};
- nfc->gain = nfc->base_gain * g_1 * g_0;
+ nfc->gain = nfc->base_gain * (g_1 * g_0);
nfc->b1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
nfc->b2 = 4.0f * b_11 / g_1;
nfc->b3 = 2.0f * b_00 / g_0;
@@ -205,11 +193,8 @@ NfcFilter4 NfcFilterCreate4(const float w0, const float w1) noexcept
float b_00, b_01, g_0;
float r;
- nfc.base_gain = 1.0f;
- nfc.gain = 1.0f;
-
- /* Calculate bass-boost coefficients. */
- r = 0.5f * w0;
+ /* Calculate bass-cut coefficients. */
+ r = 0.5f * w1;
b_10 = B[4][0] * r;
b_11 = B[4][1] * r * r;
b_00 = B[4][2] * r;
@@ -217,14 +202,14 @@ NfcFilter4 NfcFilterCreate4(const float w0, const float w1) noexcept
g_1 = 1.0f + b_10 + b_11;
g_0 = 1.0f + b_00 + b_01;
- nfc.gain *= g_1 * g_0;
- nfc.b1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
- nfc.b2 = 4.0f * b_11 / g_1;
- nfc.b3 = (2.0f*b_00 + 4.0f*b_01) / g_0;
- nfc.b4 = 4.0f * b_01 / g_0;
+ nfc.base_gain = 1.0f / (g_1 * g_0);
+ nfc.a1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
+ nfc.a2 = 4.0f * b_11 / g_1;
+ nfc.a3 = (2.0f*b_00 + 4.0f*b_01) / g_0;
+ nfc.a4 = 4.0f * b_01 / g_0;
- /* Calculate bass-cut coefficients. */
- r = 0.5f * w1;
+ /* Calculate bass-boost coefficients. */
+ r = 0.5f * w0;
b_10 = B[4][0] * r;
b_11 = B[4][1] * r * r;
b_00 = B[4][2] * r;
@@ -232,12 +217,11 @@ NfcFilter4 NfcFilterCreate4(const float w0, const float w1) noexcept
g_1 = 1.0f + b_10 + b_11;
g_0 = 1.0f + b_00 + b_01;
- nfc.base_gain /= g_1 * g_0;
- nfc.gain /= g_1 * g_0;
- nfc.a1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
- nfc.a2 = 4.0f * b_11 / g_1;
- nfc.a3 = (2.0f*b_00 + 4.0f*b_01) / g_0;
- nfc.a4 = 4.0f * b_01 / g_0;
+ nfc.gain = nfc.base_gain * (g_1 * g_0);
+ nfc.b1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
+ nfc.b2 = 4.0f * b_11 / g_1;
+ nfc.b3 = (2.0f*b_00 + 4.0f*b_01) / g_0;
+ nfc.b4 = 4.0f * b_01 / g_0;
return nfc;
}
@@ -252,7 +236,7 @@ void NfcFilterAdjust4(NfcFilter4 *nfc, const float w0) noexcept
const float g_1{1.0f + b_10 + b_11};
const float g_0{1.0f + b_00 + b_01};
- nfc->gain = nfc->base_gain * g_1 * g_0;
+ nfc->gain = nfc->base_gain * (g_1 * g_0);
nfc->b1 = (2.0f*b_10 + 4.0f*b_11) / g_1;
nfc->b2 = 4.0f * b_11 / g_1;
nfc->b3 = (2.0f*b_00 + 4.0f*b_01) / g_0;
diff --git a/core/voice.cpp b/core/voice.cpp
index 923d7275..f7a5940a 100644
--- a/core/voice.cpp
+++ b/core/voice.cpp
@@ -852,6 +852,7 @@ void Voice::prepare(DeviceBase *device)
chandata.mAmbiLFScale = 1.0f;
chandata.mAmbiSplitter = splitter;
chandata.mDryParams = DirectParams{};
+ chandata.mDryParams.NFCtrlFilter = device->mNFCtrlFilter;
std::fill_n(chandata.mWetParams.begin(), device->NumAuxSends, SendParams{});
}
/* 2-channel UHJ needs different shelf filters. However, we can't just
@@ -886,6 +887,7 @@ void Voice::prepare(DeviceBase *device)
chandata.mAmbiLFScale = 1.0f;
chandata.mAmbiSplitter = splitter;
chandata.mDryParams = DirectParams{};
+ chandata.mDryParams.NFCtrlFilter = device->mNFCtrlFilter;
std::fill_n(chandata.mWetParams.begin(), device->NumAuxSends, SendParams{});
}
mChans[0].mAmbiLFScale = 0.661f;
@@ -898,16 +900,9 @@ void Voice::prepare(DeviceBase *device)
for(auto &chandata : mChans)
{
chandata.mDryParams = DirectParams{};
+ chandata.mDryParams.NFCtrlFilter = device->mNFCtrlFilter;
std::fill_n(chandata.mWetParams.begin(), device->NumAuxSends, SendParams{});
}
mFlags &= ~VoiceIsAmbisonic;
}
-
- if(device->AvgSpeakerDist > 0.0f)
- {
- const float w1{SpeedOfSoundMetersPerSec /
- (device->AvgSpeakerDist * static_cast<float>(device->Frequency))};
- for(auto &chandata : mChans)
- chandata.mDryParams.NFCtrlFilter.init(w1);
- }
}