Clean up the biquad filter a bit
[openal-soft.git] / Alc / alcontext.h
blob5eec2e963bc7946385e12ba17d229fd02d40efc6
1 #ifndef ALCONTEXT_H
2 #define ALCONTEXT_H
4 #include <thread>
6 #include "AL/al.h"
7 #include "AL/alc.h"
8 #include "AL/alext.h"
9 #include "inprogext.h"
11 #include "atomic.h"
12 #include "vector.h"
13 #include "threads.h"
14 #include "almalloc.h"
16 #include "alListener.h"
19 struct ALsource;
20 struct ALeffectslot;
21 struct ALcontextProps;
22 struct ALlistenerProps;
23 struct ALvoiceProps;
24 struct ALeffectslotProps;
25 struct ALvoice;
26 struct ALeffectslotArray;
27 struct ll_ringbuffer;
29 enum class DistanceModel {
30 InverseClamped = AL_INVERSE_DISTANCE_CLAMPED,
31 LinearClamped = AL_LINEAR_DISTANCE_CLAMPED,
32 ExponentClamped = AL_EXPONENT_DISTANCE_CLAMPED,
33 Inverse = AL_INVERSE_DISTANCE,
34 Linear = AL_LINEAR_DISTANCE,
35 Exponent = AL_EXPONENT_DISTANCE,
36 Disable = AL_NONE,
38 Default = InverseClamped
41 struct SourceSubList {
42 uint64_t FreeMask{0u};
43 ALsource *Sources{nullptr}; /* 64 */
46 /* Effect slots are rather large, and apps aren't likely to have more than one
47 * or two (let alone 64), so hold them individually.
49 using ALeffectslotPtr = struct ALeffectslot*;
51 struct ALCcontext_struct {
52 RefCount ref{1u};
54 al::vector<SourceSubList> SourceList;
55 ALuint NumSources{0};
56 almtx_t SourceLock;
58 al::vector<ALeffectslotPtr> EffectSlotList;
59 almtx_t EffectSlotLock;
61 ATOMIC(ALenum) LastError{AL_NO_ERROR};
63 DistanceModel mDistanceModel{DistanceModel::Default};
64 ALboolean SourceDistanceModel{AL_FALSE};
66 ALfloat DopplerFactor{1.0f};
67 ALfloat DopplerVelocity{1.0f};
68 ALfloat SpeedOfSound{};
69 ALfloat MetersPerUnit{1.0f};
71 ATOMIC(ALenum) PropsClean{AL_TRUE};
72 ATOMIC(ALenum) DeferUpdates{AL_FALSE};
74 almtx_t PropLock;
76 /* Counter for the pre-mixing updates, in 31.1 fixed point (lowest bit
77 * indicates if updates are currently happening).
79 RefCount UpdateCount{0u};
80 ATOMIC(ALenum) HoldUpdates{AL_FALSE};
82 ALfloat GainBoost{1.0f};
84 ATOMIC(ALcontextProps*) Update{nullptr};
86 /* Linked lists of unused property containers, free to use for future
87 * updates.
89 ATOMIC(ALcontextProps*) FreeContextProps{nullptr};
90 ATOMIC(ALlistenerProps*) FreeListenerProps{nullptr};
91 ATOMIC(ALvoiceProps*) FreeVoiceProps{nullptr};
92 ATOMIC(ALeffectslotProps*) FreeEffectslotProps{nullptr};
94 ALvoice **Voices{nullptr};
95 ALsizei VoiceCount{0};
96 ALsizei MaxVoices{0};
98 ATOMIC(ALeffectslotArray*) ActiveAuxSlots{nullptr};
100 std::thread EventThread;
101 alsem_t EventSem;
102 ll_ringbuffer *AsyncEvents{nullptr};
103 ATOMIC(ALbitfieldSOFT) EnabledEvts{0u};
104 almtx_t EventCbLock;
105 ALEVENTPROCSOFT EventCb{};
106 void *EventParam{nullptr};
108 /* Default effect slot */
109 ALeffectslot *DefaultSlot{nullptr};
111 ALCdevice *const Device;
112 const ALCchar *ExtensionList{nullptr};
114 ATOMIC(ALCcontext*) next{nullptr};
116 ALlistener Listener{};
119 ALCcontext_struct(ALCdevice *device) : Device{device} { }
120 ALCcontext_struct(const ALCcontext_struct&) = delete;
121 ALCcontext_struct& operator=(const ALCcontext_struct&) = delete;
122 ~ALCcontext_struct();
124 DEF_NEWDEL(ALCcontext)
127 ALCcontext *GetContextRef(void);
128 void ALCcontext_DecRef(ALCcontext *context);
130 void UpdateContextProps(ALCcontext *context);
132 void ALCcontext_DeferUpdates(ALCcontext *context);
133 void ALCcontext_ProcessUpdates(ALCcontext *context);
135 inline void LockEffectSlotList(ALCcontext *context)
136 { almtx_lock(&context->EffectSlotLock); }
137 inline void UnlockEffectSlotList(ALCcontext *context)
138 { almtx_unlock(&context->EffectSlotLock); }
141 /* Simple RAII context reference. Takes the reference of the provided
142 * ALCcontext, and decrements it when leaving scope. Movable (transfer
143 * reference) but not copyable (no new references).
145 class ContextRef {
146 ALCcontext *mCtx{nullptr};
148 void release() noexcept
150 if(mCtx)
151 ALCcontext_DecRef(mCtx);
152 mCtx = nullptr;
155 public:
156 ContextRef() noexcept = default;
157 explicit ContextRef(ALCcontext *ctx) noexcept : mCtx(ctx) { }
158 ~ContextRef() { release(); }
160 ContextRef& operator=(const ContextRef&) = delete;
161 ContextRef& operator=(ContextRef&& rhs) noexcept
163 release();
164 mCtx = rhs.mCtx;
165 rhs.mCtx = nullptr;
166 return *this;
169 operator bool() const noexcept { return mCtx != nullptr; }
171 ALCcontext* operator->() noexcept { return mCtx; }
172 ALCcontext* get() noexcept { return mCtx; }
176 struct ALcontextProps {
177 ALfloat DopplerFactor;
178 ALfloat DopplerVelocity;
179 ALfloat SpeedOfSound;
180 ALboolean SourceDistanceModel;
181 DistanceModel mDistanceModel;
182 ALfloat MetersPerUnit;
184 ATOMIC(struct ALcontextProps*) next;
187 #endif /* ALCONTEXT_H */