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};
59 AF_BandPass = AF_LowPass | AF_HighPass
65 BiquadFilter HighPass;
67 NfcFilter NFCtrlFilter;
72 alignas(16) std::array<float,HrtfHistoryLength> History;
76 std::array<float,MAX_OUTPUT_CHANNELS> Current;
77 std::array<float,MAX_OUTPUT_CHANNELS> Target;
83 BiquadFilter HighPass;
86 std::array<float,MaxAmbiChannels> Current;
87 std::array<float,MaxAmbiChannels> Target;
92 struct VoiceBufferItem {
93 std::atomic<VoiceBufferItem*> mNext{nullptr};
95 CallbackType mCallback{nullptr};
96 void *mUserData{nullptr};
103 al::byte *mSamples{nullptr};
118 std::array<float,3> Position;
119 std::array<float,3> Velocity;
120 std::array<float,3> Direction;
121 std::array<float,3> OrientAt;
122 std::array<float,3> OrientUp;
124 DistanceModel mDistanceModel;
125 Resampler mResampler;
126 DirectMode DirectChannels;
127 SpatializeMode mSpatializeMode;
134 float AirAbsorptionFactor;
135 float RoomRolloffFactor;
138 std::array<float,2> StereoPan;
143 /** Direct filter and auxiliary send info. */
161 struct VoicePropsItem : public VoiceProps {
162 std::atomic<VoicePropsItem*> next{nullptr};
164 DEF_NEWDEL(VoicePropsItem)
171 VoiceCallbackStopped,
187 std::atomic<VoicePropsItem*> mUpdate{nullptr};
191 std::atomic<uint> mSourceID{0u};
192 std::atomic<State> mPlayState{Stopped};
193 std::atomic<bool> mPendingChange{false};
196 * Source offset in samples, relative to the currently playing buffer, NOT
199 std::atomic<int> mPosition;
200 /** Fractional (fixed-point) offset to the next sample. */
201 std::atomic<uint> mPositionFrac;
203 /* Current buffer queue item being played. */
204 std::atomic<VoiceBufferItem*> mCurrentBuffer;
206 /* Buffer queue item to loop to at end of queue (will be NULL for non-
209 std::atomic<VoiceBufferItem*> mLoopBuffer;
211 std::chrono::nanoseconds mStartTime{};
213 /* Properties for the attached buffer(s). */
214 FmtChannels mFmtChannels;
217 uint mFrameStep; /**< In steps of the sample type size. */
218 uint mBytesPerBlock; /**< Or for PCM formats, BytesPerFrame. */
219 uint mSamplesPerBlock; /**< Always 1 for PCM formats. */
220 AmbiLayout mAmbiLayout;
221 AmbiScaling mAmbiScaling;
224 std::unique_ptr<DecoderBase> mDecoder;
225 uint mDecoderPadding{};
227 /** Current target parameters used for mixing. */
230 ResamplerFunc mResampler;
232 InterpState mResampleState;
234 std::bitset<VoiceFlagCount> mFlags{};
235 uint mNumCallbackBlocks{0};
236 uint mCallbackBlockBase{0};
240 al::span<FloatBufferLine> Buffer;
243 std::array<TargetData,MAX_SENDS> mSend;
245 /* The first MaxResamplerPadding/2 elements are the sample history from the
246 * previous mix, with an additional MaxResamplerPadding/2 elements that are
247 * now current (which may be overwritten if the buffer data is still
250 using HistoryLine = std::array<float,MaxResamplerPadding>;
251 al::vector<HistoryLine,16> mPrevSamples{2};
254 float mAmbiHFScale, mAmbiLFScale;
255 BandSplitter mAmbiSplitter;
257 DirectParams mDryParams;
258 std::array<SendParams,MAX_SENDS> mWetParams;
260 al::vector<ChannelData> mChans{2};
265 Voice(const Voice&) = delete;
266 Voice& operator=(const Voice&) = delete;
268 void mix(const State vstate, ContextBase *Context, const std::chrono::nanoseconds deviceTime,
269 const uint SamplesToDo);
271 void prepare(DeviceBase *device);
273 static void InitMixer(al::optional<std::string> resampler);
278 extern Resampler ResamplerDefault;
280 #endif /* CORE_VOICE_H */