14 #include "bufferline.h"
15 #include "buffer_storage.h"
16 #include "devformat.h"
17 #include "filters/biquad.h"
18 #include "filters/nfc.h"
19 #include "filters/splitter.h"
20 #include "mixer/defs.h"
21 #include "mixer/hrtfdefs.h"
22 #include "opthelpers.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
{};
76 std::array
<float,MaxOutputChannels
> Current
{};
77 std::array
<float,MaxOutputChannels
> Target
{};
84 BiquadFilter HighPass
;
87 std::array
<float,MaxAmbiChannels
> Current
{};
88 std::array
<float,MaxAmbiChannels
> Target
{};
94 struct VoiceBufferItem
{
95 std::atomic
<VoiceBufferItem
*> mNext
{nullptr};
97 CallbackType mCallback
{nullptr};
98 void *mUserData
{nullptr};
100 uint mBlockAlign
{0u};
105 al::span
<std::byte
> mSamples
{};
108 ~VoiceBufferItem() = default;
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
;
149 /** Direct filter and auxiliary send info. */
167 std::array
<SendData
,MaxSendCount
> Send
;
170 struct VoicePropsItem
: public VoiceProps
{
171 std::atomic
<VoicePropsItem
*> next
{nullptr};
178 VoiceCallbackStopped
,
186 struct SIMDALIGN Voice
{
194 std::atomic
<VoicePropsItem
*> mUpdate
{nullptr};
198 std::atomic
<uint
> mSourceID
{0u};
199 std::atomic
<State
> mPlayState
{Stopped
};
200 std::atomic
<bool> mPendingChange
{false};
203 * Source offset in samples, relative to the currently playing buffer, NOT
206 std::atomic
<int> mPosition
{};
207 /** Fractional (fixed-point) offset to the next sample. */
208 std::atomic
<uint
> mPositionFrac
{};
210 /* Current buffer queue item being played. */
211 std::atomic
<VoiceBufferItem
*> mCurrentBuffer
{};
213 /* Buffer queue item to loop to at end of queue (will be NULL for non-
216 std::atomic
<VoiceBufferItem
*> mLoopBuffer
{};
218 std::chrono::nanoseconds mStartTime
{};
220 /* Properties for the attached buffer(s). */
221 FmtChannels mFmtChannels
{};
224 uint mFrameStep
{}; /**< In steps of the sample type size. */
225 uint mBytesPerBlock
{}; /**< Or for PCM formats, BytesPerFrame. */
226 uint mSamplesPerBlock
{}; /**< Always 1 for PCM formats. */
227 AmbiLayout mAmbiLayout
{};
228 AmbiScaling mAmbiScaling
{};
231 std::unique_ptr
<DecoderBase
> mDecoder
;
232 uint mDecoderPadding
{};
234 /** Current target parameters used for mixing. */
237 ResamplerFunc mResampler
{};
239 InterpState mResampleState
{};
241 std::bitset
<VoiceFlagCount
> mFlags
{};
242 uint mNumCallbackBlocks
{0};
243 uint mCallbackBlockBase
{0};
247 al::span
<FloatBufferLine
> Buffer
;
250 std::array
<TargetData
,MaxSendCount
> mSend
;
252 /* The first MaxResamplerPadding/2 elements are the sample history from the
253 * previous mix, with an additional MaxResamplerPadding/2 elements that are
254 * now current (which may be overwritten if the buffer data is still
257 using HistoryLine
= std::array
<float,MaxResamplerPadding
>;
258 al::vector
<HistoryLine
,16> mPrevSamples
{2};
261 float mAmbiHFScale
{}, mAmbiLFScale
{};
262 BandSplitter mAmbiSplitter
;
264 DirectParams mDryParams
;
265 std::array
<SendParams
,MaxSendCount
> mWetParams
;
267 al::vector
<ChannelData
> mChans
{2};
272 Voice(const Voice
&) = delete;
273 Voice
& operator=(const Voice
&) = delete;
275 void mix(const State vstate
, ContextBase
*Context
, const std::chrono::nanoseconds deviceTime
,
276 const uint SamplesToDo
);
278 void prepare(DeviceBase
*device
);
280 static void InitMixer(std::optional
<std::string
> resopt
);
283 inline Resampler ResamplerDefault
{Resampler::Gaussian
};
285 #endif /* CORE_VOICE_H */