15 #include "bufferline.h"
16 #include "buffer_storage.h"
17 #include "devformat.h"
18 #include "filters/biquad.h"
19 #include "filters/nfc.h"
20 #include "filters/splitter.h"
21 #include "mixer/defs.h"
22 #include "mixer/hrtfdefs.h"
23 #include "resampler_limits.h"
24 #include "uhjfilter.h"
30 enum class DistanceModel
: unsigned char;
32 using uint
= unsigned int;
35 inline constexpr size_t MaxSendCount
{6};
38 enum class SpatializeMode
: unsigned char {
44 enum class DirectMode
: unsigned char {
51 inline constexpr uint MaxPitch
{10};
58 AF_BandPass
= AF_LowPass
| AF_HighPass
64 BiquadFilter HighPass
;
66 NfcFilter NFCtrlFilter
;
71 alignas(16) std::array
<float,HrtfHistoryLength
> History
{};
75 std::array
<float,MaxOutputChannels
> Current
{};
76 std::array
<float,MaxOutputChannels
> Target
{};
82 BiquadFilter HighPass
;
85 std::array
<float,MaxAmbiChannels
> Current
{};
86 std::array
<float,MaxAmbiChannels
> Target
{};
91 struct VoiceBufferItem
{
92 std::atomic
<VoiceBufferItem
*> mNext
{nullptr};
94 CallbackType mCallback
{nullptr};
95 void *mUserData
{nullptr};
102 std::byte
*mSamples
{nullptr};
117 std::array
<float,3> Position
;
118 std::array
<float,3> Velocity
;
119 std::array
<float,3> Direction
;
120 std::array
<float,3> OrientAt
;
121 std::array
<float,3> OrientUp
;
123 DistanceModel mDistanceModel
;
124 Resampler mResampler
;
125 DirectMode DirectChannels
;
126 SpatializeMode mSpatializeMode
;
133 float AirAbsorptionFactor
;
134 float RoomRolloffFactor
;
137 std::array
<float,2> StereoPan
;
142 /** Direct filter and auxiliary send info. */
158 std::array
<SendData
,MaxSendCount
> Send
;
161 struct VoicePropsItem
: public VoiceProps
{
162 std::atomic
<VoicePropsItem
*> next
{nullptr};
169 VoiceCallbackStopped
,
185 std::atomic
<VoicePropsItem
*> mUpdate
{nullptr};
189 std::atomic
<uint
> mSourceID
{0u};
190 std::atomic
<State
> mPlayState
{Stopped
};
191 std::atomic
<bool> mPendingChange
{false};
194 * Source offset in samples, relative to the currently playing buffer, NOT
197 std::atomic
<int> mPosition
{};
198 /** Fractional (fixed-point) offset to the next sample. */
199 std::atomic
<uint
> mPositionFrac
{};
201 /* Current buffer queue item being played. */
202 std::atomic
<VoiceBufferItem
*> mCurrentBuffer
{};
204 /* Buffer queue item to loop to at end of queue (will be NULL for non-
207 std::atomic
<VoiceBufferItem
*> mLoopBuffer
{};
209 std::chrono::nanoseconds mStartTime
{};
211 /* Properties for the attached buffer(s). */
212 FmtChannels mFmtChannels
{};
215 uint mFrameStep
{}; /**< In steps of the sample type size. */
216 uint mBytesPerBlock
{}; /**< Or for PCM formats, BytesPerFrame. */
217 uint mSamplesPerBlock
{}; /**< Always 1 for PCM formats. */
218 AmbiLayout mAmbiLayout
{};
219 AmbiScaling mAmbiScaling
{};
222 std::unique_ptr
<DecoderBase
> mDecoder
;
223 uint mDecoderPadding
{};
225 /** Current target parameters used for mixing. */
228 ResamplerFunc mResampler
{};
230 InterpState mResampleState
{};
232 std::bitset
<VoiceFlagCount
> mFlags
{};
233 uint mNumCallbackBlocks
{0};
234 uint mCallbackBlockBase
{0};
238 al::span
<FloatBufferLine
> Buffer
;
241 std::array
<TargetData
,MaxSendCount
> mSend
;
243 /* The first MaxResamplerPadding/2 elements are the sample history from the
244 * previous mix, with an additional MaxResamplerPadding/2 elements that are
245 * now current (which may be overwritten if the buffer data is still
248 using HistoryLine
= std::array
<float,MaxResamplerPadding
>;
249 al::vector
<HistoryLine
,16> mPrevSamples
{2};
252 float mAmbiHFScale
{}, mAmbiLFScale
{};
253 BandSplitter mAmbiSplitter
;
255 DirectParams mDryParams
;
256 std::array
<SendParams
,MaxSendCount
> mWetParams
;
258 al::vector
<ChannelData
> mChans
{2};
263 Voice(const Voice
&) = delete;
264 Voice
& operator=(const Voice
&) = delete;
266 void mix(const State vstate
, ContextBase
*Context
, const std::chrono::nanoseconds deviceTime
,
267 const uint SamplesToDo
);
269 void prepare(DeviceBase
*device
);
271 static void InitMixer(std::optional
<std::string
> resopt
);
274 extern Resampler ResamplerDefault
;
276 #endif /* CORE_VOICE_H */