2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
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.
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.
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
38 #include "AL/efx-presets.h"
42 #include "alcontext.h"
45 #include "alnumeric.h"
47 #include "effects/base.h"
49 #include "opthelpers.h"
53 const EffectList gEffectList
[15]{
54 { "eaxreverb", EAXREVERB_EFFECT
, AL_EFFECT_EAXREVERB
},
55 { "reverb", REVERB_EFFECT
, AL_EFFECT_REVERB
},
56 { "autowah", AUTOWAH_EFFECT
, AL_EFFECT_AUTOWAH
},
57 { "chorus", CHORUS_EFFECT
, AL_EFFECT_CHORUS
},
58 { "compressor", COMPRESSOR_EFFECT
, AL_EFFECT_COMPRESSOR
},
59 { "distortion", DISTORTION_EFFECT
, AL_EFFECT_DISTORTION
},
60 { "echo", ECHO_EFFECT
, AL_EFFECT_ECHO
},
61 { "equalizer", EQUALIZER_EFFECT
, AL_EFFECT_EQUALIZER
},
62 { "flanger", FLANGER_EFFECT
, AL_EFFECT_FLANGER
},
63 { "fshifter", FSHIFTER_EFFECT
, AL_EFFECT_FREQUENCY_SHIFTER
},
64 { "modulator", MODULATOR_EFFECT
, AL_EFFECT_RING_MODULATOR
},
65 { "pshifter", PSHIFTER_EFFECT
, AL_EFFECT_PITCH_SHIFTER
},
66 { "vmorpher", VMORPHER_EFFECT
, AL_EFFECT_VOCAL_MORPHER
},
67 { "dedicated", DEDICATED_EFFECT
, AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
},
68 { "dedicated", DEDICATED_EFFECT
, AL_EFFECT_DEDICATED_DIALOGUE
},
71 ALboolean DisabledEffects
[MAX_EFFECTS
];
75 constexpr struct FactoryItem
{
77 EffectStateFactory
* (&GetFactory
)(void);
79 { AL_EFFECT_NULL
, NullStateFactory_getFactory
},
80 { AL_EFFECT_EAXREVERB
, ReverbStateFactory_getFactory
},
81 { AL_EFFECT_REVERB
, StdReverbStateFactory_getFactory
},
82 { AL_EFFECT_AUTOWAH
, AutowahStateFactory_getFactory
},
83 { AL_EFFECT_CHORUS
, ChorusStateFactory_getFactory
},
84 { AL_EFFECT_COMPRESSOR
, CompressorStateFactory_getFactory
},
85 { AL_EFFECT_DISTORTION
, DistortionStateFactory_getFactory
},
86 { AL_EFFECT_ECHO
, EchoStateFactory_getFactory
},
87 { AL_EFFECT_EQUALIZER
, EqualizerStateFactory_getFactory
},
88 { AL_EFFECT_FLANGER
, FlangerStateFactory_getFactory
},
89 { AL_EFFECT_FREQUENCY_SHIFTER
, FshifterStateFactory_getFactory
},
90 { AL_EFFECT_RING_MODULATOR
, ModulatorStateFactory_getFactory
},
91 { AL_EFFECT_PITCH_SHIFTER
, PshifterStateFactory_getFactory
},
92 { AL_EFFECT_VOCAL_MORPHER
, VmorpherStateFactory_getFactory
},
93 { AL_EFFECT_DEDICATED_DIALOGUE
, DedicatedStateFactory_getFactory
},
94 { AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
, DedicatedStateFactory_getFactory
}
98 template<typename
... T
>
99 void ALeffect_setParami(ALeffect
*effect
, T
&& ...args
)
100 { effect
->vtab
->setParami(&effect
->Props
, std::forward
<T
>(args
)...); }
101 template<typename
... T
>
102 void ALeffect_setParamiv(ALeffect
*effect
, T
&& ...args
)
103 { effect
->vtab
->setParamiv(&effect
->Props
, std::forward
<T
>(args
)...); }
104 template<typename
... T
>
105 void ALeffect_setParamf(ALeffect
*effect
, T
&& ...args
)
106 { effect
->vtab
->setParamf(&effect
->Props
, std::forward
<T
>(args
)...); }
107 template<typename
... T
>
108 void ALeffect_setParamfv(ALeffect
*effect
, T
&& ...args
)
109 { effect
->vtab
->setParamfv(&effect
->Props
, std::forward
<T
>(args
)...); }
111 template<typename
... T
>
112 void ALeffect_getParami(const ALeffect
*effect
, T
&& ...args
)
113 { effect
->vtab
->getParami(&effect
->Props
, std::forward
<T
>(args
)...); }
114 template<typename
... T
>
115 void ALeffect_getParamiv(const ALeffect
*effect
, T
&& ...args
)
116 { effect
->vtab
->getParamiv(&effect
->Props
, std::forward
<T
>(args
)...); }
117 template<typename
... T
>
118 void ALeffect_getParamf(const ALeffect
*effect
, T
&& ...args
)
119 { effect
->vtab
->getParamf(&effect
->Props
, std::forward
<T
>(args
)...); }
120 template<typename
... T
>
121 void ALeffect_getParamfv(const ALeffect
*effect
, T
&& ...args
)
122 { effect
->vtab
->getParamfv(&effect
->Props
, std::forward
<T
>(args
)...); }
125 void InitEffectParams(ALeffect
*effect
, ALenum type
)
127 EffectStateFactory
*factory
= getFactoryByType(type
);
130 effect
->Props
= factory
->getDefaultProps();
131 effect
->vtab
= factory
->getEffectVtable();
135 effect
->Props
= EffectProps
{};
136 effect
->vtab
= nullptr;
141 bool EnsureEffects(ALCdevice
*device
, size_t needed
)
143 size_t count
{std::accumulate(device
->EffectList
.cbegin(), device
->EffectList
.cend(), size_t{0},
144 [](size_t cur
, const EffectSubList
&sublist
) noexcept
-> size_t
145 { return cur
+ static_cast<ALuint
>(POPCNT64(sublist
.FreeMask
)); }
148 while(needed
> count
)
150 if UNLIKELY(device
->EffectList
.size() >= 1<<25)
153 device
->EffectList
.emplace_back();
154 auto sublist
= device
->EffectList
.end() - 1;
155 sublist
->FreeMask
= ~0_u64
;
156 sublist
->Effects
= static_cast<ALeffect
*>(al_calloc(alignof(ALeffect
), sizeof(ALeffect
)*64));
157 if UNLIKELY(!sublist
->Effects
)
159 device
->EffectList
.pop_back();
167 ALeffect
*AllocEffect(ALCdevice
*device
)
169 auto sublist
= std::find_if(device
->EffectList
.begin(), device
->EffectList
.end(),
170 [](const EffectSubList
&entry
) noexcept
-> bool
171 { return entry
.FreeMask
!= 0; }
173 auto lidx
= static_cast<ALuint
>(std::distance(device
->EffectList
.begin(), sublist
));
174 auto slidx
= static_cast<ALuint
>(CTZ64(sublist
->FreeMask
));
176 ALeffect
*effect
{::new (sublist
->Effects
+ slidx
) ALeffect
{}};
177 InitEffectParams(effect
, AL_EFFECT_NULL
);
179 /* Add 1 to avoid effect ID 0. */
180 effect
->id
= ((lidx
<<6) | slidx
) + 1;
182 sublist
->FreeMask
&= ~(1_u64
<< slidx
);
187 void FreeEffect(ALCdevice
*device
, ALeffect
*effect
)
189 const ALuint id
{effect
->id
- 1};
190 const size_t lidx
{id
>> 6};
191 const ALuint slidx
{id
& 0x3f};
193 al::destroy_at(effect
);
195 device
->EffectList
[lidx
].FreeMask
|= 1_u64
<< slidx
;
198 inline ALeffect
*LookupEffect(ALCdevice
*device
, ALuint id
)
200 const size_t lidx
{(id
-1) >> 6};
201 const ALuint slidx
{(id
-1) & 0x3f};
203 if UNLIKELY(lidx
>= device
->EffectList
.size())
205 EffectSubList
&sublist
= device
->EffectList
[lidx
];
206 if UNLIKELY(sublist
.FreeMask
& (1_u64
<< slidx
))
208 return sublist
.Effects
+ slidx
;
213 AL_API ALvoid AL_APIENTRY
alGenEffects(ALsizei n
, ALuint
*effects
)
216 ContextRef context
{GetContextRef()};
217 if UNLIKELY(!context
) return;
220 context
->setError(AL_INVALID_VALUE
, "Generating %d effects", n
);
221 if UNLIKELY(n
<= 0) return;
223 ALCdevice
*device
{context
->mDevice
.get()};
224 std::lock_guard
<std::mutex
> _
{device
->EffectLock
};
225 if(!EnsureEffects(device
, static_cast<ALuint
>(n
)))
227 context
->setError(AL_OUT_OF_MEMORY
, "Failed to allocate %d effect%s", n
, (n
==1)?"":"s");
233 /* Special handling for the easy and normal case. */
234 ALeffect
*effect
{AllocEffect(device
)};
235 effects
[0] = effect
->id
;
239 /* Store the allocated buffer IDs in a separate local list, to avoid
240 * modifying the user storage in case of failure.
242 al::vector
<ALuint
> ids
;
243 ids
.reserve(static_cast<ALuint
>(n
));
245 ALeffect
*effect
{AllocEffect(device
)};
246 ids
.emplace_back(effect
->id
);
248 std::copy(ids
.cbegin(), ids
.cend(), effects
);
253 AL_API ALvoid AL_APIENTRY
alDeleteEffects(ALsizei n
, const ALuint
*effects
)
256 ContextRef context
{GetContextRef()};
257 if UNLIKELY(!context
) return;
260 context
->setError(AL_INVALID_VALUE
, "Deleting %d effects", n
);
261 if UNLIKELY(n
<= 0) return;
263 ALCdevice
*device
{context
->mDevice
.get()};
264 std::lock_guard
<std::mutex
> _
{device
->EffectLock
};
266 /* First try to find any effects that are invalid. */
267 auto validate_effect
= [device
](const ALuint eid
) -> bool
268 { return !eid
|| LookupEffect(device
, eid
) != nullptr; };
270 const ALuint
*effects_end
= effects
+ n
;
271 auto inveffect
= std::find_if_not(effects
, effects_end
, validate_effect
);
272 if UNLIKELY(inveffect
!= effects_end
)
274 context
->setError(AL_INVALID_NAME
, "Invalid effect ID %u", *inveffect
);
278 /* All good. Delete non-0 effect IDs. */
279 auto delete_effect
= [device
](ALuint eid
) -> void
281 ALeffect
*effect
{eid
? LookupEffect(device
, eid
) : nullptr};
282 if(effect
) FreeEffect(device
, effect
);
284 std::for_each(effects
, effects_end
, delete_effect
);
288 AL_API ALboolean AL_APIENTRY
alIsEffect(ALuint effect
)
291 ContextRef context
{GetContextRef()};
294 ALCdevice
*device
{context
->mDevice
.get()};
295 std::lock_guard
<std::mutex
> _
{device
->EffectLock
};
296 if(!effect
|| LookupEffect(device
, effect
))
303 AL_API ALvoid AL_APIENTRY
alEffecti(ALuint effect
, ALenum param
, ALint value
)
306 ContextRef context
{GetContextRef()};
307 if UNLIKELY(!context
) return;
309 ALCdevice
*device
{context
->mDevice
.get()};
310 std::lock_guard
<std::mutex
> _
{device
->EffectLock
};
312 ALeffect
*aleffect
{LookupEffect(device
, effect
)};
313 if UNLIKELY(!aleffect
)
314 context
->setError(AL_INVALID_NAME
, "Invalid effect ID %u", effect
);
317 if(param
== AL_EFFECT_TYPE
)
319 ALboolean isOk
{value
== AL_EFFECT_NULL
};
322 for(const EffectList
&effectitem
: gEffectList
)
324 if(value
== effectitem
.val
&& !DisabledEffects
[effectitem
.type
])
333 InitEffectParams(aleffect
, value
);
335 context
->setError(AL_INVALID_VALUE
, "Effect type 0x%04x not supported", value
);
339 /* Call the appropriate handler */
340 ALeffect_setParami(aleffect
, context
.get(), param
, value
);
346 AL_API ALvoid AL_APIENTRY
alEffectiv(ALuint effect
, ALenum param
, const ALint
*values
)
352 alEffecti(effect
, param
, values
[0]);
356 ContextRef context
{GetContextRef()};
357 if UNLIKELY(!context
) return;
359 ALCdevice
*device
{context
->mDevice
.get()};
360 std::lock_guard
<std::mutex
> _
{device
->EffectLock
};
362 ALeffect
*aleffect
{LookupEffect(device
, effect
)};
363 if UNLIKELY(!aleffect
)
364 context
->setError(AL_INVALID_NAME
, "Invalid effect ID %u", effect
);
367 /* Call the appropriate handler */
368 ALeffect_setParamiv(aleffect
, context
.get(), param
, values
);
373 AL_API ALvoid AL_APIENTRY
alEffectf(ALuint effect
, ALenum param
, ALfloat value
)
376 ContextRef context
{GetContextRef()};
377 if UNLIKELY(!context
) return;
379 ALCdevice
*device
{context
->mDevice
.get()};
380 std::lock_guard
<std::mutex
> _
{device
->EffectLock
};
382 ALeffect
*aleffect
{LookupEffect(device
, effect
)};
383 if UNLIKELY(!aleffect
)
384 context
->setError(AL_INVALID_NAME
, "Invalid effect ID %u", effect
);
387 /* Call the appropriate handler */
388 ALeffect_setParamf(aleffect
, context
.get(), param
, value
);
393 AL_API ALvoid AL_APIENTRY
alEffectfv(ALuint effect
, ALenum param
, const ALfloat
*values
)
396 ContextRef context
{GetContextRef()};
397 if UNLIKELY(!context
) return;
399 ALCdevice
*device
{context
->mDevice
.get()};
400 std::lock_guard
<std::mutex
> _
{device
->EffectLock
};
402 ALeffect
*aleffect
{LookupEffect(device
, effect
)};
403 if UNLIKELY(!aleffect
)
404 context
->setError(AL_INVALID_NAME
, "Invalid effect ID %u", effect
);
407 /* Call the appropriate handler */
408 ALeffect_setParamfv(aleffect
, context
.get(), param
, values
);
413 AL_API ALvoid AL_APIENTRY
alGetEffecti(ALuint effect
, ALenum param
, ALint
*value
)
416 ContextRef context
{GetContextRef()};
417 if UNLIKELY(!context
) return;
419 ALCdevice
*device
{context
->mDevice
.get()};
420 std::lock_guard
<std::mutex
> _
{device
->EffectLock
};
422 const ALeffect
*aleffect
{LookupEffect(device
, effect
)};
423 if UNLIKELY(!aleffect
)
424 context
->setError(AL_INVALID_NAME
, "Invalid effect ID %u", effect
);
427 if(param
== AL_EFFECT_TYPE
)
428 *value
= aleffect
->type
;
431 /* Call the appropriate handler */
432 ALeffect_getParami(aleffect
, context
.get(), param
, value
);
438 AL_API ALvoid AL_APIENTRY
alGetEffectiv(ALuint effect
, ALenum param
, ALint
*values
)
444 alGetEffecti(effect
, param
, values
);
448 ContextRef context
{GetContextRef()};
449 if UNLIKELY(!context
) return;
451 ALCdevice
*device
{context
->mDevice
.get()};
452 std::lock_guard
<std::mutex
> _
{device
->EffectLock
};
454 const ALeffect
*aleffect
{LookupEffect(device
, effect
)};
455 if UNLIKELY(!aleffect
)
456 context
->setError(AL_INVALID_NAME
, "Invalid effect ID %u", effect
);
459 /* Call the appropriate handler */
460 ALeffect_getParamiv(aleffect
, context
.get(), param
, values
);
465 AL_API ALvoid AL_APIENTRY
alGetEffectf(ALuint effect
, ALenum param
, ALfloat
*value
)
468 ContextRef context
{GetContextRef()};
469 if UNLIKELY(!context
) return;
471 ALCdevice
*device
{context
->mDevice
.get()};
472 std::lock_guard
<std::mutex
> _
{device
->EffectLock
};
474 const ALeffect
*aleffect
{LookupEffect(device
, effect
)};
475 if UNLIKELY(!aleffect
)
476 context
->setError(AL_INVALID_NAME
, "Invalid effect ID %u", effect
);
479 /* Call the appropriate handler */
480 ALeffect_getParamf(aleffect
, context
.get(), param
, value
);
485 AL_API ALvoid AL_APIENTRY
alGetEffectfv(ALuint effect
, ALenum param
, ALfloat
*values
)
488 ContextRef context
{GetContextRef()};
489 if UNLIKELY(!context
) return;
491 ALCdevice
*device
{context
->mDevice
.get()};
492 std::lock_guard
<std::mutex
> _
{device
->EffectLock
};
494 const ALeffect
*aleffect
{LookupEffect(device
, effect
)};
495 if UNLIKELY(!aleffect
)
496 context
->setError(AL_INVALID_NAME
, "Invalid effect ID %u", effect
);
499 /* Call the appropriate handler */
500 ALeffect_getParamfv(aleffect
, context
.get(), param
, values
);
506 void InitEffect(ALeffect
*effect
)
508 InitEffectParams(effect
, AL_EFFECT_NULL
);
511 EffectSubList::~EffectSubList()
513 uint64_t usemask
{~FreeMask
};
516 ALsizei idx
= CTZ64(usemask
);
517 al::destroy_at(Effects
+idx
);
518 usemask
&= ~(1_u64
<< idx
);
526 EffectStateFactory
*getFactoryByType(ALenum type
)
528 auto iter
= std::find_if(std::begin(FactoryList
), std::end(FactoryList
),
529 [type
](const FactoryItem
&item
) noexcept
-> bool
530 { return item
.Type
== type
; }
532 return (iter
!= std::end(FactoryList
)) ? iter
->GetFactory() : nullptr;
536 #define DECL(x) { #x, EFX_REVERB_PRESET_##x }
537 static const struct {
539 EFXEAXREVERBPROPERTIES props
;
552 DECL(CARPETEDHALLWAY
),
568 DECL(CASTLE_SMALLROOM
),
569 DECL(CASTLE_SHORTPASSAGE
),
570 DECL(CASTLE_MEDIUMROOM
),
571 DECL(CASTLE_LARGEROOM
),
572 DECL(CASTLE_LONGPASSAGE
),
574 DECL(CASTLE_CUPBOARD
),
575 DECL(CASTLE_COURTYARD
),
578 DECL(FACTORY_SMALLROOM
),
579 DECL(FACTORY_SHORTPASSAGE
),
580 DECL(FACTORY_MEDIUMROOM
),
581 DECL(FACTORY_LARGEROOM
),
582 DECL(FACTORY_LONGPASSAGE
),
584 DECL(FACTORY_CUPBOARD
),
585 DECL(FACTORY_COURTYARD
),
586 DECL(FACTORY_ALCOVE
),
588 DECL(ICEPALACE_SMALLROOM
),
589 DECL(ICEPALACE_SHORTPASSAGE
),
590 DECL(ICEPALACE_MEDIUMROOM
),
591 DECL(ICEPALACE_LARGEROOM
),
592 DECL(ICEPALACE_LONGPASSAGE
),
593 DECL(ICEPALACE_HALL
),
594 DECL(ICEPALACE_CUPBOARD
),
595 DECL(ICEPALACE_COURTYARD
),
596 DECL(ICEPALACE_ALCOVE
),
598 DECL(SPACESTATION_SMALLROOM
),
599 DECL(SPACESTATION_SHORTPASSAGE
),
600 DECL(SPACESTATION_MEDIUMROOM
),
601 DECL(SPACESTATION_LARGEROOM
),
602 DECL(SPACESTATION_LONGPASSAGE
),
603 DECL(SPACESTATION_HALL
),
604 DECL(SPACESTATION_CUPBOARD
),
605 DECL(SPACESTATION_ALCOVE
),
607 DECL(WOODEN_SMALLROOM
),
608 DECL(WOODEN_SHORTPASSAGE
),
609 DECL(WOODEN_MEDIUMROOM
),
610 DECL(WOODEN_LARGEROOM
),
611 DECL(WOODEN_LONGPASSAGE
),
613 DECL(WOODEN_CUPBOARD
),
614 DECL(WOODEN_COURTYARD
),
617 DECL(SPORT_EMPTYSTADIUM
),
618 DECL(SPORT_SQUASHCOURT
),
619 DECL(SPORT_SMALLSWIMMINGPOOL
),
620 DECL(SPORT_LARGESWIMMINGPOOL
),
621 DECL(SPORT_GYMNASIUM
),
622 DECL(SPORT_FULLSTADIUM
),
623 DECL(SPORT_STADIUMTANNOY
),
625 DECL(PREFAB_WORKSHOP
),
626 DECL(PREFAB_SCHOOLROOM
),
627 DECL(PREFAB_PRACTISEROOM
),
628 DECL(PREFAB_OUTHOUSE
),
629 DECL(PREFAB_CARAVAN
),
633 DECL(DOME_SAINTPAULS
),
638 DECL(OUTDOORS_BACKYARD
),
639 DECL(OUTDOORS_ROLLINGPLAINS
),
640 DECL(OUTDOORS_DEEPCANYON
),
641 DECL(OUTDOORS_CREEK
),
642 DECL(OUTDOORS_VALLEY
),
648 DECL(DRIVING_COMMENTATOR
),
649 DECL(DRIVING_PITGARAGE
),
650 DECL(DRIVING_INCAR_RACER
),
651 DECL(DRIVING_INCAR_SPORTS
),
652 DECL(DRIVING_INCAR_LUXURY
),
653 DECL(DRIVING_FULLGRANDSTAND
),
654 DECL(DRIVING_EMPTYGRANDSTAND
),
655 DECL(DRIVING_TUNNEL
),
661 DECL(CITY_UNDERPASS
),
662 DECL(CITY_ABANDONED
),
666 DECL(SMALLWATERROOM
),
670 void LoadReverbPreset(const char *name
, ALeffect
*effect
)
672 if(al::strcasecmp(name
, "NONE") == 0)
674 InitEffectParams(effect
, AL_EFFECT_NULL
);
675 TRACE("Loading reverb '%s'\n", "NONE");
679 if(!DisabledEffects
[EAXREVERB_EFFECT
])
680 InitEffectParams(effect
, AL_EFFECT_EAXREVERB
);
681 else if(!DisabledEffects
[REVERB_EFFECT
])
682 InitEffectParams(effect
, AL_EFFECT_REVERB
);
684 InitEffectParams(effect
, AL_EFFECT_NULL
);
685 for(const auto &reverbitem
: reverblist
)
687 const EFXEAXREVERBPROPERTIES
*props
;
689 if(al::strcasecmp(name
, reverbitem
.name
) != 0)
692 TRACE("Loading reverb '%s'\n", reverbitem
.name
);
693 props
= &reverbitem
.props
;
694 effect
->Props
.Reverb
.Density
= props
->flDensity
;
695 effect
->Props
.Reverb
.Diffusion
= props
->flDiffusion
;
696 effect
->Props
.Reverb
.Gain
= props
->flGain
;
697 effect
->Props
.Reverb
.GainHF
= props
->flGainHF
;
698 effect
->Props
.Reverb
.GainLF
= props
->flGainLF
;
699 effect
->Props
.Reverb
.DecayTime
= props
->flDecayTime
;
700 effect
->Props
.Reverb
.DecayHFRatio
= props
->flDecayHFRatio
;
701 effect
->Props
.Reverb
.DecayLFRatio
= props
->flDecayLFRatio
;
702 effect
->Props
.Reverb
.ReflectionsGain
= props
->flReflectionsGain
;
703 effect
->Props
.Reverb
.ReflectionsDelay
= props
->flReflectionsDelay
;
704 effect
->Props
.Reverb
.ReflectionsPan
[0] = props
->flReflectionsPan
[0];
705 effect
->Props
.Reverb
.ReflectionsPan
[1] = props
->flReflectionsPan
[1];
706 effect
->Props
.Reverb
.ReflectionsPan
[2] = props
->flReflectionsPan
[2];
707 effect
->Props
.Reverb
.LateReverbGain
= props
->flLateReverbGain
;
708 effect
->Props
.Reverb
.LateReverbDelay
= props
->flLateReverbDelay
;
709 effect
->Props
.Reverb
.LateReverbPan
[0] = props
->flLateReverbPan
[0];
710 effect
->Props
.Reverb
.LateReverbPan
[1] = props
->flLateReverbPan
[1];
711 effect
->Props
.Reverb
.LateReverbPan
[2] = props
->flLateReverbPan
[2];
712 effect
->Props
.Reverb
.EchoTime
= props
->flEchoTime
;
713 effect
->Props
.Reverb
.EchoDepth
= props
->flEchoDepth
;
714 effect
->Props
.Reverb
.ModulationTime
= props
->flModulationTime
;
715 effect
->Props
.Reverb
.ModulationDepth
= props
->flModulationDepth
;
716 effect
->Props
.Reverb
.AirAbsorptionGainHF
= props
->flAirAbsorptionGainHF
;
717 effect
->Props
.Reverb
.HFReference
= props
->flHFReference
;
718 effect
->Props
.Reverb
.LFReference
= props
->flLFReference
;
719 effect
->Props
.Reverb
.RoomRolloffFactor
= props
->flRoomRolloffFactor
;
720 effect
->Props
.Reverb
.DecayHFLimit
= props
->iDecayHFLimit
? AL_TRUE
: AL_FALSE
;
724 WARN("Reverb preset '%s' not found\n", name
);