6 #include <condition_variable>
7 #include <unordered_map>
23 #define F_PI (3.14159265358979323846f)
44 SOFT_source_resampler
,
45 SOFT_source_spatialize
,
55 // Batches OpenAL updates while the object is alive, if batching isn't already
61 Batcher(ALCcontext
*context
) : mContext(context
) { }
62 Batcher(Batcher
&& rhs
) : mContext(rhs
.mContext
) { rhs
.mContext
= nullptr; }
63 Batcher(const Batcher
&) = delete;
67 alcProcessContext(mContext
);
70 Batcher
& operator=(Batcher
&&) = delete;
71 Batcher
& operator=(const Batcher
&) = delete;
76 ALContext
*const mContext
;
79 ALListener(ALContext
*ctx
) : mContext(ctx
) { }
81 void setGain(ALfloat gain
);
83 void setPosition(ALfloat x
, ALfloat y
, ALfloat z
);
84 void setPosition(const ALfloat
*pos
);
86 void setVelocity(ALfloat x
, ALfloat y
, ALfloat z
);
87 void setVelocity(const ALfloat
*vel
);
89 void setOrientation(ALfloat x1
, ALfloat y1
, ALfloat z1
, ALfloat x2
, ALfloat y2
, ALfloat z2
);
90 void setOrientation(const ALfloat
*at
, const ALfloat
*up
);
91 void setOrientation(const ALfloat
*ori
);
93 void setMetersPerUnit(ALfloat m_u
);
97 static ALContext
*sCurrentCtx
;
98 static thread_local ALContext
*sThreadCurrentCtx
;
101 static void MakeCurrent(ALContext
*context
);
102 static ALContext
*GetCurrent() { return sThreadCurrentCtx
? sThreadCurrentCtx
: sCurrentCtx
; }
104 static void MakeThreadCurrent(ALContext
*context
);
105 static ALContext
*GetThreadCurrent() { return sThreadCurrentCtx
; }
108 ALListener mListener
;
109 ALCcontext
*mContext
;
110 std::stack
<ALuint
> mSourceIds
;
112 ALDevice
*const mDevice
;
113 std::deque
<ALSource
> mAllSources
;
114 std::queue
<ALSource
*> mFreeSources
;
115 Vector
<ALSource
*> mUsedSources
;
117 Vector
<UniquePtr
<ALBuffer
>> mBuffers
;
119 Vector
<UniquePtr
<ALSourceGroup
>> mSourceGroups
;
123 Vector
<String
> mResamplers
;
125 SharedPtr
<MessageHandler
> mMessage
;
127 bool mHasExt
[AL_EXTENSION_MAX
];
129 struct PendingBuffer
{
132 SharedPtr
<Decoder
> mDecoder
;
138 RingBuffer mPendingBuffers
;
140 Vector
<ALSource
*> mStreamingSources
;
141 std::mutex mSourceStreamMutex
;
143 std::atomic
<ALuint
> mWakeInterval
;
144 std::mutex mWakeMutex
;
145 std::condition_variable mWakeThread
;
147 std::mutex mContextMutex
;
149 std::atomic
<bool> mQuitThread
;
151 void backgroundProc();
153 std::once_flag mSetExts
;
156 bool mIsConnected
: 1;
157 bool mIsBatching
: 1;
160 ALContext(ALCcontext
*context
, ALDevice
*device
);
163 ALCcontext
*getContext() const { return mContext
; }
164 long addRef() { return ++mRefs
; }
165 long decRef() { return --mRefs
; }
167 bool hasExtension(ALExtension ext
) const { return mHasExt
[ext
]; }
169 LPALGETSTRINGISOFT alGetStringiSOFT
;
170 LPALGETSOURCEI64VSOFT alGetSourcei64vSOFT
;
172 LPALGENEFFECTS alGenEffects
;
173 LPALDELETEEFFECTS alDeleteEffects
;
174 LPALISEFFECT alIsEffect
;
175 LPALEFFECTI alEffecti
;
176 LPALEFFECTIV alEffectiv
;
177 LPALEFFECTF alEffectf
;
178 LPALEFFECTFV alEffectfv
;
179 LPALGETEFFECTI alGetEffecti
;
180 LPALGETEFFECTIV alGetEffectiv
;
181 LPALGETEFFECTF alGetEffectf
;
182 LPALGETEFFECTFV alGetEffectfv
;
184 LPALGENFILTERS alGenFilters
;
185 LPALDELETEFILTERS alDeleteFilters
;
186 LPALISFILTER alIsFilter
;
187 LPALFILTERI alFilteri
;
188 LPALFILTERIV alFilteriv
;
189 LPALFILTERF alFilterf
;
190 LPALFILTERFV alFilterfv
;
191 LPALGETFILTERI alGetFilteri
;
192 LPALGETFILTERIV alGetFilteriv
;
193 LPALGETFILTERF alGetFilterf
;
194 LPALGETFILTERFV alGetFilterfv
;
196 LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots
;
197 LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots
;
198 LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot
;
199 LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti
;
200 LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv
;
201 LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf
;
202 LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv
;
203 LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti
;
204 LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv
;
205 LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf
;
206 LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv
;
208 ALuint
getSourceId(ALuint maxprio
);
209 void insertSourceId(ALuint id
) { mSourceIds
.push(id
); }
211 void addStream(ALSource
*source
);
212 void removeStream(ALSource
*source
);
213 void removeStreamNoLock(ALSource
*source
);
215 void freeSource(ALSource
*source
);
216 void freeSourceGroup(ALSourceGroup
*group
);
221 return Batcher(nullptr);
222 alcSuspendContext(mContext
);
223 return Batcher(mContext
);
226 std::unique_lock
<std::mutex
> getSourceStreamLock()
227 { return std::unique_lock
<std::mutex
>(mSourceStreamMutex
); }
229 template<typename R
, typename
... Args
>
230 void send(R
MessageHandler::* func
, Args
&&... args
)
231 { if(mMessage
.get()) (mMessage
.get()->*func
)(std::forward
<Args
>(args
)...); }
233 Device
getDevice() { return Device(mDevice
); }
240 Listener
getListener() { return Listener(&mListener
); }
242 SharedPtr
<MessageHandler
> setMessageHandler(SharedPtr
<MessageHandler
> handler
);
243 SharedPtr
<MessageHandler
> getMessageHandler() const { return mMessage
; }
245 void setAsyncWakeInterval(ALuint msec
);
246 ALuint
getAsyncWakeInterval() const { return mWakeInterval
.load(); }
248 SharedPtr
<Decoder
> createDecoder(const String
&name
);
250 bool isSupported(ChannelConfig channels
, SampleType type
) const;
252 const Vector
<String
> &getAvailableResamplers();
253 ALsizei
getDefaultResamplerIndex() const;
255 Buffer
getBuffer(const String
&name
);
256 Buffer
getBufferAsync(const String
&name
);
257 void removeBuffer(const String
&name
);
258 void removeBuffer(Buffer buffer
) { removeBuffer(buffer
.getName()); }
260 Source
createSource();
262 AuxiliaryEffectSlot
createAuxiliaryEffectSlot();
264 Effect
createEffect();
266 SourceGroup
createSourceGroup(String name
);
267 SourceGroup
getSourceGroup(const String
&name
);
269 void setDopplerFactor(ALfloat factor
);
271 void setSpeedOfSound(ALfloat speed
);
273 void setDistanceModel(DistanceModel model
);
279 inline void CheckContext(const ALContext
*ctx
)
281 if(ctx
!= ALContext::GetCurrent())
282 throw std::runtime_error("Called context is not current");
287 #endif /* CONTEXT_H */