1 #ifndef CORE_MIXER_HRTFBASE_H
2 #define CORE_MIXER_HRTFBASE_H
9 #include "opthelpers.h"
12 using uint = unsigned int;
14 using ApplyCoeffsT = void(&)(float2 *RESTRICT Values, const size_t irSize,
15 const ConstHrirSpan Coeffs, const float left, const float right);
17 template<ApplyCoeffsT ApplyCoeffs>
18 inline void MixHrtfBase(const float *InSamples, float2 *RESTRICT AccumSamples, const size_t IrSize,
19 const MixHrtfFilter *hrtfparams, const size_t BufferSize)
21 ASSUME(BufferSize > 0);
23 const ConstHrirSpan Coeffs{hrtfparams->Coeffs};
24 const float gainstep{hrtfparams->GainStep};
25 const float gain{hrtfparams->Gain};
27 size_t ldelay{HrtfHistoryLength - hrtfparams->Delay[0]};
28 size_t rdelay{HrtfHistoryLength - hrtfparams->Delay[1]};
29 float stepcount{0.0f};
30 for(size_t i{0u};i < BufferSize;++i)
32 const float g{gain + gainstep*stepcount};
33 const float left{InSamples[ldelay++] * g};
34 const float right{InSamples[rdelay++] * g};
35 ApplyCoeffs(AccumSamples+i, IrSize, Coeffs, left, right);
41 template<ApplyCoeffsT ApplyCoeffs>
42 inline void MixHrtfBlendBase(const float *InSamples, float2 *RESTRICT AccumSamples,
43 const size_t IrSize, const HrtfFilter *oldparams, const MixHrtfFilter *newparams,
44 const size_t BufferSize)
46 ASSUME(BufferSize > 0);
48 const ConstHrirSpan OldCoeffs{oldparams->Coeffs};
49 const float oldGainStep{oldparams->Gain / static_cast<float>(BufferSize)};
50 const ConstHrirSpan NewCoeffs{newparams->Coeffs};
51 const float newGainStep{newparams->GainStep};
53 if(oldparams->Gain > GainSilenceThreshold) LIKELY
55 size_t ldelay{HrtfHistoryLength - oldparams->Delay[0]};
56 size_t rdelay{HrtfHistoryLength - oldparams->Delay[1]};
57 auto stepcount = static_cast<float>(BufferSize);
58 for(size_t i{0u};i < BufferSize;++i)
60 const float g{oldGainStep*stepcount};
61 const float left{InSamples[ldelay++] * g};
62 const float right{InSamples[rdelay++] * g};
63 ApplyCoeffs(AccumSamples+i, IrSize, OldCoeffs, left, right);
69 if(newGainStep*static_cast<float>(BufferSize) > GainSilenceThreshold) LIKELY
71 size_t ldelay{HrtfHistoryLength+1 - newparams->Delay[0]};
72 size_t rdelay{HrtfHistoryLength+1 - newparams->Delay[1]};
73 float stepcount{1.0f};
74 for(size_t i{1u};i < BufferSize;++i)
76 const float g{newGainStep*stepcount};
77 const float left{InSamples[ldelay++] * g};
78 const float right{InSamples[rdelay++] * g};
79 ApplyCoeffs(AccumSamples+i, IrSize, NewCoeffs, left, right);
86 template<ApplyCoeffsT ApplyCoeffs>
87 inline void MixDirectHrtfBase(const FloatBufferSpan LeftOut, const FloatBufferSpan RightOut,
88 const al::span<const FloatBufferLine> InSamples, float2 *RESTRICT AccumSamples,
89 float *TempBuf, HrtfChannelState *ChanState, const size_t IrSize, const size_t BufferSize)
91 ASSUME(BufferSize > 0);
93 for(const FloatBufferLine &input : InSamples)
95 /* For dual-band processing, the signal needs extra scaling applied to
96 * the high frequency response. The band-splitter applies this scaling
97 * with a consistent phase shift regardless of the scale amount.
99 ChanState->mSplitter.processHfScale({input.data(), BufferSize}, TempBuf,
100 ChanState->mHfScale);
102 /* Now apply the HRIR coefficients to this channel. */
103 const float *RESTRICT tempbuf{al::assume_aligned<16>(TempBuf)};
104 const ConstHrirSpan Coeffs{ChanState->mCoeffs};
105 for(size_t i{0u};i < BufferSize;++i)
107 const float insample{tempbuf[i]};
108 ApplyCoeffs(AccumSamples+i, IrSize, Coeffs, insample, insample);
114 /* Add the HRTF signal to the existing "direct" signal. */
115 float *RESTRICT left{al::assume_aligned<16>(LeftOut.data())};
116 float *RESTRICT right{al::assume_aligned<16>(RightOut.data())};
117 for(size_t i{0u};i < BufferSize;++i)
118 left[i] += AccumSamples[i][0];
119 for(size_t i{0u};i < BufferSize;++i)
120 right[i] += AccumSamples[i][1];
122 /* Copy the new in-progress accumulation values to the front and clear the
123 * following samples for the next mix.
125 auto accum_iter = std::copy_n(AccumSamples+BufferSize, HrirLength, AccumSamples);
126 std::fill_n(accum_iter, BufferSize, float2{});
129 #endif /* CORE_MIXER_HRTFBASE_H */