dedicated.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /**
  2. * OpenAL cross platform audio library
  3. * Copyright (C) 2011 by Chris Robinson.
  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.
  8. *
  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.
  13. *
  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
  19. */
  20. #include "config.h"
  21. #include <stdlib.h>
  22. #include "alMain.h"
  23. #include "alAuxEffectSlot.h"
  24. #include "alError.h"
  25. #include "alu.h"
  26. #include "filters/defs.h"
  27. typedef struct ALdedicatedState {
  28. DERIVE_FROM_TYPE(ALeffectState);
  29. ALfloat CurrentGains[MAX_OUTPUT_CHANNELS];
  30. ALfloat TargetGains[MAX_OUTPUT_CHANNELS];
  31. } ALdedicatedState;
  32. static ALvoid ALdedicatedState_Destruct(ALdedicatedState *state);
  33. static ALboolean ALdedicatedState_deviceUpdate(ALdedicatedState *state, ALCdevice *device);
  34. static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props);
  35. static ALvoid ALdedicatedState_process(ALdedicatedState *state, ALsizei SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALsizei NumChannels);
  36. DECLARE_DEFAULT_ALLOCATORS(ALdedicatedState)
  37. DEFINE_ALEFFECTSTATE_VTABLE(ALdedicatedState);
  38. static void ALdedicatedState_Construct(ALdedicatedState *state)
  39. {
  40. ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
  41. SET_VTABLE2(ALdedicatedState, ALeffectState, state);
  42. }
  43. static ALvoid ALdedicatedState_Destruct(ALdedicatedState *state)
  44. {
  45. ALeffectState_Destruct(STATIC_CAST(ALeffectState,state));
  46. }
  47. static ALboolean ALdedicatedState_deviceUpdate(ALdedicatedState *state, ALCdevice *UNUSED(device))
  48. {
  49. ALsizei i;
  50. for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
  51. state->CurrentGains[i] = 0.0f;
  52. return AL_TRUE;
  53. }
  54. static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
  55. {
  56. const ALCdevice *device = context->Device;
  57. ALfloat Gain;
  58. ALsizei i;
  59. for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
  60. state->TargetGains[i] = 0.0f;
  61. Gain = slot->Params.Gain * props->Dedicated.Gain;
  62. if(slot->Params.EffectType == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT)
  63. {
  64. int idx;
  65. if((idx=GetChannelIdxByName(&device->RealOut, LFE)) != -1)
  66. {
  67. STATIC_CAST(ALeffectState,state)->OutBuffer = device->RealOut.Buffer;
  68. STATIC_CAST(ALeffectState,state)->OutChannels = device->RealOut.NumChannels;
  69. state->TargetGains[idx] = Gain;
  70. }
  71. }
  72. else if(slot->Params.EffectType == AL_EFFECT_DEDICATED_DIALOGUE)
  73. {
  74. int idx;
  75. /* Dialog goes to the front-center speaker if it exists, otherwise it
  76. * plays from the front-center location. */
  77. if((idx=GetChannelIdxByName(&device->RealOut, FrontCenter)) != -1)
  78. {
  79. STATIC_CAST(ALeffectState,state)->OutBuffer = device->RealOut.Buffer;
  80. STATIC_CAST(ALeffectState,state)->OutChannels = device->RealOut.NumChannels;
  81. state->TargetGains[idx] = Gain;
  82. }
  83. else
  84. {
  85. ALfloat coeffs[MAX_AMBI_COEFFS];
  86. CalcAngleCoeffs(0.0f, 0.0f, 0.0f, coeffs);
  87. STATIC_CAST(ALeffectState,state)->OutBuffer = device->Dry.Buffer;
  88. STATIC_CAST(ALeffectState,state)->OutChannels = device->Dry.NumChannels;
  89. ComputeDryPanGains(&device->Dry, coeffs, Gain, state->TargetGains);
  90. }
  91. }
  92. }
  93. static ALvoid ALdedicatedState_process(ALdedicatedState *state, ALsizei SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
  94. {
  95. MixSamples(SamplesIn[0], NumChannels, SamplesOut, state->CurrentGains,
  96. state->TargetGains, SamplesToDo, 0, SamplesToDo);
  97. }
  98. typedef struct DedicatedStateFactory {
  99. DERIVE_FROM_TYPE(EffectStateFactory);
  100. } DedicatedStateFactory;
  101. ALeffectState *DedicatedStateFactory_create(DedicatedStateFactory *UNUSED(factory))
  102. {
  103. ALdedicatedState *state;
  104. NEW_OBJ0(state, ALdedicatedState)();
  105. if(!state) return NULL;
  106. return STATIC_CAST(ALeffectState, state);
  107. }
  108. DEFINE_EFFECTSTATEFACTORY_VTABLE(DedicatedStateFactory);
  109. EffectStateFactory *DedicatedStateFactory_getFactory(void)
  110. {
  111. static DedicatedStateFactory DedicatedFactory = { { GET_VTABLE2(DedicatedStateFactory, EffectStateFactory) } };
  112. return STATIC_CAST(EffectStateFactory, &DedicatedFactory);
  113. }
  114. void ALdedicated_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint UNUSED(val))
  115. { alSetError(context, AL_INVALID_ENUM, "Invalid dedicated integer property 0x%04x", param); }
  116. void ALdedicated_setParamiv(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, const ALint *UNUSED(vals))
  117. { alSetError(context, AL_INVALID_ENUM, "Invalid dedicated integer-vector property 0x%04x", param); }
  118. void ALdedicated_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val)
  119. {
  120. ALeffectProps *props = &effect->Props;
  121. switch(param)
  122. {
  123. case AL_DEDICATED_GAIN:
  124. if(!(val >= 0.0f && isfinite(val)))
  125. SETERR_RETURN(context, AL_INVALID_VALUE,, "Dedicated gain out of range");
  126. props->Dedicated.Gain = val;
  127. break;
  128. default:
  129. alSetError(context, AL_INVALID_ENUM, "Invalid dedicated float property 0x%04x", param);
  130. }
  131. }
  132. void ALdedicated_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals)
  133. { ALdedicated_setParamf(effect, context, param, vals[0]); }
  134. void ALdedicated_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint *UNUSED(val))
  135. { alSetError(context, AL_INVALID_ENUM, "Invalid dedicated integer property 0x%04x", param); }
  136. void ALdedicated_getParamiv(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint *UNUSED(vals))
  137. { alSetError(context, AL_INVALID_ENUM, "Invalid dedicated integer-vector property 0x%04x", param); }
  138. void ALdedicated_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val)
  139. {
  140. const ALeffectProps *props = &effect->Props;
  141. switch(param)
  142. {
  143. case AL_DEDICATED_GAIN:
  144. *val = props->Dedicated.Gain;
  145. break;
  146. default:
  147. alSetError(context, AL_INVALID_ENUM, "Invalid dedicated float property 0x%04x", param);
  148. }
  149. }
  150. void ALdedicated_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals)
  151. { ALdedicated_getParamf(effect, context, param, vals); }
  152. DEFINE_ALEFFECT_VTABLE(ALdedicated);