Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/openal-0.0.8/src/al_listen.c @ 17

Last change on this file since 17 was 17, checked in by landauf, 16 years ago

added openal

File size: 6.8 KB
Line 
1
2/* -*- mode: C; tab-width:8; c-basic-offset:8 -*-
3 * vi:set ts=8:
4 *
5 * al_listen.c
6 *
7 * Functions related to management and use of listeners.
8 */
9#include "al_siteconfig.h"
10
11#include <AL/al.h>
12#include <AL/alext.h>
13#include <stdlib.h>
14
15#include "al_error.h"
16#include "al_listen.h"
17#include "al_main.h"
18#include "alc/alc_speaker.h"
19
20#define MAX_LISTENER_NUM_VALUES 6
21
22static ALint
23numValuesForAttribute( ALenum param )
24{
25        switch (param) {
26        case AL_POSITION:
27        case AL_VELOCITY:
28                return 3;
29        case AL_GAIN:
30        case AL_GAIN_LINEAR_LOKI:
31                return 1;
32        case AL_ORIENTATION:
33                return 6;
34                break;
35        default:
36                return 0;
37        }
38}
39
40static void
41setListenerAttributef( ALenum param, const ALfloat *values, ALint numValues)
42{
43        /* TODO: As usual, we should better have a getter for a *locked* context */
44        AL_context *cc = _alcDCGetContext();
45        if( cc == NULL ) {
46                _alDCSetError(AL_INVALID_OPERATION);
47                return;
48        }
49        _alcDCLockContext();
50
51        if (numValues != numValuesForAttribute(param)) {
52                _alDCSetError(AL_INVALID_ENUM);
53                _alcDCUnlockContext();
54                return;
55        }
56        if( values == NULL ) {
57                _alDCSetError(AL_INVALID_VALUE);
58                _alcDCUnlockContext();
59                return;
60        }
61
62        switch( param ) {
63        case AL_POSITION:
64                if ((cc->listener.position[0] == values[0]) &&
65                    (cc->listener.position[1] == values[1]) &&
66                    (cc->listener.position[2] == values[2])) {
67                        break;
68                }
69                cc->listener.position[0] = values[0];
70                cc->listener.position[1] = values[1];
71                cc->listener.position[2] = values[2];
72                _alcDCSpeakerMove();
73                break;
74
75        case AL_VELOCITY:
76                cc->listener.velocity[0] = values[0];
77                cc->listener.velocity[1] = values[1];
78                cc->listener.velocity[2] = values[2];
79                break;
80
81        case AL_GAIN:
82        case AL_GAIN_LINEAR_LOKI:
83                if (values[0] < 0.0f) {
84                        _alDCSetError(AL_INVALID_VALUE);
85                        break;
86                }
87                cc->listener.gain = values[0];
88                break;
89
90        case AL_ORIENTATION:
91                if ((cc->listener.orientation[0] == values[0]) &&
92                    (cc->listener.orientation[1] == values[1]) &&
93                    (cc->listener.orientation[2] == values[2]) &&
94                    (cc->listener.orientation[3] == values[3]) &&
95                    (cc->listener.orientation[4] == values[4]) &&
96                    (cc->listener.orientation[5] == values[5])) {
97                        break;
98                }
99                cc->listener.orientation[0] = values[0]; /* at */
100                cc->listener.orientation[1] = values[1];
101                cc->listener.orientation[2] = values[2];
102                cc->listener.orientation[3] = values[3]; /* up */
103                cc->listener.orientation[4] = values[4];
104                cc->listener.orientation[5] = values[5];
105                _alcDCSpeakerMove();
106                break;
107
108        default:
109                _alDCSetError( AL_INVALID_ENUM );
110                break;
111        }
112
113        _alcDCUnlockContext();
114}
115
116static void
117setListenerAttributei( ALenum param, const ALint *intValues, ALint numValues)
118{
119        ALfloat floatValues[MAX_LISTENER_NUM_VALUES];
120        int i;
121        for (i = 0; i < numValues; i++) {
122                floatValues[i] = (ALfloat)intValues[i];
123        }
124        setListenerAttributef(param, floatValues, numValues);
125}
126
127void
128alListenerf( ALenum param, ALfloat value )
129{
130        setListenerAttributef(param, &value, 1);
131}
132
133void
134alListener3f( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 )
135{
136        ALfloat values[3];
137        values[0] = value1;
138        values[1] = value2;
139        values[2] = value3;
140        setListenerAttributef(param, values, 3);
141}
142
143void
144alListenerfv( ALenum param, const ALfloat *values )
145{
146        setListenerAttributef(param, values, numValuesForAttribute(param));
147}
148 
149void
150alListeneri( ALenum param, ALint value )
151{
152        setListenerAttributei(param, &value, 1);
153}
154
155void
156alListener3i( ALenum param, ALint value1, ALint value2, ALint value3 )
157{
158        ALint values[3];
159        values[0] = value1;
160        values[1] = value2;
161        values[2] = value3;
162        setListenerAttributei(param, values, 3);
163}
164
165void
166alListeneriv( ALenum param, const ALint *values )
167{
168        setListenerAttributei(param, values, numValuesForAttribute(param));
169}
170
171static ALboolean
172getListenerAttribute( ALenum param, ALfloat *values, ALint numValues )
173{
174        ALboolean ok = AL_FALSE;
175        /* TODO: As usual, we should better have a getter for a *locked* context */
176        AL_context *cc = _alcDCGetContext();
177        if( cc == NULL ) {
178                _alDCSetError(AL_INVALID_OPERATION);
179                return ok;
180        }
181        _alcDCLockContext();
182
183        if (numValues != numValuesForAttribute(param)) {
184                _alDCSetError(AL_INVALID_ENUM);
185                _alcDCUnlockContext();
186                return ok;
187        }
188        if( values == NULL ) {
189                _alDCSetError(AL_INVALID_VALUE);
190                _alcDCUnlockContext();
191                return ok;
192        }
193
194        switch( param ) {
195        case AL_POSITION:
196                values[0] = cc->listener.position[0];
197                values[1] = cc->listener.position[1];
198                values[2] = cc->listener.position[2];
199                ok = AL_TRUE;
200                break;
201
202        case AL_VELOCITY:
203                values[0] = cc->listener.velocity[0];
204                values[1] = cc->listener.velocity[1];
205                values[2] = cc->listener.velocity[2];
206                ok = AL_TRUE;
207                break;
208
209        case AL_GAIN:
210        case AL_GAIN_LINEAR_LOKI:
211                values[0] = cc->listener.gain;
212                ok = AL_TRUE;
213                break;
214
215        case AL_ORIENTATION:
216                values[0] = cc->listener.orientation[0]; /* at */
217                values[1] = cc->listener.orientation[1];
218                values[2] = cc->listener.orientation[2];
219                values[3] = cc->listener.orientation[3]; /* up */
220                values[4] = cc->listener.orientation[4];
221                values[5] = cc->listener.orientation[5];
222                ok = AL_TRUE;
223                break;
224
225        default:
226                _alDCSetError( AL_INVALID_ENUM );
227                break;
228        }
229
230        _alcDCUnlockContext();
231        return ok;
232}
233
234void
235alGetListenerf( ALenum param, ALfloat *value )
236{
237        getListenerAttribute(param, value, 1);
238}
239
240void
241alGetListener3f( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 )
242{
243        ALfloat floatValues[3];
244        if (getListenerAttribute(param, floatValues, 3)) {
245                *value1 = floatValues[0];
246                *value2 = floatValues[1];
247                *value3 = floatValues[2];
248        }
249}
250
251void
252alGetListenerfv( ALenum param, ALfloat *values )
253{
254        getListenerAttribute(param, values, numValuesForAttribute(param));
255}
256
257void
258alGetListeneri( ALenum param, ALint *value )
259{
260        ALfloat floatValues[1];
261        if (getListenerAttribute(param, floatValues, 1)) {
262                *value = floatValues[0];
263        }
264}
265
266void
267alGetListener3i( ALenum param, ALint *value1, ALint *value2, ALint *value3 )
268{
269        ALfloat floatValues[3];
270        if (getListenerAttribute(param, floatValues, 3)) {
271                *value1 = (ALint)floatValues[0];
272                *value2 = (ALint)floatValues[1];
273                *value3 = (ALint)floatValues[2];
274        }
275}
276
277void
278alGetListeneriv( ALenum param, ALint *values )
279{
280        ALfloat floatValues[MAX_LISTENER_NUM_VALUES];
281        int i;
282        int n = numValuesForAttribute(param);
283        if (getListenerAttribute(param, floatValues, n)) {
284                for (i = 0; i < n; i++) {
285                        values[i] = (ALint)floatValues[i];
286                }
287        }
288}
289
290/*
291 * Initializes already allocated listener.
292 */
293void
294_alInitListener( AL_listener *listener )
295{
296        listener->position[0] = 0.0f;
297        listener->position[1] = 0.0f;
298        listener->position[2] = 0.0f;
299
300        listener->velocity[0] = 0.0f;
301        listener->velocity[1] = 0.0f;
302        listener->velocity[2] = 0.0f;
303
304        listener->gain = 1.0f;
305
306        /* at */
307        listener->orientation[0] = 0.0f;
308        listener->orientation[1] = 0.0f;
309        listener->orientation[2] = -1.0f;
310
311        /* up */
312        listener->orientation[3] = 0.0f;
313        listener->orientation[4] = 1.0f;
314        listener->orientation[5] = 0.0f;
315}
316
317/*
318 * Doesn't do anything.
319 */
320void
321_alDestroyListener(UNUSED(AL_listener *ls))
322{
323}
Note: See TracBrowser for help on using the repository browser.