diff --git a/alc/alc.cpp b/alc/alc.cpp index c71d84ae..4579232b 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -2093,8 +2093,6 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) nanoseconds::rep sample_delay{0}; if(device->mUhjEncoder) sample_delay += UhjEncoder::sFilterDelay; - if(device->mHrtfState) - sample_delay += HrtfDirectDelay; if(auto *ambidec = device->AmbiDecoder.get()) { if(ambidec->hasStablizer()) diff --git a/core/device.h b/core/device.h index 48d04f77..58a30f1b 100644 --- a/core/device.h +++ b/core/device.h @@ -197,7 +197,7 @@ struct DeviceBase { }; /* Persistent storage for HRTF mixing. */ - alignas(16) float2 HrtfAccumData[BufferLineSize + HrirLength + HrtfDirectDelay]; + alignas(16) float2 HrtfAccumData[BufferLineSize + HrirLength]; /* Mixing buffer used by the Dry mix and Real output. */ al::vector MixBuffer; diff --git a/core/hrtf.h b/core/hrtf.h index 61e5bada..9cf11efb 100644 --- a/core/hrtf.h +++ b/core/hrtf.h @@ -58,7 +58,7 @@ struct AngularPoint { struct DirectHrtfState { - std::array mTemp; + std::array mTemp; /* HRTF filter state for dry buffer content */ uint mIrSize{0}; diff --git a/core/mixer/hrtfbase.h b/core/mixer/hrtfbase.h index 79b09a3d..ade6f693 100644 --- a/core/mixer/hrtfbase.h +++ b/core/mixer/hrtfbase.h @@ -90,46 +90,15 @@ inline void MixDirectHrtfBase(const FloatBufferSpan LeftOut, const FloatBufferSp { ASSUME(BufferSize > 0); - /* Add the existing signal directly to the accumulation buffer, unfiltered, - * and with a delay to align with the input delay. - */ - for(size_t i{0};i < BufferSize;++i) - { - AccumSamples[HrtfDirectDelay+i][0] += LeftOut[i]; - AccumSamples[HrtfDirectDelay+i][1] += RightOut[i]; - } - for(const FloatBufferLine &input : InSamples) { /* For dual-band processing, the signal needs extra scaling applied to - * the high frequency response. The band-splitter alone creates a - * frequency-dependent phase shift, which is not ideal. To counteract - * it, combine it with a backwards phase shift. + * the high frequency response. The band-splitter applies this scaling + * with a consistent phase shift regardless of the scale amount. */ + al::span tempbuf{al::assume_aligned<16>(TempBuf), BufferSize}; + std::copy(input.begin(), input.begin()+BufferSize, tempbuf.begin()); - /* Load the input signal backwards, into a temp buffer with delay - * padding. The delay serves to reduce the error caused by the IIR - * filter's phase shift on a partial input. - */ - al::span tempbuf{al::assume_aligned<16>(TempBuf), HrtfDirectDelay+BufferSize}; - auto tmpiter = std::reverse_copy(input.begin(), input.begin()+BufferSize, tempbuf.begin()); - std::copy(ChanState->mDelay.cbegin(), ChanState->mDelay.cend(), tmpiter); - - /* Save the unfiltered newest input samples for next time. */ - std::copy_n(tempbuf.begin(), ChanState->mDelay.size(), ChanState->mDelay.begin()); - - /* Apply the all-pass on the reversed signal and reverse the resulting - * sample array. This produces the forward response with a backwards - * phase shift (+n degrees becomes -n degrees). - */ - ChanState->mSplitter.applyAllpass(tempbuf); - tempbuf = tempbuf.subspan(); - std::reverse(tempbuf.begin(), tempbuf.end()); - - /* Now apply the HF scale with the band-splitter. This applies the - * forward phase shift, which cancels out with the backwards phase - * shift to get the original phase on the scaled signal. - */ ChanState->mSplitter.processHfScale(tempbuf, ChanState->mHfScale); /* Now apply the HRIR coefficients to this channel. */ @@ -143,16 +112,16 @@ inline void MixDirectHrtfBase(const FloatBufferSpan LeftOut, const FloatBufferSp ++ChanState; } + /* Add the HRTF signal to the existing "direct" signal. */ for(size_t i{0u};i < BufferSize;++i) - LeftOut[i] = AccumSamples[i][0]; + LeftOut[i] += AccumSamples[i][0]; for(size_t i{0u};i < BufferSize;++i) - RightOut[i] = AccumSamples[i][1]; + RightOut[i] += AccumSamples[i][1]; /* Copy the new in-progress accumulation values to the front and clear the * following samples for the next mix. */ - auto accum_iter = std::copy_n(AccumSamples+BufferSize, HrirLength+HrtfDirectDelay, - AccumSamples); + auto accum_iter = std::copy_n(AccumSamples+BufferSize, HrirLength, AccumSamples); std::fill_n(accum_iter, BufferSize, float2{}); } diff --git a/core/mixer/hrtfdefs.h b/core/mixer/hrtfdefs.h index 7046a31e..3c903ed8 100644 --- a/core/mixer/hrtfdefs.h +++ b/core/mixer/hrtfdefs.h @@ -26,8 +26,6 @@ constexpr uint HrirMask{HrirLength - 1}; constexpr uint MinIrLength{8}; -constexpr uint HrtfDirectDelay{256}; - using HrirArray = std::array; using HrirSpan = al::span; using ConstHrirSpan = al::span; @@ -47,7 +45,6 @@ struct HrtfFilter { struct HrtfChannelState { - std::array mDelay{}; BandSplitter mSplitter; float mHfScale{}; alignas(16) HrirArray mCoeffs{}; diff --git a/core/voice.cpp b/core/voice.cpp index 07400b07..0060737f 100644 --- a/core/voice.cpp +++ b/core/voice.cpp @@ -355,10 +355,7 @@ void DoHrtfMix(const float *samples, const uint DstBufferSize, DirectParams &par { const uint IrSize{Device->mIrSize}; auto &HrtfSamples = Device->HrtfSourceData; - /* Source HRTF mixing needs to include the direct delay so it remains - * aligned with the direct mix's HRTF filtering. - */ - float2 *AccumSamples{Device->HrtfAccumData + HrtfDirectDelay}; + auto &AccumSamples = Device->HrtfAccumData; /* Copy the HRTF history and new input samples into a temp buffer. */ auto src_iter = std::copy(parms.Hrtf.History.begin(), parms.Hrtf.History.end(),