Rename some struct members for clarity
[openal-soft.git] / core / voice.h
blob000174b6391d0a1d9e91bc6479e0212d766c7325
1 #ifndef CORE_VOICE_H
2 #define CORE_VOICE_H
4 #include <array>
5 #include <atomic>
6 #include <bitset>
7 #include <chrono>
8 #include <memory>
9 #include <stddef.h>
10 #include <string>
12 #include "albyte.h"
13 #include "almalloc.h"
14 #include "aloptional.h"
15 #include "alspan.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"
26 #include "vector.h"
28 struct ContextBase;
29 struct DeviceBase;
30 struct EffectSlot;
31 enum class DistanceModel : unsigned char;
33 using uint = unsigned int;
36 #define MAX_SENDS 6
39 enum class SpatializeMode : unsigned char {
40 Off,
41 On,
42 Auto
45 enum class DirectMode : unsigned char {
46 Off,
47 DropMismatch,
48 RemixMismatch
52 constexpr uint MaxPitch{10};
54 /* Maximum number of extra source samples that may need to be loaded, for
55 * resampling or conversion purposes.
57 constexpr uint MaxPostVoiceLoad{MaxResamplerEdge + DecoderBase::sMaxPadding};
60 enum {
61 AF_None = 0,
62 AF_LowPass = 1,
63 AF_HighPass = 2,
64 AF_BandPass = AF_LowPass | AF_HighPass
68 struct DirectParams {
69 BiquadFilter LowPass;
70 BiquadFilter HighPass;
72 NfcFilter NFCtrlFilter;
74 struct {
75 HrtfFilter Old;
76 HrtfFilter Target;
77 alignas(16) std::array<float,HrtfHistoryLength> History;
78 } Hrtf;
80 struct {
81 std::array<float,MAX_OUTPUT_CHANNELS> Current;
82 std::array<float,MAX_OUTPUT_CHANNELS> Target;
83 } Gains;
86 struct SendParams {
87 BiquadFilter LowPass;
88 BiquadFilter HighPass;
90 struct {
91 std::array<float,MaxAmbiChannels> Current;
92 std::array<float,MaxAmbiChannels> Target;
93 } Gains;
97 struct VoiceBufferItem {
98 std::atomic<VoiceBufferItem*> mNext{nullptr};
100 CallbackType mCallback{nullptr};
101 void *mUserData{nullptr};
103 uint mBlockAlign{0u};
104 uint mSampleLen{0u};
105 uint mLoopStart{0u};
106 uint mLoopEnd{0u};
108 al::byte *mSamples{nullptr};
112 struct VoiceProps {
113 float Pitch;
114 float Gain;
115 float OuterGain;
116 float MinGain;
117 float MaxGain;
118 float InnerAngle;
119 float OuterAngle;
120 float RefDistance;
121 float MaxDistance;
122 float RolloffFactor;
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;
128 bool HeadRelative;
129 DistanceModel mDistanceModel;
130 Resampler mResampler;
131 DirectMode DirectChannels;
132 SpatializeMode mSpatializeMode;
134 bool DryGainHFAuto;
135 bool WetGainAuto;
136 bool WetGainHFAuto;
137 float OuterGainHF;
139 float AirAbsorptionFactor;
140 float RoomRolloffFactor;
141 float DopplerFactor;
143 std::array<float,2> StereoPan;
145 float Radius;
146 float EnhWidth;
148 /** Direct filter and auxiliary send info. */
149 struct {
150 float Gain;
151 float GainHF;
152 float HFReference;
153 float GainLF;
154 float LFReference;
155 } Direct;
156 struct SendData {
157 EffectSlot *Slot;
158 float Gain;
159 float GainHF;
160 float HFReference;
161 float GainLF;
162 float LFReference;
163 } Send[MAX_SENDS];
166 struct VoicePropsItem : public VoiceProps {
167 std::atomic<VoicePropsItem*> next{nullptr};
169 DEF_NEWDEL(VoicePropsItem)
172 enum : uint {
173 VoiceIsStatic,
174 VoiceIsCallback,
175 VoiceIsAmbisonic,
176 VoiceCallbackStopped,
177 VoiceIsFading,
178 VoiceHasHrtf,
179 VoiceHasNfc,
181 VoiceFlagCount
184 struct Voice {
185 enum State {
186 Stopped,
187 Playing,
188 Stopping,
189 Pending
192 std::atomic<VoicePropsItem*> mUpdate{nullptr};
194 VoiceProps mProps;
196 std::atomic<uint> mSourceID{0u};
197 std::atomic<State> mPlayState{Stopped};
198 std::atomic<bool> mPendingChange{false};
201 * Source offset in samples, relative to the currently playing buffer, NOT
202 * the whole queue.
204 std::atomic<int> mPosition;
205 /** Fractional (fixed-point) offset to the next sample. */
206 std::atomic<uint> mPositionFrac;
208 /* Current buffer queue item being played. */
209 std::atomic<VoiceBufferItem*> mCurrentBuffer;
211 /* Buffer queue item to loop to at end of queue (will be NULL for non-
212 * looping voices).
214 std::atomic<VoiceBufferItem*> mLoopBuffer;
216 std::chrono::nanoseconds mStartTime{};
218 /* Properties for the attached buffer(s). */
219 FmtChannels mFmtChannels;
220 FmtType mFmtType;
221 uint mFrequency;
222 uint mFrameStep; /**< In steps of the sample type size. */
223 uint mBytesPerBlock; /**< Or for PCM formats, BytesPerFrame. */
224 uint mSamplesPerBlock; /**< Always 1 for PCM formats. */
225 AmbiLayout mAmbiLayout;
226 AmbiScaling mAmbiScaling;
227 uint mAmbiOrder;
229 std::unique_ptr<DecoderBase> mDecoder;
230 uint mDecoderPadding{};
232 /** Current target parameters used for mixing. */
233 uint mStep{0};
235 ResamplerFunc mResampler;
237 InterpState mResampleState;
239 std::bitset<VoiceFlagCount> mFlags{};
240 uint mNumCallbackBlocks{0};
241 uint mCallbackBlockBase{0};
243 struct TargetData {
244 int FilterType;
245 al::span<FloatBufferLine> Buffer;
247 TargetData mDirect;
248 std::array<TargetData,MAX_SENDS> mSend;
250 /* The first MaxResamplerPadding/2 elements are the sample history from the
251 * previous mix, with an additional MaxResamplerPadding/2 elements that are
252 * now current (which may be overwritten if the buffer data is still
253 * available).
255 using HistoryLine = std::array<float,MaxResamplerPadding>;
256 al::vector<HistoryLine,16> mPrevSamples{2};
258 struct ChannelData {
259 float mAmbiHFScale, mAmbiLFScale;
260 BandSplitter mAmbiSplitter;
262 DirectParams mDryParams;
263 std::array<SendParams,MAX_SENDS> mWetParams;
265 al::vector<ChannelData> mChans{2};
267 Voice() = default;
268 ~Voice() = default;
270 Voice(const Voice&) = delete;
271 Voice& operator=(const Voice&) = delete;
273 void mix(const State vstate, ContextBase *Context, const std::chrono::nanoseconds deviceTime,
274 const uint SamplesToDo);
276 void prepare(DeviceBase *device);
278 static void InitMixer(al::optional<std::string> resampler);
280 DEF_NEWDEL(Voice)
283 extern Resampler ResamplerDefault;
285 #endif /* CORE_VOICE_H */