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
{};
120 std::array
<float,3> Position
;
121 std::array
<float,3> Velocity
;
122 std::array
<float,3> Direction
;
123 std::array
<float,3> OrientAt
;
124 std::array
<float,3> OrientUp
;
126 DistanceModel mDistanceModel
;
127 Resampler mResampler
;
128 DirectMode DirectChannels
;
129 SpatializeMode mSpatializeMode
;
136 float AirAbsorptionFactor
;
137 float RoomRolloffFactor
;
140 std::array
<float,2> StereoPan
;
146 /** Direct filter and auxiliary send info. */
164 std::array
<SendData
,MaxSendCount
> Send
;
167 struct VoicePropsItem
: public VoiceProps
{
168 std::atomic
<VoicePropsItem
*> next
{nullptr};
175 VoiceCallbackStopped
,
183 struct SIMDALIGN Voice
{
191 std::atomic
<VoicePropsItem
*> mUpdate
{nullptr};
195 std::atomic
<uint
> mSourceID
{0u};
196 std::atomic
<State
> mPlayState
{Stopped
};
197 std::atomic
<bool> mPendingChange
{false};
200 * Source offset in samples, relative to the currently playing buffer, NOT
203 std::atomic
<int> mPosition
{};
204 /** Fractional (fixed-point) offset to the next sample. */
205 std::atomic
<uint
> mPositionFrac
{};
207 /* Current buffer queue item being played. */
208 std::atomic
<VoiceBufferItem
*> mCurrentBuffer
{};
210 /* Buffer queue item to loop to at end of queue (will be NULL for non-
213 std::atomic
<VoiceBufferItem
*> mLoopBuffer
{};
215 std::chrono::nanoseconds mStartTime
{};
217 /* Properties for the attached buffer(s). */
218 FmtChannels mFmtChannels
{};
221 uint mFrameStep
{}; /**< In steps of the sample type size. */
222 uint mBytesPerBlock
{}; /**< Or for PCM formats, BytesPerFrame. */
223 uint mSamplesPerBlock
{}; /**< Always 1 for PCM formats. */
224 AmbiLayout mAmbiLayout
{};
225 AmbiScaling mAmbiScaling
{};
228 std::unique_ptr
<DecoderBase
> mDecoder
;
229 uint mDecoderPadding
{};
231 /** Current target parameters used for mixing. */
234 ResamplerFunc mResampler
{};
236 InterpState mResampleState
{};
238 std::bitset
<VoiceFlagCount
> mFlags
{};
239 uint mNumCallbackBlocks
{0};
240 uint mCallbackBlockBase
{0};
244 al::span
<FloatBufferLine
> Buffer
;
247 std::array
<TargetData
,MaxSendCount
> mSend
;
249 /* The first MaxResamplerPadding/2 elements are the sample history from the
250 * previous mix, with an additional MaxResamplerPadding/2 elements that are
251 * now current (which may be overwritten if the buffer data is still
254 using HistoryLine
= std::array
<float,MaxResamplerPadding
>;
255 al::vector
<HistoryLine
,16> mPrevSamples
{2};
258 float mAmbiHFScale
{}, mAmbiLFScale
{};
259 BandSplitter mAmbiSplitter
;
261 DirectParams mDryParams
;
262 std::array
<SendParams
,MaxSendCount
> mWetParams
;
264 al::vector
<ChannelData
> mChans
{2};
269 Voice(const Voice
&) = delete;
270 Voice
& operator=(const Voice
&) = delete;
272 void mix(const State vstate
, ContextBase
*Context
, const std::chrono::nanoseconds deviceTime
,
273 const uint SamplesToDo
);
275 void prepare(DeviceBase
*device
);
277 static void InitMixer(std::optional
<std::string
> resopt
);
280 inline Resampler ResamplerDefault
{Resampler::Gaussian
};
282 #endif /* CORE_VOICE_H */