rlm@0
|
1 /**
|
rlm@0
|
2 * OpenAL cross platform audio library
|
rlm@0
|
3 * Copyright (C) 1999-2007 by authors.
|
rlm@0
|
4 * This library is free software; you can redistribute it and/or
|
rlm@0
|
5 * modify it under the terms of the GNU Library General Public
|
rlm@0
|
6 * License as published by the Free Software Foundation; either
|
rlm@0
|
7 * version 2 of the License, or (at your option) any later version.
|
rlm@0
|
8 *
|
rlm@0
|
9 * This library is distributed in the hope that it will be useful,
|
rlm@0
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
rlm@0
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
rlm@0
|
12 * Library General Public License for more details.
|
rlm@0
|
13 *
|
rlm@0
|
14 * You should have received a copy of the GNU Library General Public
|
rlm@0
|
15 * License along with this library; if not, write to the
|
rlm@0
|
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
rlm@0
|
17 * Boston, MA 02111-1307, USA.
|
rlm@0
|
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
|
rlm@0
|
19 */
|
rlm@0
|
20
|
rlm@0
|
21 #include "config.h"
|
rlm@0
|
22
|
rlm@0
|
23 #include <stdlib.h>
|
rlm@0
|
24 #include <math.h>
|
rlm@0
|
25
|
rlm@0
|
26 #include "AL/al.h"
|
rlm@0
|
27 #include "AL/alc.h"
|
rlm@0
|
28 #include "alMain.h"
|
rlm@0
|
29 #include "alAuxEffectSlot.h"
|
rlm@0
|
30 #include "alThunk.h"
|
rlm@0
|
31 #include "alError.h"
|
rlm@0
|
32 #include "alSource.h"
|
rlm@0
|
33
|
rlm@0
|
34
|
rlm@0
|
35 static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect);
|
rlm@0
|
36
|
rlm@0
|
37 #define LookupEffectSlot(m, k) ((ALeffectslot*)LookupUIntMapKey(&(m), (k)))
|
rlm@0
|
38 #define LookupEffect(m, k) ((ALeffect*)LookupUIntMapKey(&(m), (k)))
|
rlm@0
|
39
|
rlm@0
|
40 AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
|
rlm@0
|
41 {
|
rlm@0
|
42 ALCcontext *Context;
|
rlm@0
|
43 ALCdevice *Device;
|
rlm@0
|
44
|
rlm@0
|
45 Context = GetLockedContext();
|
rlm@0
|
46 if(!Context) return;
|
rlm@0
|
47
|
rlm@0
|
48 Device = Context->Device;
|
rlm@0
|
49 if(n < 0 || IsBadWritePtr((void*)effectslots, n * sizeof(ALuint)))
|
rlm@0
|
50 alSetError(Context, AL_INVALID_VALUE);
|
rlm@0
|
51 else if((ALuint)n > Device->AuxiliaryEffectSlotMax - Context->EffectSlotMap.size)
|
rlm@0
|
52 alSetError(Context, AL_INVALID_VALUE);
|
rlm@0
|
53 else
|
rlm@0
|
54 {
|
rlm@0
|
55 ALenum err;
|
rlm@0
|
56 ALsizei i, j;
|
rlm@0
|
57
|
rlm@0
|
58 i = 0;
|
rlm@0
|
59 while(i < n)
|
rlm@0
|
60 {
|
rlm@0
|
61 ALeffectslot *slot = calloc(1, sizeof(ALeffectslot));
|
rlm@0
|
62 if(!slot || !(slot->EffectState=NoneCreate()))
|
rlm@0
|
63 {
|
rlm@0
|
64 free(slot);
|
rlm@0
|
65 // We must have run out or memory
|
rlm@0
|
66 alSetError(Context, AL_OUT_OF_MEMORY);
|
rlm@0
|
67 alDeleteAuxiliaryEffectSlots(i, effectslots);
|
rlm@0
|
68 break;
|
rlm@0
|
69 }
|
rlm@0
|
70
|
rlm@0
|
71 err = NewThunkEntry(&slot->effectslot);
|
rlm@0
|
72 if(err == AL_NO_ERROR)
|
rlm@0
|
73 err = InsertUIntMapEntry(&Context->EffectSlotMap, slot->effectslot, slot);
|
rlm@0
|
74 if(err != AL_NO_ERROR)
|
rlm@0
|
75 {
|
rlm@0
|
76 FreeThunkEntry(slot->effectslot);
|
rlm@0
|
77 ALEffect_Destroy(slot->EffectState);
|
rlm@0
|
78 free(slot);
|
rlm@0
|
79
|
rlm@0
|
80 alSetError(Context, err);
|
rlm@0
|
81 alDeleteAuxiliaryEffectSlots(i, effectslots);
|
rlm@0
|
82 break;
|
rlm@0
|
83 }
|
rlm@0
|
84
|
rlm@0
|
85 effectslots[i++] = slot->effectslot;
|
rlm@0
|
86
|
rlm@0
|
87 slot->Gain = 1.0;
|
rlm@0
|
88 slot->AuxSendAuto = AL_TRUE;
|
rlm@0
|
89 slot->NeedsUpdate = AL_FALSE;
|
rlm@0
|
90 for(j = 0;j < BUFFERSIZE;j++)
|
rlm@0
|
91 slot->WetBuffer[j] = 0.0f;
|
rlm@0
|
92 for(j = 0;j < 1;j++)
|
rlm@0
|
93 {
|
rlm@0
|
94 slot->ClickRemoval[j] = 0.0f;
|
rlm@0
|
95 slot->PendingClicks[j] = 0.0f;
|
rlm@0
|
96 }
|
rlm@0
|
97 slot->refcount = 0;
|
rlm@0
|
98 }
|
rlm@0
|
99 }
|
rlm@0
|
100
|
rlm@0
|
101 UnlockContext(Context);
|
rlm@0
|
102 }
|
rlm@0
|
103
|
rlm@0
|
104 AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
|
rlm@0
|
105 {
|
rlm@0
|
106 ALCcontext *Context;
|
rlm@0
|
107 ALeffectslot *EffectSlot;
|
rlm@0
|
108 ALboolean SlotsValid = AL_FALSE;
|
rlm@0
|
109 ALsizei i;
|
rlm@0
|
110
|
rlm@0
|
111 Context = GetLockedContext();
|
rlm@0
|
112 if(!Context) return;
|
rlm@0
|
113
|
rlm@0
|
114 if(n < 0)
|
rlm@0
|
115 alSetError(Context, AL_INVALID_VALUE);
|
rlm@0
|
116 else
|
rlm@0
|
117 {
|
rlm@0
|
118 SlotsValid = AL_TRUE;
|
rlm@0
|
119 // Check that all effectslots are valid
|
rlm@0
|
120 for(i = 0;i < n;i++)
|
rlm@0
|
121 {
|
rlm@0
|
122 if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslots[i])) == NULL)
|
rlm@0
|
123 {
|
rlm@0
|
124 alSetError(Context, AL_INVALID_NAME);
|
rlm@0
|
125 SlotsValid = AL_FALSE;
|
rlm@0
|
126 break;
|
rlm@0
|
127 }
|
rlm@0
|
128 else if(EffectSlot->refcount > 0)
|
rlm@0
|
129 {
|
rlm@0
|
130 alSetError(Context, AL_INVALID_NAME);
|
rlm@0
|
131 SlotsValid = AL_FALSE;
|
rlm@0
|
132 break;
|
rlm@0
|
133 }
|
rlm@0
|
134 }
|
rlm@0
|
135 }
|
rlm@0
|
136
|
rlm@0
|
137 if(SlotsValid)
|
rlm@0
|
138 {
|
rlm@0
|
139 // All effectslots are valid
|
rlm@0
|
140 for(i = 0;i < n;i++)
|
rlm@0
|
141 {
|
rlm@0
|
142 // Recheck that the effectslot is valid, because there could be duplicated names
|
rlm@0
|
143 if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslots[i])) == NULL)
|
rlm@0
|
144 continue;
|
rlm@0
|
145
|
rlm@0
|
146 ALEffect_Destroy(EffectSlot->EffectState);
|
rlm@0
|
147
|
rlm@0
|
148 RemoveUIntMapKey(&Context->EffectSlotMap, EffectSlot->effectslot);
|
rlm@0
|
149 FreeThunkEntry(EffectSlot->effectslot);
|
rlm@0
|
150
|
rlm@0
|
151 memset(EffectSlot, 0, sizeof(ALeffectslot));
|
rlm@0
|
152 free(EffectSlot);
|
rlm@0
|
153 }
|
rlm@0
|
154 }
|
rlm@0
|
155
|
rlm@0
|
156 UnlockContext(Context);
|
rlm@0
|
157 }
|
rlm@0
|
158
|
rlm@0
|
159 AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot)
|
rlm@0
|
160 {
|
rlm@0
|
161 ALCcontext *Context;
|
rlm@0
|
162 ALboolean result;
|
rlm@0
|
163
|
rlm@0
|
164 Context = GetLockedContext();
|
rlm@0
|
165 if(!Context) return AL_FALSE;
|
rlm@0
|
166
|
rlm@0
|
167 result = (LookupEffectSlot(Context->EffectSlotMap, effectslot) ?
|
rlm@0
|
168 AL_TRUE : AL_FALSE);
|
rlm@0
|
169
|
rlm@0
|
170 UnlockContext(Context);
|
rlm@0
|
171
|
rlm@0
|
172 return result;
|
rlm@0
|
173 }
|
rlm@0
|
174
|
rlm@0
|
175 AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue)
|
rlm@0
|
176 {
|
rlm@0
|
177 ALCdevice *Device;
|
rlm@0
|
178 ALCcontext *Context;
|
rlm@0
|
179 ALeffectslot *EffectSlot;
|
rlm@0
|
180
|
rlm@0
|
181 Context = GetLockedContext();
|
rlm@0
|
182 if(!Context) return;
|
rlm@0
|
183
|
rlm@0
|
184 Device = Context->Device;
|
rlm@0
|
185 if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslot)) != NULL)
|
rlm@0
|
186 {
|
rlm@0
|
187 switch(param)
|
rlm@0
|
188 {
|
rlm@0
|
189 case AL_EFFECTSLOT_EFFECT: {
|
rlm@0
|
190 ALeffect *effect = NULL;
|
rlm@0
|
191
|
rlm@0
|
192 if(iValue == 0 ||
|
rlm@0
|
193 (effect=LookupEffect(Device->EffectMap, iValue)) != NULL)
|
rlm@0
|
194 {
|
rlm@0
|
195 InitializeEffect(Context, EffectSlot, effect);
|
rlm@0
|
196 Context->UpdateSources = AL_TRUE;
|
rlm@0
|
197 }
|
rlm@0
|
198 else
|
rlm@0
|
199 alSetError(Context, AL_INVALID_VALUE);
|
rlm@0
|
200 } break;
|
rlm@0
|
201
|
rlm@0
|
202 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
|
rlm@0
|
203 if(iValue == AL_TRUE || iValue == AL_FALSE)
|
rlm@0
|
204 {
|
rlm@0
|
205 EffectSlot->AuxSendAuto = iValue;
|
rlm@0
|
206 Context->UpdateSources = AL_TRUE;
|
rlm@0
|
207 }
|
rlm@0
|
208 else
|
rlm@0
|
209 alSetError(Context, AL_INVALID_VALUE);
|
rlm@0
|
210 break;
|
rlm@0
|
211
|
rlm@0
|
212 default:
|
rlm@0
|
213 alSetError(Context, AL_INVALID_ENUM);
|
rlm@0
|
214 break;
|
rlm@0
|
215 }
|
rlm@0
|
216 }
|
rlm@0
|
217 else
|
rlm@0
|
218 alSetError(Context, AL_INVALID_NAME);
|
rlm@0
|
219
|
rlm@0
|
220 UnlockContext(Context);
|
rlm@0
|
221 }
|
rlm@0
|
222
|
rlm@0
|
223 AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues)
|
rlm@0
|
224 {
|
rlm@0
|
225 ALCcontext *Context;
|
rlm@0
|
226
|
rlm@0
|
227 switch(param)
|
rlm@0
|
228 {
|
rlm@0
|
229 case AL_EFFECTSLOT_EFFECT:
|
rlm@0
|
230 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
|
rlm@0
|
231 alAuxiliaryEffectSloti(effectslot, param, piValues[0]);
|
rlm@0
|
232 return;
|
rlm@0
|
233 }
|
rlm@0
|
234
|
rlm@0
|
235 Context = GetLockedContext();
|
rlm@0
|
236 if(!Context) return;
|
rlm@0
|
237
|
rlm@0
|
238 if(LookupEffectSlot(Context->EffectSlotMap, effectslot) != NULL)
|
rlm@0
|
239 {
|
rlm@0
|
240 switch(param)
|
rlm@0
|
241 {
|
rlm@0
|
242 default:
|
rlm@0
|
243 alSetError(Context, AL_INVALID_ENUM);
|
rlm@0
|
244 break;
|
rlm@0
|
245 }
|
rlm@0
|
246 }
|
rlm@0
|
247 else
|
rlm@0
|
248 alSetError(Context, AL_INVALID_NAME);
|
rlm@0
|
249
|
rlm@0
|
250 UnlockContext(Context);
|
rlm@0
|
251 }
|
rlm@0
|
252
|
rlm@0
|
253 AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue)
|
rlm@0
|
254 {
|
rlm@0
|
255 ALCcontext *Context;
|
rlm@0
|
256 ALeffectslot *EffectSlot;
|
rlm@0
|
257
|
rlm@0
|
258 Context = GetLockedContext();
|
rlm@0
|
259 if(!Context) return;
|
rlm@0
|
260
|
rlm@0
|
261 if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslot)) != NULL)
|
rlm@0
|
262 {
|
rlm@0
|
263 switch(param)
|
rlm@0
|
264 {
|
rlm@0
|
265 case AL_EFFECTSLOT_GAIN:
|
rlm@0
|
266 if(flValue >= 0.0f && flValue <= 1.0f)
|
rlm@0
|
267 {
|
rlm@0
|
268 EffectSlot->Gain = flValue;
|
rlm@0
|
269 EffectSlot->NeedsUpdate = AL_TRUE;
|
rlm@0
|
270 }
|
rlm@0
|
271 else
|
rlm@0
|
272 alSetError(Context, AL_INVALID_VALUE);
|
rlm@0
|
273 break;
|
rlm@0
|
274
|
rlm@0
|
275 default:
|
rlm@0
|
276 alSetError(Context, AL_INVALID_ENUM);
|
rlm@0
|
277 break;
|
rlm@0
|
278 }
|
rlm@0
|
279 }
|
rlm@0
|
280 else
|
rlm@0
|
281 alSetError(Context, AL_INVALID_NAME);
|
rlm@0
|
282
|
rlm@0
|
283 UnlockContext(Context);
|
rlm@0
|
284 }
|
rlm@0
|
285
|
rlm@0
|
286 AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues)
|
rlm@0
|
287 {
|
rlm@0
|
288 ALCcontext *Context;
|
rlm@0
|
289
|
rlm@0
|
290 switch(param)
|
rlm@0
|
291 {
|
rlm@0
|
292 case AL_EFFECTSLOT_GAIN:
|
rlm@0
|
293 alAuxiliaryEffectSlotf(effectslot, param, pflValues[0]);
|
rlm@0
|
294 return;
|
rlm@0
|
295 }
|
rlm@0
|
296
|
rlm@0
|
297 Context = GetLockedContext();
|
rlm@0
|
298 if(!Context) return;
|
rlm@0
|
299
|
rlm@0
|
300 if(LookupEffectSlot(Context->EffectSlotMap, effectslot) != NULL)
|
rlm@0
|
301 {
|
rlm@0
|
302 switch(param)
|
rlm@0
|
303 {
|
rlm@0
|
304 default:
|
rlm@0
|
305 alSetError(Context, AL_INVALID_ENUM);
|
rlm@0
|
306 break;
|
rlm@0
|
307 }
|
rlm@0
|
308 }
|
rlm@0
|
309 else
|
rlm@0
|
310 alSetError(Context, AL_INVALID_NAME);
|
rlm@0
|
311
|
rlm@0
|
312 UnlockContext(Context);
|
rlm@0
|
313 }
|
rlm@0
|
314
|
rlm@0
|
315 AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue)
|
rlm@0
|
316 {
|
rlm@0
|
317 ALCcontext *Context;
|
rlm@0
|
318 ALeffectslot *EffectSlot;
|
rlm@0
|
319
|
rlm@0
|
320 Context = GetLockedContext();
|
rlm@0
|
321 if(!Context) return;
|
rlm@0
|
322
|
rlm@0
|
323 if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslot)) != NULL)
|
rlm@0
|
324 {
|
rlm@0
|
325 switch(param)
|
rlm@0
|
326 {
|
rlm@0
|
327 case AL_EFFECTSLOT_EFFECT:
|
rlm@0
|
328 *piValue = EffectSlot->effect.effect;
|
rlm@0
|
329 break;
|
rlm@0
|
330
|
rlm@0
|
331 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
|
rlm@0
|
332 *piValue = EffectSlot->AuxSendAuto;
|
rlm@0
|
333 break;
|
rlm@0
|
334
|
rlm@0
|
335 default:
|
rlm@0
|
336 alSetError(Context, AL_INVALID_ENUM);
|
rlm@0
|
337 break;
|
rlm@0
|
338 }
|
rlm@0
|
339 }
|
rlm@0
|
340 else
|
rlm@0
|
341 alSetError(Context, AL_INVALID_NAME);
|
rlm@0
|
342
|
rlm@0
|
343 UnlockContext(Context);
|
rlm@0
|
344 }
|
rlm@0
|
345
|
rlm@0
|
346 AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues)
|
rlm@0
|
347 {
|
rlm@0
|
348 ALCcontext *Context;
|
rlm@0
|
349
|
rlm@0
|
350 switch(param)
|
rlm@0
|
351 {
|
rlm@0
|
352 case AL_EFFECTSLOT_EFFECT:
|
rlm@0
|
353 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
|
rlm@0
|
354 alGetAuxiliaryEffectSloti(effectslot, param, piValues);
|
rlm@0
|
355 return;
|
rlm@0
|
356 }
|
rlm@0
|
357
|
rlm@0
|
358 Context = GetLockedContext();
|
rlm@0
|
359 if(!Context) return;
|
rlm@0
|
360
|
rlm@0
|
361 if(LookupEffectSlot(Context->EffectSlotMap, effectslot) != NULL)
|
rlm@0
|
362 {
|
rlm@0
|
363 switch(param)
|
rlm@0
|
364 {
|
rlm@0
|
365 default:
|
rlm@0
|
366 alSetError(Context, AL_INVALID_ENUM);
|
rlm@0
|
367 break;
|
rlm@0
|
368 }
|
rlm@0
|
369 }
|
rlm@0
|
370 else
|
rlm@0
|
371 alSetError(Context, AL_INVALID_NAME);
|
rlm@0
|
372
|
rlm@0
|
373 UnlockContext(Context);
|
rlm@0
|
374 }
|
rlm@0
|
375
|
rlm@0
|
376 AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue)
|
rlm@0
|
377 {
|
rlm@0
|
378 ALCcontext *Context;
|
rlm@0
|
379 ALeffectslot *EffectSlot;
|
rlm@0
|
380
|
rlm@0
|
381 Context = GetLockedContext();
|
rlm@0
|
382 if(!Context) return;
|
rlm@0
|
383
|
rlm@0
|
384 if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslot)) != NULL)
|
rlm@0
|
385 {
|
rlm@0
|
386 switch(param)
|
rlm@0
|
387 {
|
rlm@0
|
388 case AL_EFFECTSLOT_GAIN:
|
rlm@0
|
389 *pflValue = EffectSlot->Gain;
|
rlm@0
|
390 break;
|
rlm@0
|
391
|
rlm@0
|
392 default:
|
rlm@0
|
393 alSetError(Context, AL_INVALID_ENUM);
|
rlm@0
|
394 break;
|
rlm@0
|
395 }
|
rlm@0
|
396 }
|
rlm@0
|
397 else
|
rlm@0
|
398 alSetError(Context, AL_INVALID_NAME);
|
rlm@0
|
399
|
rlm@0
|
400 UnlockContext(Context);
|
rlm@0
|
401 }
|
rlm@0
|
402
|
rlm@0
|
403 AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues)
|
rlm@0
|
404 {
|
rlm@0
|
405 ALCcontext *Context;
|
rlm@0
|
406
|
rlm@0
|
407 switch(param)
|
rlm@0
|
408 {
|
rlm@0
|
409 case AL_EFFECTSLOT_GAIN:
|
rlm@0
|
410 alGetAuxiliaryEffectSlotf(effectslot, param, pflValues);
|
rlm@0
|
411 return;
|
rlm@0
|
412 }
|
rlm@0
|
413
|
rlm@0
|
414 Context = GetLockedContext();
|
rlm@0
|
415 if(!Context) return;
|
rlm@0
|
416
|
rlm@0
|
417 if(LookupEffectSlot(Context->EffectSlotMap, effectslot) != NULL)
|
rlm@0
|
418 {
|
rlm@0
|
419 switch(param)
|
rlm@0
|
420 {
|
rlm@0
|
421 default:
|
rlm@0
|
422 alSetError(Context, AL_INVALID_ENUM);
|
rlm@0
|
423 break;
|
rlm@0
|
424 }
|
rlm@0
|
425 }
|
rlm@0
|
426 else
|
rlm@0
|
427 alSetError(Context, AL_INVALID_NAME);
|
rlm@0
|
428
|
rlm@0
|
429 UnlockContext(Context);
|
rlm@0
|
430 }
|
rlm@0
|
431
|
rlm@0
|
432
|
rlm@0
|
433 static ALvoid NoneDestroy(ALeffectState *State)
|
rlm@0
|
434 { free(State); }
|
rlm@0
|
435 static ALboolean NoneDeviceUpdate(ALeffectState *State, ALCdevice *Device)
|
rlm@0
|
436 {
|
rlm@0
|
437 return AL_TRUE;
|
rlm@0
|
438 (void)State;
|
rlm@0
|
439 (void)Device;
|
rlm@0
|
440 }
|
rlm@0
|
441 static ALvoid NoneUpdate(ALeffectState *State, ALCcontext *Context, const ALeffectslot *Slot)
|
rlm@0
|
442 {
|
rlm@0
|
443 (void)State;
|
rlm@0
|
444 (void)Context;
|
rlm@0
|
445 (void)Slot;
|
rlm@0
|
446 }
|
rlm@0
|
447 static ALvoid NoneProcess(ALeffectState *State, const ALeffectslot *Slot, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS])
|
rlm@0
|
448 {
|
rlm@0
|
449 (void)State;
|
rlm@0
|
450 (void)Slot;
|
rlm@0
|
451 (void)SamplesToDo;
|
rlm@0
|
452 (void)SamplesIn;
|
rlm@0
|
453 (void)SamplesOut;
|
rlm@0
|
454 }
|
rlm@0
|
455 ALeffectState *NoneCreate(void)
|
rlm@0
|
456 {
|
rlm@0
|
457 ALeffectState *state;
|
rlm@0
|
458
|
rlm@0
|
459 state = calloc(1, sizeof(*state));
|
rlm@0
|
460 if(!state)
|
rlm@0
|
461 return NULL;
|
rlm@0
|
462
|
rlm@0
|
463 state->Destroy = NoneDestroy;
|
rlm@0
|
464 state->DeviceUpdate = NoneDeviceUpdate;
|
rlm@0
|
465 state->Update = NoneUpdate;
|
rlm@0
|
466 state->Process = NoneProcess;
|
rlm@0
|
467
|
rlm@0
|
468 return state;
|
rlm@0
|
469 }
|
rlm@0
|
470
|
rlm@0
|
471 static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect)
|
rlm@0
|
472 {
|
rlm@0
|
473 if(EffectSlot->effect.type != (effect?effect->type:AL_EFFECT_NULL))
|
rlm@0
|
474 {
|
rlm@0
|
475 ALeffectState *NewState = NULL;
|
rlm@0
|
476 if(!effect || effect->type == AL_EFFECT_NULL)
|
rlm@0
|
477 NewState = NoneCreate();
|
rlm@0
|
478 else if(effect->type == AL_EFFECT_EAXREVERB)
|
rlm@0
|
479 NewState = EAXVerbCreate();
|
rlm@0
|
480 else if(effect->type == AL_EFFECT_REVERB)
|
rlm@0
|
481 NewState = VerbCreate();
|
rlm@0
|
482 else if(effect->type == AL_EFFECT_ECHO)
|
rlm@0
|
483 NewState = EchoCreate();
|
rlm@0
|
484 else if(effect->type == AL_EFFECT_RING_MODULATOR)
|
rlm@0
|
485 NewState = ModulatorCreate();
|
rlm@0
|
486 else if(effect->type == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT)
|
rlm@0
|
487 NewState = DedicatedLFECreate();
|
rlm@0
|
488 else if(effect->type == AL_EFFECT_DEDICATED_DIALOGUE)
|
rlm@0
|
489 NewState = DedicatedDLGCreate();
|
rlm@0
|
490 /* No new state? An error occured.. */
|
rlm@0
|
491 if(NewState == NULL ||
|
rlm@0
|
492 ALEffect_DeviceUpdate(NewState, Context->Device) == AL_FALSE)
|
rlm@0
|
493 {
|
rlm@0
|
494 if(NewState)
|
rlm@0
|
495 ALEffect_Destroy(NewState);
|
rlm@0
|
496 alSetError(Context, AL_OUT_OF_MEMORY);
|
rlm@0
|
497 return;
|
rlm@0
|
498 }
|
rlm@0
|
499 if(EffectSlot->EffectState)
|
rlm@0
|
500 ALEffect_Destroy(EffectSlot->EffectState);
|
rlm@0
|
501 EffectSlot->EffectState = NewState;
|
rlm@0
|
502
|
rlm@0
|
503 if(!effect)
|
rlm@0
|
504 memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect));
|
rlm@0
|
505 else
|
rlm@0
|
506 memcpy(&EffectSlot->effect, effect, sizeof(*effect));
|
rlm@0
|
507 /* FIXME: This should be done asychronously, but since the EfefctState
|
rlm@0
|
508 * object was changed, it needs an update before its Process method can
|
rlm@0
|
509 * be called (coming changes may not guarantee an update when the
|
rlm@0
|
510 * NeedsUpdate flag is set). */
|
rlm@0
|
511 EffectSlot->NeedsUpdate = AL_FALSE;
|
rlm@0
|
512 ALEffect_Update(EffectSlot->EffectState, Context, EffectSlot);
|
rlm@0
|
513 }
|
rlm@0
|
514 else
|
rlm@0
|
515 {
|
rlm@0
|
516 if(!effect)
|
rlm@0
|
517 memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect));
|
rlm@0
|
518 else
|
rlm@0
|
519 memcpy(&EffectSlot->effect, effect, sizeof(*effect));
|
rlm@0
|
520 EffectSlot->NeedsUpdate = AL_TRUE;
|
rlm@0
|
521 }
|
rlm@0
|
522 }
|
rlm@0
|
523
|
rlm@0
|
524
|
rlm@0
|
525 ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context)
|
rlm@0
|
526 {
|
rlm@0
|
527 ALsizei pos;
|
rlm@0
|
528 for(pos = 0;pos < Context->EffectSlotMap.size;pos++)
|
rlm@0
|
529 {
|
rlm@0
|
530 ALeffectslot *temp = Context->EffectSlotMap.array[pos].value;
|
rlm@0
|
531 Context->EffectSlotMap.array[pos].value = NULL;
|
rlm@0
|
532
|
rlm@0
|
533 // Release effectslot structure
|
rlm@0
|
534 ALEffect_Destroy(temp->EffectState);
|
rlm@0
|
535
|
rlm@0
|
536 FreeThunkEntry(temp->effectslot);
|
rlm@0
|
537 memset(temp, 0, sizeof(ALeffectslot));
|
rlm@0
|
538 free(temp);
|
rlm@0
|
539 }
|
rlm@0
|
540 }
|