10 #include "filters/biquad.h"
11 #include "filters/nfc.h"
12 #include "filters/splitter.h"
15 enum class DistanceModel
;
19 SpatializeOff
= AL_FALSE
,
20 SpatializeOn
= AL_TRUE
,
21 SpatializeAuto
= AL_AUTO_SOFT
24 enum class Resampler
{
35 extern Resampler ResamplerDefault
;
37 /* The number of distinct scale and phase intervals within the bsinc filter
40 #define BSINC_SCALE_BITS 4
41 #define BSINC_SCALE_COUNT (1<<BSINC_SCALE_BITS)
42 #define BSINC_PHASE_BITS 5
43 #define BSINC_PHASE_COUNT (1<<BSINC_PHASE_BITS)
45 /* Interpolator state. Kind of a misnomer since the interpolator itself is
46 * stateless. This just keeps it from having to recompute scale-related
47 * mappings for every sample.
50 float sf
; /* Scale interpolation factor. */
51 ALuint m
; /* Coefficient count. */
52 ALuint l
; /* Left coefficient offset. */
53 /* Filter coefficients, followed by the scale, phase, and scale-phase
54 * delta coefficients. Starting at phase index 0, each subsequent phase
55 * index follows contiguously.
64 using ResamplerFunc
= const float*(*)(const InterpState
*state
, const float *RESTRICT src
,
65 ALuint frac
, ALuint increment
, const al::span
<float> dst
);
67 ResamplerFunc
PrepareResampler(Resampler resampler
, ALuint increment
, InterpState
*state
);
74 AF_BandPass
= AF_LowPass
| AF_HighPass
78 struct MixHrtfFilter
{
79 const HrirArray
*Coeffs
;
88 BiquadFilter HighPass
;
90 NfcFilter NFCtrlFilter
;
99 float Current
[MAX_OUTPUT_CHANNELS
];
100 float Target
[MAX_OUTPUT_CHANNELS
];
105 BiquadFilter LowPass
;
106 BiquadFilter HighPass
;
109 float Current
[MAX_OUTPUT_CHANNELS
];
110 float Target
[MAX_OUTPUT_CHANNELS
];
115 struct ALvoicePropsBase
{
126 std::array
<float,3> Position
;
127 std::array
<float,3> Velocity
;
128 std::array
<float,3> Direction
;
129 std::array
<float,3> OrientAt
;
130 std::array
<float,3> OrientUp
;
132 DistanceModel mDistanceModel
;
133 Resampler mResampler
;
135 SpatializeMode mSpatializeMode
;
142 float AirAbsorptionFactor
;
143 float RoomRolloffFactor
;
146 std::array
<float,2> StereoPan
;
150 /** Direct filter and auxiliary send info. */
168 struct ALvoiceProps
: public ALvoicePropsBase
{
169 std::atomic
<ALvoiceProps
*> next
{nullptr};
171 DEF_NEWDEL(ALvoiceProps
)
174 #define VOICE_IS_STATIC (1u<<0)
175 #define VOICE_IS_FADING (1u<<1) /* Fading sources use gain stepping for smooth transitions. */
176 #define VOICE_IS_AMBISONIC (1u<<2) /* Voice needs HF scaling for ambisonic upsampling. */
177 #define VOICE_HAS_HRTF (1u<<3)
178 #define VOICE_HAS_NFC (1u<<4)
187 std::atomic
<ALvoiceProps
*> mUpdate
{nullptr};
189 std::atomic
<ALuint
> mSourceID
{0u};
190 std::atomic
<State
> mPlayState
{Stopped
};
192 ALvoicePropsBase mProps
;
195 * Source offset in samples, relative to the currently playing buffer, NOT
198 std::atomic
<ALuint
> mPosition
;
199 /** Fractional (fixed-point) offset to the next sample. */
200 std::atomic
<ALuint
> mPositionFrac
;
202 /* Current buffer queue item being played. */
203 std::atomic
<ALbufferlistitem
*> mCurrentBuffer
;
205 /* Buffer queue item to loop to at end of queue (will be NULL for non-
208 std::atomic
<ALbufferlistitem
*> mLoopBuffer
;
210 /* Properties for the attached buffer(s). */
211 FmtChannels mFmtChannels
;
216 /** Current target parameters used for mixing. */
219 ResamplerFunc mResampler
;
221 InterpState mResampleState
;
227 al::span
<FloatBufferLine
> Buffer
;
233 al::span
<FloatBufferLine
> Buffer
;
235 std::array
<SendData
,MAX_SENDS
> mSend
;
238 alignas(16) std::array
<float,MAX_RESAMPLER_PADDING
> mPrevSamples
;
241 BandSplitter mAmbiSplitter
;
243 DirectParams mDryParams
;
244 std::array
<SendParams
,MAX_SENDS
> mWetParams
;
246 std::array
<ChannelData
,MAX_INPUT_CHANNELS
> mChans
;
249 ALvoice(const ALvoice
&) = delete;
250 ALvoice(ALvoice
&& rhs
) noexcept
{ *this = std::move(rhs
); }
251 ~ALvoice() { delete mUpdate
.exchange(nullptr, std::memory_order_acq_rel
); }
252 ALvoice
& operator=(const ALvoice
&) = delete;
253 ALvoice
& operator=(ALvoice
&& rhs
) noexcept
255 ALvoiceProps
*old_update
{mUpdate
.load(std::memory_order_relaxed
)};
256 mUpdate
.store(rhs
.mUpdate
.exchange(old_update
, std::memory_order_relaxed
),
257 std::memory_order_relaxed
);
259 mSourceID
.store(rhs
.mSourceID
.load(std::memory_order_relaxed
), std::memory_order_relaxed
);
260 mPlayState
.store(rhs
.mPlayState
.load(std::memory_order_relaxed
),
261 std::memory_order_relaxed
);
265 mPosition
.store(rhs
.mPosition
.load(std::memory_order_relaxed
), std::memory_order_relaxed
);
266 mPositionFrac
.store(rhs
.mPositionFrac
.load(std::memory_order_relaxed
),
267 std::memory_order_relaxed
);
269 mCurrentBuffer
.store(rhs
.mCurrentBuffer
.load(std::memory_order_relaxed
),
270 std::memory_order_relaxed
);
271 mLoopBuffer
.store(rhs
.mLoopBuffer
.load(std::memory_order_relaxed
),
272 std::memory_order_relaxed
);
274 mFmtChannels
= rhs
.mFmtChannels
;
275 mFrequency
= rhs
.mFrequency
;
276 mNumChannels
= rhs
.mNumChannels
;
277 mSampleSize
= rhs
.mSampleSize
;
280 mResampler
= rhs
.mResampler
;
282 mResampleState
= rhs
.mResampleState
;
286 mDirect
= rhs
.mDirect
;
293 void mix(ALvoice::State vstate
, ALCcontext
*Context
, const ALuint SamplesToDo
);