Always mix to the real output for DirectChannels
[openal-soft.git] / OpenAL32 / alListener.c
blob668654730c80d460e2ee20b344545d70ee8ef302
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 "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 switch(param)
38 case AL_GAIN:
39 if(!(value >= 0.0f && isfinite(value)))
40 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
42 context->Listener->Gain = value;
43 ATOMIC_STORE(&context->UpdateSources, AL_TRUE);
44 break;
46 case AL_METERS_PER_UNIT:
47 if(!(value >= 0.0f && isfinite(value)))
48 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
50 context->Listener->MetersPerUnit = value;
51 ATOMIC_STORE(&context->UpdateSources, AL_TRUE);
52 break;
54 default:
55 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
58 done:
59 ALCcontext_DecRef(context);
63 AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3)
65 ALCcontext *context;
67 context = GetContextRef();
68 if(!context) return;
70 switch(param)
72 case AL_POSITION:
73 if(!(isfinite(value1) && isfinite(value2) && isfinite(value3)))
74 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
76 LockContext(context);
77 aluVectorSet(&context->Listener->Position, value1, value2, value3, 1.0f);
78 ATOMIC_STORE(&context->UpdateSources, AL_TRUE);
79 UnlockContext(context);
80 break;
82 case AL_VELOCITY:
83 if(!(isfinite(value1) && isfinite(value2) && isfinite(value3)))
84 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
86 LockContext(context);
87 aluVectorSet(&context->Listener->Velocity, value1, value2, value3, 0.0f);
88 ATOMIC_STORE(&context->UpdateSources, AL_TRUE);
89 UnlockContext(context);
90 break;
92 default:
93 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
96 done:
97 ALCcontext_DecRef(context);
101 AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values)
103 ALCcontext *context;
105 if(values)
107 switch(param)
109 case AL_GAIN:
110 case AL_METERS_PER_UNIT:
111 alListenerf(param, values[0]);
112 return;
114 case AL_POSITION:
115 case AL_VELOCITY:
116 alListener3f(param, values[0], values[1], values[2]);
117 return;
121 context = GetContextRef();
122 if(!context) return;
124 if(!(values))
125 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
126 switch(param)
128 case AL_ORIENTATION:
129 if(!(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]) &&
130 isfinite(values[3]) && isfinite(values[4]) && isfinite(values[5])))
131 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
133 LockContext(context);
134 /* AT then UP */
135 context->Listener->Forward[0] = values[0];
136 context->Listener->Forward[1] = values[1];
137 context->Listener->Forward[2] = values[2];
138 context->Listener->Up[0] = values[3];
139 context->Listener->Up[1] = values[4];
140 context->Listener->Up[2] = values[5];
141 ATOMIC_STORE(&context->UpdateSources, AL_TRUE);
142 UnlockContext(context);
143 break;
145 default:
146 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
149 done:
150 ALCcontext_DecRef(context);
154 AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint UNUSED(value))
156 ALCcontext *context;
158 context = GetContextRef();
159 if(!context) return;
161 switch(param)
163 default:
164 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
167 done:
168 ALCcontext_DecRef(context);
172 AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, ALint value3)
174 ALCcontext *context;
176 switch(param)
178 case AL_POSITION:
179 case AL_VELOCITY:
180 alListener3f(param, (ALfloat)value1, (ALfloat)value2, (ALfloat)value3);
181 return;
184 context = GetContextRef();
185 if(!context) return;
187 switch(param)
189 default:
190 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
193 done:
194 ALCcontext_DecRef(context);
198 AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values)
200 ALCcontext *context;
202 if(values)
204 ALfloat fvals[6];
205 switch(param)
207 case AL_POSITION:
208 case AL_VELOCITY:
209 alListener3f(param, (ALfloat)values[0], (ALfloat)values[1], (ALfloat)values[2]);
210 return;
212 case AL_ORIENTATION:
213 fvals[0] = (ALfloat)values[0];
214 fvals[1] = (ALfloat)values[1];
215 fvals[2] = (ALfloat)values[2];
216 fvals[3] = (ALfloat)values[3];
217 fvals[4] = (ALfloat)values[4];
218 fvals[5] = (ALfloat)values[5];
219 alListenerfv(param, fvals);
220 return;
224 context = GetContextRef();
225 if(!context) return;
227 if(!(values))
228 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
229 switch(param)
231 default:
232 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
235 done:
236 ALCcontext_DecRef(context);
240 AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value)
242 ALCcontext *context;
244 context = GetContextRef();
245 if(!context) return;
247 if(!(value))
248 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
249 switch(param)
251 case AL_GAIN:
252 *value = context->Listener->Gain;
253 break;
255 case AL_METERS_PER_UNIT:
256 *value = context->Listener->MetersPerUnit;
257 break;
259 default:
260 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
263 done:
264 ALCcontext_DecRef(context);
268 AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3)
270 ALCcontext *context;
272 context = GetContextRef();
273 if(!context) return;
275 if(!(value1 && value2 && value3))
276 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
277 switch(param)
279 case AL_POSITION:
280 LockContext(context);
281 *value1 = context->Listener->Position.v[0];
282 *value2 = context->Listener->Position.v[1];
283 *value3 = context->Listener->Position.v[2];
284 UnlockContext(context);
285 break;
287 case AL_VELOCITY:
288 LockContext(context);
289 *value1 = context->Listener->Velocity.v[0];
290 *value2 = context->Listener->Velocity.v[1];
291 *value3 = context->Listener->Velocity.v[2];
292 UnlockContext(context);
293 break;
295 default:
296 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
299 done:
300 ALCcontext_DecRef(context);
304 AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values)
306 ALCcontext *context;
308 switch(param)
310 case AL_GAIN:
311 case AL_METERS_PER_UNIT:
312 alGetListenerf(param, values);
313 return;
315 case AL_POSITION:
316 case AL_VELOCITY:
317 alGetListener3f(param, values+0, values+1, values+2);
318 return;
321 context = GetContextRef();
322 if(!context) return;
324 if(!(values))
325 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
326 switch(param)
328 case AL_ORIENTATION:
329 LockContext(context);
330 // AT then UP
331 values[0] = context->Listener->Forward[0];
332 values[1] = context->Listener->Forward[1];
333 values[2] = context->Listener->Forward[2];
334 values[3] = context->Listener->Up[0];
335 values[4] = context->Listener->Up[1];
336 values[5] = context->Listener->Up[2];
337 UnlockContext(context);
338 break;
340 default:
341 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
344 done:
345 ALCcontext_DecRef(context);
349 AL_API ALvoid AL_APIENTRY alGetListeneri(ALenum param, ALint *value)
351 ALCcontext *context;
353 context = GetContextRef();
354 if(!context) return;
356 if(!(value))
357 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
358 switch(param)
360 default:
361 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
364 done:
365 ALCcontext_DecRef(context);
369 AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *value2, ALint *value3)
371 ALCcontext *context;
373 context = GetContextRef();
374 if(!context) return;
376 if(!(value1 && value2 && value3))
377 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
378 switch (param)
380 case AL_POSITION:
381 LockContext(context);
382 *value1 = (ALint)context->Listener->Position.v[0];
383 *value2 = (ALint)context->Listener->Position.v[1];
384 *value3 = (ALint)context->Listener->Position.v[2];
385 UnlockContext(context);
386 break;
388 case AL_VELOCITY:
389 LockContext(context);
390 *value1 = (ALint)context->Listener->Velocity.v[0];
391 *value2 = (ALint)context->Listener->Velocity.v[1];
392 *value3 = (ALint)context->Listener->Velocity.v[2];
393 UnlockContext(context);
394 break;
396 default:
397 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
400 done:
401 ALCcontext_DecRef(context);
405 AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint* values)
407 ALCcontext *context;
409 switch(param)
411 case AL_POSITION:
412 case AL_VELOCITY:
413 alGetListener3i(param, values+0, values+1, values+2);
414 return;
417 context = GetContextRef();
418 if(!context) return;
420 if(!(values))
421 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
422 switch(param)
424 case AL_ORIENTATION:
425 LockContext(context);
426 // AT then UP
427 values[0] = (ALint)context->Listener->Forward[0];
428 values[1] = (ALint)context->Listener->Forward[1];
429 values[2] = (ALint)context->Listener->Forward[2];
430 values[3] = (ALint)context->Listener->Up[0];
431 values[4] = (ALint)context->Listener->Up[1];
432 values[5] = (ALint)context->Listener->Up[2];
433 UnlockContext(context);
434 break;
436 default:
437 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
440 done:
441 ALCcontext_DecRef(context);