1 #ifndef CORE_MIXER_DEFS_H
2 #define CORE_MIXER_DEFS_H
11 #include "core/bufferline.h"
12 #include "core/cubic_defs.h"
14 struct HrtfChannelState
;
18 using uint
= unsigned int;
19 using float2
= std::array
<float,2>;
22 inline constexpr int MixerFracBits
{16};
23 inline constexpr int MixerFracOne
{1 << MixerFracBits
};
24 inline constexpr int MixerFracMask
{MixerFracOne
- 1};
25 inline constexpr int MixerFracHalf
{MixerFracOne
>> 1};
27 inline constexpr float GainSilenceThreshold
{0.00001f
}; /* -100dB */
30 enum class Resampler
: std::uint8_t {
43 /* Interpolator state. Kind of a misnomer since the interpolator itself is
44 * stateless. This just keeps it from having to recompute scale-related
45 * mappings for every sample.
48 float sf
; /* Scale interpolation factor. */
49 uint m
; /* Coefficient count. */
50 uint l
; /* Left coefficient offset. */
51 /* Filter coefficients, followed by the phase, scale, and scale-phase
52 * delta coefficients. Starting at phase index 0, each subsequent phase
53 * index follows contiguously.
55 al::span
<const float> filter
;
59 /* Filter coefficients, and coefficient deltas. Starting at phase index 0,
60 * each subsequent phase index follows contiguously.
62 al::span
<const CubicCoefficients
,CubicPhaseCount
> filter
;
63 CubicState(al::span
<const CubicCoefficients
,CubicPhaseCount
> f
) : filter
{f
} { }
66 using InterpState
= std::variant
<std::monostate
,CubicState
,BsincState
>;
68 using ResamplerFunc
= void(*)(const InterpState
*state
, const al::span
<const float> src
, uint frac
,
69 const uint increment
, const al::span
<float> dst
);
71 ResamplerFunc
PrepareResampler(Resampler resampler
, uint increment
, InterpState
*state
);
74 template<typename TypeTag
, typename InstTag
>
75 void Resample_(const InterpState
*state
, const al::span
<const float> src
, uint frac
,
76 const uint increment
, const al::span
<float> dst
);
78 template<typename InstTag
>
79 void Mix_(const al::span
<const float> InSamples
, const al::span
<FloatBufferLine
> OutBuffer
,
80 const al::span
<float> CurrentGains
, const al::span
<const float> TargetGains
,
81 const size_t Counter
, const size_t OutPos
);
82 template<typename InstTag
>
83 void Mix_(const al::span
<const float> InSamples
, const al::span
<float> OutBuffer
,
84 float &CurrentGain
, const float TargetGain
, const size_t Counter
);
86 template<typename InstTag
>
87 void MixHrtf_(const al::span
<const float> InSamples
, const al::span
<float2
> AccumSamples
,
88 const uint IrSize
, const MixHrtfFilter
*hrtfparams
, const size_t SamplesToDo
);
89 template<typename InstTag
>
90 void MixHrtfBlend_(const al::span
<const float> InSamples
, const al::span
<float2
> AccumSamples
,
91 const uint IrSize
, const HrtfFilter
*oldparams
, const MixHrtfFilter
*newparams
,
92 const size_t SamplesToDo
);
93 template<typename InstTag
>
94 void MixDirectHrtf_(const FloatBufferSpan LeftOut
, const FloatBufferSpan RightOut
,
95 const al::span
<const FloatBufferLine
> InSamples
, const al::span
<float2
> AccumSamples
,
96 const al::span
<float,BufferLineSize
> TempBuf
, const al::span
<HrtfChannelState
> ChanState
,
97 const size_t IrSize
, const size_t SamplesToDo
);
99 /* Vectorized resampler helpers */
101 constexpr void InitPosArrays(uint pos
, uint frac
, const uint increment
,
102 const al::span
<uint
,N
> frac_arr
, const al::span
<uint
,N
> pos_arr
)
104 static_assert(pos_arr
.size() == frac_arr
.size());
107 for(size_t i
{1};i
< pos_arr
.size();++i
)
109 const uint frac_tmp
{frac_arr
[i
-1] + increment
};
110 pos_arr
[i
] = pos_arr
[i
-1] + (frac_tmp
>>MixerFracBits
);
111 frac_arr
[i
] = frac_tmp
&MixerFracMask
;
115 #endif /* CORE_MIXER_DEFS_H */