14 #include "aloptional.h"
16 #include "bufferline.h"
17 #include "buffer_storage.h"
18 #include "devformat.h"
19 #include "filters/biquad.h"
20 #include "filters/nfc.h"
21 #include "filters/splitter.h"
22 #include "mixer/defs.h"
23 #include "mixer/hrtfdefs.h"
24 #include "resampler_limits.h"
25 #include "uhjfilter.h"
31 enum class DistanceModel
: unsigned char;
33 using uint
= unsigned int;
39 enum class SpatializeMode
: unsigned char {
45 enum class DirectMode
: unsigned char {
52 constexpr uint MaxPitch
{10};
54 /* Maximum number of extra source samples that may need to be loaded, for
55 * resampling or conversion purposes.
57 constexpr uint MaxPostVoiceLoad
{MaxResamplerEdge
+ DecoderBase::sMaxPadding
};
64 AF_BandPass
= AF_LowPass
| AF_HighPass
70 BiquadFilter HighPass
;
72 NfcFilter NFCtrlFilter
;
77 alignas(16) std::array
<float,HrtfHistoryLength
> History
;
81 std::array
<float,MAX_OUTPUT_CHANNELS
> Current
;
82 std::array
<float,MAX_OUTPUT_CHANNELS
> Target
;
88 BiquadFilter HighPass
;
91 std::array
<float,MaxAmbiChannels
> Current
;
92 std::array
<float,MaxAmbiChannels
> Target
;
97 struct VoiceBufferItem
{
98 std::atomic
<VoiceBufferItem
*> mNext
{nullptr};
100 CallbackType mCallback
{nullptr};
101 void *mUserData
{nullptr};
103 uint mBlockAlign
{0u};
108 al::byte
*mSamples
{nullptr};
123 std::array
<float,3> Position
;
124 std::array
<float,3> Velocity
;
125 std::array
<float,3> Direction
;
126 std::array
<float,3> OrientAt
;
127 std::array
<float,3> OrientUp
;
129 DistanceModel mDistanceModel
;
130 Resampler mResampler
;
131 DirectMode DirectChannels
;
132 SpatializeMode mSpatializeMode
;
139 float AirAbsorptionFactor
;
140 float RoomRolloffFactor
;
143 std::array
<float,2> StereoPan
;
148 /** Direct filter and auxiliary send info. */
166 struct VoicePropsItem
: public VoiceProps
{
167 std::atomic
<VoicePropsItem
*> next
{nullptr};
169 DEF_NEWDEL(VoicePropsItem
)
176 VoiceCallbackStopped
,
192 std::atomic
<VoicePropsItem
*> mUpdate
{nullptr};
196 std::atomic
<uint
> mSourceID
{0u};
197 std::atomic
<State
> mPlayState
{Stopped
};
198 std::atomic
<bool> mPendingChange
{false};
201 * Source offset in samples, relative to the currently playing buffer, NOT
204 std::atomic
<int> mPosition
;
205 /** Fractional (fixed-point) offset to the next sample. */
206 std::atomic
<uint
> mPositionFrac
;
208 /* Current buffer queue item being played. */
209 std::atomic
<VoiceBufferItem
*> mCurrentBuffer
;
211 /* Buffer queue item to loop to at end of queue (will be NULL for non-
214 std::atomic
<VoiceBufferItem
*> mLoopBuffer
;
216 std::chrono::nanoseconds mStartTime
{};
218 /* Properties for the attached buffer(s). */
219 FmtChannels mFmtChannels
;
222 uint mFrameStep
; /**< In steps of the sample type size. */
223 uint mBytesPerBlock
; /**< Or for PCM formats, BytesPerFrame. */
224 uint mSamplesPerBlock
; /**< Always 1 for PCM formats. */
225 AmbiLayout mAmbiLayout
;
226 AmbiScaling mAmbiScaling
;
229 std::unique_ptr
<DecoderBase
> mDecoder
;
230 uint mDecoderPadding
{};
232 /** Current target parameters used for mixing. */
235 ResamplerFunc mResampler
;
237 InterpState mResampleState
;
239 std::bitset
<VoiceFlagCount
> mFlags
{};
240 uint mNumCallbackBlocks
{0};
241 uint mCallbackBlockBase
{0};
245 al::span
<FloatBufferLine
> Buffer
;
248 std::array
<TargetData
,MAX_SENDS
> mSend
;
250 /* The first MaxResamplerPadding/2 elements are the sample history from the
251 * previous mix, with an additional MaxResamplerPadding/2 elements that are
252 * now current (which may be overwritten if the buffer data is still
255 using HistoryLine
= std::array
<float,MaxResamplerPadding
>;
256 al::vector
<HistoryLine
,16> mPrevSamples
{2};
259 float mAmbiHFScale
, mAmbiLFScale
;
260 BandSplitter mAmbiSplitter
;
262 DirectParams mDryParams
;
263 std::array
<SendParams
,MAX_SENDS
> mWetParams
;
265 al::vector
<ChannelData
> mChans
{2};
270 Voice(const Voice
&) = delete;
271 Voice
& operator=(const Voice
&) = delete;
273 void mix(const State vstate
, ContextBase
*Context
, const std::chrono::nanoseconds deviceTime
,
274 const uint SamplesToDo
);
276 void prepare(DeviceBase
*device
);
278 static void InitMixer(al::optional
<std::string
> resampler
);
283 extern Resampler ResamplerDefault
;
285 #endif /* CORE_VOICE_H */