zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
alAuxEffectSlot.c
Go to the documentation of this file.
1 
21 #include "config.h"
22 
23 #include <stdlib.h>
24 #include <math.h>
25 
26 #include "AL/al.h"
27 #include "AL/alc.h"
28 #include "alMain.h"
29 #include "alAuxEffectSlot.h"
30 #include "alThunk.h"
31 #include "alError.h"
32 #include "alSource.h"
33 
34 
35 static ALenum AddEffectSlotArray(ALCcontext *Context, ALsizei count, const ALuint *slots);
36 static ALvoid RemoveEffectSlotArray(ALCcontext *Context, ALeffectslot *slot);
37 
38 
40 {
41  ALCcontext *Context;
42  ALsizei cur = 0;
43 
44  Context = GetContextRef();
45  if(!Context) return;
46 
47  al_try
48  {
49  ALenum err;
50 
51  CHECK_VALUE(Context, n >= 0);
52  for(cur = 0;cur < n;cur++)
53  {
54  ALeffectslot *slot = al_calloc(16, sizeof(ALeffectslot));
55  err = AL_OUT_OF_MEMORY;
56  if(!slot || (err=InitEffectSlot(slot)) != AL_NO_ERROR)
57  {
58  al_free(slot);
59  al_throwerr(Context, err);
60  break;
61  }
62 
63  err = NewThunkEntry(&slot->id);
64  if(err == AL_NO_ERROR)
65  err = InsertUIntMapEntry(&Context->EffectSlotMap, slot->id, slot);
66  if(err != AL_NO_ERROR)
67  {
68  FreeThunkEntry(slot->id);
70  al_free(slot);
71 
72  al_throwerr(Context, err);
73  }
74 
75  effectslots[cur] = slot->id;
76  }
77  err = AddEffectSlotArray(Context, n, effectslots);
78  if(err != AL_NO_ERROR)
79  al_throwerr(Context, err);
80  }
81  al_catchany()
82  {
83  if(cur > 0)
84  alDeleteAuxiliaryEffectSlots(cur, effectslots);
85  }
86  al_endtry;
87 
88  ALCcontext_DecRef(Context);
89 }
90 
92 {
93  ALCcontext *Context;
94  ALeffectslot *slot;
95  ALsizei i;
96 
97  Context = GetContextRef();
98  if(!Context) return;
99 
100  al_try
101  {
102  CHECK_VALUE(Context, n >= 0);
103  for(i = 0;i < n;i++)
104  {
105  if((slot=LookupEffectSlot(Context, effectslots[i])) == NULL)
106  al_throwerr(Context, AL_INVALID_NAME);
107  if(slot->ref != 0)
109  }
110 
111  // All effectslots are valid
112  for(i = 0;i < n;i++)
113  {
114  if((slot=RemoveEffectSlot(Context, effectslots[i])) == NULL)
115  continue;
116  FreeThunkEntry(slot->id);
117 
118  RemoveEffectSlotArray(Context, slot);
120 
121  memset(slot, 0, sizeof(*slot));
122  al_free(slot);
123  }
124  }
125  al_endtry;
126 
127  ALCcontext_DecRef(Context);
128 }
129 
131 {
132  ALCcontext *Context;
134 
135  Context = GetContextRef();
136  if(!Context) return AL_FALSE;
137 
138  result = (LookupEffectSlot(Context, effectslot) ? AL_TRUE : AL_FALSE);
139 
140  ALCcontext_DecRef(Context);
141 
142  return result;
143 }
144 
146 {
147  ALCcontext *Context;
148  ALeffectslot *Slot;
149  ALeffect *effect = NULL;
150  ALenum err;
151 
152  Context = GetContextRef();
153  if(!Context) return;
154 
155  al_try
156  {
157  ALCdevice *device = Context->Device;
158  if((Slot=LookupEffectSlot(Context, effectslot)) == NULL)
159  al_throwerr(Context, AL_INVALID_NAME);
160  switch(param)
161  {
163  CHECK_VALUE(Context, value == 0 || (effect=LookupEffect(device, value)) != NULL);
164 
165  err = InitializeEffect(device, Slot, effect);
166  if(err != AL_NO_ERROR)
167  al_throwerr(Context, err);
168  Context->UpdateSources = AL_TRUE;
169  break;
170 
172  CHECK_VALUE(Context, value == AL_TRUE || value == AL_FALSE);
173 
174  Slot->AuxSendAuto = value;
175  Context->UpdateSources = AL_TRUE;
176  break;
177 
178  default:
179  al_throwerr(Context, AL_INVALID_ENUM);
180  }
181  }
182  al_endtry;
183 
184  ALCcontext_DecRef(Context);
185 }
186 
188 {
189  ALCcontext *Context;
190 
191  switch(param)
192  {
195  alAuxiliaryEffectSloti(effectslot, param, values[0]);
196  return;
197  }
198 
199  Context = GetContextRef();
200  if(!Context) return;
201 
202  al_try
203  {
204  if(LookupEffectSlot(Context, effectslot) == NULL)
205  al_throwerr(Context, AL_INVALID_NAME);
206  switch(param)
207  {
208  default:
209  al_throwerr(Context, AL_INVALID_ENUM);
210  }
211  }
212  al_endtry;
213 
214  ALCcontext_DecRef(Context);
215 }
216 
218 {
219  ALCcontext *Context;
220  ALeffectslot *Slot;
221 
222  Context = GetContextRef();
223  if(!Context) return;
224 
225  al_try
226  {
227  if((Slot=LookupEffectSlot(Context, effectslot)) == NULL)
228  al_throwerr(Context, AL_INVALID_NAME);
229  switch(param)
230  {
231  case AL_EFFECTSLOT_GAIN:
232  CHECK_VALUE(Context, value >= 0.0f && value <= 1.0f);
233 
234  Slot->Gain = value;
235  Slot->NeedsUpdate = AL_TRUE;
236  break;
237 
238  default:
239  al_throwerr(Context, AL_INVALID_ENUM);
240  }
241  }
242  al_endtry;
243 
244  ALCcontext_DecRef(Context);
245 }
246 
248 {
249  ALCcontext *Context;
250 
251  switch(param)
252  {
253  case AL_EFFECTSLOT_GAIN:
254  alAuxiliaryEffectSlotf(effectslot, param, values[0]);
255  return;
256  }
257 
258  Context = GetContextRef();
259  if(!Context) return;
260 
261  al_try
262  {
263  if(LookupEffectSlot(Context, effectslot) == NULL)
264  al_throwerr(Context, AL_INVALID_NAME);
265  switch(param)
266  {
267  default:
268  al_throwerr(Context, AL_INVALID_ENUM);
269  }
270  }
271  al_endtry;
272 
273  ALCcontext_DecRef(Context);
274 }
275 
277 {
278  ALCcontext *Context;
279  ALeffectslot *Slot;
280 
281  Context = GetContextRef();
282  if(!Context) return;
283 
284  al_try
285  {
286  if((Slot=LookupEffectSlot(Context, effectslot)) == NULL)
287  al_throwerr(Context, AL_INVALID_NAME);
288  switch(param)
289  {
291  *value = Slot->effect.id;
292  break;
293 
295  *value = Slot->AuxSendAuto;
296  break;
297 
298  default:
299  al_throwerr(Context, AL_INVALID_ENUM);
300  }
301  }
302  al_endtry;
303 
304  ALCcontext_DecRef(Context);
305 }
306 
308 {
309  ALCcontext *Context;
310 
311  switch(param)
312  {
315  alGetAuxiliaryEffectSloti(effectslot, param, values);
316  return;
317  }
318 
319  Context = GetContextRef();
320  if(!Context) return;
321 
322  al_try
323  {
324  if(LookupEffectSlot(Context, effectslot) == NULL)
325  al_throwerr(Context, AL_INVALID_NAME);
326  switch(param)
327  {
328  default:
329  al_throwerr(Context, AL_INVALID_ENUM);
330  }
331  }
332  al_endtry;
333 
334  ALCcontext_DecRef(Context);
335 }
336 
338 {
339  ALCcontext *Context;
340  ALeffectslot *Slot;
341 
342  Context = GetContextRef();
343  if(!Context) return;
344 
345  al_try
346  {
347  if((Slot=LookupEffectSlot(Context, effectslot)) == NULL)
348  al_throwerr(Context, AL_INVALID_NAME);
349  switch(param)
350  {
351  case AL_EFFECTSLOT_GAIN:
352  *value = Slot->Gain;
353  break;
354 
355  default:
356  al_throwerr(Context, AL_INVALID_ENUM);
357  }
358  }
359  al_endtry;
360 
361  ALCcontext_DecRef(Context);
362 }
363 
365 {
366  ALCcontext *Context;
367 
368  switch(param)
369  {
370  case AL_EFFECTSLOT_GAIN:
371  alGetAuxiliaryEffectSlotf(effectslot, param, values);
372  return;
373  }
374 
375  Context = GetContextRef();
376  if(!Context) return;
377 
378  al_try
379  {
380  if(LookupEffectSlot(Context, effectslot) == NULL)
381  al_throwerr(Context, AL_INVALID_NAME);
382  switch(param)
383  {
384  default:
385  al_throwerr(Context, AL_INVALID_ENUM);
386  }
387  }
388  al_endtry;
389 
390  ALCcontext_DecRef(Context);
391 }
392 
393 
395 { free(State); }
397 {
398  return AL_TRUE;
399  (void)State;
400  (void)Device;
401 }
403 {
404  (void)State;
405  (void)Device;
406  (void)Slot;
407 }
408 static ALvoid NoneProcess(ALeffectState *State, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE])
409 {
410  (void)State;
411  (void)SamplesToDo;
412  (void)SamplesIn;
413  (void)SamplesOut;
414 }
416 {
417  ALeffectState *state;
418 
419  state = calloc(1, sizeof(*state));
420  if(!state)
421  return NULL;
422 
423  state->Destroy = NoneDestroy;
425  state->Update = NoneUpdate;
426  state->Process = NoneProcess;
427 
428  return state;
429 }
430 
431 
433 {
434  ALeffectslot **slotlist, **slotlistend;
435 
436  LockContext(Context);
437  slotlist = Context->ActiveEffectSlots;
438  slotlistend = slotlist + Context->ActiveEffectSlotCount;
439  while(slotlist != slotlistend)
440  {
441  if(*slotlist == slot)
442  {
443  *slotlist = *(--slotlistend);
444  Context->ActiveEffectSlotCount--;
445  break;
446  }
447  slotlist++;
448  }
449  UnlockContext(Context);
450 }
451 
452 static ALenum AddEffectSlotArray(ALCcontext *Context, ALsizei count, const ALuint *slots)
453 {
454  ALsizei i;
455 
456  LockContext(Context);
457  if(count > Context->MaxActiveEffectSlots-Context->ActiveEffectSlotCount)
458  {
459  ALsizei newcount;
460  void *temp = NULL;
461 
462  newcount = Context->MaxActiveEffectSlots ? (Context->MaxActiveEffectSlots<<1) : 1;
463  if(newcount > Context->MaxActiveEffectSlots)
464  temp = realloc(Context->ActiveEffectSlots,
465  newcount * sizeof(*Context->ActiveEffectSlots));
466  if(!temp)
467  {
468  UnlockContext(Context);
469  return AL_OUT_OF_MEMORY;
470  }
471  Context->ActiveEffectSlots = temp;
472  Context->MaxActiveEffectSlots = newcount;
473  }
474  for(i = 0;i < count;i++)
475  {
476  ALeffectslot *slot = LookupEffectSlot(Context, slots[i]);
477  assert(slot != NULL);
478  Context->ActiveEffectSlots[Context->ActiveEffectSlotCount++] = slot;
479  }
480  UnlockContext(Context);
481  return AL_NO_ERROR;
482 }
483 
484 ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect)
485 {
486  ALenum newtype = (effect ? effect->type : AL_EFFECT_NULL);
487  ALeffectState *State = NULL;
488  ALenum err = AL_NO_ERROR;
489 
490  ALCdevice_Lock(Device);
491  if(newtype == AL_EFFECT_NULL && EffectSlot->effect.type != AL_EFFECT_NULL)
492  {
493  State = NoneCreate();
494  if(!State) err = AL_OUT_OF_MEMORY;
495  }
496  else if(newtype == AL_EFFECT_EAXREVERB || newtype == AL_EFFECT_REVERB)
497  {
498  if(EffectSlot->effect.type != AL_EFFECT_EAXREVERB && EffectSlot->effect.type != AL_EFFECT_REVERB)
499  {
500  State = ReverbCreate();
501  if(!State) err = AL_OUT_OF_MEMORY;
502  }
503  }
504  else if(newtype == AL_EFFECT_ECHO && EffectSlot->effect.type != AL_EFFECT_ECHO)
505  {
506  State = EchoCreate();
507  if(!State) err = AL_OUT_OF_MEMORY;
508  }
509  else if(newtype == AL_EFFECT_RING_MODULATOR && EffectSlot->effect.type != AL_EFFECT_RING_MODULATOR)
510  {
511  State = ModulatorCreate();
512  if(!State) err = AL_OUT_OF_MEMORY;
513  }
515  {
517  {
518  State = DedicatedCreate();
519  if(!State) err = AL_OUT_OF_MEMORY;
520  }
521  }
522 
523  if(err != AL_NO_ERROR)
524  {
525  ALCdevice_Unlock(Device);
526  return err;
527  }
528 
529  if(State)
530  {
531  FPUCtl oldMode;
532  SetMixerFPUMode(&oldMode);
533 
534  if(ALeffectState_DeviceUpdate(State, Device) == AL_FALSE)
535  {
536  RestoreFPUMode(&oldMode);
537  ALCdevice_Unlock(Device);
538  ALeffectState_Destroy(State);
539  return AL_OUT_OF_MEMORY;
540  }
541  State = ExchangePtr((XchgPtr*)&EffectSlot->EffectState, State);
542 
543  if(!effect)
544  memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect));
545  else
546  memcpy(&EffectSlot->effect, effect, sizeof(*effect));
547  /* FIXME: This should be done asynchronously, but since the EffectState
548  * object was changed, it needs an update before its Process method can
549  * be called. */
550  EffectSlot->NeedsUpdate = AL_FALSE;
551  ALeffectState_Update(EffectSlot->EffectState, Device, EffectSlot);
552  ALCdevice_Unlock(Device);
553 
554  RestoreFPUMode(&oldMode);
555 
556  ALeffectState_Destroy(State);
557  State = NULL;
558  }
559  else
560  {
561  if(!effect)
562  memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect));
563  else
564  memcpy(&EffectSlot->effect, effect, sizeof(*effect));
565  ALCdevice_Unlock(Device);
566  EffectSlot->NeedsUpdate = AL_TRUE;
567  }
568 
569  return AL_NO_ERROR;
570 }
571 
572 
574 {
575  ALint i, c;
576 
577  if(!(slot->EffectState=NoneCreate()))
578  return AL_OUT_OF_MEMORY;
579 
580  slot->Gain = 1.0;
581  slot->AuxSendAuto = AL_TRUE;
582  slot->NeedsUpdate = AL_FALSE;
583  for(c = 0;c < 1;c++)
584  {
585  for(i = 0;i < BUFFERSIZE;i++)
586  slot->WetBuffer[c][i] = 0.0f;
587  slot->ClickRemoval[c] = 0.0f;
588  slot->PendingClicks[c] = 0.0f;
589  }
590  slot->ref = 0;
591 
592  return AL_NO_ERROR;
593 }
594 
596 {
597  ALsizei pos;
598  for(pos = 0;pos < Context->EffectSlotMap.size;pos++)
599  {
600  ALeffectslot *temp = Context->EffectSlotMap.array[pos].value;
601  Context->EffectSlotMap.array[pos].value = NULL;
602 
604 
605  FreeThunkEntry(temp->id);
606  memset(temp, 0, sizeof(ALeffectslot));
607  al_free(temp);
608  }
609 }
#define AL_APIENTRY
Definition: al.h:21
volatile ALenum UpdateSources
Definition: alMain.h:686
void FreeThunkEntry(ALuint index)
Definition: alThunk.c:83
ALvoid(* Process)(struct ALeffectState *State, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat(*RESTRICT SamplesOut)[BUFFERSIZE])
void ALvoid
Definition: al.h:74
GLenum GLint param
Definition: gl2ext.h:1491
LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf
Definition: alreverb.c:72
static ALvoid NoneProcess(ALeffectState *State, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat(*RESTRICT SamplesOut)[BUFFERSIZE])
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1824
#define CHECK_VALUE(ctx, cond)
Definition: alMain.h:875
void *volatile XchgPtr
Definition: alMain.h:119
#define ALeffectState_Update(a, b, c)
ALeffectState * EffectState
#define AL_TRUE
Definition: al.h:86
LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots
Definition: alreverb.c:64
UIntMap EffectSlotMap
Definition: alMain.h:682
#define NULL
Definition: ftobjs.h:61
ALsizei ActiveEffectSlotCount
Definition: alMain.h:701
GLclampf f
Definition: glew.h:3390
struct UIntMap::@59 * array
#define al_throwerr(ctx, err)
Definition: alMain.h:866
GLclampd n
Definition: glew.h:7287
ALeffectState * ModulatorCreate(void)
Definition: alcModulator.c:184
int ALsizei
Definition: al.h:62
LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf
Definition: alreverb.c:68
SDL_EventEntry * free
Definition: SDL_events.c:80
#define AL_EFFECTSLOT_GAIN
Definition: efx.h:171
ALvoid(* Destroy)(struct ALeffectState *State)
#define al_try
Definition: alMain.h:838
int ALint
Definition: al.h:56
static ALboolean NoneDeviceUpdate(ALeffectState *State, ALCdevice *Device)
#define memset
Definition: SDL_malloc.c:633
#define AL_FALSE
Definition: al.h:83
LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv
Definition: alreverb.c:71
LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti
Definition: alreverb.c:70
#define ALeffectState_DeviceUpdate(a, b)
#define al_endtry
Definition: alMain.h:853
#define assert(x)
Definition: SDL_malloc.c:1234
volatile ALenum NeedsUpdate
void RestoreFPUMode(const FPUCtl *ctl)
Definition: helpers.c:235
ALuint id
Definition: alEffect.h:89
void SetMixerFPUMode(FPUCtl *ctl)
Definition: helpers.c:193
ALCcontext * GetContextRef(void)
Definition: ALc.c:1999
float ALfloat
Definition: al.h:68
#define calloc
Definition: SDL_malloc.c:636
ALeffectState * NoneCreate(void)
#define AL_EFFECTSLOT_EFFECT
Definition: efx.h:170
ALvoid * value
Definition: alMain.h:310
#define ALeffectState_Destroy(a)
void * al_calloc(size_t alignment, size_t size)
Definition: helpers.c:161
#define ALCdevice_Unlock(a)
Definition: alMain.h:647
ALenum InitEffectSlot(ALeffectslot *slot)
ALsizei MaxActiveEffectSlots
Definition: alMain.h:702
GLuint64EXT * result
Definition: glew.h:12708
ALeffect effect
ALfloat PendingClicks[1]
static ALvoid NoneDestroy(ALeffectState *State)
#define al_catchany()
Definition: alMain.h:851
#define AL_INVALID_NAME
Definition: al.h:367
ALboolean(* DeviceUpdate)(struct ALeffectState *State, ALCdevice *Device)
GLint GLsizei count
Definition: gl2ext.h:1011
#define AL_EFFECT_REVERB
Definition: efx.h:155
#define AL_EFFECT_DEDICATED_DIALOGUE
Definition: alext.h:202
ALsizei size
Definition: alMain.h:312
const GLfloat * c
Definition: glew.h:14913
LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv
Definition: alreverb.c:73
void al_free(void *ptr)
Definition: helpers.c:168
#define realloc
Definition: SDL_malloc.c:637
int ALenum
Definition: al.h:65
#define AL_EFFECT_NULL
Definition: efx.h:154
ALenum NewThunkEntry(ALuint *index)
Definition: alThunk.c:47
#define LookupEffectSlot(m, k)
Definition: alMain.h:711
volatile ALfloat Gain
unsigned int ALuint
Definition: al.h:59
enum State_ State
ALvoid(* Update)(struct ALeffectState *State, ALCdevice *Device, const struct ALeffectslot *Slot)
#define AL_API
Definition: al.h:14
#define RemoveEffectSlot(m, k)
Definition: alMain.h:713
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context)
ALeffectState * ReverbCreate(void)
Definition: alcReverb.c:1188
ALeffectState * EchoCreate(void)
Definition: alcEcho.c:159
#define LookupEffect(m, k)
Definition: alMain.h:668
ALeffectState * DedicatedCreate(void)
Definition: alcDedicated.c:82
LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti
Definition: alreverb.c:66
void ALCcontext_DecRef(ALCcontext *context)
Definition: ALc.c:1949
EGLSurface EGLint void ** value
Definition: eglext.h:301
Definition: alMain.h:738
ALfloat ClickRemoval[1]
#define memcpy
Definition: SDL_malloc.c:634
LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv
Definition: alreverb.c:69
#define AL_OUT_OF_MEMORY
Definition: al.h:379
char ALboolean
Definition: al.h:38
volatile ALboolean AuxSendAuto
#define AL_EFFECT_RING_MODULATOR
Definition: efx.h:163
#define AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
Definition: alext.h:203
ALCdevice * Device
Definition: alMain.h:704
static __inline void LockContext(ALCcontext *context)
Definition: alMain.h:728
#define AL_EFFECT_ECHO
Definition: efx.h:158
static ALenum AddEffectSlotArray(ALCcontext *Context, ALsizei count, const ALuint *slots)
int i
Definition: pngrutil.c:1377
#define AL_EFFECT_EAXREVERB
Definition: efx.h:167
ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect)
ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value)
Definition: helpers.c:565
static __inline void UnlockContext(ALCcontext *context)
Definition: alMain.h:730
#define BUFFERSIZE
Definition: alMain.h:556
struct ALeffectslot ** ActiveEffectSlots
Definition: alMain.h:700
#define AL_INVALID_ENUM
Definition: al.h:370
static ALvoid RemoveEffectSlotArray(ALCcontext *Context, ALeffectslot *slot)
LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv
Definition: alreverb.c:67
LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots
Definition: alreverb.c:63
ALenum type
Definition: alEffect.h:27
#define AL_NO_ERROR
Definition: al.h:364
#define AL_INVALID_OPERATION
Definition: al.h:376
GLint GLsizei const GLuint64 * values
Definition: glew.h:3473
#define ALCdevice_Lock(a)
Definition: alMain.h:646
static ALvoid NoneUpdate(ALeffectState *State, ALCdevice *Device, const ALeffectslot *Slot)
#define AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
Definition: efx.h:172
LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot
Definition: alreverb.c:65