Fix matrix multiply used by the SSE cubic resampler
[openal-soft/openal-hmr.git] / OpenAL32 / alListener.c
blob07fadbe0984a8b949f65d557871b32573cbb3ae9
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 param, ALfloat value)
31 ALCcontext *Context;
33 Context = GetContextRef();
34 if(!Context) return;
36 al_try
38 switch(param)
40 case AL_GAIN:
41 CHECK_VALUE(Context, value >= 0.0f && isfinite(value));
43 Context->Listener.Gain = value;
44 Context->UpdateSources = AL_TRUE;
45 break;
47 case AL_METERS_PER_UNIT:
48 CHECK_VALUE(Context, value >= 0.0f && isfinite(value));
50 Context->Listener.MetersPerUnit = value;
51 Context->UpdateSources = AL_TRUE;
52 break;
54 default:
55 al_throwerr(Context, AL_INVALID_ENUM);
58 al_endtry;
60 ALCcontext_DecRef(Context);
64 AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3)
66 ALCcontext *Context;
68 Context = GetContextRef();
69 if(!Context) return;
71 al_try
73 switch(param)
75 case AL_POSITION:
76 CHECK_VALUE(Context, isfinite(value1) && isfinite(value2) && isfinite(value3));
78 LockContext(Context);
79 Context->Listener.Position[0] = value1;
80 Context->Listener.Position[1] = value2;
81 Context->Listener.Position[2] = value3;
82 Context->UpdateSources = AL_TRUE;
83 UnlockContext(Context);
84 break;
86 case AL_VELOCITY:
87 CHECK_VALUE(Context, isfinite(value1) && isfinite(value2) && isfinite(value3));
89 LockContext(Context);
90 Context->Listener.Velocity[0] = value1;
91 Context->Listener.Velocity[1] = value2;
92 Context->Listener.Velocity[2] = value3;
93 Context->UpdateSources = AL_TRUE;
94 UnlockContext(Context);
95 break;
97 default:
98 al_throwerr(Context, AL_INVALID_ENUM);
101 al_endtry;
103 ALCcontext_DecRef(Context);
107 AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values)
109 ALCcontext *Context;
111 if(values)
113 switch(param)
115 case AL_GAIN:
116 case AL_METERS_PER_UNIT:
117 alListenerf(param, values[0]);
118 return;
120 case AL_POSITION:
121 case AL_VELOCITY:
122 alListener3f(param, values[0], values[1], values[2]);
123 return;
127 Context = GetContextRef();
128 if(!Context) return;
130 al_try
132 ALfloat U[3], V[3], N[3];
133 CHECK_VALUE(Context, values);
134 switch(param)
136 case AL_ORIENTATION:
137 CHECK_VALUE(Context, isfinite(values[0]) && isfinite(values[1]) &&
138 isfinite(values[2]) && isfinite(values[3]) &&
139 isfinite(values[4]) && isfinite(values[5]));
141 /* AT then UP */
142 N[0] = values[0];
143 N[1] = values[1];
144 N[2] = values[2];
145 aluNormalize(N);
146 V[0] = values[3];
147 V[1] = values[4];
148 V[2] = values[5];
149 aluNormalize(V);
150 /* Build and normalize right-vector */
151 aluCrossproduct(N, V, U);
152 aluNormalize(U);
154 LockContext(Context);
155 Context->Listener.Forward[0] = values[0];
156 Context->Listener.Forward[1] = values[1];
157 Context->Listener.Forward[2] = values[2];
158 Context->Listener.Up[0] = values[3];
159 Context->Listener.Up[1] = values[4];
160 Context->Listener.Up[2] = values[5];
161 Context->Listener.Matrix[0][0] = U[0];
162 Context->Listener.Matrix[0][1] = V[0];
163 Context->Listener.Matrix[0][2] = -N[0];
164 Context->Listener.Matrix[0][3] = 0.0f;
165 Context->Listener.Matrix[1][0] = U[1];
166 Context->Listener.Matrix[1][1] = V[1];
167 Context->Listener.Matrix[1][2] = -N[1];
168 Context->Listener.Matrix[1][3] = 0.0f;
169 Context->Listener.Matrix[2][0] = U[2];
170 Context->Listener.Matrix[2][1] = V[2];
171 Context->Listener.Matrix[2][2] = -N[2];
172 Context->Listener.Matrix[2][3] = 0.0f;
173 Context->Listener.Matrix[3][0] = 0.0f;
174 Context->Listener.Matrix[3][1] = 0.0f;
175 Context->Listener.Matrix[3][2] = 0.0f;
176 Context->Listener.Matrix[3][3] = 1.0f;
177 Context->UpdateSources = AL_TRUE;
178 UnlockContext(Context);
179 break;
181 default:
182 al_throwerr(Context, AL_INVALID_ENUM);
185 al_endtry;
187 ALCcontext_DecRef(Context);
191 AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint value)
193 ALCcontext *Context;
195 (void)value;
197 Context = GetContextRef();
198 if(!Context) return;
200 al_try
202 switch(param)
204 default:
205 al_throwerr(Context, AL_INVALID_ENUM);
208 al_endtry;
210 ALCcontext_DecRef(Context);
214 AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, ALint value3)
216 ALCcontext *Context;
218 switch(param)
220 case AL_POSITION:
221 case AL_VELOCITY:
222 alListener3f(param, (ALfloat)value1, (ALfloat)value2, (ALfloat)value3);
223 return;
226 Context = GetContextRef();
227 if(!Context) return;
229 al_try
231 switch(param)
233 default:
234 al_throwerr(Context, AL_INVALID_ENUM);
237 al_endtry;
239 ALCcontext_DecRef(Context);
243 AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values)
245 ALCcontext *Context;
247 if(values)
249 ALfloat fvals[6];
250 switch(param)
252 case AL_POSITION:
253 case AL_VELOCITY:
254 alListener3f(param, (ALfloat)values[0], (ALfloat)values[1], (ALfloat)values[2]);
255 return;
257 case AL_ORIENTATION:
258 fvals[0] = (ALfloat)values[0];
259 fvals[1] = (ALfloat)values[1];
260 fvals[2] = (ALfloat)values[2];
261 fvals[3] = (ALfloat)values[3];
262 fvals[4] = (ALfloat)values[4];
263 fvals[5] = (ALfloat)values[5];
264 alListenerfv(param, fvals);
265 return;
269 Context = GetContextRef();
270 if(!Context) return;
272 al_try
274 CHECK_VALUE(Context, values);
275 switch(param)
277 default:
278 al_throwerr(Context, AL_INVALID_ENUM);
281 al_endtry;
283 ALCcontext_DecRef(Context);
287 AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value)
289 ALCcontext *Context;
291 Context = GetContextRef();
292 if(!Context) return;
294 al_try
296 CHECK_VALUE(Context, value);
297 switch(param)
299 case AL_GAIN:
300 *value = Context->Listener.Gain;
301 break;
303 case AL_METERS_PER_UNIT:
304 *value = Context->Listener.MetersPerUnit;
305 break;
307 default:
308 al_throwerr(Context, AL_INVALID_ENUM);
311 al_endtry;
313 ALCcontext_DecRef(Context);
317 AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3)
319 ALCcontext *Context;
321 Context = GetContextRef();
322 if(!Context) return;
324 al_try
326 CHECK_VALUE(Context, value1 && value2 && value3);
327 switch(param)
329 case AL_POSITION:
330 LockContext(Context);
331 *value1 = Context->Listener.Position[0];
332 *value2 = Context->Listener.Position[1];
333 *value3 = Context->Listener.Position[2];
334 UnlockContext(Context);
335 break;
337 case AL_VELOCITY:
338 LockContext(Context);
339 *value1 = Context->Listener.Velocity[0];
340 *value2 = Context->Listener.Velocity[1];
341 *value3 = Context->Listener.Velocity[2];
342 UnlockContext(Context);
343 break;
345 default:
346 al_throwerr(Context, AL_INVALID_ENUM);
349 al_endtry;
351 ALCcontext_DecRef(Context);
355 AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values)
357 ALCcontext *Context;
359 switch(param)
361 case AL_GAIN:
362 case AL_METERS_PER_UNIT:
363 alGetListenerf(param, values);
364 return;
366 case AL_POSITION:
367 case AL_VELOCITY:
368 alGetListener3f(param, values+0, values+1, values+2);
369 return;
372 Context = GetContextRef();
373 if(!Context) return;
375 al_try
377 CHECK_VALUE(Context, values);
378 switch(param)
380 case AL_ORIENTATION:
381 LockContext(Context);
382 // AT then UP
383 values[0] = Context->Listener.Forward[0];
384 values[1] = Context->Listener.Forward[1];
385 values[2] = Context->Listener.Forward[2];
386 values[3] = Context->Listener.Up[0];
387 values[4] = Context->Listener.Up[1];
388 values[5] = Context->Listener.Up[2];
389 UnlockContext(Context);
390 break;
392 default:
393 al_throwerr(Context, AL_INVALID_ENUM);
396 al_endtry;
398 ALCcontext_DecRef(Context);
402 AL_API ALvoid AL_APIENTRY alGetListeneri(ALenum param, ALint *value)
404 ALCcontext *Context;
406 Context = GetContextRef();
407 if(!Context) return;
409 al_try
411 CHECK_VALUE(Context, value);
412 switch(param)
414 default:
415 al_throwerr(Context, AL_INVALID_ENUM);
418 al_endtry;
420 ALCcontext_DecRef(Context);
424 AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *value2, ALint *value3)
426 ALCcontext *Context;
428 Context = GetContextRef();
429 if(!Context) return;
431 al_try
433 CHECK_VALUE(Context, value1 && value2 && value3);
434 switch (param)
436 case AL_POSITION:
437 LockContext(Context);
438 *value1 = (ALint)Context->Listener.Position[0];
439 *value2 = (ALint)Context->Listener.Position[1];
440 *value3 = (ALint)Context->Listener.Position[2];
441 UnlockContext(Context);
442 break;
444 case AL_VELOCITY:
445 LockContext(Context);
446 *value1 = (ALint)Context->Listener.Velocity[0];
447 *value2 = (ALint)Context->Listener.Velocity[1];
448 *value3 = (ALint)Context->Listener.Velocity[2];
449 UnlockContext(Context);
450 break;
452 default:
453 al_throwerr(Context, AL_INVALID_ENUM);
456 al_endtry;
458 ALCcontext_DecRef(Context);
462 AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint* values)
464 ALCcontext *Context;
466 switch(param)
468 case AL_POSITION:
469 case AL_VELOCITY:
470 alGetListener3i(param, values+0, values+1, values+2);
471 return;
474 Context = GetContextRef();
475 if(!Context) return;
477 al_try
479 CHECK_VALUE(Context, values);
480 switch(param)
482 case AL_ORIENTATION:
483 LockContext(Context);
484 // AT then UP
485 values[0] = (ALint)Context->Listener.Forward[0];
486 values[1] = (ALint)Context->Listener.Forward[1];
487 values[2] = (ALint)Context->Listener.Forward[2];
488 values[3] = (ALint)Context->Listener.Up[0];
489 values[4] = (ALint)Context->Listener.Up[1];
490 values[5] = (ALint)Context->Listener.Up[2];
491 UnlockContext(Context);
492 break;
494 default:
495 al_throwerr(Context, AL_INVALID_ENUM);
498 al_endtry;
500 ALCcontext_DecRef(Context);