Returned pa_operations can be NULL
[openal-soft.git] / OpenAL32 / alListener.c
blob32a12cfbc5d5a886fc9de82f746a314249c26915
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., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include "alMain.h"
24 #include "AL/alc.h"
25 #include "alError.h"
26 #include "alListener.h"
27 #include "alSource.h"
29 AL_API ALvoid AL_APIENTRY alListenerf(ALenum eParam, ALfloat flValue)
31 ALCcontext *Context;
33 Context = GetContextRef();
34 if(!Context) return;
36 switch(eParam)
38 case AL_GAIN:
39 if(flValue >= 0.0f && isfinite(flValue))
41 Context->Listener.Gain = flValue;
42 Context->UpdateSources = AL_TRUE;
44 else
45 alSetError(Context, AL_INVALID_VALUE);
46 break;
48 case AL_METERS_PER_UNIT:
49 if(flValue > 0.0f && isfinite(flValue))
51 Context->Listener.MetersPerUnit = flValue;
52 Context->UpdateSources = AL_TRUE;
54 else
55 alSetError(Context, AL_INVALID_VALUE);
56 break;
58 default:
59 alSetError(Context, AL_INVALID_ENUM);
60 break;
63 ALCcontext_DecRef(Context);
67 AL_API ALvoid AL_APIENTRY alListener3f(ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
69 ALCcontext *Context;
71 Context = GetContextRef();
72 if(!Context) return;
74 switch(eParam)
76 case AL_POSITION:
77 if(isfinite(flValue1) && isfinite(flValue2) && isfinite(flValue3))
79 LockContext(Context);
80 Context->Listener.Position[0] = flValue1;
81 Context->Listener.Position[1] = flValue2;
82 Context->Listener.Position[2] = flValue3;
83 Context->UpdateSources = AL_TRUE;
84 UnlockContext(Context);
86 else
87 alSetError(Context, AL_INVALID_VALUE);
88 break;
90 case AL_VELOCITY:
91 if(isfinite(flValue1) && isfinite(flValue2) && isfinite(flValue3))
93 LockContext(Context);
94 Context->Listener.Velocity[0] = flValue1;
95 Context->Listener.Velocity[1] = flValue2;
96 Context->Listener.Velocity[2] = flValue3;
97 Context->UpdateSources = AL_TRUE;
98 UnlockContext(Context);
100 else
101 alSetError(Context, AL_INVALID_VALUE);
102 break;
104 default:
105 alSetError(Context, AL_INVALID_ENUM);
106 break;
109 ALCcontext_DecRef(Context);
113 AL_API ALvoid AL_APIENTRY alListenerfv(ALenum eParam, const ALfloat *pflValues)
115 ALCcontext *Context;
117 if(pflValues)
119 switch(eParam)
121 case AL_GAIN:
122 case AL_METERS_PER_UNIT:
123 alListenerf(eParam, pflValues[0]);
124 return;
126 case AL_POSITION:
127 case AL_VELOCITY:
128 alListener3f(eParam, pflValues[0], pflValues[1], pflValues[2]);
129 return;
133 Context = GetContextRef();
134 if(!Context) return;
136 if(pflValues)
138 switch(eParam)
140 case AL_ORIENTATION:
141 if(isfinite(pflValues[0]) && isfinite(pflValues[1]) &&
142 isfinite(pflValues[2]) && isfinite(pflValues[3]) &&
143 isfinite(pflValues[4]) && isfinite(pflValues[5]))
145 ALfloat U[3], V[3], N[3];
147 /* AT then UP */
148 N[0] = pflValues[0];
149 N[1] = pflValues[1];
150 N[2] = pflValues[2];
151 aluNormalize(N);
152 V[0] = pflValues[3];
153 V[1] = pflValues[4];
154 V[2] = pflValues[5];
155 aluNormalize(V);
156 /* Build and normalize right-vector */
157 aluCrossproduct(N, V, U);
158 aluNormalize(U);
160 LockContext(Context);
161 Context->Listener.Forward[0] = pflValues[0];
162 Context->Listener.Forward[1] = pflValues[1];
163 Context->Listener.Forward[2] = pflValues[2];
164 Context->Listener.Up[0] = pflValues[3];
165 Context->Listener.Up[1] = pflValues[4];
166 Context->Listener.Up[2] = pflValues[5];
167 Context->Listener.Matrix[0][0] = U[0];
168 Context->Listener.Matrix[0][1] = V[0];
169 Context->Listener.Matrix[0][2] = -N[0];
170 Context->Listener.Matrix[0][3] = 0.0f;
171 Context->Listener.Matrix[1][0] = U[1];
172 Context->Listener.Matrix[1][1] = V[1];
173 Context->Listener.Matrix[1][2] = -N[1];
174 Context->Listener.Matrix[1][3] = 0.0f;
175 Context->Listener.Matrix[2][0] = U[2];
176 Context->Listener.Matrix[2][1] = V[2];
177 Context->Listener.Matrix[2][2] = -N[2];
178 Context->Listener.Matrix[2][3] = 0.0f;
179 Context->Listener.Matrix[3][0] = 0.0f;
180 Context->Listener.Matrix[3][1] = 0.0f;
181 Context->Listener.Matrix[3][2] = 0.0f;
182 Context->Listener.Matrix[3][3] = 1.0f;
183 Context->UpdateSources = AL_TRUE;
184 UnlockContext(Context);
186 else
187 alSetError(Context, AL_INVALID_VALUE);
188 break;
190 default:
191 alSetError(Context, AL_INVALID_ENUM);
192 break;
195 else
196 alSetError(Context, AL_INVALID_VALUE);
198 ALCcontext_DecRef(Context);
202 AL_API ALvoid AL_APIENTRY alListeneri(ALenum eParam, ALint lValue)
204 ALCcontext *Context;
206 (void)lValue;
208 Context = GetContextRef();
209 if(!Context) return;
211 switch(eParam)
213 default:
214 alSetError(Context, AL_INVALID_ENUM);
215 break;
218 ALCcontext_DecRef(Context);
222 AL_API void AL_APIENTRY alListener3i(ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
224 ALCcontext *Context;
226 switch(eParam)
228 case AL_POSITION:
229 case AL_VELOCITY:
230 alListener3f(eParam, (ALfloat)lValue1, (ALfloat)lValue2, (ALfloat)lValue3);
231 return;
234 Context = GetContextRef();
235 if(!Context) return;
237 switch(eParam)
239 default:
240 alSetError(Context, AL_INVALID_ENUM);
241 break;
244 ALCcontext_DecRef(Context);
248 AL_API void AL_APIENTRY alListeneriv( ALenum eParam, const ALint* plValues )
250 ALCcontext *Context;
251 ALfloat flValues[6];
253 if(plValues)
255 switch(eParam)
257 case AL_POSITION:
258 case AL_VELOCITY:
259 alListener3f(eParam, (ALfloat)plValues[0], (ALfloat)plValues[1], (ALfloat)plValues[2]);
260 return;
262 case AL_ORIENTATION:
263 flValues[0] = (ALfloat)plValues[0];
264 flValues[1] = (ALfloat)plValues[1];
265 flValues[2] = (ALfloat)plValues[2];
266 flValues[3] = (ALfloat)plValues[3];
267 flValues[4] = (ALfloat)plValues[4];
268 flValues[5] = (ALfloat)plValues[5];
269 alListenerfv(eParam, flValues);
270 return;
274 Context = GetContextRef();
275 if(!Context) return;
277 if(plValues)
279 switch(eParam)
281 default:
282 alSetError(Context, AL_INVALID_ENUM);
283 break;
286 else
287 alSetError(Context, AL_INVALID_VALUE);
289 ALCcontext_DecRef(Context);
293 AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum eParam, ALfloat *pflValue)
295 ALCcontext *Context;
297 Context = GetContextRef();
298 if(!Context) return;
300 if(pflValue)
302 switch(eParam)
304 case AL_GAIN:
305 *pflValue = Context->Listener.Gain;
306 break;
308 case AL_METERS_PER_UNIT:
309 *pflValue = Context->Listener.MetersPerUnit;
310 break;
312 default:
313 alSetError(Context, AL_INVALID_ENUM);
314 break;
317 else
318 alSetError(Context, AL_INVALID_VALUE);
320 ALCcontext_DecRef(Context);
324 AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum eParam, ALfloat *pflValue1, ALfloat *pflValue2, ALfloat *pflValue3)
326 ALCcontext *Context;
328 Context = GetContextRef();
329 if(!Context) return;
331 if(pflValue1 && pflValue2 && pflValue3)
333 switch(eParam)
335 case AL_POSITION:
336 LockContext(Context);
337 *pflValue1 = Context->Listener.Position[0];
338 *pflValue2 = Context->Listener.Position[1];
339 *pflValue3 = Context->Listener.Position[2];
340 UnlockContext(Context);
341 break;
343 case AL_VELOCITY:
344 LockContext(Context);
345 *pflValue1 = Context->Listener.Velocity[0];
346 *pflValue2 = Context->Listener.Velocity[1];
347 *pflValue3 = Context->Listener.Velocity[2];
348 UnlockContext(Context);
349 break;
351 default:
352 alSetError(Context, AL_INVALID_ENUM);
353 break;
356 else
357 alSetError(Context, AL_INVALID_VALUE);
359 ALCcontext_DecRef(Context);
363 AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum eParam, ALfloat *pflValues)
365 ALCcontext *Context;
367 switch(eParam)
369 case AL_GAIN:
370 case AL_METERS_PER_UNIT:
371 alGetListenerf(eParam, pflValues);
372 return;
374 case AL_POSITION:
375 case AL_VELOCITY:
376 alGetListener3f(eParam, pflValues+0, pflValues+1, pflValues+2);
377 return;
380 Context = GetContextRef();
381 if(!Context) return;
383 if(pflValues)
385 switch(eParam)
387 case AL_ORIENTATION:
388 LockContext(Context);
389 // AT then UP
390 pflValues[0] = Context->Listener.Forward[0];
391 pflValues[1] = Context->Listener.Forward[1];
392 pflValues[2] = Context->Listener.Forward[2];
393 pflValues[3] = Context->Listener.Up[0];
394 pflValues[4] = Context->Listener.Up[1];
395 pflValues[5] = Context->Listener.Up[2];
396 UnlockContext(Context);
397 break;
399 default:
400 alSetError(Context, AL_INVALID_ENUM);
401 break;
404 else
405 alSetError(Context, AL_INVALID_VALUE);
407 ALCcontext_DecRef(Context);
411 AL_API ALvoid AL_APIENTRY alGetListeneri(ALenum eParam, ALint *plValue)
413 ALCcontext *Context;
415 Context = GetContextRef();
416 if(!Context) return;
418 if(plValue)
420 switch(eParam)
422 default:
423 alSetError(Context, AL_INVALID_ENUM);
424 break;
427 else
428 alSetError(Context, AL_INVALID_VALUE);
430 ALCcontext_DecRef(Context);
434 AL_API void AL_APIENTRY alGetListener3i(ALenum eParam, ALint *plValue1, ALint *plValue2, ALint *plValue3)
436 ALCcontext *Context;
438 Context = GetContextRef();
439 if(!Context) return;
441 if(plValue1 && plValue2 && plValue3)
443 switch (eParam)
445 case AL_POSITION:
446 LockContext(Context);
447 *plValue1 = (ALint)Context->Listener.Position[0];
448 *plValue2 = (ALint)Context->Listener.Position[1];
449 *plValue3 = (ALint)Context->Listener.Position[2];
450 UnlockContext(Context);
451 break;
453 case AL_VELOCITY:
454 LockContext(Context);
455 *plValue1 = (ALint)Context->Listener.Velocity[0];
456 *plValue2 = (ALint)Context->Listener.Velocity[1];
457 *plValue3 = (ALint)Context->Listener.Velocity[2];
458 UnlockContext(Context);
459 break;
461 default:
462 alSetError(Context, AL_INVALID_ENUM);
463 break;
466 else
467 alSetError(Context, AL_INVALID_VALUE);
469 ALCcontext_DecRef(Context);
473 AL_API void AL_APIENTRY alGetListeneriv(ALenum eParam, ALint* plValues)
475 ALCcontext *Context;
477 switch(eParam)
479 case AL_POSITION:
480 case AL_VELOCITY:
481 alGetListener3i(eParam, plValues+0, plValues+1, plValues+2);
482 return;
485 Context = GetContextRef();
486 if(!Context) return;
488 if(plValues)
490 switch(eParam)
492 case AL_ORIENTATION:
493 LockContext(Context);
494 // AT then UP
495 plValues[0] = (ALint)Context->Listener.Forward[0];
496 plValues[1] = (ALint)Context->Listener.Forward[1];
497 plValues[2] = (ALint)Context->Listener.Forward[2];
498 plValues[3] = (ALint)Context->Listener.Up[0];
499 plValues[4] = (ALint)Context->Listener.Up[1];
500 plValues[5] = (ALint)Context->Listener.Up[2];
501 UnlockContext(Context);
502 break;
504 default:
505 alSetError(Context, AL_INVALID_ENUM);
506 break;
509 else
510 alSetError(Context, AL_INVALID_VALUE);
512 ALCcontext_DecRef(Context);