Fully progress the source to a stopped state when no buffers are playable
[openal-soft.git] / OpenAL32 / alListener.c
blobb3c192dc6f44a39fdb12872fd3c6d3179a726845
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 *pContext;
32 ALboolean updateAll = AL_FALSE;
34 pContext = GetContextSuspended();
35 if(!pContext) return;
37 switch(eParam)
39 case AL_GAIN:
40 if(flValue >= 0.0f)
42 pContext->Listener.Gain = flValue;
43 updateAll = AL_TRUE;
45 else
46 alSetError(pContext, AL_INVALID_VALUE);
47 break;
49 case AL_METERS_PER_UNIT:
50 if(flValue > 0.0f)
52 pContext->Listener.MetersPerUnit = flValue;
53 updateAll = AL_TRUE;
55 else
56 alSetError(pContext, AL_INVALID_VALUE);
57 break;
59 default:
60 alSetError(pContext, AL_INVALID_ENUM);
61 break;
64 // Force updating the sources for these parameters, since even head-
65 // relative sources are affected
66 if(updateAll)
68 ALsizei pos;
69 for(pos = 0;pos < pContext->SourceMap.size;pos++)
71 ALsource *source = pContext->SourceMap.array[pos].value;
72 source->NeedsUpdate = AL_TRUE;
76 ProcessContext(pContext);
80 AL_API ALvoid AL_APIENTRY alListener3f(ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
82 ALCcontext *pContext;
83 ALboolean updateWorld = AL_FALSE;
85 pContext = GetContextSuspended();
86 if(!pContext) return;
88 switch(eParam)
90 case AL_POSITION:
91 pContext->Listener.Position[0] = flValue1;
92 pContext->Listener.Position[1] = flValue2;
93 pContext->Listener.Position[2] = flValue3;
94 updateWorld = AL_TRUE;
95 break;
97 case AL_VELOCITY:
98 pContext->Listener.Velocity[0] = flValue1;
99 pContext->Listener.Velocity[1] = flValue2;
100 pContext->Listener.Velocity[2] = flValue3;
101 updateWorld = AL_TRUE;
102 break;
104 default:
105 alSetError(pContext, AL_INVALID_ENUM);
106 break;
109 if(updateWorld)
111 ALsizei pos;
112 for(pos = 0;pos < pContext->SourceMap.size;pos++)
114 ALsource *source = pContext->SourceMap.array[pos].value;
115 if(!source->bHeadRelative)
116 source->NeedsUpdate = AL_TRUE;
120 ProcessContext(pContext);
124 AL_API ALvoid AL_APIENTRY alListenerfv(ALenum eParam, const ALfloat *pflValues)
126 ALCcontext *pContext;
127 ALboolean updateWorld = AL_FALSE;
129 pContext = GetContextSuspended();
130 if(!pContext) return;
132 if(pflValues)
134 switch(eParam)
136 case AL_GAIN:
137 case AL_METERS_PER_UNIT:
138 alListenerf(eParam, pflValues[0]);
139 break;
141 case AL_POSITION:
142 case AL_VELOCITY:
143 alListener3f(eParam, pflValues[0], pflValues[1], pflValues[2]);
144 break;
146 case AL_ORIENTATION:
147 // AT then UP
148 pContext->Listener.Forward[0] = pflValues[0];
149 pContext->Listener.Forward[1] = pflValues[1];
150 pContext->Listener.Forward[2] = pflValues[2];
151 pContext->Listener.Up[0] = pflValues[3];
152 pContext->Listener.Up[1] = pflValues[4];
153 pContext->Listener.Up[2] = pflValues[5];
154 updateWorld = AL_TRUE;
155 break;
157 default:
158 alSetError(pContext, AL_INVALID_ENUM);
159 break;
162 else
163 alSetError(pContext, AL_INVALID_VALUE);
165 if(updateWorld)
167 ALsizei pos;
168 for(pos = 0;pos < pContext->SourceMap.size;pos++)
170 ALsource *source = pContext->SourceMap.array[pos].value;
171 if(!source->bHeadRelative)
172 source->NeedsUpdate = AL_TRUE;
176 ProcessContext(pContext);
180 AL_API ALvoid AL_APIENTRY alListeneri(ALenum eParam, ALint lValue)
182 ALCcontext *pContext;
184 (void)lValue;
186 pContext = GetContextSuspended();
187 if(!pContext) return;
189 switch(eParam)
191 default:
192 alSetError(pContext, AL_INVALID_ENUM);
193 break;
196 ProcessContext(pContext);
200 AL_API void AL_APIENTRY alListener3i(ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
202 ALCcontext *pContext;
204 pContext = GetContextSuspended();
205 if(!pContext) return;
207 switch(eParam)
209 case AL_POSITION:
210 case AL_VELOCITY:
211 alListener3f(eParam, (ALfloat)lValue1, (ALfloat)lValue2, (ALfloat)lValue3);
212 break;
214 default:
215 alSetError(pContext, AL_INVALID_ENUM);
216 break;
219 ProcessContext(pContext);
223 AL_API void AL_APIENTRY alListeneriv( ALenum eParam, const ALint* plValues )
225 ALCcontext *pContext;
226 ALfloat flValues[6];
228 pContext = GetContextSuspended();
229 if(!pContext) return;
231 if(plValues)
233 switch(eParam)
235 case AL_POSITION:
236 case AL_VELOCITY:
237 flValues[0] = (ALfloat)plValues[0];
238 flValues[1] = (ALfloat)plValues[1];
239 flValues[2] = (ALfloat)plValues[2];
240 alListenerfv(eParam, flValues);
241 break;
243 case AL_ORIENTATION:
244 flValues[0] = (ALfloat)plValues[0];
245 flValues[1] = (ALfloat)plValues[1];
246 flValues[2] = (ALfloat)plValues[2];
247 flValues[3] = (ALfloat)plValues[3];
248 flValues[4] = (ALfloat)plValues[4];
249 flValues[5] = (ALfloat)plValues[5];
250 alListenerfv(eParam, flValues);
251 break;
253 default:
254 alSetError(pContext, AL_INVALID_ENUM);
255 break;
258 else
259 alSetError(pContext, AL_INVALID_VALUE);
261 ProcessContext(pContext);
265 AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum eParam, ALfloat *pflValue)
267 ALCcontext *pContext;
269 pContext = GetContextSuspended();
270 if(!pContext) return;
272 if(pflValue)
274 switch(eParam)
276 case AL_GAIN:
277 *pflValue = pContext->Listener.Gain;
278 break;
280 case AL_METERS_PER_UNIT:
281 *pflValue = pContext->Listener.MetersPerUnit;
282 break;
284 default:
285 alSetError(pContext, AL_INVALID_ENUM);
286 break;
289 else
290 alSetError(pContext, AL_INVALID_VALUE);
292 ProcessContext(pContext);
296 AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum eParam, ALfloat *pflValue1, ALfloat *pflValue2, ALfloat *pflValue3)
298 ALCcontext *pContext;
300 pContext = GetContextSuspended();
301 if(!pContext) return;
303 if(pflValue1 && pflValue2 && pflValue3)
305 switch(eParam)
307 case AL_POSITION:
308 *pflValue1 = pContext->Listener.Position[0];
309 *pflValue2 = pContext->Listener.Position[1];
310 *pflValue3 = pContext->Listener.Position[2];
311 break;
313 case AL_VELOCITY:
314 *pflValue1 = pContext->Listener.Velocity[0];
315 *pflValue2 = pContext->Listener.Velocity[1];
316 *pflValue3 = pContext->Listener.Velocity[2];
317 break;
319 default:
320 alSetError(pContext, AL_INVALID_ENUM);
321 break;
324 else
325 alSetError(pContext, AL_INVALID_VALUE);
327 ProcessContext(pContext);
331 AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum eParam, ALfloat *pflValues)
333 ALCcontext *pContext;
335 pContext = GetContextSuspended();
336 if(!pContext) return;
338 if(pflValues)
340 switch(eParam)
342 case AL_GAIN:
343 pflValues[0] = pContext->Listener.Gain;
344 break;
346 case AL_METERS_PER_UNIT:
347 pflValues[0] = pContext->Listener.MetersPerUnit;
348 break;
350 case AL_POSITION:
351 pflValues[0] = pContext->Listener.Position[0];
352 pflValues[1] = pContext->Listener.Position[1];
353 pflValues[2] = pContext->Listener.Position[2];
354 break;
356 case AL_VELOCITY:
357 pflValues[0] = pContext->Listener.Velocity[0];
358 pflValues[1] = pContext->Listener.Velocity[1];
359 pflValues[2] = pContext->Listener.Velocity[2];
360 break;
362 case AL_ORIENTATION:
363 // AT then UP
364 pflValues[0] = pContext->Listener.Forward[0];
365 pflValues[1] = pContext->Listener.Forward[1];
366 pflValues[2] = pContext->Listener.Forward[2];
367 pflValues[3] = pContext->Listener.Up[0];
368 pflValues[4] = pContext->Listener.Up[1];
369 pflValues[5] = pContext->Listener.Up[2];
370 break;
372 default:
373 alSetError(pContext, AL_INVALID_ENUM);
374 break;
377 else
378 alSetError(pContext, AL_INVALID_VALUE);
380 ProcessContext(pContext);
384 AL_API ALvoid AL_APIENTRY alGetListeneri(ALenum eParam, ALint *plValue)
386 ALCcontext *pContext;
388 pContext = GetContextSuspended();
389 if(!pContext) return;
391 if(plValue)
393 switch(eParam)
395 default:
396 alSetError(pContext, AL_INVALID_ENUM);
397 break;
400 else
401 alSetError(pContext, AL_INVALID_VALUE);
403 ProcessContext(pContext);
407 AL_API void AL_APIENTRY alGetListener3i(ALenum eParam, ALint *plValue1, ALint *plValue2, ALint *plValue3)
409 ALCcontext *pContext;
411 pContext = GetContextSuspended();
412 if(!pContext) return;
414 if(plValue1 && plValue2 && plValue3)
416 switch (eParam)
418 case AL_POSITION:
419 *plValue1 = (ALint)pContext->Listener.Position[0];
420 *plValue2 = (ALint)pContext->Listener.Position[1];
421 *plValue3 = (ALint)pContext->Listener.Position[2];
422 break;
424 case AL_VELOCITY:
425 *plValue1 = (ALint)pContext->Listener.Velocity[0];
426 *plValue2 = (ALint)pContext->Listener.Velocity[1];
427 *plValue3 = (ALint)pContext->Listener.Velocity[2];
428 break;
430 default:
431 alSetError(pContext, AL_INVALID_ENUM);
432 break;
435 else
436 alSetError(pContext, AL_INVALID_VALUE);
438 ProcessContext(pContext);
442 AL_API void AL_APIENTRY alGetListeneriv(ALenum eParam, ALint* plValues)
444 ALCcontext *pContext;
446 pContext = GetContextSuspended();
447 if(!pContext) return;
449 if(plValues)
451 switch(eParam)
453 case AL_POSITION:
454 plValues[0] = (ALint)pContext->Listener.Position[0];
455 plValues[1] = (ALint)pContext->Listener.Position[1];
456 plValues[2] = (ALint)pContext->Listener.Position[2];
457 break;
459 case AL_VELOCITY:
460 plValues[0] = (ALint)pContext->Listener.Velocity[0];
461 plValues[1] = (ALint)pContext->Listener.Velocity[1];
462 plValues[2] = (ALint)pContext->Listener.Velocity[2];
463 break;
465 case AL_ORIENTATION:
466 // AT then UP
467 plValues[0] = (ALint)pContext->Listener.Forward[0];
468 plValues[1] = (ALint)pContext->Listener.Forward[1];
469 plValues[2] = (ALint)pContext->Listener.Forward[2];
470 plValues[3] = (ALint)pContext->Listener.Up[0];
471 plValues[4] = (ALint)pContext->Listener.Up[1];
472 plValues[5] = (ALint)pContext->Listener.Up[2];
473 break;
475 default:
476 alSetError(pContext, AL_INVALID_ENUM);
477 break;
480 else
481 alSetError(pContext, AL_INVALID_VALUE);
483 ProcessContext(pContext);