Remove some unused members
[openal-soft.git] / al / listener.cpp
blob4aa261ddfd2f9cc1fa4c4f359425de07107c48e2
1 /**
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
21 #include "config.h"
23 #include "listener.h"
25 #include <cmath>
26 #include <mutex>
28 #include "AL/al.h"
29 #include "AL/alc.h"
30 #include "AL/efx.h"
32 #include "alc/context.h"
33 #include "almalloc.h"
34 #include "atomic.h"
35 #include "core/except.h"
36 #include "opthelpers.h"
39 namespace {
41 inline void UpdateProps(ALCcontext *context)
43 if(!context->mDeferUpdates)
45 UpdateContextProps(context);
46 return;
48 context->mPropsDirty = true;
51 #ifdef ALSOFT_EAX
52 inline void CommitAndUpdateProps(ALCcontext *context)
54 if(!context->mDeferUpdates)
56 if(context->has_eax())
58 context->mHoldUpdates.store(true, std::memory_order_release);
59 while((context->mUpdateCount.load(std::memory_order_acquire)&1) != 0) {
60 /* busy-wait */
63 context->eax_commit_and_update_sources();
65 UpdateContextProps(context);
66 context->mHoldUpdates.store(false, std::memory_order_release);
67 return;
69 context->mPropsDirty = true;
72 #else
74 inline void CommitAndUpdateProps(ALCcontext *context)
75 { UpdateProps(context); }
76 #endif
78 } // namespace
80 AL_API void AL_APIENTRY alListenerf(ALenum param, ALfloat value)
81 START_API_FUNC
83 ContextRef context{GetContextRef()};
84 if(!context) [[unlikely]] return;
86 ALlistener &listener = context->mListener;
87 std::lock_guard<std::mutex> _{context->mPropLock};
88 switch(param)
90 case AL_GAIN:
91 if(!(value >= 0.0f && std::isfinite(value)))
92 return context->setError(AL_INVALID_VALUE, "Listener gain out of range");
93 listener.Gain = value;
94 UpdateProps(context.get());
95 break;
97 case AL_METERS_PER_UNIT:
98 if(!(value >= AL_MIN_METERS_PER_UNIT && value <= AL_MAX_METERS_PER_UNIT))
99 return context->setError(AL_INVALID_VALUE, "Listener meters per unit out of range");
100 listener.mMetersPerUnit = value;
101 UpdateProps(context.get());
102 break;
104 default:
105 context->setError(AL_INVALID_ENUM, "Invalid listener float property");
108 END_API_FUNC
110 AL_API void AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3)
111 START_API_FUNC
113 ContextRef context{GetContextRef()};
114 if(!context) [[unlikely]] return;
116 ALlistener &listener = context->mListener;
117 std::lock_guard<std::mutex> _{context->mPropLock};
118 switch(param)
120 case AL_POSITION:
121 if(!(std::isfinite(value1) && std::isfinite(value2) && std::isfinite(value3)))
122 return context->setError(AL_INVALID_VALUE, "Listener position out of range");
123 listener.Position[0] = value1;
124 listener.Position[1] = value2;
125 listener.Position[2] = value3;
126 CommitAndUpdateProps(context.get());
127 break;
129 case AL_VELOCITY:
130 if(!(std::isfinite(value1) && std::isfinite(value2) && std::isfinite(value3)))
131 return context->setError(AL_INVALID_VALUE, "Listener velocity out of range");
132 listener.Velocity[0] = value1;
133 listener.Velocity[1] = value2;
134 listener.Velocity[2] = value3;
135 CommitAndUpdateProps(context.get());
136 break;
138 default:
139 context->setError(AL_INVALID_ENUM, "Invalid listener 3-float property");
142 END_API_FUNC
144 AL_API void AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values)
145 START_API_FUNC
147 if(values)
149 switch(param)
151 case AL_GAIN:
152 case AL_METERS_PER_UNIT:
153 alListenerf(param, values[0]);
154 return;
156 case AL_POSITION:
157 case AL_VELOCITY:
158 alListener3f(param, values[0], values[1], values[2]);
159 return;
163 ContextRef context{GetContextRef()};
164 if(!context) [[unlikely]] return;
166 if(!values) [[unlikely]]
167 return context->setError(AL_INVALID_VALUE, "NULL pointer");
169 ALlistener &listener = context->mListener;
170 std::lock_guard<std::mutex> _{context->mPropLock};
171 switch(param)
173 case AL_ORIENTATION:
174 if(!(std::isfinite(values[0]) && std::isfinite(values[1]) && std::isfinite(values[2]) &&
175 std::isfinite(values[3]) && std::isfinite(values[4]) && std::isfinite(values[5])))
176 return context->setError(AL_INVALID_VALUE, "Listener orientation out of range");
177 /* AT then UP */
178 listener.OrientAt[0] = values[0];
179 listener.OrientAt[1] = values[1];
180 listener.OrientAt[2] = values[2];
181 listener.OrientUp[0] = values[3];
182 listener.OrientUp[1] = values[4];
183 listener.OrientUp[2] = values[5];
184 CommitAndUpdateProps(context.get());
185 break;
187 default:
188 context->setError(AL_INVALID_ENUM, "Invalid listener float-vector property");
191 END_API_FUNC
194 AL_API void AL_APIENTRY alListeneri(ALenum param, ALint /*value*/)
195 START_API_FUNC
197 ContextRef context{GetContextRef()};
198 if(!context) [[unlikely]] return;
200 std::lock_guard<std::mutex> _{context->mPropLock};
201 switch(param)
203 default:
204 context->setError(AL_INVALID_ENUM, "Invalid listener integer property");
207 END_API_FUNC
209 AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, ALint value3)
210 START_API_FUNC
212 switch(param)
214 case AL_POSITION:
215 case AL_VELOCITY:
216 alListener3f(param, static_cast<ALfloat>(value1), static_cast<ALfloat>(value2),
217 static_cast<ALfloat>(value3));
218 return;
221 ContextRef context{GetContextRef()};
222 if(!context) [[unlikely]] return;
224 std::lock_guard<std::mutex> _{context->mPropLock};
225 switch(param)
227 default:
228 context->setError(AL_INVALID_ENUM, "Invalid listener 3-integer property");
231 END_API_FUNC
233 AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values)
234 START_API_FUNC
236 if(values)
238 ALfloat fvals[6];
239 switch(param)
241 case AL_POSITION:
242 case AL_VELOCITY:
243 alListener3f(param, static_cast<ALfloat>(values[0]), static_cast<ALfloat>(values[1]),
244 static_cast<ALfloat>(values[2]));
245 return;
247 case AL_ORIENTATION:
248 fvals[0] = static_cast<ALfloat>(values[0]);
249 fvals[1] = static_cast<ALfloat>(values[1]);
250 fvals[2] = static_cast<ALfloat>(values[2]);
251 fvals[3] = static_cast<ALfloat>(values[3]);
252 fvals[4] = static_cast<ALfloat>(values[4]);
253 fvals[5] = static_cast<ALfloat>(values[5]);
254 alListenerfv(param, fvals);
255 return;
259 ContextRef context{GetContextRef()};
260 if(!context) [[unlikely]] return;
262 std::lock_guard<std::mutex> _{context->mPropLock};
263 if(!values) [[unlikely]]
264 context->setError(AL_INVALID_VALUE, "NULL pointer");
265 else switch(param)
267 default:
268 context->setError(AL_INVALID_ENUM, "Invalid listener integer-vector property");
271 END_API_FUNC
274 AL_API void AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value)
275 START_API_FUNC
277 ContextRef context{GetContextRef()};
278 if(!context) [[unlikely]] return;
280 ALlistener &listener = context->mListener;
281 std::lock_guard<std::mutex> _{context->mPropLock};
282 if(!value)
283 context->setError(AL_INVALID_VALUE, "NULL pointer");
284 else switch(param)
286 case AL_GAIN:
287 *value = listener.Gain;
288 break;
290 case AL_METERS_PER_UNIT:
291 *value = listener.mMetersPerUnit;
292 break;
294 default:
295 context->setError(AL_INVALID_ENUM, "Invalid listener float property");
298 END_API_FUNC
300 AL_API void AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3)
301 START_API_FUNC
303 ContextRef context{GetContextRef()};
304 if(!context) [[unlikely]] return;
306 ALlistener &listener = context->mListener;
307 std::lock_guard<std::mutex> _{context->mPropLock};
308 if(!value1 || !value2 || !value3)
309 context->setError(AL_INVALID_VALUE, "NULL pointer");
310 else switch(param)
312 case AL_POSITION:
313 *value1 = listener.Position[0];
314 *value2 = listener.Position[1];
315 *value3 = listener.Position[2];
316 break;
318 case AL_VELOCITY:
319 *value1 = listener.Velocity[0];
320 *value2 = listener.Velocity[1];
321 *value3 = listener.Velocity[2];
322 break;
324 default:
325 context->setError(AL_INVALID_ENUM, "Invalid listener 3-float property");
328 END_API_FUNC
330 AL_API void AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values)
331 START_API_FUNC
333 switch(param)
335 case AL_GAIN:
336 case AL_METERS_PER_UNIT:
337 alGetListenerf(param, values);
338 return;
340 case AL_POSITION:
341 case AL_VELOCITY:
342 alGetListener3f(param, values+0, values+1, values+2);
343 return;
346 ContextRef context{GetContextRef()};
347 if(!context) [[unlikely]] return;
349 ALlistener &listener = context->mListener;
350 std::lock_guard<std::mutex> _{context->mPropLock};
351 if(!values)
352 context->setError(AL_INVALID_VALUE, "NULL pointer");
353 else switch(param)
355 case AL_ORIENTATION:
356 // AT then UP
357 values[0] = listener.OrientAt[0];
358 values[1] = listener.OrientAt[1];
359 values[2] = listener.OrientAt[2];
360 values[3] = listener.OrientUp[0];
361 values[4] = listener.OrientUp[1];
362 values[5] = listener.OrientUp[2];
363 break;
365 default:
366 context->setError(AL_INVALID_ENUM, "Invalid listener float-vector property");
369 END_API_FUNC
372 AL_API void AL_APIENTRY alGetListeneri(ALenum param, ALint *value)
373 START_API_FUNC
375 ContextRef context{GetContextRef()};
376 if(!context) [[unlikely]] return;
378 std::lock_guard<std::mutex> _{context->mPropLock};
379 if(!value)
380 context->setError(AL_INVALID_VALUE, "NULL pointer");
381 else switch(param)
383 default:
384 context->setError(AL_INVALID_ENUM, "Invalid listener integer property");
387 END_API_FUNC
389 AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *value2, ALint *value3)
390 START_API_FUNC
392 ContextRef context{GetContextRef()};
393 if(!context) [[unlikely]] return;
395 ALlistener &listener = context->mListener;
396 std::lock_guard<std::mutex> _{context->mPropLock};
397 if(!value1 || !value2 || !value3)
398 context->setError(AL_INVALID_VALUE, "NULL pointer");
399 else switch(param)
401 case AL_POSITION:
402 *value1 = static_cast<ALint>(listener.Position[0]);
403 *value2 = static_cast<ALint>(listener.Position[1]);
404 *value3 = static_cast<ALint>(listener.Position[2]);
405 break;
407 case AL_VELOCITY:
408 *value1 = static_cast<ALint>(listener.Velocity[0]);
409 *value2 = static_cast<ALint>(listener.Velocity[1]);
410 *value3 = static_cast<ALint>(listener.Velocity[2]);
411 break;
413 default:
414 context->setError(AL_INVALID_ENUM, "Invalid listener 3-integer property");
417 END_API_FUNC
419 AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint* values)
420 START_API_FUNC
422 switch(param)
424 case AL_POSITION:
425 case AL_VELOCITY:
426 alGetListener3i(param, values+0, values+1, values+2);
427 return;
430 ContextRef context{GetContextRef()};
431 if(!context) [[unlikely]] return;
433 ALlistener &listener = context->mListener;
434 std::lock_guard<std::mutex> _{context->mPropLock};
435 if(!values)
436 context->setError(AL_INVALID_VALUE, "NULL pointer");
437 else switch(param)
439 case AL_ORIENTATION:
440 // AT then UP
441 values[0] = static_cast<ALint>(listener.OrientAt[0]);
442 values[1] = static_cast<ALint>(listener.OrientAt[1]);
443 values[2] = static_cast<ALint>(listener.OrientAt[2]);
444 values[3] = static_cast<ALint>(listener.OrientUp[0]);
445 values[4] = static_cast<ALint>(listener.OrientUp[1]);
446 values[5] = static_cast<ALint>(listener.OrientUp[2]);
447 break;
449 default:
450 context->setError(AL_INVALID_ENUM, "Invalid listener integer-vector property");
453 END_API_FUNC