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 set3DParameters(const Vector3
&position
, const Vector3
&velocity
, std::pair
<Vector3
,Vector3
> orientation
);
85 void setPosition(ALfloat x
, ALfloat y
, ALfloat z
);
86 void setPosition(const ALfloat
*pos
);
88 void setVelocity(ALfloat x
, ALfloat y
, ALfloat z
);
89 void setVelocity(const ALfloat
*vel
);
91 void setOrientation(ALfloat x1
, ALfloat y1
, ALfloat z1
, ALfloat x2
, ALfloat y2
, ALfloat z2
);
92 void setOrientation(const ALfloat
*at
, const ALfloat
*up
);
93 void setOrientation(const ALfloat
*ori
);
95 void setMetersPerUnit(ALfloat m_u
);
99 static ALContext
*sCurrentCtx
;
100 static thread_local ALContext
*sThreadCurrentCtx
;
103 static void MakeCurrent(ALContext
*context
);
104 static ALContext
*GetCurrent() { return sThreadCurrentCtx
? sThreadCurrentCtx
: sCurrentCtx
; }
106 static void MakeThreadCurrent(ALContext
*context
);
107 static ALContext
*GetThreadCurrent() { return sThreadCurrentCtx
; }
110 ALListener mListener
;
111 ALCcontext
*mContext
;
112 std::stack
<ALuint
> mSourceIds
;
114 ALDevice
*const mDevice
;
115 std::deque
<ALSource
> mAllSources
;
116 std::queue
<ALSource
*> mFreeSources
;
117 Vector
<ALSource
*> mUsedSources
;
119 Vector
<UniquePtr
<ALBuffer
>> mBuffers
;
121 Vector
<UniquePtr
<ALSourceGroup
>> mSourceGroups
;
125 Vector
<String
> mResamplers
;
127 SharedPtr
<MessageHandler
> mMessage
;
129 bool mHasExt
[AL_EXTENSION_MAX
];
131 struct PendingBuffer
{
134 SharedPtr
<Decoder
> mDecoder
;
140 RingBuffer mPendingBuffers
;
142 Vector
<ALSource
*> mStreamingSources
;
143 std::mutex mSourceStreamMutex
;
145 std::atomic
<std::chrono::milliseconds
> mWakeInterval
;
146 std::mutex mWakeMutex
;
147 std::condition_variable mWakeThread
;
149 std::mutex mContextMutex
;
151 std::atomic
<bool> mQuitThread
;
153 void backgroundProc();
155 std::once_flag mSetExts
;
158 Buffer
doCreateBuffer(const String
&name
, Vector
<UniquePtr
<ALBuffer
>>::iterator iter
, SharedPtr
<Decoder
> decoder
);
159 Buffer
doCreateBufferAsync(const String
&name
, Vector
<UniquePtr
<ALBuffer
>>::iterator iter
, SharedPtr
<Decoder
> decoder
);
161 bool mIsConnected
: 1;
162 bool mIsBatching
: 1;
165 ALContext(ALCcontext
*context
, ALDevice
*device
);
168 ALCcontext
*getContext() const { return mContext
; }
169 long addRef() { return ++mRefs
; }
170 long decRef() { return --mRefs
; }
172 bool hasExtension(ALExtension ext
) const { return mHasExt
[ext
]; }
174 LPALGETSTRINGISOFT alGetStringiSOFT
;
175 LPALGETSOURCEI64VSOFT alGetSourcei64vSOFT
;
176 LPALGETSOURCEDVSOFT alGetSourcedvSOFT
;
178 LPALGENEFFECTS alGenEffects
;
179 LPALDELETEEFFECTS alDeleteEffects
;
180 LPALISEFFECT alIsEffect
;
181 LPALEFFECTI alEffecti
;
182 LPALEFFECTIV alEffectiv
;
183 LPALEFFECTF alEffectf
;
184 LPALEFFECTFV alEffectfv
;
185 LPALGETEFFECTI alGetEffecti
;
186 LPALGETEFFECTIV alGetEffectiv
;
187 LPALGETEFFECTF alGetEffectf
;
188 LPALGETEFFECTFV alGetEffectfv
;
190 LPALGENFILTERS alGenFilters
;
191 LPALDELETEFILTERS alDeleteFilters
;
192 LPALISFILTER alIsFilter
;
193 LPALFILTERI alFilteri
;
194 LPALFILTERIV alFilteriv
;
195 LPALFILTERF alFilterf
;
196 LPALFILTERFV alFilterfv
;
197 LPALGETFILTERI alGetFilteri
;
198 LPALGETFILTERIV alGetFilteriv
;
199 LPALGETFILTERF alGetFilterf
;
200 LPALGETFILTERFV alGetFilterfv
;
202 LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots
;
203 LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots
;
204 LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot
;
205 LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti
;
206 LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv
;
207 LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf
;
208 LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv
;
209 LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti
;
210 LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv
;
211 LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf
;
212 LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv
;
214 ALuint
getSourceId(ALuint maxprio
);
215 void insertSourceId(ALuint id
) { mSourceIds
.push(id
); }
217 void addStream(ALSource
*source
);
218 void removeStream(ALSource
*source
);
219 void removeStreamNoLock(ALSource
*source
);
221 void freeSource(ALSource
*source
);
222 void freeSourceGroup(ALSourceGroup
*group
);
227 return Batcher(nullptr);
228 alcSuspendContext(mContext
);
229 return Batcher(mContext
);
232 std::unique_lock
<std::mutex
> getSourceStreamLock()
233 { return std::unique_lock
<std::mutex
>(mSourceStreamMutex
); }
235 template<typename R
, typename
... Args
>
236 void send(R
MessageHandler::* func
, Args
&&... args
)
237 { if(mMessage
.get()) (mMessage
.get()->*func
)(std::forward
<Args
>(args
)...); }
239 Device
getDevice() { return Device(mDevice
); }
246 Listener
getListener() { return Listener(&mListener
); }
248 SharedPtr
<MessageHandler
> setMessageHandler(SharedPtr
<MessageHandler
> handler
);
249 SharedPtr
<MessageHandler
> getMessageHandler() const { return mMessage
; }
251 void setAsyncWakeInterval(std::chrono::milliseconds msec
);
252 std::chrono::milliseconds
getAsyncWakeInterval() const { return mWakeInterval
.load(); }
254 SharedPtr
<Decoder
> createDecoder(const String
&name
);
256 bool isSupported(ChannelConfig channels
, SampleType type
) const;
258 const Vector
<String
> &getAvailableResamplers();
259 ALsizei
getDefaultResamplerIndex() const;
261 Buffer
getBuffer(const String
&name
);
262 Buffer
getBufferAsync(const String
&name
);
263 Buffer
createBufferFrom(const String
&name
, SharedPtr
<Decoder
> decoder
);
264 Buffer
createBufferAsyncFrom(const String
&name
, SharedPtr
<Decoder
> decoder
);
265 void removeBuffer(const String
&name
);
266 void removeBuffer(Buffer buffer
) { removeBuffer(buffer
.getName()); }
268 Source
createSource();
270 AuxiliaryEffectSlot
createAuxiliaryEffectSlot();
272 Effect
createEffect();
274 SourceGroup
createSourceGroup(String name
);
275 SourceGroup
getSourceGroup(const String
&name
);
277 void setDopplerFactor(ALfloat factor
);
279 void setSpeedOfSound(ALfloat speed
);
281 void setDistanceModel(DistanceModel model
);
287 inline void CheckContext(const ALContext
*ctx
)
289 if(EXPECT(ctx
!= ALContext::GetCurrent(), false))
290 throw std::runtime_error("Called context is not current");
295 #endif /* CONTEXT_H */