diff options
-rw-r--r-- | alc/alc.cpp | 1 | ||||
-rw-r--r-- | alc/panning.cpp | 4 | ||||
-rw-r--r-- | core/device.h | 9 | ||||
-rw-r--r-- | core/filters/nfc.cpp | 108 | ||||
-rw-r--r-- | core/voice.cpp | 11 |
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); - } } |