Get rid of an unnecessary struct
[openal-soft.git] / alc / voice.h
blob9e96bdc551cd941f6c9632af768725f93bfa9aeb
1 #ifndef VOICE_H
2 #define VOICE_H
4 #include <array>
6 #include "AL/al.h"
7 #include "AL/alext.h"
9 #include "al/buffer.h"
10 #include "alspan.h"
11 #include "alu.h"
12 #include "devformat.h"
13 #include "filters/biquad.h"
14 #include "filters/nfc.h"
15 #include "filters/splitter.h"
16 #include "hrtf.h"
18 enum class DistanceModel;
21 enum SpatializeMode {
22 SpatializeOff = AL_FALSE,
23 SpatializeOn = AL_TRUE,
24 SpatializeAuto = AL_AUTO_SOFT
27 enum class DirectMode : unsigned char {
28 Off = AL_FALSE,
29 DropMismatch = AL_DROP_UNMATCHED_SOFT,
30 RemixMismatch = AL_REMIX_UNMATCHED_SOFT
33 enum class Resampler {
34 Point,
35 Linear,
36 Cubic,
37 FastBSinc12,
38 BSinc12,
39 FastBSinc24,
40 BSinc24,
42 Max = BSinc24
44 extern Resampler ResamplerDefault;
46 /* The number of distinct scale and phase intervals within the bsinc filter
47 * table.
49 #define BSINC_SCALE_BITS 4
50 #define BSINC_SCALE_COUNT (1<<BSINC_SCALE_BITS)
51 #define BSINC_PHASE_BITS 5
52 #define BSINC_PHASE_COUNT (1<<BSINC_PHASE_BITS)
54 /* Interpolator state. Kind of a misnomer since the interpolator itself is
55 * stateless. This just keeps it from having to recompute scale-related
56 * mappings for every sample.
58 struct BsincState {
59 float sf; /* Scale interpolation factor. */
60 ALuint m; /* Coefficient count. */
61 ALuint l; /* Left coefficient offset. */
62 /* Filter coefficients, followed by the phase, scale, and scale-phase
63 * delta coefficients. Starting at phase index 0, each subsequent phase
64 * index follows contiguously.
66 const float *filter;
69 union InterpState {
70 BsincState bsinc;
73 using ResamplerFunc = const float*(*)(const InterpState *state, const float *RESTRICT src,
74 ALuint frac, ALuint increment, const al::span<float> dst);
76 ResamplerFunc PrepareResampler(Resampler resampler, ALuint increment, InterpState *state);
79 enum {
80 AF_None = 0,
81 AF_LowPass = 1,
82 AF_HighPass = 2,
83 AF_BandPass = AF_LowPass | AF_HighPass
87 struct MixHrtfFilter {
88 const HrirArray *Coeffs;
89 ALuint Delay[2];
90 float Gain;
91 float GainStep;
95 struct DirectParams {
96 BiquadFilter LowPass;
97 BiquadFilter HighPass;
99 NfcFilter NFCtrlFilter;
101 struct {
102 HrtfFilter Old;
103 HrtfFilter Target;
104 alignas(16) std::array<float,HRTF_HISTORY_LENGTH> History;
105 } Hrtf;
107 struct {
108 std::array<float,MAX_OUTPUT_CHANNELS> Current;
109 std::array<float,MAX_OUTPUT_CHANNELS> Target;
110 } Gains;
113 struct SendParams {
114 BiquadFilter LowPass;
115 BiquadFilter HighPass;
117 struct {
118 std::array<float,MAX_OUTPUT_CHANNELS> Current;
119 std::array<float,MAX_OUTPUT_CHANNELS> Target;
120 } Gains;
124 struct ALvoicePropsBase {
125 float Pitch;
126 float Gain;
127 float OuterGain;
128 float MinGain;
129 float MaxGain;
130 float InnerAngle;
131 float OuterAngle;
132 float RefDistance;
133 float MaxDistance;
134 float RolloffFactor;
135 std::array<float,3> Position;
136 std::array<float,3> Velocity;
137 std::array<float,3> Direction;
138 std::array<float,3> OrientAt;
139 std::array<float,3> OrientUp;
140 bool HeadRelative;
141 DistanceModel mDistanceModel;
142 Resampler mResampler;
143 DirectMode DirectChannels;
144 SpatializeMode mSpatializeMode;
146 bool DryGainHFAuto;
147 bool WetGainAuto;
148 bool WetGainHFAuto;
149 float OuterGainHF;
151 float AirAbsorptionFactor;
152 float RoomRolloffFactor;
153 float DopplerFactor;
155 std::array<float,2> StereoPan;
157 float Radius;
159 /** Direct filter and auxiliary send info. */
160 struct {
161 float Gain;
162 float GainHF;
163 float HFReference;
164 float GainLF;
165 float LFReference;
166 } Direct;
167 struct SendData {
168 ALeffectslot *Slot;
169 float Gain;
170 float GainHF;
171 float HFReference;
172 float GainLF;
173 float LFReference;
174 } Send[MAX_SENDS];
177 struct ALvoiceProps : public ALvoicePropsBase {
178 std::atomic<ALvoiceProps*> next{nullptr};
180 DEF_NEWDEL(ALvoiceProps)
183 #define VOICE_IS_STATIC (1u<<0)
184 #define VOICE_IS_FADING (1u<<1) /* Fading sources use gain stepping for smooth transitions. */
185 #define VOICE_IS_AMBISONIC (1u<<2) /* Voice needs HF scaling for ambisonic upsampling. */
186 #define VOICE_HAS_HRTF (1u<<3)
187 #define VOICE_HAS_NFC (1u<<4)
189 struct ALvoice {
190 enum State {
191 Stopped = 0,
192 Playing = 1,
193 Stopping = 2
196 std::atomic<ALvoiceProps*> mUpdate{nullptr};
198 std::atomic<ALuint> mSourceID{0u};
199 std::atomic<State> mPlayState{Stopped};
201 ALvoicePropsBase mProps;
204 * Source offset in samples, relative to the currently playing buffer, NOT
205 * the whole queue.
207 std::atomic<ALuint> mPosition;
208 /** Fractional (fixed-point) offset to the next sample. */
209 std::atomic<ALuint> mPositionFrac;
211 /* Current buffer queue item being played. */
212 std::atomic<ALbufferlistitem*> mCurrentBuffer;
214 /* Buffer queue item to loop to at end of queue (will be NULL for non-
215 * looping voices).
217 std::atomic<ALbufferlistitem*> mLoopBuffer;
219 /* Properties for the attached buffer(s). */
220 FmtChannels mFmtChannels;
221 ALuint mFrequency;
222 ALuint mNumChannels;
223 ALuint mSampleSize;
224 AmbiLayout mAmbiLayout;
225 AmbiNorm mAmbiScaling;
226 ALuint mAmbiOrder;
228 /** Current target parameters used for mixing. */
229 ALuint mStep;
231 ResamplerFunc mResampler;
233 InterpState mResampleState;
235 ALuint mFlags;
237 struct TargetData {
238 int FilterType;
239 al::span<FloatBufferLine> Buffer;
241 TargetData mDirect;
242 std::array<TargetData,MAX_SENDS> mSend;
244 struct ChannelData {
245 alignas(16) std::array<float,MAX_RESAMPLER_PADDING> mPrevSamples;
247 float mAmbiScale;
248 BandSplitter mAmbiSplitter;
250 DirectParams mDryParams;
251 std::array<SendParams,MAX_SENDS> mWetParams;
253 std::array<ChannelData,MAX_INPUT_CHANNELS> mChans;
255 ALvoice() = default;
256 ALvoice(const ALvoice&) = delete;
257 ALvoice(ALvoice&& rhs) noexcept { *this = std::move(rhs); }
258 ~ALvoice() { delete mUpdate.exchange(nullptr, std::memory_order_acq_rel); }
259 ALvoice& operator=(const ALvoice&) = delete;
260 ALvoice& operator=(ALvoice&& rhs) noexcept
262 ALvoiceProps *old_update{mUpdate.load(std::memory_order_relaxed)};
263 mUpdate.store(rhs.mUpdate.exchange(old_update, std::memory_order_relaxed),
264 std::memory_order_relaxed);
266 mSourceID.store(rhs.mSourceID.load(std::memory_order_relaxed), std::memory_order_relaxed);
267 mPlayState.store(rhs.mPlayState.load(std::memory_order_relaxed),
268 std::memory_order_relaxed);
270 mProps = rhs.mProps;
272 mPosition.store(rhs.mPosition.load(std::memory_order_relaxed), std::memory_order_relaxed);
273 mPositionFrac.store(rhs.mPositionFrac.load(std::memory_order_relaxed),
274 std::memory_order_relaxed);
276 mCurrentBuffer.store(rhs.mCurrentBuffer.load(std::memory_order_relaxed),
277 std::memory_order_relaxed);
278 mLoopBuffer.store(rhs.mLoopBuffer.load(std::memory_order_relaxed),
279 std::memory_order_relaxed);
281 mFmtChannels = rhs.mFmtChannels;
282 mFrequency = rhs.mFrequency;
283 mNumChannels = rhs.mNumChannels;
284 mSampleSize = rhs.mSampleSize;
285 mAmbiLayout = rhs.mAmbiLayout;
286 mAmbiScaling = rhs.mAmbiScaling;
287 mAmbiOrder = rhs.mAmbiOrder;
289 mStep = rhs.mStep;
290 mResampler = rhs.mResampler;
292 mResampleState = rhs.mResampleState;
294 mFlags = rhs.mFlags;
296 mDirect = rhs.mDirect;
297 mSend = rhs.mSend;
298 mChans = rhs.mChans;
300 return *this;
303 void mix(const State vstate, ALCcontext *Context, const ALuint SamplesToDo);
306 #endif /* VOICE_H */