12 #include "filters/biquad.h"
13 #include "filters/nfc.h"
14 #include "filters/splitter.h"
17 enum class DistanceModel
;
21 SpatializeOff
= AL_FALSE
,
22 SpatializeOn
= AL_TRUE
,
23 SpatializeAuto
= AL_AUTO_SOFT
26 enum class Resampler
{
37 extern Resampler ResamplerDefault
;
39 /* The number of distinct scale and phase intervals within the bsinc filter
42 #define BSINC_SCALE_BITS 4
43 #define BSINC_SCALE_COUNT (1<<BSINC_SCALE_BITS)
44 #define BSINC_PHASE_BITS 5
45 #define BSINC_PHASE_COUNT (1<<BSINC_PHASE_BITS)
47 /* Interpolator state. Kind of a misnomer since the interpolator itself is
48 * stateless. This just keeps it from having to recompute scale-related
49 * mappings for every sample.
52 float sf
; /* Scale interpolation factor. */
53 ALuint m
; /* Coefficient count. */
54 ALuint l
; /* Left coefficient offset. */
55 /* Filter coefficients, followed by the phase, scale, and scale-phase
56 * delta coefficients. Starting at phase index 0, each subsequent phase
57 * index follows contiguously.
66 using ResamplerFunc
= const float*(*)(const InterpState
*state
, const float *RESTRICT src
,
67 ALuint frac
, ALuint increment
, const al::span
<float> dst
);
69 ResamplerFunc
PrepareResampler(Resampler resampler
, ALuint increment
, InterpState
*state
);
76 AF_BandPass
= AF_LowPass
| AF_HighPass
80 struct MixHrtfFilter
{
81 const HrirArray
*Coeffs
;
90 BiquadFilter HighPass
;
92 NfcFilter NFCtrlFilter
;
101 std::array
<float,MAX_OUTPUT_CHANNELS
> Current
;
102 std::array
<float,MAX_OUTPUT_CHANNELS
> Target
;
107 BiquadFilter LowPass
;
108 BiquadFilter HighPass
;
111 std::array
<float,MAX_OUTPUT_CHANNELS
> Current
;
112 std::array
<float,MAX_OUTPUT_CHANNELS
> Target
;
117 struct ALvoicePropsBase
{
128 std::array
<float,3> Position
;
129 std::array
<float,3> Velocity
;
130 std::array
<float,3> Direction
;
131 std::array
<float,3> OrientAt
;
132 std::array
<float,3> OrientUp
;
134 DistanceModel mDistanceModel
;
135 Resampler mResampler
;
137 SpatializeMode mSpatializeMode
;
144 float AirAbsorptionFactor
;
145 float RoomRolloffFactor
;
148 std::array
<float,2> StereoPan
;
152 /** Direct filter and auxiliary send info. */
170 struct ALvoiceProps
: public ALvoicePropsBase
{
171 std::atomic
<ALvoiceProps
*> next
{nullptr};
173 DEF_NEWDEL(ALvoiceProps
)
176 #define VOICE_IS_STATIC (1u<<0)
177 #define VOICE_IS_FADING (1u<<1) /* Fading sources use gain stepping for smooth transitions. */
178 #define VOICE_IS_AMBISONIC (1u<<2) /* Voice needs HF scaling for ambisonic upsampling. */
179 #define VOICE_HAS_HRTF (1u<<3)
180 #define VOICE_HAS_NFC (1u<<4)
189 std::atomic
<ALvoiceProps
*> mUpdate
{nullptr};
191 std::atomic
<ALuint
> mSourceID
{0u};
192 std::atomic
<State
> mPlayState
{Stopped
};
194 ALvoicePropsBase mProps
;
197 * Source offset in samples, relative to the currently playing buffer, NOT
200 std::atomic
<ALuint
> mPosition
;
201 /** Fractional (fixed-point) offset to the next sample. */
202 std::atomic
<ALuint
> mPositionFrac
;
204 /* Current buffer queue item being played. */
205 std::atomic
<ALbufferlistitem
*> mCurrentBuffer
;
207 /* Buffer queue item to loop to at end of queue (will be NULL for non-
210 std::atomic
<ALbufferlistitem
*> mLoopBuffer
;
212 /* Properties for the attached buffer(s). */
213 FmtChannels mFmtChannels
;
218 /** Current target parameters used for mixing. */
221 ResamplerFunc mResampler
;
223 InterpState mResampleState
;
229 al::span
<FloatBufferLine
> Buffer
;
232 std::array
<TargetData
,MAX_SENDS
> mSend
;
235 alignas(16) std::array
<float,MAX_RESAMPLER_PADDING
> mPrevSamples
;
238 BandSplitter mAmbiSplitter
;
240 DirectParams mDryParams
;
241 std::array
<SendParams
,MAX_SENDS
> mWetParams
;
243 std::array
<ChannelData
,MAX_INPUT_CHANNELS
> mChans
;
246 ALvoice(const ALvoice
&) = delete;
247 ALvoice(ALvoice
&& rhs
) noexcept
{ *this = std::move(rhs
); }
248 ~ALvoice() { delete mUpdate
.exchange(nullptr, std::memory_order_acq_rel
); }
249 ALvoice
& operator=(const ALvoice
&) = delete;
250 ALvoice
& operator=(ALvoice
&& rhs
) noexcept
252 ALvoiceProps
*old_update
{mUpdate
.load(std::memory_order_relaxed
)};
253 mUpdate
.store(rhs
.mUpdate
.exchange(old_update
, std::memory_order_relaxed
),
254 std::memory_order_relaxed
);
256 mSourceID
.store(rhs
.mSourceID
.load(std::memory_order_relaxed
), std::memory_order_relaxed
);
257 mPlayState
.store(rhs
.mPlayState
.load(std::memory_order_relaxed
),
258 std::memory_order_relaxed
);
262 mPosition
.store(rhs
.mPosition
.load(std::memory_order_relaxed
), std::memory_order_relaxed
);
263 mPositionFrac
.store(rhs
.mPositionFrac
.load(std::memory_order_relaxed
),
264 std::memory_order_relaxed
);
266 mCurrentBuffer
.store(rhs
.mCurrentBuffer
.load(std::memory_order_relaxed
),
267 std::memory_order_relaxed
);
268 mLoopBuffer
.store(rhs
.mLoopBuffer
.load(std::memory_order_relaxed
),
269 std::memory_order_relaxed
);
271 mFmtChannels
= rhs
.mFmtChannels
;
272 mFrequency
= rhs
.mFrequency
;
273 mNumChannels
= rhs
.mNumChannels
;
274 mSampleSize
= rhs
.mSampleSize
;
277 mResampler
= rhs
.mResampler
;
279 mResampleState
= rhs
.mResampleState
;
283 mDirect
= rhs
.mDirect
;
290 void mix(State vstate
, ALCcontext
*Context
, const ALuint SamplesToDo
);