aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2021-12-11 21:42:34 -0800
committerChris Robinson <[email protected]>2021-12-11 21:42:34 -0800
commit5e3fcb3a934844f1d70aa23a8a871a6915565ed2 (patch)
tree34957fb6f4f8da7b522f131f781844e21a4c8f33
parent01dd34f305b9ad2c8e6bf0642cd976f9788fdf3a (diff)
Avoid initializing the NFC filter for every voice channel
It can be initialized once with the device's speaker distance since it won't change in between resets, then copied into the voice where it can be adjusted as needed.
-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);
- }
}