2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2000 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
32 #include "alc/context.h"
35 #include "core/except.h"
36 #include "opthelpers.h"
41 inline void UpdateProps(ALCcontext *context)
43 if(!context->mDeferUpdates)
45 UpdateContextProps(context);
48 context->mPropsDirty = true;
51 inline void CommitAndUpdateProps(ALCcontext *context)
53 if(!context->mDeferUpdates)
56 if(context->eaxNeedsCommit())
58 context->mPropsDirty = true;
59 context->applyAllUpdates();
63 UpdateContextProps(context);
66 context->mPropsDirty = true;
71 AL_API void AL_APIENTRY alListenerf(ALenum param, ALfloat value)
74 ContextRef context{GetContextRef()};
75 if(!context) UNLIKELY return;
77 ALlistener &listener = context->mListener;
78 std::lock_guard<std::mutex> _{context->mPropLock};
82 if(!(value >= 0.0f && std::isfinite(value)))
83 return context->setError(AL_INVALID_VALUE, "Listener gain out of range");
84 listener.Gain = value;
85 UpdateProps(context.get());
88 case AL_METERS_PER_UNIT:
89 if(!(value >= AL_MIN_METERS_PER_UNIT && value <= AL_MAX_METERS_PER_UNIT))
90 return context->setError(AL_INVALID_VALUE, "Listener meters per unit out of range");
91 listener.mMetersPerUnit = value;
92 UpdateProps(context.get());
96 context->setError(AL_INVALID_ENUM, "Invalid listener float property");
101 AL_API void AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3)
104 ContextRef context{GetContextRef()};
105 if(!context) UNLIKELY return;
107 ALlistener &listener = context->mListener;
108 std::lock_guard<std::mutex> _{context->mPropLock};
112 if(!(std::isfinite(value1) && std::isfinite(value2) && std::isfinite(value3)))
113 return context->setError(AL_INVALID_VALUE, "Listener position out of range");
114 listener.Position[0] = value1;
115 listener.Position[1] = value2;
116 listener.Position[2] = value3;
117 CommitAndUpdateProps(context.get());
121 if(!(std::isfinite(value1) && std::isfinite(value2) && std::isfinite(value3)))
122 return context->setError(AL_INVALID_VALUE, "Listener velocity out of range");
123 listener.Velocity[0] = value1;
124 listener.Velocity[1] = value2;
125 listener.Velocity[2] = value3;
126 CommitAndUpdateProps(context.get());
130 context->setError(AL_INVALID_ENUM, "Invalid listener 3-float property");
135 AL_API void AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values)
143 case AL_METERS_PER_UNIT:
144 alListenerf(param, values[0]);
149 alListener3f(param, values[0], values[1], values[2]);
154 ContextRef context{GetContextRef()};
155 if(!context) UNLIKELY return;
158 return context->setError(AL_INVALID_VALUE, "NULL pointer");
160 ALlistener &listener = context->mListener;
161 std::lock_guard<std::mutex> _{context->mPropLock};
165 if(!(std::isfinite(values[0]) && std::isfinite(values[1]) && std::isfinite(values[2]) &&
166 std::isfinite(values[3]) && std::isfinite(values[4]) && std::isfinite(values[5])))
167 return context->setError(AL_INVALID_VALUE, "Listener orientation out of range");
169 listener.OrientAt[0] = values[0];
170 listener.OrientAt[1] = values[1];
171 listener.OrientAt[2] = values[2];
172 listener.OrientUp[0] = values[3];
173 listener.OrientUp[1] = values[4];
174 listener.OrientUp[2] = values[5];
175 CommitAndUpdateProps(context.get());
179 context->setError(AL_INVALID_ENUM, "Invalid listener float-vector property");
185 AL_API void AL_APIENTRY alListeneri(ALenum param, ALint /*value*/)
188 ContextRef context{GetContextRef()};
189 if(!context) UNLIKELY return;
191 std::lock_guard<std::mutex> _{context->mPropLock};
195 context->setError(AL_INVALID_ENUM, "Invalid listener integer property");
200 AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, ALint value3)
207 alListener3f(param, static_cast<ALfloat>(value1), static_cast<ALfloat>(value2),
208 static_cast<ALfloat>(value3));
212 ContextRef context{GetContextRef()};
213 if(!context) UNLIKELY return;
215 std::lock_guard<std::mutex> _{context->mPropLock};
219 context->setError(AL_INVALID_ENUM, "Invalid listener 3-integer property");
224 AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values)
234 alListener3f(param, static_cast<ALfloat>(values[0]), static_cast<ALfloat>(values[1]),
235 static_cast<ALfloat>(values[2]));
239 fvals[0] = static_cast<ALfloat>(values[0]);
240 fvals[1] = static_cast<ALfloat>(values[1]);
241 fvals[2] = static_cast<ALfloat>(values[2]);
242 fvals[3] = static_cast<ALfloat>(values[3]);
243 fvals[4] = static_cast<ALfloat>(values[4]);
244 fvals[5] = static_cast<ALfloat>(values[5]);
245 alListenerfv(param, fvals);
250 ContextRef context{GetContextRef()};
251 if(!context) UNLIKELY return;
253 std::lock_guard<std::mutex> _{context->mPropLock};
255 context->setError(AL_INVALID_VALUE, "NULL pointer");
259 context->setError(AL_INVALID_ENUM, "Invalid listener integer-vector property");
265 AL_API void AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value)
268 ContextRef context{GetContextRef()};
269 if(!context) UNLIKELY return;
271 ALlistener &listener = context->mListener;
272 std::lock_guard<std::mutex> _{context->mPropLock};
274 context->setError(AL_INVALID_VALUE, "NULL pointer");
278 *value = listener.Gain;
281 case AL_METERS_PER_UNIT:
282 *value = listener.mMetersPerUnit;
286 context->setError(AL_INVALID_ENUM, "Invalid listener float property");
291 AL_API void AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3)
294 ContextRef context{GetContextRef()};
295 if(!context) UNLIKELY return;
297 ALlistener &listener = context->mListener;
298 std::lock_guard<std::mutex> _{context->mPropLock};
299 if(!value1 || !value2 || !value3)
300 context->setError(AL_INVALID_VALUE, "NULL pointer");
304 *value1 = listener.Position[0];
305 *value2 = listener.Position[1];
306 *value3 = listener.Position[2];
310 *value1 = listener.Velocity[0];
311 *value2 = listener.Velocity[1];
312 *value3 = listener.Velocity[2];
316 context->setError(AL_INVALID_ENUM, "Invalid listener 3-float property");
321 AL_API void AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values)
327 case AL_METERS_PER_UNIT:
328 alGetListenerf(param, values);
333 alGetListener3f(param, values+0, values+1, values+2);
337 ContextRef context{GetContextRef()};
338 if(!context) UNLIKELY return;
340 ALlistener &listener = context->mListener;
341 std::lock_guard<std::mutex> _{context->mPropLock};
343 context->setError(AL_INVALID_VALUE, "NULL pointer");
348 values[0] = listener.OrientAt[0];
349 values[1] = listener.OrientAt[1];
350 values[2] = listener.OrientAt[2];
351 values[3] = listener.OrientUp[0];
352 values[4] = listener.OrientUp[1];
353 values[5] = listener.OrientUp[2];
357 context->setError(AL_INVALID_ENUM, "Invalid listener float-vector property");
363 AL_API void AL_APIENTRY alGetListeneri(ALenum param, ALint *value)
366 ContextRef context{GetContextRef()};
367 if(!context) UNLIKELY return;
369 std::lock_guard<std::mutex> _{context->mPropLock};
371 context->setError(AL_INVALID_VALUE, "NULL pointer");
375 context->setError(AL_INVALID_ENUM, "Invalid listener integer property");
380 AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *value2, ALint *value3)
383 ContextRef context{GetContextRef()};
384 if(!context) UNLIKELY return;
386 ALlistener &listener = context->mListener;
387 std::lock_guard<std::mutex> _{context->mPropLock};
388 if(!value1 || !value2 || !value3)
389 context->setError(AL_INVALID_VALUE, "NULL pointer");
393 *value1 = static_cast<ALint>(listener.Position[0]);
394 *value2 = static_cast<ALint>(listener.Position[1]);
395 *value3 = static_cast<ALint>(listener.Position[2]);
399 *value1 = static_cast<ALint>(listener.Velocity[0]);
400 *value2 = static_cast<ALint>(listener.Velocity[1]);
401 *value3 = static_cast<ALint>(listener.Velocity[2]);
405 context->setError(AL_INVALID_ENUM, "Invalid listener 3-integer property");
410 AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint* values)
417 alGetListener3i(param, values+0, values+1, values+2);
421 ContextRef context{GetContextRef()};
422 if(!context) UNLIKELY return;
424 ALlistener &listener = context->mListener;
425 std::lock_guard<std::mutex> _{context->mPropLock};
427 context->setError(AL_INVALID_VALUE, "NULL pointer");
432 values[0] = static_cast<ALint>(listener.OrientAt[0]);
433 values[1] = static_cast<ALint>(listener.OrientAt[1]);
434 values[2] = static_cast<ALint>(listener.OrientAt[2]);
435 values[3] = static_cast<ALint>(listener.OrientUp[0]);
436 values[4] = static_cast<ALint>(listener.OrientUp[1]);
437 values[5] = static_cast<ALint>(listener.OrientUp[2]);
441 context->setError(AL_INVALID_ENUM, "Invalid listener integer-vector property");