28 #if (AUDIO_TK == AUDIO_TK_OPENAL) && defined(HAVE_ALEXT)
29 static LPALGENEFFECTS alGenEffects;
30 static LPALDELETEEFFECTS alDeleteEffects;
31 static LPALISEFFECT alIsEffect;
32 static LPALEFFECTI alEffecti;
33 static LPALEFFECTIV alEffectiv;
34 static LPALEFFECTF alEffectf;
35 static LPALEFFECTFV alEffectfv;
36 static LPALGETEFFECTI alGetEffecti;
37 static LPALGETEFFECTIV alGetEffectiv;
38 static LPALGETEFFECTF alGetEffectf;
39 static LPALGETEFFECTFV alGetEffectfv;
40 static LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
41 static LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
42 static LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot;
43 static LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
44 static LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv;
45 static LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf;
46 static LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv;
47 static LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti;
48 static LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv;
49 static LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf;
50 static LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv;
54 #if (AUDIO_TK == AUDIO_TK_OPENAL) && defined(HAVE_ALEXT)
55 , effect(0u), slot(0u)
60 #if (AUDIO_TK == AUDIO_TK_OPENAL) && defined(HAVE_ALEXT)
63 alGenAuxiliaryEffectSlots(1, &
slot);
69 #if (AUDIO_TK == AUDIO_TK_OPENAL) && defined(HAVE_ALEXT)
72 alDeleteEffects(1, &
effect);
73 if (alIsAuxiliaryEffectSlot(
slot))
74 alDeleteAuxiliaryEffectSlots(1, &
slot);
81 #if (AUDIO_TK == AUDIO_TK_OPENAL) && defined(HAVE_ALEXT)
85 alAuxiliaryEffectSloti(
slot, AL_EFFECTSLOT_EFFECT,
effect);
92 #if AUDIO_TK == AUDIO_TK_OPENAL
96 #if defined(HAVE_ALEXT)
97 if (
slot) alSource3i(source, AL_AUXILIARY_SEND_FILTER,
slot, 0, AL_FILTER_NULL);
106 return float(p->
GetPropertyInt(key, int32_t(default_value * ratio))) / ratio;
113 return (p->
GetPropertyInt(key, int32_t(default_value ? 1 : 0)) != 0);
119 #if (AUDIO_TK == AUDIO_TK_OPENAL) && defined(HAVE_ALEXT)
120 alEffecti(
effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB);
126 #if (AUDIO_TK == AUDIO_TK_OPENAL) && defined(HAVE_ALEXT)
149 #if (AUDIO_TK == AUDIO_TK_OPENAL) && defined(HAVE_ALEXT)
150 alEffecti(
effect, AL_EFFECT_TYPE, AL_EFFECT_ECHO);
156 #if (AUDIO_TK == AUDIO_TK_OPENAL) && defined(HAVE_ALEXT)
171 #if (AUDIO_TK == AUDIO_TK_OPENAL) && defined(HAVE_ALEXT)
172 alEffecti(
effect, AL_EFFECT_TYPE, AL_EFFECT_EQUALIZER);
178 #if (AUDIO_TK == AUDIO_TK_OPENAL) && defined(HAVE_ALEXT)
198 is_effect_available[i] =
false;
203 is_initialized =
false;
204 #if (AUDIO_TK == AUDIO_TK_OPENAL) && defined(HAVE_ALEXT)
205 #define LOAD_ALPROC(x) ((void *&)(x) = alGetProcAddress(#x))
209 LogF(
"ALExt: No efx extensions available. Sound modifications disabled.");
212 LOAD_ALPROC(alGenEffects);
213 LOAD_ALPROC(alDeleteEffects);
214 LOAD_ALPROC(alIsEffect);
215 LOAD_ALPROC(alEffecti);
216 LOAD_ALPROC(alEffectiv);
217 LOAD_ALPROC(alEffectf);
218 LOAD_ALPROC(alEffectfv);
219 LOAD_ALPROC(alGetEffecti);
220 LOAD_ALPROC(alGetEffectiv);
221 LOAD_ALPROC(alGetEffectf);
222 LOAD_ALPROC(alGetEffectfv);
223 LOAD_ALPROC(alGenAuxiliaryEffectSlots);
224 LOAD_ALPROC(alDeleteAuxiliaryEffectSlots);
225 LOAD_ALPROC(alIsAuxiliaryEffectSlot);
226 LOAD_ALPROC(alAuxiliaryEffectSloti);
227 LOAD_ALPROC(alAuxiliaryEffectSlotiv);
228 LOAD_ALPROC(alAuxiliaryEffectSlotf);
229 LOAD_ALPROC(alAuxiliaryEffectSlotfv);
230 LOAD_ALPROC(alGetAuxiliaryEffectSloti);
231 LOAD_ALPROC(alGetAuxiliaryEffectSlotiv);
232 LOAD_ALPROC(alGetAuxiliaryEffectSlotf);
233 LOAD_ALPROC(alGetAuxiliaryEffectSlotfv);
236 LogF(
"ALExt: Error loading efx extensions. Sound modifications disabled.");
241 static const struct {
245 #define AL_TEST_EFFECT(effect) { effect, #effect }
246 AL_TEST_EFFECT(AL_EFFECT_REVERB),
247 AL_TEST_EFFECT(AL_EFFECT_ECHO),
248 AL_TEST_EFFECT(AL_EFFECT_EQUALIZER),
249 #undef AL_TEST_EFFECT
252 alGenEffects(1, &effect);
253 ALenum err = alGetError();
254 if (err != AL_NO_ERROR)
256 LogF(
"OpenAL alGenEffects Error: %s", alGetString(err));
258 for (
auto test_effect : test_effects)
260 alEffecti(effect, AL_EFFECT_TYPE, test_effect.effect);
262 bool is_ok = (err == AL_NO_ERROR);
263 is_effect_available[test_effect.effect] = is_ok;
265 if (!is_ok) target_string = &sUnavailableEffects;
else target_string = &sAvailableEffects;
267 target_string->
Append(test_effect.name);
268 if (!is_ok) target_string->
AppendFormat(
" (%s)", alGetString(err));
270 if (alIsEffect(effect)) alDeleteEffects(1, &effect);
271 if (sAvailableEffects.
getLength() == 0) sAvailableEffects =
"(none)";
272 if (sUnavailableEffects.
getLength() == 0) sUnavailableEffects =
"(none)";
273 LogF(
"OpenAL extensions loaded. Available: %s. Unavailable: %s.", sAvailableEffects.
getData(), sUnavailableEffects.
getData());
279 is_initialized =
true;
285 for (
auto iter = sound_modifiers.begin(); iter != sound_modifiers.end(); )
298 auto iter = std::find_if(sound_modifiers.begin(), sound_modifiers.end(),
299 [props](
const C4SoundModifier *mod) { return mod->GetProps() == props; });
300 if (iter != sound_modifiers.end())
return *iter;
302 if (!create_if_not_found)
return nullptr;
305 if (!is_effect_available[effect_type])
return nullptr;
329 int32_t global_modifier_index = player_number + 1;
330 if (global_modifier_index < 0)
return;
331 size_t index =
static_cast<size_t>(global_modifier_index);
332 if (index >= global_modifiers.size()) global_modifiers.resize(index+1);
333 if (new_modifier != global_modifiers[index])
337 global_modifiers[index] = new_modifier;
340 if (pInst->GetModifier() == old_modifier)
341 pInst->SetModifier(new_modifier,
true);
343 if (new_modifier) new_modifier->
AddRef();
344 if (old_modifier) old_modifier->
DelRef();
351 int32_t list_index = player_index + 1;
352 if (list_index < 0 ||
static_cast<size_t>(list_index) >= global_modifiers.size())
return nullptr;
355 if (!result && list_index) result = global_modifiers[0];
C4Application Application
bool LogF(const char *strMessage,...)
@ P_Reverb_Late_Reverb_Gain
@ P_Reverb_Late_Reverb_Delay
@ P_Reverb_Reflections_Delay
@ P_Reverb_Room_Rolloff_Factor
@ P_Equalizer_Mid2_Center
@ P_Reverb_Reflections_Gain
@ P_Equalizer_Mid1_Center
@ P_Reverb_Air_Absorption_GainHF
@ P_Equalizer_High_Cutoff
C4MusicSystem MusicSystem
C4SoundSystem SoundSystem
ALCdevice * GetDevice() const
int32_t GetPropertyInt(C4PropertyName k, int32_t default_val=0) const
C4SoundModifierEcho(C4PropList *in_props)
C4SoundModifierEqualizer(C4PropList *in_props)
float GetFloatProp(C4PropertyName key, float ratio, float default_value)
bool GetBoolProp(C4PropertyName key, bool default_value)
virtual ~C4SoundModifier()
int32_t GetRefCount() const
void ApplyTo(ALuint source)
C4SoundModifier(C4PropList *in_props)
C4SoundModifier * Get(class C4PropList *props, bool create_if_not_found)
void Add(C4SoundModifier *new_modifier)
void Remove(C4SoundModifier *prev_modifier)
C4SoundModifier * GetGlobalModifier(int32_t player_index) const
void SetGlobalModifier(C4SoundModifier *new_modifier, int32_t player_index)
C4SoundModifierReverb(C4PropList *in_props)
C4SoundInstance * GetFirstInstance() const
C4SoundInstance * GetNextInstance(C4SoundInstance *prev) const
C4SoundModifierList Modifiers
void SetPropList(C4PropList *PropList)
C4PropList * _getPropList() const
void AppendFormat(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
const char * getData() const
void Append(const char *pnData, size_t iChars)