13 #include "buffer_storage.h"
14 #include "devformat.h"
15 #include "filters/biquad.h"
16 #include "filters/nfc.h"
17 #include "filters/splitter.h"
20 enum class DistanceModel
;
23 enum class SpatializeMode
: unsigned char {
29 enum class DirectMode
: unsigned char {
31 DropMismatch
= AL_DROP_UNMATCHED_SOFT
,
32 RemixMismatch
= AL_REMIX_UNMATCHED_SOFT
35 enum class Resampler
{
46 extern Resampler ResamplerDefault
;
49 /* Interpolator state. Kind of a misnomer since the interpolator itself is
50 * stateless. This just keeps it from having to recompute scale-related
51 * mappings for every sample.
54 float sf
; /* Scale interpolation factor. */
55 ALuint m
; /* Coefficient count. */
56 ALuint l
; /* Left coefficient offset. */
57 /* Filter coefficients, followed by the phase, scale, and scale-phase
58 * delta coefficients. Starting at phase index 0, each subsequent phase
59 * index follows contiguously.
68 using ResamplerFunc
= const float*(*)(const InterpState
*state
, const float *RESTRICT src
,
69 ALuint frac
, ALuint increment
, const al::span
<float> dst
);
71 ResamplerFunc
PrepareResampler(Resampler resampler
, ALuint increment
, InterpState
*state
);
78 AF_BandPass
= AF_LowPass
| AF_HighPass
82 struct MixHrtfFilter
{
83 const HrirArray
*Coeffs
;
84 std::array
<ALuint
,2> Delay
;
92 BiquadFilter HighPass
;
94 NfcFilter NFCtrlFilter
;
99 alignas(16) std::array
<float,HRTF_HISTORY_LENGTH
> History
;
103 std::array
<float,MAX_OUTPUT_CHANNELS
> Current
;
104 std::array
<float,MAX_OUTPUT_CHANNELS
> Target
;
109 BiquadFilter LowPass
;
110 BiquadFilter HighPass
;
113 std::array
<float,MAX_OUTPUT_CHANNELS
> Current
;
114 std::array
<float,MAX_OUTPUT_CHANNELS
> Target
;
130 std::array
<float,3> Position
;
131 std::array
<float,3> Velocity
;
132 std::array
<float,3> Direction
;
133 std::array
<float,3> OrientAt
;
134 std::array
<float,3> OrientUp
;
136 DistanceModel mDistanceModel
;
137 Resampler mResampler
;
138 DirectMode DirectChannels
;
139 SpatializeMode mSpatializeMode
;
146 float AirAbsorptionFactor
;
147 float RoomRolloffFactor
;
150 std::array
<float,2> StereoPan
;
154 /** Direct filter and auxiliary send info. */
172 struct VoicePropsItem
: public VoiceProps
{
173 std::atomic
<VoicePropsItem
*> next
{nullptr};
175 DEF_NEWDEL(VoicePropsItem
)
178 #define VOICE_IS_STATIC (1u<<0)
179 #define VOICE_IS_CALLBACK (1u<<1)
180 #define VOICE_IS_AMBISONIC (1u<<2) /* Voice needs HF scaling for ambisonic upsampling. */
181 #define VOICE_CALLBACK_STOPPED (1u<<3)
182 #define VOICE_IS_FADING (1u<<4) /* Fading sources use gain stepping for smooth transitions. */
183 #define VOICE_HAS_HRTF (1u<<5)
184 #define VOICE_HAS_NFC (1u<<6)
186 #define VOICE_TYPE_MASK (VOICE_IS_STATIC | VOICE_IS_CALLBACK)
196 std::atomic
<VoicePropsItem
*> mUpdate
{nullptr};
200 std::atomic
<ALuint
> mSourceID
{0u};
201 std::atomic
<State
> mPlayState
{Stopped
};
202 std::atomic
<bool> mPendingChange
{false};
205 * Source offset in samples, relative to the currently playing buffer, NOT
208 std::atomic
<ALuint
> mPosition
;
209 /** Fractional (fixed-point) offset to the next sample. */
210 std::atomic
<ALuint
> mPositionFrac
;
212 /* Current buffer queue item being played. */
213 std::atomic
<ALbufferlistitem
*> mCurrentBuffer
;
215 /* Buffer queue item to loop to at end of queue (will be NULL for non-
218 std::atomic
<ALbufferlistitem
*> mLoopBuffer
;
220 /* Properties for the attached buffer(s). */
221 FmtChannels mFmtChannels
;
224 AmbiLayout mAmbiLayout
;
225 AmbiScaling mAmbiScaling
;
228 /** Current target parameters used for mixing. */
231 ResamplerFunc mResampler
;
233 InterpState mResampleState
;
236 ALuint mNumCallbackSamples
{0};
240 al::span
<FloatBufferLine
> Buffer
;
243 std::array
<TargetData
,MAX_SENDS
> mSend
;
246 alignas(16) std::array
<float,MAX_RESAMPLER_PADDING
> mPrevSamples
;
249 BandSplitter mAmbiSplitter
;
251 DirectParams mDryParams
;
252 std::array
<SendParams
,MAX_SENDS
> mWetParams
;
254 al::vector
<ChannelData
> mChans
{2};
257 Voice(const Voice
&) = delete;
258 ~Voice() { delete mUpdate
.exchange(nullptr, std::memory_order_acq_rel
); }
259 Voice
& operator=(const Voice
&) = delete;
261 void mix(const State vstate
, ALCcontext
*Context
, const ALuint SamplesToDo
);