Use virtual functions for the decoder
[openal-soft.git] / core / voice.h
blob3cf10d22278d2544918c1b0f5934ae8ab7cf9edb
1 #ifndef CORE_VOICE_H
2 #define CORE_VOICE_H
4 #include <array>
5 #include <atomic>
6 #include <bitset>
7 #include <memory>
8 #include <stddef.h>
9 #include <string>
11 #include "albyte.h"
12 #include "almalloc.h"
13 #include "aloptional.h"
14 #include "alspan.h"
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"
25 #include "vector.h"
27 struct ContextBase;
28 struct DeviceBase;
29 struct EffectSlot;
30 enum class DistanceModel : unsigned char;
32 using uint = unsigned int;
35 #define MAX_SENDS 6
38 enum class SpatializeMode : unsigned char {
39 Off,
40 On,
41 Auto
44 enum class DirectMode : unsigned char {
45 Off,
46 DropMismatch,
47 RemixMismatch
51 /* Maximum number of extra source samples that may need to be loaded, for
52 * resampling or conversion purposes.
54 constexpr uint MaxPostVoiceLoad{MaxResamplerEdge + UhjDecoder::sFilterDelay};
57 enum {
58 AF_None = 0,
59 AF_LowPass = 1,
60 AF_HighPass = 2,
61 AF_BandPass = AF_LowPass | AF_HighPass
65 struct DirectParams {
66 BiquadFilter LowPass;
67 BiquadFilter HighPass;
69 NfcFilter NFCtrlFilter;
71 struct {
72 HrtfFilter Old;
73 HrtfFilter Target;
74 alignas(16) std::array<float,HrtfHistoryLength> History;
75 } Hrtf;
77 struct {
78 std::array<float,MAX_OUTPUT_CHANNELS> Current;
79 std::array<float,MAX_OUTPUT_CHANNELS> Target;
80 } Gains;
83 struct SendParams {
84 BiquadFilter LowPass;
85 BiquadFilter HighPass;
87 struct {
88 std::array<float,MAX_OUTPUT_CHANNELS> Current;
89 std::array<float,MAX_OUTPUT_CHANNELS> Target;
90 } Gains;
94 struct VoiceBufferItem {
95 std::atomic<VoiceBufferItem*> mNext{nullptr};
97 CallbackType mCallback{nullptr};
98 void *mUserData{nullptr};
100 uint mSampleLen{0u};
101 uint mLoopStart{0u};
102 uint mLoopEnd{0u};
104 al::byte *mSamples{nullptr};
108 struct VoiceProps {
109 float Pitch;
110 float Gain;
111 float OuterGain;
112 float MinGain;
113 float MaxGain;
114 float InnerAngle;
115 float OuterAngle;
116 float RefDistance;
117 float MaxDistance;
118 float RolloffFactor;
119 std::array<float,3> Position;
120 std::array<float,3> Velocity;
121 std::array<float,3> Direction;
122 std::array<float,3> OrientAt;
123 std::array<float,3> OrientUp;
124 bool HeadRelative;
125 DistanceModel mDistanceModel;
126 Resampler mResampler;
127 DirectMode DirectChannels;
128 SpatializeMode mSpatializeMode;
130 bool DryGainHFAuto;
131 bool WetGainAuto;
132 bool WetGainHFAuto;
133 float OuterGainHF;
135 float AirAbsorptionFactor;
136 float RoomRolloffFactor;
137 float DopplerFactor;
139 std::array<float,2> StereoPan;
141 float Radius;
142 float EnhWidth;
144 /** Direct filter and auxiliary send info. */
145 struct {
146 float Gain;
147 float GainHF;
148 float HFReference;
149 float GainLF;
150 float LFReference;
151 } Direct;
152 struct SendData {
153 EffectSlot *Slot;
154 float Gain;
155 float GainHF;
156 float HFReference;
157 float GainLF;
158 float LFReference;
159 } Send[MAX_SENDS];
162 struct VoicePropsItem : public VoiceProps {
163 std::atomic<VoicePropsItem*> next{nullptr};
165 DEF_NEWDEL(VoicePropsItem)
168 enum : uint {
169 VoiceIsStatic,
170 VoiceIsCallback,
171 VoiceIsAmbisonic,
172 VoiceCallbackStopped,
173 VoiceIsFading,
174 VoiceHasHrtf,
175 VoiceHasNfc,
177 VoiceFlagCount
180 struct Voice {
181 enum State {
182 Stopped,
183 Playing,
184 Stopping,
185 Pending
188 std::atomic<VoicePropsItem*> mUpdate{nullptr};
190 VoiceProps mProps;
192 std::atomic<uint> mSourceID{0u};
193 std::atomic<State> mPlayState{Stopped};
194 std::atomic<bool> mPendingChange{false};
197 * Source offset in samples, relative to the currently playing buffer, NOT
198 * the whole queue.
200 std::atomic<uint> mPosition;
201 /** Fractional (fixed-point) offset to the next sample. */
202 std::atomic<uint> mPositionFrac;
204 /* Current buffer queue item being played. */
205 std::atomic<VoiceBufferItem*> mCurrentBuffer;
207 /* Buffer queue item to loop to at end of queue (will be NULL for non-
208 * looping voices).
210 std::atomic<VoiceBufferItem*> mLoopBuffer;
212 /* Properties for the attached buffer(s). */
213 FmtChannels mFmtChannels;
214 FmtType mFmtType;
215 uint mFrequency;
216 uint mFrameStep; /**< In steps of the sample type size. */
217 uint mFrameSize; /**< In bytes. */
218 AmbiLayout mAmbiLayout;
219 AmbiScaling mAmbiScaling;
220 uint mAmbiOrder;
222 std::unique_ptr<DecoderBase> mDecoder;
224 /** Current target parameters used for mixing. */
225 uint mStep{0};
227 ResamplerFunc mResampler;
229 InterpState mResampleState;
231 std::bitset<VoiceFlagCount> mFlags{};
232 uint mNumCallbackSamples{0};
234 struct TargetData {
235 int FilterType;
236 al::span<FloatBufferLine> Buffer;
238 TargetData mDirect;
239 std::array<TargetData,MAX_SENDS> mSend;
241 /* The first MaxResamplerPadding/2 elements are the sample history from the
242 * previous mix, with an additional MaxResamplerPadding/2 elements that are
243 * now current (which may be overwritten if the buffer data is still
244 * available).
246 using HistoryLine = std::array<float,MaxResamplerPadding>;
247 al::vector<HistoryLine,16> mPrevSamples{2};
249 struct ChannelData {
250 float mAmbiHFScale, mAmbiLFScale;
251 BandSplitter mAmbiSplitter;
253 DirectParams mDryParams;
254 std::array<SendParams,MAX_SENDS> mWetParams;
256 al::vector<ChannelData> mChans{2};
258 Voice() = default;
259 ~Voice() = default;
261 Voice(const Voice&) = delete;
262 Voice& operator=(const Voice&) = delete;
264 void mix(const State vstate, ContextBase *Context, const uint SamplesToDo);
266 void prepare(DeviceBase *device);
268 static void InitMixer(al::optional<std::string> resampler);
270 DEF_NEWDEL(Voice)
273 extern Resampler ResamplerDefault;
275 #endif /* CORE_VOICE_H */