From 8d40ecca4d4c1dbd8d71c921d38f8e5bc66968d7 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 27 Nov 2023 21:15:28 -0800 Subject: Avoid extra multiplies --- alc/effects/reverb.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'alc/effects/reverb.cpp') diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp index 0f1fcca1..603d20c3 100644 --- a/alc/effects/reverb.cpp +++ b/alc/effects/reverb.cpp @@ -1604,7 +1604,7 @@ void ReverbPipeline::processLate(size_t offset, const size_t samplesToDo, size_t late_delay_tap1{offset - mLateDelayTap[j][1]}; size_t late_feedb_tap{offset - mLate.Offset[j]}; const float midGain{mLate.T60[j].MidGain}; - const float densityGain{mLate.DensityGain * midGain}; + const float densityGain{mLate.DensityGain}; const float densityStep{late_delay_tap0 != late_delay_tap1 ? densityGain*fadeStep : 0.0f}; float fadeCount{0.0f}; @@ -1641,9 +1641,9 @@ void ReverbPipeline::processLate(size_t offset, const size_t samplesToDo, const float fade0{densityGain - densityStep*fadeCount}; const float fade1{densityStep*fadeCount}; fadeCount += 1.0f; - tempSamples[j][i] = out*midGain + + tempSamples[j][i] = (out + in_delay.Line[late_delay_tap0++][j]*fade0 + - in_delay.Line[late_delay_tap1++][j]*fade1; + in_delay.Line[late_delay_tap1++][j]*fade1) * midGain; ++i; } while(--td); } -- cgit v1.2.3 From ed0420f4297712d8104da8eef5301e3d9b899056 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 2 Dec 2023 00:42:13 -0800 Subject: Adjust the secondary early reflections This reduces the delay to provide a direct (no delay) line from the early reflections to the late reverb delay buffer. This also reduces the early reflection output gain by half. The reasoning here is that EFX seems to expect only one set of initial reflections, while we use two. And being close enough in time, nearly doubles the amount of output energy. This does seem to improve the "harshness" of certain reverbs, smoothing the difference between reverbs, and makes it more like other implementations (still some work to do on late reverb, though). --- alc/effects/reverb.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'alc/effects/reverb.cpp') diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp index 603d20c3..6a9d1997 100644 --- a/alc/effects/reverb.cpp +++ b/alc/effects/reverb.cpp @@ -252,7 +252,7 @@ constexpr std::array EARLY_ALLPASS_LENGTHS{{ * Using an average dimension of 1m, we get: */ constexpr std::array EARLY_LINE_LENGTHS{{ - 5.9850400e-4f, 1.0913150e-3f, 1.5376658e-3f, 1.9419362e-3f + 0.0000000e+0f, 4.9281100e-4f, 9.3916180e-4f, 1.3434322e-3f }}; /* The late all-pass filter lengths are based on the late line lengths: @@ -1057,7 +1057,7 @@ void ReverbPipeline::updateDelayLine(const float earlyDelay, const float lateDel * output. */ length = (LATE_LINE_LENGTHS[i] - LATE_LINE_LENGTHS.front())/float{NUM_LINES}*density_mult + - std::max(lateDelay - EARLY_LINE_LENGTHS[0]*density_mult, 0.0f); + lateDelay; mLateDelayTap[i][1] = float2uint(length * frequency); } } @@ -1504,10 +1504,11 @@ void ReverbPipeline::processEarly(size_t offset, const size_t samplesToDo, mEarlyDelayTap[j][0] = mEarlyDelayTap[j][1]; } - /* Apply a vector all-pass, to help color the initial reflections based - * on the diffusion strength. + /* Apply a vector all-pass, to help color the initial reflections. + * Don't apply diffusion-based scattering since these are still the + * first reflections. */ - mEarly.VecAp.process(tempSamples, offset, mixX, mixY, todo); + mEarly.VecAp.process(tempSamples, offset, 1.0f, 0.0f, todo); /* Apply a delay and bounce to generate secondary reflections, combine * with the primary reflections and write out the result for mixing. @@ -1525,7 +1526,7 @@ void ReverbPipeline::processEarly(size_t offset, const size_t samplesToDo, size_t td{minz(early_delay.Mask+1 - feedb_tap, todo - i)}; do { float sample{early_delay.Line[feedb_tap++][j]}; - out[i] = tempSamples[j][i] + sample*feedb_coeff; + out[i] = (tempSamples[j][i] + sample*feedb_coeff) * 0.5f; tempSamples[j][i] = sample; ++i; } while(--td); -- cgit v1.2.3 From 8f661a2f59e63cbed540b512dc564a3aca7c4211 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 8 Dec 2023 04:33:32 -0800 Subject: Fix some clang-tidy warnings --- al/auxeffectslot.h | 16 +++--- al/eax/api.h | 10 ++-- al/eax/call.h | 42 +++++++-------- al/eax/fx_slots.h | 9 ++-- al/effect.cpp | 14 +++-- al/effect.h | 10 ++-- al/effects/effects.h | 2 +- al/event.cpp | 2 +- al/source.cpp | 31 ++++++----- al/source.h | 8 +-- alc/alc.cpp | 10 ++-- alc/alu.cpp | 4 +- alc/backends/alsa.cpp | 2 +- alc/backends/coreaudio.cpp | 4 +- alc/backends/dsound.cpp | 6 +-- alc/backends/oboe.cpp | 4 +- alc/backends/oss.cpp | 2 +- alc/backends/pipewire.cpp | 5 +- alc/backends/portaudio.cpp | 4 +- alc/backends/sndio.cpp | 2 +- alc/backends/wasapi.cpp | 2 +- alc/backends/winmm.cpp | 5 +- alc/context.h | 2 +- alc/effects/base.h | 42 ++++++++------- alc/effects/reverb.cpp | 5 -- common/albit.h | 7 +-- common/almalloc.h | 56 ++++++++++---------- common/alnumbers.h | 8 +-- common/alnumeric.h | 2 +- common/alspan.h | 102 ++++++++++++++++++------------------- common/intrusive_ptr.h | 6 +-- common/pffft.cpp | 30 +++++------ common/ringbuffer.h | 25 ++++----- common/vecmat.h | 8 +-- core/async_event.h | 3 +- core/effects/base.h | 4 +- core/except.h | 6 +-- examples/alffplay.cpp | 61 ++++++++++------------ utils/alsoft-config/mainwindow.cpp | 4 +- 39 files changed, 281 insertions(+), 284 deletions(-) (limited to 'alc/effects/reverb.cpp') diff --git a/al/auxeffectslot.h b/al/auxeffectslot.h index 36216022..bfd4038e 100644 --- a/al/auxeffectslot.h +++ b/al/auxeffectslot.h @@ -89,12 +89,12 @@ struct ALeffectslot { public: void eax_initialize(ALCcontext& al_context, EaxFxSlotIndexValue index); - EaxFxSlotIndexValue eax_get_index() const noexcept { return eax_fx_slot_index_; } - const EAX50FXSLOTPROPERTIES& eax_get_eax_fx_slot() const noexcept + [[nodiscard]] auto eax_get_index() const noexcept -> EaxFxSlotIndexValue { return eax_fx_slot_index_; } + [[nodiscard]] auto eax_get_eax_fx_slot() const noexcept -> const EAX50FXSLOTPROPERTIES& { return eax_; } // Returns `true` if all sources should be updated, or `false` otherwise. - bool eax_dispatch(const EaxCall& call) + [[nodiscard]] auto eax_dispatch(const EaxCall& call) -> bool { return call.is_get() ? eax_get(call) : eax_set(call); } void eax_commit(); @@ -282,14 +282,14 @@ private: dst = src; } - constexpr bool eax4_fx_slot_is_legacy() const noexcept + [[nodiscard]] constexpr auto eax4_fx_slot_is_legacy() const noexcept -> bool { return eax_fx_slot_index_ < 2; } void eax4_fx_slot_ensure_unlocked() const; - static ALenum eax_get_efx_effect_type(const GUID& guid); - const GUID& eax_get_eax_default_effect_guid() const noexcept; - long eax_get_eax_default_lock() const noexcept; + [[nodiscard]] static auto eax_get_efx_effect_type(const GUID& guid) -> ALenum; + [[nodiscard]] auto eax_get_eax_default_effect_guid() const noexcept -> const GUID&; + [[nodiscard]] auto eax_get_eax_default_lock() const noexcept -> long; void eax4_fx_slot_set_defaults(Eax4Props& props) noexcept; void eax5_fx_slot_set_defaults(Eax5Props& props) noexcept; @@ -312,7 +312,7 @@ private: void eax4_fx_slot_set_all(const EaxCall& call); void eax5_fx_slot_set_all(const EaxCall& call); - bool eax_fx_slot_should_update_sources() const noexcept; + [[nodiscard]] auto eax_fx_slot_should_update_sources() const noexcept -> bool; // Returns `true` if all sources should be updated, or `false` otherwise. bool eax4_fx_slot_set(const EaxCall& call); diff --git a/al/eax/api.h b/al/eax/api.h index 18d93ef8..038fdf75 100644 --- a/al/eax/api.h +++ b/al/eax/api.h @@ -22,12 +22,12 @@ #ifndef _WIN32 -typedef struct _GUID { +using GUID = struct _GUID { std::uint32_t Data1; std::uint16_t Data2; std::uint16_t Data3; - std::uint8_t Data4[8]; -} GUID; + std::array Data4; +}; inline bool operator==(const GUID& lhs, const GUID& rhs) noexcept { return std::memcmp(&lhs, &rhs, sizeof(GUID)) == 0; } @@ -654,11 +654,11 @@ struct EAXSPEAKERLEVELPROPERTIES { }; // EAXSPEAKERLEVELPROPERTIES struct EAX40ACTIVEFXSLOTS { - GUID guidActiveFXSlots[EAX40_MAX_ACTIVE_FXSLOTS]; + std::array guidActiveFXSlots; }; // EAX40ACTIVEFXSLOTS struct EAX50ACTIVEFXSLOTS { - GUID guidActiveFXSlots[EAX50_MAX_ACTIVE_FXSLOTS]; + std::array guidActiveFXSlots; }; // EAX50ACTIVEFXSLOTS // Use this structure for EAXSOURCE_OBSTRUCTIONPARAMETERS property. diff --git a/al/eax/call.h b/al/eax/call.h index 45ff328c..04e94f3e 100644 --- a/al/eax/call.h +++ b/al/eax/call.h @@ -31,16 +31,16 @@ public: ALvoid* property_buffer, ALuint property_size); - bool is_get() const noexcept { return mCallType == EaxCallType::get; } - bool is_deferred() const noexcept { return mIsDeferred; } - int get_version() const noexcept { return mVersion; } - EaxCallPropertySetId get_property_set_id() const noexcept { return mPropertySetId; } - ALuint get_property_id() const noexcept { return mPropertyId; } - ALuint get_property_al_name() const noexcept { return mPropertySourceId; } - EaxFxSlotIndex get_fx_slot_index() const noexcept { return mFxSlotIndex; } + [[nodiscard]] auto is_get() const noexcept -> bool { return mCallType == EaxCallType::get; } + [[nodiscard]] auto is_deferred() const noexcept -> bool { return mIsDeferred; } + [[nodiscard]] auto get_version() const noexcept -> int { return mVersion; } + [[nodiscard]] auto get_property_set_id() const noexcept -> EaxCallPropertySetId { return mPropertySetId; } + [[nodiscard]] auto get_property_id() const noexcept -> ALuint { return mPropertyId; } + [[nodiscard]] auto get_property_al_name() const noexcept -> ALuint { return mPropertySourceId; } + [[nodiscard]] auto get_fx_slot_index() const noexcept -> EaxFxSlotIndex { return mFxSlotIndex; } template - TValue& get_value() const + [[nodiscard]] auto get_value() const -> TValue& { if(mPropertyBufferSize < sizeof(TValue)) fail_too_small(); @@ -49,7 +49,7 @@ public: } template - al::span get_values(size_t max_count) const + [[nodiscard]] auto get_values(size_t max_count) const -> al::span { if(max_count == 0 || mPropertyBufferSize < sizeof(TValue)) fail_too_small(); @@ -59,28 +59,28 @@ public: } template - al::span get_values() const + [[nodiscard]] auto get_values() const -> al::span { return get_values(~0_uz); } template - void set_value(const TValue& value) const + auto set_value(const TValue& value) const -> void { get_value() = value; } private: - const EaxCallType mCallType; - int mVersion; - EaxFxSlotIndex mFxSlotIndex; - EaxCallPropertySetId mPropertySetId; - bool mIsDeferred; - - const ALuint mPropertyId; - const ALuint mPropertySourceId; - ALvoid*const mPropertyBuffer; - const ALuint mPropertyBufferSize; + const EaxCallType mCallType{}; + int mVersion{}; + EaxFxSlotIndex mFxSlotIndex{}; + EaxCallPropertySetId mPropertySetId{}; + bool mIsDeferred{}; + + const ALuint mPropertyId{}; + const ALuint mPropertySourceId{}; + ALvoid*const mPropertyBuffer{}; + const ALuint mPropertyBufferSize{}; [[noreturn]] static void fail(const char* message); [[noreturn]] static void fail_too_small(); diff --git a/al/eax/fx_slots.h b/al/eax/fx_slots.h index 18b2d3ad..b7ed1031 100644 --- a/al/eax/fx_slots.h +++ b/al/eax/fx_slots.h @@ -25,11 +25,9 @@ public: } - const ALeffectslot& get( - EaxFxSlotIndex index) const; + [[nodiscard]] auto get(EaxFxSlotIndex index) const -> const ALeffectslot&; - ALeffectslot& get( - EaxFxSlotIndex index); + [[nodiscard]] auto get(EaxFxSlotIndex index) -> ALeffectslot&; private: using Items = std::array; @@ -39,8 +37,7 @@ private: [[noreturn]] - static void fail( - const char* message); + static void fail(const char* message); void initialize_fx_slots(ALCcontext& al_context); }; // EaxFxSlots diff --git a/al/effect.cpp b/al/effect.cpp index 3e48e91b..e99226c8 100644 --- a/al/effect.cpp +++ b/al/effect.cpp @@ -58,7 +58,7 @@ #include "eax/exception.h" #endif // ALSOFT_EAX -const EffectList gEffectList[16]{ +const std::array gEffectList{{ { "eaxreverb", EAXREVERB_EFFECT, AL_EFFECT_EAXREVERB }, { "reverb", REVERB_EFFECT, AL_EFFECT_REVERB }, { "autowah", AUTOWAH_EFFECT, AL_EFFECT_AUTOWAH }, @@ -75,9 +75,7 @@ const EffectList gEffectList[16]{ { "dedicated", DEDICATED_EFFECT, AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT }, { "dedicated", DEDICATED_EFFECT, AL_EFFECT_DEDICATED_DIALOGUE }, { "convolution", CONVOLUTION_EFFECT, AL_EFFECT_CONVOLUTION_SOFT }, -}; - -bool DisabledEffects[MAX_EFFECTS]; +}}; effect_exception::effect_exception(ALenum code, const char *msg, ...) : mErrorCode{code} @@ -328,7 +326,7 @@ FORCE_ALIGN void AL_APIENTRY alEffectiDirect(ALCcontext *context, ALuint effect, { for(const EffectList &effectitem : gEffectList) { - if(value == effectitem.val && !DisabledEffects[effectitem.type]) + if(value == effectitem.val && !DisabledEffects.test(effectitem.type)) { isOk = true; break; @@ -687,9 +685,9 @@ void LoadReverbPreset(const char *name, ALeffect *effect) return; } - if(!DisabledEffects[EAXREVERB_EFFECT]) + if(!DisabledEffects.test(EAXREVERB_EFFECT)) InitEffectParams(effect, AL_EFFECT_EAXREVERB); - else if(!DisabledEffects[REVERB_EFFECT]) + else if(!DisabledEffects.test(REVERB_EFFECT)) InitEffectParams(effect, AL_EFFECT_REVERB); else InitEffectParams(effect, AL_EFFECT_NULL); @@ -742,7 +740,7 @@ bool IsValidEffectType(ALenum type) noexcept for(const auto &effect_item : gEffectList) { - if(type == effect_item.val && !DisabledEffects[effect_item.type]) + if(type == effect_item.val && !DisabledEffects.test(effect_item.type)) return true; } return false; diff --git a/al/effect.h b/al/effect.h index 27e9dd72..7c5c40dc 100644 --- a/al/effect.h +++ b/al/effect.h @@ -1,6 +1,8 @@ #ifndef AL_EFFECT_H #define AL_EFFECT_H +#include +#include #include #include "AL/al.h" @@ -29,16 +31,14 @@ enum { MAX_EFFECTS }; -extern bool DisabledEffects[MAX_EFFECTS]; - -extern float ReverbBoost; +inline std::bitset DisabledEffects; struct EffectList { const char name[16]; - int type; + ALuint type; ALenum val; }; -extern const EffectList gEffectList[16]; +extern const std::array gEffectList; struct ALeffect { diff --git a/al/effects/effects.h b/al/effects/effects.h index f30f256a..66fc8c44 100644 --- a/al/effects/effects.h +++ b/al/effects/effects.h @@ -24,7 +24,7 @@ public: effect_exception(ALenum code, const char *msg, ...); ~effect_exception() override; - ALenum errorCode() const noexcept { return mErrorCode; } + [[nodiscard]] auto errorCode() const noexcept -> ALenum { return mErrorCode; } }; diff --git a/al/event.cpp b/al/event.cpp index 8b76ceff..95b07dc2 100644 --- a/al/event.cpp +++ b/al/event.cpp @@ -118,7 +118,7 @@ int EventThread(ALCcontext *context) }; auto proc_disconnect = [context,enabledevts](AsyncDisconnectEvent &evt) { - const std::string_view message{evt.msg}; + const std::string_view message{evt.msg.data()}; context->debugMessage(DebugSource::System, DebugType::Error, 0, DebugSeverity::High, message); diff --git a/al/source.cpp b/al/source.cpp index c9ec8f21..9c449434 100644 --- a/al/source.cpp +++ b/al/source.cpp @@ -3917,27 +3917,30 @@ void ALsource::eax4_translate(const Eax4Props& src, Eax5Props& dst) noexcept // Active FX slots. // - for (auto i = 0; i < EAX50_MAX_ACTIVE_FXSLOTS; ++i) { + for(size_t i{0};i < EAX50_MAX_ACTIVE_FXSLOTS;++i) + { auto& dst_id = dst.active_fx_slots.guidActiveFXSlots[i]; - if (i < EAX40_MAX_ACTIVE_FXSLOTS) { + if(i < EAX40_MAX_ACTIVE_FXSLOTS) + { const auto& src_id = src.active_fx_slots.guidActiveFXSlots[i]; - if (src_id == EAX_NULL_GUID) + if(src_id == EAX_NULL_GUID) dst_id = EAX_NULL_GUID; - else if (src_id == EAX_PrimaryFXSlotID) + else if(src_id == EAX_PrimaryFXSlotID) dst_id = EAX_PrimaryFXSlotID; - else if (src_id == EAXPROPERTYID_EAX40_FXSlot0) + else if(src_id == EAXPROPERTYID_EAX40_FXSlot0) dst_id = EAXPROPERTYID_EAX50_FXSlot0; - else if (src_id == EAXPROPERTYID_EAX40_FXSlot1) + else if(src_id == EAXPROPERTYID_EAX40_FXSlot1) dst_id = EAXPROPERTYID_EAX50_FXSlot1; - else if (src_id == EAXPROPERTYID_EAX40_FXSlot2) + else if(src_id == EAXPROPERTYID_EAX40_FXSlot2) dst_id = EAXPROPERTYID_EAX50_FXSlot2; - else if (src_id == EAXPROPERTYID_EAX40_FXSlot3) + else if(src_id == EAXPROPERTYID_EAX40_FXSlot3) dst_id = EAXPROPERTYID_EAX50_FXSlot3; else assert(false && "Unknown active FX slot ID."); - } else + } + else dst_id = EAX_NULL_GUID; } @@ -4359,7 +4362,7 @@ void ALsource::eax4_set(const EaxCall& call, Eax4Props& props) break; case EAXSOURCE_ACTIVEFXSLOTID: - eax4_defer_active_fx_slot_id(call, props.active_fx_slots.guidActiveFXSlots); + eax4_defer_active_fx_slot_id(call, al::span{props.active_fx_slots.guidActiveFXSlots}); break; default: @@ -4440,7 +4443,7 @@ void ALsource::eax5_set(const EaxCall& call, Eax5Props& props) break; case EAXSOURCE_ACTIVEFXSLOTID: - eax5_defer_active_fx_slot_id(call, props.active_fx_slots.guidActiveFXSlots); + eax5_defer_active_fx_slot_id(call, al::span{props.active_fx_slots.guidActiveFXSlots}); break; case EAXSOURCE_MACROFXFACTOR: @@ -4730,7 +4733,8 @@ void ALsource::eax4_get(const EaxCall& call, const Eax4Props& props) break; case EAXSOURCE_ACTIVEFXSLOTID: - eax_get_active_fx_slot_id(call, props.active_fx_slots.guidActiveFXSlots, EAX40_MAX_ACTIVE_FXSLOTS); + eax_get_active_fx_slot_id(call, props.active_fx_slots.guidActiveFXSlots.data(), + EAX40_MAX_ACTIVE_FXSLOTS); break; default: @@ -4802,7 +4806,8 @@ void ALsource::eax5_get(const EaxCall& call, const Eax5Props& props) break; case EAXSOURCE_ACTIVEFXSLOTID: - eax_get_active_fx_slot_id(call, props.active_fx_slots.guidActiveFXSlots, EAX50_MAX_ACTIVE_FXSLOTS); + eax_get_active_fx_slot_id(call, props.active_fx_slots.guidActiveFXSlots.data(), + EAX50_MAX_ACTIVE_FXSLOTS); break; case EAXSOURCE_MACROFXFACTOR: diff --git a/al/source.h b/al/source.h index c7694f83..26d425ef 100644 --- a/al/source.h +++ b/al/source.h @@ -978,21 +978,21 @@ private: } template - void eax_defer_active_fx_slot_id(const EaxCall& call, GUID (&dst_ids)[TIdCount]) + void eax_defer_active_fx_slot_id(const EaxCall& call, const al::span dst_ids) { const auto src_ids = call.get_values(TIdCount); std::for_each(src_ids.cbegin(), src_ids.cend(), TValidator{}); - std::uninitialized_copy(src_ids.cbegin(), src_ids.cend(), dst_ids); + std::uninitialized_copy(src_ids.cbegin(), src_ids.cend(), dst_ids.begin()); } template - void eax4_defer_active_fx_slot_id(const EaxCall& call, GUID (&dst_ids)[TIdCount]) + void eax4_defer_active_fx_slot_id(const EaxCall& call, const al::span dst_ids) { eax_defer_active_fx_slot_id(call, dst_ids); } template - void eax5_defer_active_fx_slot_id(const EaxCall& call, GUID (&dst_ids)[TIdCount]) + void eax5_defer_active_fx_slot_id(const EaxCall& call, const al::span dst_ids) { eax_defer_active_fx_slot_id(call, dst_ids); } diff --git a/alc/alc.cpp b/alc/alc.cpp index 9a919032..1ceae5ee 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -660,7 +660,7 @@ void alc_initconfig(void) { if(len == strlen(effectitem.name) && strncmp(effectitem.name, str, len) == 0) - DisabledEffects[effectitem.type] = true; + DisabledEffects.set(effectitem.type); } } while(next++); } @@ -683,15 +683,15 @@ void alc_initconfig(void) else eax_g_is_enabled = true; - if((DisabledEffects[EAXREVERB_EFFECT] || DisabledEffects[CHORUS_EFFECT]) + if((DisabledEffects.test(EAXREVERB_EFFECT) || DisabledEffects.test(CHORUS_EFFECT)) && eax_g_is_enabled) { eax_g_is_enabled = false; TRACE("EAX disabled because %s disabled.\n", - (DisabledEffects[EAXREVERB_EFFECT] && DisabledEffects[CHORUS_EFFECT]) + (DisabledEffects.test(EAXREVERB_EFFECT) && DisabledEffects.test(CHORUS_EFFECT)) ? "EAXReverb and Chorus are" : - DisabledEffects[EAXREVERB_EFFECT] ? "EAXReverb is" : - DisabledEffects[CHORUS_EFFECT] ? "Chorus is" : ""); + DisabledEffects.test(EAXREVERB_EFFECT) ? "EAXReverb is" : + DisabledEffects.test(CHORUS_EFFECT) ? "Chorus is" : ""); } } #endif // ALSOFT_EAX diff --git a/alc/alu.cpp b/alc/alu.cpp index 7b3cd957..fe47f9be 100644 --- a/alc/alu.cpp +++ b/alc/alu.cpp @@ -2257,10 +2257,10 @@ void DeviceBase::handleDisconnect(const char *msg, ...) va_list args; va_start(args, msg); - int msglen{vsnprintf(disconnect.msg, sizeof(disconnect.msg), msg, args)}; + int msglen{vsnprintf(disconnect.msg.data(), disconnect.msg.size(), msg, args)}; va_end(args); - if(msglen < 0 || static_cast(msglen) >= sizeof(disconnect.msg)) + if(msglen < 0 || static_cast(msglen) >= disconnect.msg.size()) disconnect.msg[sizeof(disconnect.msg)-1] = 0; for(ContextBase *ctx : *mContexts.load()) diff --git a/alc/backends/alsa.cpp b/alc/backends/alsa.cpp index 5aae834a..47c6385e 100644 --- a/alc/backends/alsa.cpp +++ b/alc/backends/alsa.cpp @@ -1039,7 +1039,7 @@ void AlsaCapture::captureSamples(std::byte *buffer, uint samples) { if(mRing) { - mRing->read(buffer, samples); + std::ignore = mRing->read(buffer, samples); return; } diff --git a/alc/backends/coreaudio.cpp b/alc/backends/coreaudio.cpp index 16b0781e..50e3bc66 100644 --- a/alc/backends/coreaudio.cpp +++ b/alc/backends/coreaudio.cpp @@ -657,7 +657,7 @@ OSStatus CoreAudioCapture::RecordProc(AudioUnitRenderActionFlags *ioActionFlags, return err; } - mRing->write(mCaptureData.data(), inNumberFrames); + std::ignore = mRing->write(mCaptureData.data(), inNumberFrames); return noErr; } @@ -924,7 +924,7 @@ void CoreAudioCapture::captureSamples(std::byte *buffer, uint samples) { if(!mConverter) { - mRing->read(buffer, samples); + std::ignore = mRing->read(buffer, samples); return; } diff --git a/alc/backends/dsound.cpp b/alc/backends/dsound.cpp index 58aa69b2..12196f74 100644 --- a/alc/backends/dsound.cpp +++ b/alc/backends/dsound.cpp @@ -717,7 +717,7 @@ void DSoundCapture::stop() } void DSoundCapture::captureSamples(std::byte *buffer, uint samples) -{ mRing->read(buffer, samples); } +{ std::ignore = mRing->read(buffer, samples); } uint DSoundCapture::availableSamples() { @@ -740,9 +740,9 @@ uint DSoundCapture::availableSamples() } if(SUCCEEDED(hr)) { - mRing->write(ReadPtr1, ReadCnt1/FrameSize); + std::ignore = mRing->write(ReadPtr1, ReadCnt1/FrameSize); if(ReadPtr2 != nullptr && ReadCnt2 > 0) - mRing->write(ReadPtr2, ReadCnt2/FrameSize); + std::ignore = mRing->write(ReadPtr2, ReadCnt2/FrameSize); hr = mDSCbuffer->Unlock(ReadPtr1, ReadCnt1, ReadPtr2, ReadCnt2); mCursor = ReadCursor; } diff --git a/alc/backends/oboe.cpp b/alc/backends/oboe.cpp index b7bab19a..9666063a 100644 --- a/alc/backends/oboe.cpp +++ b/alc/backends/oboe.cpp @@ -230,7 +230,7 @@ struct OboeCapture final : public BackendBase, public oboe::AudioStreamCallback oboe::DataCallbackResult OboeCapture::onAudioReady(oboe::AudioStream*, void *audioData, int32_t numFrames) { - mRing->write(audioData, static_cast(numFrames)); + std::ignore = mRing->write(audioData, static_cast(numFrames)); return oboe::DataCallbackResult::Continue; } @@ -330,7 +330,7 @@ uint OboeCapture::availableSamples() { return static_cast(mRing->readSpace()); } void OboeCapture::captureSamples(std::byte *buffer, uint samples) -{ mRing->read(buffer, samples); } +{ std::ignore = mRing->read(buffer, samples); } } // namespace diff --git a/alc/backends/oss.cpp b/alc/backends/oss.cpp index 87d3ba35..010b0749 100644 --- a/alc/backends/oss.cpp +++ b/alc/backends/oss.cpp @@ -617,7 +617,7 @@ void OSScapture::stop() } void OSScapture::captureSamples(std::byte *buffer, uint samples) -{ mRing->read(buffer, samples); } +{ std::ignore = mRing->read(buffer, samples); } uint OSScapture::availableSamples() { return static_cast(mRing->readSpace()); } diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp index 01896b01..96b6623f 100644 --- a/alc/backends/pipewire.cpp +++ b/alc/backends/pipewire.cpp @@ -1933,7 +1933,8 @@ void PipeWireCapture::inputCallback() noexcept const uint offset{minu(bufdata->chunk->offset, bufdata->maxsize)}; const uint size{minu(bufdata->chunk->size, bufdata->maxsize - offset)}; - mRing->write(static_cast(bufdata->data) + offset, size / mRing->getElemSize()); + std::ignore = mRing->write(static_cast(bufdata->data) + offset, + size / mRing->getElemSize()); pw_stream_queue_buffer(mStream.get(), pw_buf); } @@ -2154,7 +2155,7 @@ uint PipeWireCapture::availableSamples() { return static_cast(mRing->readSpace()); } void PipeWireCapture::captureSamples(std::byte *buffer, uint samples) -{ mRing->read(buffer, samples); } +{ std::ignore = mRing->read(buffer, samples); } } // namespace diff --git a/alc/backends/portaudio.cpp b/alc/backends/portaudio.cpp index 979a54d6..2e2e33cc 100644 --- a/alc/backends/portaudio.cpp +++ b/alc/backends/portaudio.cpp @@ -271,7 +271,7 @@ PortCapture::~PortCapture() int PortCapture::readCallback(const void *inputBuffer, void*, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo*, const PaStreamCallbackFlags) noexcept { - mRing->write(inputBuffer, framesPerBuffer); + std::ignore = mRing->write(inputBuffer, framesPerBuffer); return 0; } @@ -350,7 +350,7 @@ uint PortCapture::availableSamples() { return static_cast(mRing->readSpace()); } void PortCapture::captureSamples(std::byte *buffer, uint samples) -{ mRing->read(buffer, samples); } +{ std::ignore = mRing->read(buffer, samples); } } // namespace diff --git a/alc/backends/sndio.cpp b/alc/backends/sndio.cpp index d54c337b..8bf63a59 100644 --- a/alc/backends/sndio.cpp +++ b/alc/backends/sndio.cpp @@ -497,7 +497,7 @@ void SndioCapture::stop() } void SndioCapture::captureSamples(std::byte *buffer, uint samples) -{ mRing->read(buffer, samples); } +{ std::ignore = mRing->read(buffer, samples); } uint SndioCapture::availableSamples() { return static_cast(mRing->readSpace()); } diff --git a/alc/backends/wasapi.cpp b/alc/backends/wasapi.cpp index 436ee402..139fa696 100644 --- a/alc/backends/wasapi.cpp +++ b/alc/backends/wasapi.cpp @@ -2651,7 +2651,7 @@ void WasapiCapture::stopProxy() void WasapiCapture::captureSamples(std::byte *buffer, uint samples) -{ mRing->read(buffer, samples); } +{ std::ignore = mRing->read(buffer, samples); } uint WasapiCapture::availableSamples() { return static_cast(mRing->readSpace()); } diff --git a/alc/backends/winmm.cpp b/alc/backends/winmm.cpp index f0fb0a1c..15776d17 100644 --- a/alc/backends/winmm.cpp +++ b/alc/backends/winmm.cpp @@ -435,7 +435,8 @@ int WinMMCapture::captureProc() WAVEHDR &waveHdr = mWaveBuffer[widx]; widx = (widx+1) % mWaveBuffer.size(); - mRing->write(waveHdr.lpData, waveHdr.dwBytesRecorded / mFormat.nBlockAlign); + std::ignore = mRing->write(waveHdr.lpData, + waveHdr.dwBytesRecorded / mFormat.nBlockAlign); mReadable.fetch_sub(1, std::memory_order_acq_rel); waveInAddBuffer(mInHdl, &waveHdr, sizeof(WAVEHDR)); } while(--todo); @@ -573,7 +574,7 @@ void WinMMCapture::stop() } void WinMMCapture::captureSamples(std::byte *buffer, uint samples) -{ mRing->read(buffer, samples); } +{ std::ignore = mRing->read(buffer, samples); } uint WinMMCapture::availableSamples() { return static_cast(mRing->readSpace()); } diff --git a/alc/context.h b/alc/context.h index b190c5ea..32db76c7 100644 --- a/alc/context.h +++ b/alc/context.h @@ -560,7 +560,7 @@ private: using ContextRef = al::intrusive_ptr; -ContextRef GetContextRef(void); +ContextRef GetContextRef(); void UpdateContextProps(ALCcontext *context); diff --git a/alc/effects/base.h b/alc/effects/base.h index 95695857..025ac663 100644 --- a/alc/effects/base.h +++ b/alc/effects/base.h @@ -4,23 +4,29 @@ #include "core/effects/base.h" -EffectStateFactory *NullStateFactory_getFactory(void); -EffectStateFactory *ReverbStateFactory_getFactory(void); -EffectStateFactory *StdReverbStateFactory_getFactory(void); -EffectStateFactory *AutowahStateFactory_getFactory(void); -EffectStateFactory *ChorusStateFactory_getFactory(void); -EffectStateFactory *CompressorStateFactory_getFactory(void); -EffectStateFactory *DistortionStateFactory_getFactory(void); -EffectStateFactory *EchoStateFactory_getFactory(void); -EffectStateFactory *EqualizerStateFactory_getFactory(void); -EffectStateFactory *FlangerStateFactory_getFactory(void); -EffectStateFactory *FshifterStateFactory_getFactory(void); -EffectStateFactory *ModulatorStateFactory_getFactory(void); -EffectStateFactory *PshifterStateFactory_getFactory(void); -EffectStateFactory* VmorpherStateFactory_getFactory(void); - -EffectStateFactory *DedicatedStateFactory_getFactory(void); - -EffectStateFactory *ConvolutionStateFactory_getFactory(void); +/* This is a user config option for modifying the overall output of the reverb + * effect. + */ +inline float ReverbBoost{1.0f}; + + +EffectStateFactory *NullStateFactory_getFactory(); +EffectStateFactory *ReverbStateFactory_getFactory(); +EffectStateFactory *StdReverbStateFactory_getFactory(); +EffectStateFactory *AutowahStateFactory_getFactory(); +EffectStateFactory *ChorusStateFactory_getFactory(); +EffectStateFactory *CompressorStateFactory_getFactory(); +EffectStateFactory *DistortionStateFactory_getFactory(); +EffectStateFactory *EchoStateFactory_getFactory(); +EffectStateFactory *EqualizerStateFactory_getFactory(); +EffectStateFactory *FlangerStateFactory_getFactory(); +EffectStateFactory *FshifterStateFactory_getFactory(); +EffectStateFactory *ModulatorStateFactory_getFactory(); +EffectStateFactory *PshifterStateFactory_getFactory(); +EffectStateFactory* VmorpherStateFactory_getFactory(); + +EffectStateFactory *DedicatedStateFactory_getFactory(); + +EffectStateFactory *ConvolutionStateFactory_getFactory(); #endif /* EFFECTS_BASE_H */ diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp index 6a9d1997..5157cf72 100644 --- a/alc/effects/reverb.cpp +++ b/alc/effects/reverb.cpp @@ -48,11 +48,6 @@ #include "vecmat.h" #include "vector.h" -/* This is a user config option for modifying the overall output of the reverb - * effect. - */ -float ReverbBoost = 1.0f; - namespace { using uint = unsigned int; diff --git a/common/albit.h b/common/albit.h index 82a4a00d..d54a189c 100644 --- a/common/albit.h +++ b/common/albit.h @@ -1,6 +1,7 @@ #ifndef AL_BIT_H #define AL_BIT_H +#include #include #include #include @@ -17,9 +18,9 @@ std::enable_if_t, To> bit_cast(const From &src) noexcept { - alignas(To) char dst[sizeof(To)]; - std::memcpy(&dst[0], &src, sizeof(To)); - return *std::launder(reinterpret_cast(&dst[0])); + alignas(To) std::array dst; + std::memcpy(dst.data(), &src, sizeof(To)); + return *std::launder(reinterpret_cast(dst.data())); } #ifdef __BYTE_ORDER__ diff --git a/common/almalloc.h b/common/almalloc.h index 873473ca..288b5075 100644 --- a/common/almalloc.h +++ b/common/almalloc.h @@ -211,34 +211,34 @@ struct FlexArray { FlexArray(index_type size) : mStore{size} { } ~FlexArray() = default; - index_type size() const noexcept { return mStore.mSize; } - bool empty() const noexcept { return mStore.mSize == 0; } - - pointer data() noexcept { return mStore.mArray; } - const_pointer data() const noexcept { return mStore.mArray; } - - reference operator[](index_type i) noexcept { return mStore.mArray[i]; } - const_reference operator[](index_type i) const noexcept { return mStore.mArray[i]; } - - reference front() noexcept { return mStore.mArray[0]; } - const_reference front() const noexcept { return mStore.mArray[0]; } - - reference back() noexcept { return mStore.mArray[mStore.mSize-1]; } - const_reference back() const noexcept { return mStore.mArray[mStore.mSize-1]; } - - iterator begin() noexcept { return mStore.mArray; } - const_iterator begin() const noexcept { return mStore.mArray; } - const_iterator cbegin() const noexcept { return mStore.mArray; } - iterator end() noexcept { return mStore.mArray + mStore.mSize; } - const_iterator end() const noexcept { return mStore.mArray + mStore.mSize; } - const_iterator cend() const noexcept { return mStore.mArray + mStore.mSize; } - - reverse_iterator rbegin() noexcept { return end(); } - const_reverse_iterator rbegin() const noexcept { return end(); } - const_reverse_iterator crbegin() const noexcept { return cend(); } - reverse_iterator rend() noexcept { return begin(); } - const_reverse_iterator rend() const noexcept { return begin(); } - const_reverse_iterator crend() const noexcept { return cbegin(); } + [[nodiscard]] auto size() const noexcept -> index_type { return mStore.mSize; } + [[nodiscard]] auto empty() const noexcept -> bool { return mStore.mSize == 0; } + + [[nodiscard]] auto data() noexcept -> pointer { return mStore.mArray; } + [[nodiscard]] auto data() const noexcept -> const_pointer { return mStore.mArray; } + + [[nodiscard]] auto operator[](index_type i) noexcept -> reference { return mStore.mArray[i]; } + [[nodiscard]] auto operator[](index_type i) const noexcept -> const_reference { return mStore.mArray[i]; } + + [[nodiscard]] auto front() noexcept -> reference { return mStore.mArray[0]; } + [[nodiscard]] auto front() const noexcept -> const_reference { return mStore.mArray[0]; } + + [[nodiscard]] auto back() noexcept -> reference { return mStore.mArray[mStore.mSize-1]; } + [[nodiscard]] auto back() const noexcept -> const_reference { return mStore.mArray[mStore.mSize-1]; } + + [[nodiscard]] auto begin() noexcept -> iterator { return mStore.mArray; } + [[nodiscard]] auto begin() const noexcept -> const_iterator { return mStore.mArray; } + [[nodiscard]] auto cbegin() const noexcept -> const_iterator { return mStore.mArray; } + [[nodiscard]] auto end() noexcept -> iterator { return mStore.mArray + mStore.mSize; } + [[nodiscard]] auto end() const noexcept -> const_iterator { return mStore.mArray + mStore.mSize; } + [[nodiscard]] auto cend() const noexcept -> const_iterator { return mStore.mArray + mStore.mSize; } + + [[nodiscard]] auto rbegin() noexcept -> reverse_iterator { return end(); } + [[nodiscard]] auto rbegin() const noexcept -> const_reverse_iterator { return end(); } + [[nodiscard]] auto crbegin() const noexcept -> const_reverse_iterator { return cend(); } + [[nodiscard]] auto rend() noexcept -> reverse_iterator { return begin(); } + [[nodiscard]] auto rend() const noexcept -> const_reverse_iterator { return begin(); } + [[nodiscard]] auto crend() const noexcept -> const_reverse_iterator { return cbegin(); } DEF_PLACE_NEWDEL() }; diff --git a/common/alnumbers.h b/common/alnumbers.h index e92d7b87..7abe6b32 100644 --- a/common/alnumbers.h +++ b/common/alnumbers.h @@ -3,9 +3,7 @@ #include -namespace al { - -namespace numbers { +namespace al::numbers { namespace detail_ { template @@ -29,8 +27,6 @@ inline constexpr auto inv_pi = inv_pi_v; inline constexpr auto sqrt2 = sqrt2_v; inline constexpr auto sqrt3 = sqrt3_v; -} // namespace numbers - -} // namespace al +} // namespace al::numbers #endif /* COMMON_ALNUMBERS_H */ diff --git a/common/alnumeric.h b/common/alnumeric.h index 6281b012..cb8704b2 100644 --- a/common/alnumeric.h +++ b/common/alnumeric.h @@ -245,7 +245,7 @@ inline float fast_roundf(float f) noexcept /* Integral limit, where sub-integral precision is not available for * floats. */ - static constexpr float ilim[2]{ + static constexpr std::array ilim{ 8388608.0f /* 0x1.0p+23 */, -8388608.0f /* -0x1.0p+23 */ }; diff --git a/common/alspan.h b/common/alspan.h index 341ce7c8..d91747c2 100644 --- a/common/alspan.h +++ b/common/alspan.h @@ -107,43 +107,43 @@ public: constexpr span& operator=(const span &rhs) noexcept = default; - constexpr reference front() const { return *mData; } - constexpr reference back() const { return *(mData+E-1); } - constexpr reference operator[](index_type idx) const { return mData[idx]; } - constexpr pointer data() const noexcept { return mData; } - - constexpr index_type size() const noexcept { return E; } - constexpr index_type size_bytes() const noexcept { return E * sizeof(value_type); } - constexpr bool empty() const noexcept { return E == 0; } - - constexpr iterator begin() const noexcept { return mData; } - constexpr iterator end() const noexcept { return mData+E; } - constexpr const_iterator cbegin() const noexcept { return mData; } - constexpr const_iterator cend() const noexcept { return mData+E; } - - constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator{end()}; } - constexpr reverse_iterator rend() const noexcept { return reverse_iterator{begin()}; } - constexpr const_reverse_iterator crbegin() const noexcept + [[nodiscard]] constexpr auto front() const -> reference { return *mData; } + [[nodiscard]] constexpr auto back() const -> reference { return *(mData+E-1); } + [[nodiscard]] constexpr auto operator[](index_type idx) const -> reference { return mData[idx]; } + [[nodiscard]] constexpr auto data() const noexcept -> pointer { return mData; } + + [[nodiscard]] constexpr auto size() const noexcept -> index_type { return E; } + [[nodiscard]] constexpr auto size_bytes() const noexcept -> index_type { return E * sizeof(value_type); } + [[nodiscard]] constexpr auto empty() const noexcept -> bool { return E == 0; } + + [[nodiscard]] constexpr auto begin() const noexcept -> iterator { return mData; } + [[nodiscard]] constexpr auto end() const noexcept -> iterator { return mData+E; } + [[nodiscard]] constexpr auto cbegin() const noexcept -> const_iterator { return mData; } + [[nodiscard]] constexpr auto cend() const noexcept -> const_iterator { return mData+E; } + + [[nodiscard]] constexpr auto rbegin() const noexcept -> reverse_iterator { return reverse_iterator{end()}; } + [[nodiscard]] constexpr auto rend() const noexcept -> reverse_iterator { return reverse_iterator{begin()}; } + [[nodiscard]] constexpr auto crbegin() const noexcept -> const_reverse_iterator { return const_reverse_iterator{cend()}; } - constexpr const_reverse_iterator crend() const noexcept + [[nodiscard]] constexpr auto crend() const noexcept -> const_reverse_iterator { return const_reverse_iterator{cbegin()}; } template - constexpr span first() const + [[nodiscard]] constexpr auto first() const -> span { static_assert(E >= C, "New size exceeds original capacity"); return span{mData, C}; } template - constexpr span last() const + [[nodiscard]] constexpr auto last() const -> span { static_assert(E >= C, "New size exceeds original capacity"); return span{mData+(E-C), C}; } template - constexpr auto subspan() const -> std::enable_if_t> + [[nodiscard]] constexpr auto subspan() const -> std::enable_if_t> { static_assert(E >= O, "Offset exceeds extent"); static_assert(E-O >= C, "New size exceeds original capacity"); @@ -151,7 +151,7 @@ public: } template - constexpr auto subspan() const -> std::enable_if_t> + [[nodiscard]] constexpr auto subspan() const -> std::enable_if_t> { static_assert(E >= O, "Offset exceeds extent"); return span{mData+O, E-O}; @@ -161,10 +161,10 @@ public: * defining the specialization. As a result, these methods need to be * defined later. */ - constexpr span first(size_t count) const; - constexpr span last(size_t count) const; - constexpr span subspan(size_t offset, - size_t count=dynamic_extent) const; + [[nodiscard]] constexpr auto first(size_t count) const -> span; + [[nodiscard]] constexpr auto last(size_t count) const -> span; + [[nodiscard]] constexpr auto subspan(size_t offset, + size_t count=dynamic_extent) const -> span; private: pointer mData{nullptr}; @@ -221,51 +221,51 @@ public: constexpr span& operator=(const span &rhs) noexcept = default; - constexpr reference front() const { return *mData; } - constexpr reference back() const { return *(mDataEnd-1); } - constexpr reference operator[](index_type idx) const { return mData[idx]; } - constexpr pointer data() const noexcept { return mData; } + [[nodiscard]] constexpr auto front() const -> reference { return *mData; } + [[nodiscard]] constexpr auto back() const -> reference { return *(mDataEnd-1); } + [[nodiscard]] constexpr auto operator[](index_type idx) const -> reference { return mData[idx]; } + [[nodiscard]] constexpr auto data() const noexcept -> pointer { return mData; } - constexpr index_type size() const noexcept { return static_cast(mDataEnd-mData); } - constexpr index_type size_bytes() const noexcept + [[nodiscard]] constexpr auto size() const noexcept -> index_type { return static_cast(mDataEnd-mData); } + [[nodiscard]] constexpr auto size_bytes() const noexcept -> index_type { return static_cast(mDataEnd-mData) * sizeof(value_type); } - constexpr bool empty() const noexcept { return mData == mDataEnd; } + [[nodiscard]] constexpr auto empty() const noexcept -> bool { return mData == mDataEnd; } - constexpr iterator begin() const noexcept { return mData; } - constexpr iterator end() const noexcept { return mDataEnd; } - constexpr const_iterator cbegin() const noexcept { return mData; } - constexpr const_iterator cend() const noexcept { return mDataEnd; } + [[nodiscard]] constexpr auto begin() const noexcept -> iterator { return mData; } + [[nodiscard]] constexpr auto end() const noexcept -> iterator { return mDataEnd; } + [[nodiscard]] constexpr auto cbegin() const noexcept -> const_iterator { return mData; } + [[nodiscard]] constexpr auto cend() const noexcept -> const_iterator { return mDataEnd; } - constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator{end()}; } - constexpr reverse_iterator rend() const noexcept { return reverse_iterator{begin()}; } - constexpr const_reverse_iterator crbegin() const noexcept + [[nodiscard]] constexpr auto rbegin() const noexcept -> reverse_iterator { return reverse_iterator{end()}; } + [[nodiscard]] constexpr auto rend() const noexcept -> reverse_iterator { return reverse_iterator{begin()}; } + [[nodiscard]] constexpr auto crbegin() const noexcept -> const_reverse_iterator { return const_reverse_iterator{cend()}; } - constexpr const_reverse_iterator crend() const noexcept + [[nodiscard]] constexpr auto crend() const noexcept -> const_reverse_iterator { return const_reverse_iterator{cbegin()}; } template - constexpr span first() const + [[nodiscard]] constexpr auto first() const -> span { return span{mData, C}; } - constexpr span first(size_t count) const + [[nodiscard]] constexpr auto first(size_t count) const -> span { return (count >= size()) ? *this : span{mData, mData+count}; } template - constexpr span last() const + [[nodiscard]] constexpr auto last() const -> span { return span{mDataEnd-C, C}; } - constexpr span last(size_t count) const + [[nodiscard]] constexpr auto last(size_t count) const -> span { return (count >= size()) ? *this : span{mDataEnd-count, mDataEnd}; } template - constexpr auto subspan() const -> std::enable_if_t> + [[nodiscard]] constexpr auto subspan() const -> std::enable_if_t> { return span{mData+O, C}; } template - constexpr auto subspan() const -> std::enable_if_t> + [[nodiscard]] constexpr auto subspan() const -> std::enable_if_t> { return span{mData+O, mDataEnd}; } - constexpr span subspan(size_t offset, size_t count=dynamic_extent) const + [[nodiscard]] constexpr auto subspan(size_t offset, size_t count=dynamic_extent) const -> span { return (offset > size()) ? span{} : (count >= size()-offset) ? span{mData+offset, mDataEnd} : @@ -278,21 +278,21 @@ private: }; template -constexpr inline auto span::first(size_t count) const -> span +[[nodiscard]] constexpr inline auto span::first(size_t count) const -> span { return (count >= size()) ? span{mData, extent} : span{mData, count}; } template -constexpr inline auto span::last(size_t count) const -> span +[[nodiscard]] constexpr inline auto span::last(size_t count) const -> span { return (count >= size()) ? span{mData, extent} : span{mData+extent-count, count}; } template -constexpr inline auto span::subspan(size_t offset, size_t count) const +[[nodiscard]] constexpr inline auto span::subspan(size_t offset, size_t count) const -> span { return (offset > size()) ? span{} : diff --git a/common/intrusive_ptr.h b/common/intrusive_ptr.h index 714a5617..0152b92a 100644 --- a/common/intrusive_ptr.h +++ b/common/intrusive_ptr.h @@ -81,9 +81,9 @@ public: explicit operator bool() const noexcept { return mPtr != nullptr; } - T& operator*() const noexcept { return *mPtr; } - T* operator->() const noexcept { return mPtr; } - T* get() const noexcept { return mPtr; } + [[nodiscard]] auto operator*() const noexcept -> T& { return *mPtr; } + [[nodiscard]] auto operator->() const noexcept -> T* { return mPtr; } + [[nodiscard]] auto get() const noexcept -> T* { return mPtr; } void reset(T *ptr=nullptr) noexcept { diff --git a/common/pffft.cpp b/common/pffft.cpp index 8e849cb4..505c9791 100644 --- a/common/pffft.cpp +++ b/common/pffft.cpp @@ -58,11 +58,11 @@ #include "pffft.h" #include -#include +#include #include +#include +#include #include -#include -#include #include #include "albit.h" @@ -90,7 +90,7 @@ using uint = unsigned int; * Altivec support macros */ #if defined(__ppc__) || defined(__ppc64__) || defined(__powerpc__) || defined(__powerpc64__) -typedef vector float v4sf; +using v4sf = vector float; #define SIMD_SZ 4 #define VZERO() ((vector float) vec_splat_u8(0)) #define VMUL(a,b) vec_madd(a,b, VZERO()) @@ -142,7 +142,7 @@ force_inline void vtranspose4(v4sf &x0, v4sf &x1, v4sf &x2, v4sf &x3) noexcept (defined(_M_IX86_FP) && _M_IX86_FP >= 1) #include -typedef __m128 v4sf; +using v4sf = __m128; #define SIMD_SZ 4 // 4 floats by simd vector -- this is pretty much hardcoded in the preprocess/finalize functions anyway so you will have to work if you want to enable AVX with its 256-bit vectors. #define VZERO _mm_setzero_ps #define VMUL _mm_mul_ps @@ -178,7 +178,7 @@ force_inline void vtranspose4(v4sf &x0, v4sf &x1, v4sf &x2, v4sf &x3) noexcept #elif defined(__ARM_NEON) || defined(__aarch64__) || defined(__arm64) #include -typedef float32x4_t v4sf; +using v4sf = float32x4_t; #define SIMD_SZ 4 #define VZERO() vdupq_n_f32(0) #define VMUL vmulq_f32 @@ -297,7 +297,7 @@ force_inline v4sf vswaphl(v4sf a, v4sf b) noexcept // fallback mode for situations where SIMD is not available, use scalar mode instead #ifdef PFFFT_SIMD_DISABLE -typedef float v4sf; +using v4sf = float; #define SIMD_SZ 1 #define VZERO() 0.f #define VMUL(a,b) ((a)*(b)) @@ -335,14 +335,14 @@ force_inline void vcplxmulconj(v4sf &ar, v4sf &ai, v4sf br, v4sf bi) noexcept [[maybe_unused]] void validate_pffft_simd() { using float4 = std::array; - static constexpr float f[16]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + static constexpr std::array f{{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}}; float4 a0_f, a1_f, a2_f, a3_f, t_f, u_f; v4sf a0_v, a1_v, a2_v, a3_v, t_v, u_v; - std::memcpy(&a0_v, f, 4*sizeof(float)); - std::memcpy(&a1_v, f+4, 4*sizeof(float)); - std::memcpy(&a2_v, f+8, 4*sizeof(float)); - std::memcpy(&a3_v, f+12, 4*sizeof(float)); + std::memcpy(&a0_v, f.data(), 4*sizeof(float)); + std::memcpy(&a1_v, f.data()+4, 4*sizeof(float)); + std::memcpy(&a2_v, f.data()+8, 4*sizeof(float)); + std::memcpy(&a3_v, f.data()+12, 4*sizeof(float)); t_v = VZERO(); t_f = al::bit_cast(t_v); printf("VZERO=[%2g %2g %2g %2g]\n", t_f[0], t_f[1], t_f[2], t_f[3]); assertv4(t, 0, 0, 0, 0); @@ -1331,7 +1331,7 @@ uint decompose(const uint n, const al::span ifac, const al::span ifac) { - static constexpr uint ntryh[]{4,2,3,5}; + static constexpr std::array ntryh{4u,2u,3u,5u}; const uint nf{decompose(n, ifac, ntryh)}; const double argh{2.0*al::numbers::pi / n}; @@ -1365,7 +1365,7 @@ void rffti1_ps(const uint n, float *wa, const al::span ifac) void cffti1_ps(const uint n, float *wa, const al::span ifac) { - static constexpr uint ntryh[]{5,3,4,2}; + static constexpr std::array ntryh{5u,3u,4u,2u}; const uint nf{decompose(n, ifac, ntryh)}; const double argh{2.0*al::numbers::pi / n}; @@ -1814,7 +1814,7 @@ void pffft_transform_internal(const PFFFT_Setup *setup, const v4sf *vinput, v4sf const size_t Ncvec{setup->Ncvec}; const bool nf_odd{(setup->ifac[1]&1) != 0}; - v4sf *buff[2]{voutput, scratch}; + std::array buff{voutput, scratch}; bool ib{nf_odd != ordered}; if(direction == PFFFT_FORWARD) { diff --git a/common/ringbuffer.h b/common/ringbuffer.h index 8c65c3af..718238a3 100644 --- a/common/ringbuffer.h +++ b/common/ringbuffer.h @@ -36,26 +36,26 @@ public: RingBuffer(const std::size_t count) : mBuffer{count} { } /** Reset the read and write pointers to zero. This is not thread safe. */ - void reset() noexcept; + auto reset() noexcept -> void; /** * The non-copying data reader. Returns two ringbuffer data pointers that * hold the current readable data. If the readable data is in one segment * the second segment has zero length. */ - DataPair getReadVector() const noexcept; + [[nodiscard]] auto getReadVector() const noexcept -> DataPair; /** * The non-copying data writer. Returns two ringbuffer data pointers that * hold the current writeable data. If the writeable data is in one segment * the second segment has zero length. */ - DataPair getWriteVector() const noexcept; + [[nodiscard]] auto getWriteVector() const noexcept -> DataPair; /** * Return the number of elements available for reading. This is the number * of elements in front of the read pointer and behind the write pointer. */ - std::size_t readSpace() const noexcept + [[nodiscard]] auto readSpace() const noexcept -> size_t { const size_t w{mWritePtr.load(std::memory_order_acquire)}; const size_t r{mReadPtr.load(std::memory_order_acquire)}; @@ -66,14 +66,14 @@ public: * The copying data reader. Copy at most `cnt' elements into `dest'. * Returns the actual number of elements copied. */ - std::size_t read(void *dest, std::size_t cnt) noexcept; + [[nodiscard]] auto read(void *dest, size_t cnt) noexcept -> size_t; /** * The copying data reader w/o read pointer advance. Copy at most `cnt' * elements into `dest'. Returns the actual number of elements copied. */ - std::size_t peek(void *dest, std::size_t cnt) const noexcept; + [[nodiscard]] auto peek(void *dest, size_t cnt) const noexcept -> size_t; /** Advance the read pointer `cnt' places. */ - void readAdvance(std::size_t cnt) noexcept + auto readAdvance(size_t cnt) noexcept -> void { mReadPtr.fetch_add(cnt, std::memory_order_acq_rel); } @@ -81,7 +81,7 @@ public: * Return the number of elements available for writing. This is the number * of elements in front of the write pointer and behind the read pointer. */ - std::size_t writeSpace() const noexcept + [[nodiscard]] auto writeSpace() const noexcept -> size_t { const size_t w{mWritePtr.load(std::memory_order_acquire)}; const size_t r{mReadPtr.load(std::memory_order_acquire) + mWriteSize - mSizeMask}; @@ -92,12 +92,12 @@ public: * The copying data writer. Copy at most `cnt' elements from `src'. Returns * the actual number of elements copied. */ - std::size_t write(const void *src, std::size_t cnt) noexcept; + [[nodiscard]] auto write(const void *src, size_t cnt) noexcept -> size_t; /** Advance the write pointer `cnt' places. */ - void writeAdvance(std::size_t cnt) noexcept + auto writeAdvance(size_t cnt) noexcept -> void { mWritePtr.fetch_add(cnt, std::memory_order_acq_rel); } - std::size_t getElemSize() const noexcept { return mElemSize; } + [[nodiscard]] auto getElemSize() const noexcept -> size_t { return mElemSize; } /** * Create a new ringbuffer to hold at least `sz' elements of `elem_sz' @@ -105,7 +105,8 @@ public: * (even if it is already a power of two, to ensure the requested amount * can be written). */ - static std::unique_ptr Create(std::size_t sz, std::size_t elem_sz, int limit_writes); + [[nodiscard]] + static auto Create(size_t sz, size_t elem_sz, int limit_writes) -> std::unique_ptr; DEF_FAM_NEWDEL(RingBuffer, mBuffer) }; diff --git a/common/vecmat.h b/common/vecmat.h index a45f262f..0cdb82eb 100644 --- a/common/vecmat.h +++ b/common/vecmat.h @@ -14,7 +14,7 @@ namespace alu { template class VectorR { static_assert(std::is_floating_point::value, "Must use floating-point types"); - alignas(16) T mVals[4]; + alignas(16) std::array mVals; public: constexpr VectorR() noexcept = default; @@ -58,7 +58,7 @@ public: return T{0}; } - constexpr VectorR cross_product(const alu::VectorR &rhs) const noexcept + [[nodiscard]] constexpr auto cross_product(const alu::VectorR &rhs) const noexcept -> VectorR { return VectorR{ mVals[1]*rhs.mVals[2] - mVals[2]*rhs.mVals[1], @@ -67,7 +67,7 @@ public: T{0}}; } - constexpr T dot_product(const alu::VectorR &rhs) const noexcept + [[nodiscard]] constexpr auto dot_product(const alu::VectorR &rhs) const noexcept -> T { return mVals[0]*rhs.mVals[0] + mVals[1]*rhs.mVals[1] + mVals[2]*rhs.mVals[2]; } }; using Vector = VectorR; @@ -75,7 +75,7 @@ using Vector = VectorR; template class MatrixR { static_assert(std::is_floating_point::value, "Must use floating-point types"); - alignas(16) T mVals[16]; + alignas(16) std::array mVals; public: constexpr MatrixR() noexcept = default; diff --git a/core/async_event.h b/core/async_event.h index f1ca0c7b..20857c9c 100644 --- a/core/async_event.h +++ b/core/async_event.h @@ -1,6 +1,7 @@ #ifndef CORE_EVENT_H #define CORE_EVENT_H +#include #include #include @@ -39,7 +40,7 @@ struct AsyncBufferCompleteEvent { }; struct AsyncDisconnectEvent { - char msg[244]; + std::array msg; }; struct AsyncEffectReleaseEvent { diff --git a/core/effects/base.h b/core/effects/base.h index 83df7cf0..7d8770fb 100644 --- a/core/effects/base.h +++ b/core/effects/base.h @@ -71,10 +71,10 @@ union EffectProps { float DecayLFRatio; float ReflectionsGain; float ReflectionsDelay; - float ReflectionsPan[3]; + std::array ReflectionsPan; float LateReverbGain; float LateReverbDelay; - float LateReverbPan[3]; + std::array LateReverbPan; float EchoTime; float EchoDepth; float ModulationTime; diff --git a/core/except.h b/core/except.h index 0e28e9df..eec876db 100644 --- a/core/except.h +++ b/core/except.h @@ -14,12 +14,12 @@ class base_exception : public std::exception { protected: base_exception() = default; - virtual ~base_exception(); + ~base_exception() override; - void setMessage(const char *msg, std::va_list args); + auto setMessage(const char *msg, std::va_list args) -> void; public: - const char *what() const noexcept override { return mMessage.c_str(); } + [[nodiscard]] auto what() const noexcept -> const char* override { return mMessage.c_str(); } }; } // namespace al diff --git a/examples/alffplay.cpp b/examples/alffplay.cpp index 1f02ef70..54803035 100644 --- a/examples/alffplay.cpp +++ b/examples/alffplay.cpp @@ -474,8 +474,8 @@ nanoseconds AudioState::getClockNoLock() // Get the current device clock time and latency. auto device = alcGetContextsDevice(alcGetCurrentContext()); - ALCint64SOFT devtimes[2]{0,0}; - alcGetInteger64vSOFT(device, ALC_DEVICE_CLOCK_LATENCY_SOFT, 2, devtimes); + std::array devtimes{}; + alcGetInteger64vSOFT(device, ALC_DEVICE_CLOCK_LATENCY_SOFT, 2, devtimes.data()); auto latency = nanoseconds{devtimes[1]}; auto device_time = nanoseconds{devtimes[0]}; @@ -494,15 +494,14 @@ nanoseconds AudioState::getClockNoLock() * actually the timestamp of the first sample frame played. The audio * clock, then, is that plus the current source offset. */ - ALint64SOFT offset[2]; + std::array offset{}; if(alGetSourcei64vSOFT) - alGetSourcei64vSOFT(mSource, AL_SAMPLE_OFFSET_LATENCY_SOFT, offset); + alGetSourcei64vSOFT(mSource, AL_SAMPLE_OFFSET_LATENCY_SOFT, offset.data()); else { ALint ioffset; alGetSourcei(mSource, AL_SAMPLE_OFFSET, &ioffset); offset[0] = ALint64SOFT{ioffset} << 32; - offset[1] = 0; } /* NOTE: The source state must be checked last, in case an underrun * occurs and the source stops between getting the state and retrieving @@ -550,15 +549,14 @@ nanoseconds AudioState::getClockNoLock() nanoseconds pts{mCurrentPts}; if(mSource) { - ALint64SOFT offset[2]; + std::array offset{}; if(alGetSourcei64vSOFT) - alGetSourcei64vSOFT(mSource, AL_SAMPLE_OFFSET_LATENCY_SOFT, offset); + alGetSourcei64vSOFT(mSource, AL_SAMPLE_OFFSET_LATENCY_SOFT, offset.data()); else { ALint ioffset; alGetSourcei(mSource, AL_SAMPLE_OFFSET, &ioffset); offset[0] = ALint64SOFT{ioffset} << 32; - offset[1] = 0; } ALint queued, status; alGetSourcei(mSource, AL_BUFFERS_QUEUED, &queued); @@ -610,8 +608,8 @@ bool AudioState::startPlayback() /* Subtract the total buffer queue time from the current pts to get the * pts of the start of the queue. */ - int64_t srctimes[2]{0,0}; - alGetSourcei64vSOFT(mSource, AL_SAMPLE_OFFSET_CLOCK_SOFT, srctimes); + std::array srctimes{}; + alGetSourcei64vSOFT(mSource, AL_SAMPLE_OFFSET_CLOCK_SOFT, srctimes.data()); auto device_time = nanoseconds{srctimes[1]}; auto src_offset = duration_cast(fixed32{srctimes[0]}) / mCodecCtx->sample_rate; @@ -1151,9 +1149,9 @@ int AudioState::handler() mSwresCtx.reset(ps); if(err != 0) { - char errstr[AV_ERROR_MAX_STRING_SIZE]{}; + std::array errstr{}; std::cerr<< "Failed to allocate SwrContext: " - < errstr{}; std::cerr<< "Failed to allocate SwrContext: " - < errstr{}; std::cerr<< "Failed to initialize audio converter: " - <(M_PI / 3.0), static_cast(-M_PI / 3.0)}; - alSourcefv(mSource, AL_STEREO_ANGLES, angles); + const std::array angles{static_cast(M_PI / 3.0), static_cast(-M_PI / 3.0)}; + alSourcefv(mSource, AL_STEREO_ANGLES, angles.data()); } if(has_bfmt_ex) { @@ -1260,7 +1258,7 @@ int AudioState::handler() /* Prefill the codec buffer. */ auto packet_sender = [this]() { - while(1) + while(true) { const int ret{mQueue.sendPacket(mCodecCtx.get())}; if(ret == AVErrorEOF) break; @@ -1287,7 +1285,7 @@ int AudioState::handler() mCurrentPts += skip; } - while(1) + while(true) { if(mMovie.mQuit.load(std::memory_order_relaxed)) { @@ -1451,7 +1449,7 @@ void VideoState::updateVideo(SDL_Window *screen, SDL_Renderer *renderer, bool re auto clocktime = mMovie.getMasterClock(); bool updated{false}; - while(1) + while(true) { size_t next_idx{(read_idx+1)%mPictQ.size()}; if(next_idx == mPictQWrite.load(std::memory_order_acquire)) @@ -1546,18 +1544,15 @@ void VideoState::updateVideo(SDL_Window *screen, SDL_Renderer *renderer, bool re } /* point pict at the queue */ - uint8_t *pict_data[3]; + std::array pict_data; pict_data[0] = static_cast(pixels); pict_data[1] = pict_data[0] + w*h; pict_data[2] = pict_data[1] + w*h/4; - int pict_linesize[3]; - pict_linesize[0] = pitch; - pict_linesize[1] = pitch / 2; - pict_linesize[2] = pitch / 2; + std::array pict_linesize{pitch, pitch/2, pitch/2}; - sws_scale(mSwscaleCtx.get(), reinterpret_cast(frame->data), frame->linesize, - 0, h, pict_data, pict_linesize); + sws_scale(mSwscaleCtx.get(), reinterpret_cast(frame->data), + frame->linesize, 0, h, pict_data.data(), pict_linesize.data()); SDL_UnlockTexture(mImage); } @@ -1599,7 +1594,7 @@ int VideoState::handler() /* Prefill the codec buffer. */ auto packet_sender = [this]() { - while(1) + while(true) { const int ret{mQueue.sendPacket(mCodecCtx.get())}; if(ret == AVErrorEOF) break; @@ -1613,7 +1608,7 @@ int VideoState::handler() } auto current_pts = nanoseconds::zero(); - while(1) + while(true) { size_t write_idx{mPictQWrite.load(std::memory_order_relaxed)}; Picture *vp{&mPictQ[write_idx]}; @@ -2062,7 +2057,7 @@ int main(int argc, char *argv[]) while(fileidx < argc && !movState) { - movState = std::unique_ptr{new MovieState{argv[fileidx++]}}; + movState = std::make_unique(argv[fileidx++]); if(!movState->prepare()) movState = nullptr; } if(!movState) @@ -2077,7 +2072,7 @@ int main(int argc, char *argv[]) Next, Quit } eom_action{EomAction::Next}; seconds last_time{seconds::min()}; - while(1) + while(true) { /* SDL_WaitEventTimeout is broken, just force a 10ms sleep. */ std::this_thread::sleep_for(milliseconds{10}); @@ -2145,7 +2140,7 @@ int main(int argc, char *argv[]) movState = nullptr; while(fileidx < argc && !movState) { - movState = std::unique_ptr{new MovieState{argv[fileidx++]}}; + movState = std::make_unique(argv[fileidx++]); if(!movState->prepare()) movState = nullptr; } if(movState) diff --git a/utils/alsoft-config/mainwindow.cpp b/utils/alsoft-config/mainwindow.cpp index bee7022f..207c98c4 100644 --- a/utils/alsoft-config/mainwindow.cpp +++ b/utils/alsoft-config/mainwindow.cpp @@ -583,7 +583,7 @@ QStringList MainWindow::collectHrtfs() break; } ++i; - } while(1); + } while(true); } } } @@ -618,7 +618,7 @@ QStringList MainWindow::collectHrtfs() break; } ++i; - } while(1); + } while(true); } } } -- cgit v1.2.3 From ec40e4fefef954544c25285bfeae4a44c1134a44 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 11 Dec 2023 15:08:12 -0800 Subject: Finish cleanup for effects --- alc/effects/autowah.cpp | 49 ++++++++++--------- alc/effects/chorus.cpp | 33 +++++++------ alc/effects/compressor.cpp | 9 ++-- alc/effects/convolution.cpp | 115 +++++++++++++++++++++++--------------------- alc/effects/dedicated.cpp | 4 +- alc/effects/distortion.cpp | 14 +++--- alc/effects/echo.cpp | 34 ++++++------- alc/effects/equalizer.cpp | 15 +++--- alc/effects/fshifter.cpp | 17 ++++--- alc/effects/modulator.cpp | 5 +- alc/effects/pshifter.cpp | 12 ++--- alc/effects/reverb.cpp | 98 +++++++++++++++++++------------------ alc/effects/vmorpher.cpp | 104 +++++++++++++++++++-------------------- core/effectslot.cpp | 5 +- 14 files changed, 265 insertions(+), 249 deletions(-) (limited to 'alc/effects/reverb.cpp') diff --git a/alc/effects/autowah.cpp b/alc/effects/autowah.cpp index 4f874ef2..6d66f99f 100644 --- a/alc/effects/autowah.cpp +++ b/alc/effects/autowah.cpp @@ -59,12 +59,13 @@ struct AutowahState final : public EffectState { float mEnvDelay; /* Filter components derived from the envelope. */ - struct { + struct FilterParam { float cos_w0; float alpha; - } mEnv[BufferLineSize]; + }; + std::array mEnv; - struct { + struct ChannelData { uint mTargetChannel{InvalidChannelIndex}; /* Effect filters' history. */ @@ -75,10 +76,11 @@ struct AutowahState final : public EffectState { /* Effect gains for each output channel */ float mCurrentGain; float mTargetGain; - } mChans[MaxAmbiChannels]; + }; + std::array mChans; /* Effects buffers */ - alignas(16) float mBufferOut[BufferLineSize]; + alignas(16) FloatBufferLine mBufferOut; void deviceUpdate(const DeviceBase *device, const BufferStorage *buffer) override; @@ -155,17 +157,16 @@ void AutowahState::process(const size_t samplesToDo, float env_delay{mEnvDelay}; for(size_t i{0u};i < samplesToDo;i++) { - float w0, sample, a; - /* Envelope follower described on the book: Audio Effects, Theory, * Implementation and Application. */ - sample = peak_gain * std::fabs(samplesIn[0][i]); - a = (sample > env_delay) ? attack_rate : release_rate; + const float sample{peak_gain * std::fabs(samplesIn[0][i])}; + const float a{(sample > env_delay) ? attack_rate : release_rate}; env_delay = lerpf(sample, env_delay, a); /* Calculate the cos and alpha components for this sample's filter. */ - w0 = minf((bandwidth*env_delay + freq_min), 0.46f) * (al::numbers::pi_v*2.0f); + const float w0{minf((bandwidth*env_delay + freq_min), 0.46f) * + (al::numbers::pi_v*2.0f)}; mEnv[i].cos_w0 = std::cos(w0); mEnv[i].alpha = std::sin(w0)/(2.0f * QFactor); } @@ -194,18 +195,18 @@ void AutowahState::process(const size_t samplesToDo, { const float alpha{mEnv[i].alpha}; const float cos_w0{mEnv[i].cos_w0}; - float input, output; - float a[3], b[3]; - - b[0] = 1.0f + alpha*res_gain; - b[1] = -2.0f * cos_w0; - b[2] = 1.0f - alpha*res_gain; - a[0] = 1.0f + alpha/res_gain; - a[1] = -2.0f * cos_w0; - a[2] = 1.0f - alpha/res_gain; - - input = insamples[i]; - output = input*(b[0]/a[0]) + z1; + + const std::array b{ + 1.0f + alpha*res_gain, + -2.0f * cos_w0, + 1.0f - alpha*res_gain}; + const std::array a{ + 1.0f + alpha/res_gain, + -2.0f * cos_w0, + 1.0f - alpha/res_gain}; + + const float input{insamples[i]}; + const float output{input*(b[0]/a[0]) + z1}; z1 = input*(b[1]/a[0]) - output*(a[1]/a[0]) + z2; z2 = input*(b[2]/a[0]) - output*(a[2]/a[0]); mBufferOut[i] = output; @@ -214,8 +215,8 @@ void AutowahState::process(const size_t samplesToDo, chandata->mFilter.z2 = z2; /* Now, mix the processed sound data to the output. */ - MixSamples({mBufferOut, samplesToDo}, samplesOut[outidx].data(), chandata->mCurrentGain, - chandata->mTargetGain, samplesToDo); + MixSamples({mBufferOut.data(), samplesToDo}, samplesOut[outidx].data(), + chandata->mCurrentGain, chandata->mTargetGain, samplesToDo); ++chandata; } } diff --git a/alc/effects/chorus.cpp b/alc/effects/chorus.cpp index 9cbc922f..098b33a1 100644 --- a/alc/effects/chorus.cpp +++ b/alc/effects/chorus.cpp @@ -58,16 +58,17 @@ struct ChorusState final : public EffectState { uint mLfoDisp{0}; /* Calculated delays to apply to the left and right outputs. */ - uint mModDelays[2][BufferLineSize]; + std::array,2> mModDelays; /* Temp storage for the modulated left and right outputs. */ - alignas(16) float mBuffer[2][BufferLineSize]; + alignas(16) std::array mBuffer; /* Gains for left and right outputs. */ - struct { - float Current[MaxAmbiChannels]{}; - float Target[MaxAmbiChannels]{}; - } mGains[2]; + struct OutGains { + std::array Current{}; + std::array Target{}; + }; + std::array mGains; /* effect parameters */ ChorusWaveform mWaveform{}; @@ -99,8 +100,8 @@ void ChorusState::deviceUpdate(const DeviceBase *Device, const BufferStorage*) std::fill(mDelayBuffer.begin(), mDelayBuffer.end(), 0.0f); for(auto &e : mGains) { - std::fill(std::begin(e.Current), std::end(e.Current), 0.0f); - std::fill(std::begin(e.Target), std::end(e.Target), 0.0f); + e.Current.fill(0.0f); + e.Target.fill(0.0f); } } @@ -266,10 +267,10 @@ void ChorusState::process(const size_t samplesToDo, const al::span(mBuffer[0])}; - float *RESTRICT rbuffer{al::assume_aligned<16>(mBuffer[1])}; + const uint *RESTRICT ldelays{mModDelays[0].data()}; + const uint *RESTRICT rdelays{mModDelays[1].data()}; + float *RESTRICT lbuffer{al::assume_aligned<16>(mBuffer[0].data())}; + float *RESTRICT rbuffer{al::assume_aligned<16>(mBuffer[1].data())}; for(size_t i{0u};i < samplesToDo;++i) { // Feed the buffer's input first (necessary for delays < 1). @@ -292,10 +293,10 @@ void ChorusState::process(const size_t samplesToDo, const al::span mChans; /* Effect parameters */ bool mEnabled{true}; @@ -119,8 +120,8 @@ void CompressorState::process(const size_t samplesToDo, { for(size_t base{0u};base < samplesToDo;) { - float gains[256]; - const size_t td{minz(256, samplesToDo-base)}; + std::array gains; + const size_t td{minz(gains.size(), samplesToDo-base)}; /* Generate the per-sample gains from the signal envelope. */ float env{mEnvFollower}; diff --git a/alc/effects/convolution.cpp b/alc/effects/convolution.cpp index c877456d..1fcb419c 100644 --- a/alc/effects/convolution.cpp +++ b/alc/effects/convolution.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef HAVE_SSE_INTRINSICS #include @@ -325,10 +326,10 @@ void ConvolutionState::deviceUpdate(const DeviceBase *device, const BufferStorag /* Load the samples from the buffer. */ const size_t srclinelength{RoundUp(buffer->mSampleLen+DecoderPadding, 16)}; - auto srcsamples = std::make_unique(srclinelength * numChannels); - std::fill_n(srcsamples.get(), srclinelength * numChannels, 0.0f); + auto srcsamples = std::vector(srclinelength * numChannels); + std::fill(srcsamples.begin(), srcsamples.end(), 0.0f); for(size_t c{0};c < numChannels && c < realChannels;++c) - LoadSamples(srcsamples.get() + srclinelength*c, buffer->mData.data() + bytesPerSample*c, + LoadSamples(srcsamples.data() + srclinelength*c, buffer->mData.data() + bytesPerSample*c, realChannels, buffer->mType, buffer->mSampleLen); if(IsUHJ(mChannels)) @@ -336,12 +337,11 @@ void ConvolutionState::deviceUpdate(const DeviceBase *device, const BufferStorag auto decoder = std::make_unique(); std::array samples{}; for(size_t c{0};c < numChannels;++c) - samples[c] = srcsamples.get() + srclinelength*c; + samples[c] = srcsamples.data() + srclinelength*c; decoder->decode({samples.data(), numChannels}, buffer->mSampleLen, buffer->mSampleLen); } - auto ressamples = std::make_unique(buffer->mSampleLen + - (resampler ? resampledCount : 0)); + auto ressamples = std::vector(buffer->mSampleLen + (resampler ? resampledCount : 0)); auto ffttmp = al::vector(ConvolveUpdateSize); auto fftbuffer = std::vector>(ConvolveUpdateSize); @@ -351,19 +351,20 @@ void ConvolutionState::deviceUpdate(const DeviceBase *device, const BufferStorag /* Resample to match the device. */ if(resampler) { - std::copy_n(srcsamples.get() + srclinelength*c, buffer->mSampleLen, - ressamples.get() + resampledCount); - resampler.process(buffer->mSampleLen, ressamples.get()+resampledCount, - resampledCount, ressamples.get()); + std::copy_n(srcsamples.data() + srclinelength*c, buffer->mSampleLen, + ressamples.data() + resampledCount); + resampler.process(buffer->mSampleLen, ressamples.data()+resampledCount, + resampledCount, ressamples.data()); } else - std::copy_n(srcsamples.get() + srclinelength*c, buffer->mSampleLen, ressamples.get()); + std::copy_n(srcsamples.data() + srclinelength*c, buffer->mSampleLen, + ressamples.data()); /* Store the first segment's samples in reverse in the time-domain, to * apply as a FIR filter. */ const size_t first_size{minz(resampledCount, ConvolveUpdateSamples)}; - std::transform(ressamples.get(), ressamples.get()+first_size, mFilter[c].rbegin(), + std::transform(ressamples.data(), ressamples.data()+first_size, mFilter[c].rbegin(), [](const double d) noexcept -> float { return static_cast(d); }); size_t done{first_size}; @@ -408,43 +409,49 @@ void ConvolutionState::update(const ContextBase *context, const EffectSlot *slot * to have its own output target since the main mixing buffer won't have an * LFE channel (due to being B-Format). */ - static constexpr ChanPosMap MonoMap[1]{ - { FrontCenter, std::array{0.0f, 0.0f, -1.0f} } - }, StereoMap[2]{ - { FrontLeft, std::array{-sin30, 0.0f, -cos30} }, - { FrontRight, std::array{ sin30, 0.0f, -cos30} }, - }, RearMap[2]{ - { BackLeft, std::array{-sin30, 0.0f, cos30} }, - { BackRight, std::array{ sin30, 0.0f, cos30} }, - }, QuadMap[4]{ - { FrontLeft, std::array{-sin45, 0.0f, -cos45} }, - { FrontRight, std::array{ sin45, 0.0f, -cos45} }, - { BackLeft, std::array{-sin45, 0.0f, cos45} }, - { BackRight, std::array{ sin45, 0.0f, cos45} }, - }, X51Map[6]{ - { FrontLeft, std::array{-sin30, 0.0f, -cos30} }, - { FrontRight, std::array{ sin30, 0.0f, -cos30} }, - { FrontCenter, std::array{ 0.0f, 0.0f, -1.0f} }, - { LFE, {} }, - { SideLeft, std::array{-sin110, 0.0f, -cos110} }, - { SideRight, std::array{ sin110, 0.0f, -cos110} }, - }, X61Map[7]{ - { FrontLeft, std::array{-sin30, 0.0f, -cos30} }, - { FrontRight, std::array{ sin30, 0.0f, -cos30} }, - { FrontCenter, std::array{ 0.0f, 0.0f, -1.0f} }, - { LFE, {} }, - { BackCenter, std::array{ 0.0f, 0.0f, 1.0f} }, - { SideLeft, std::array{-1.0f, 0.0f, 0.0f} }, - { SideRight, std::array{ 1.0f, 0.0f, 0.0f} }, - }, X71Map[8]{ - { FrontLeft, std::array{-sin30, 0.0f, -cos30} }, - { FrontRight, std::array{ sin30, 0.0f, -cos30} }, - { FrontCenter, std::array{ 0.0f, 0.0f, -1.0f} }, - { LFE, {} }, - { BackLeft, std::array{-sin30, 0.0f, cos30} }, - { BackRight, std::array{ sin30, 0.0f, cos30} }, - { SideLeft, std::array{ -1.0f, 0.0f, 0.0f} }, - { SideRight, std::array{ 1.0f, 0.0f, 0.0f} }, + static constexpr std::array MonoMap{ + ChanPosMap{FrontCenter, std::array{0.0f, 0.0f, -1.0f}} + }; + static constexpr std::array StereoMap{ + ChanPosMap{FrontLeft, std::array{-sin30, 0.0f, -cos30}}, + ChanPosMap{FrontRight, std::array{ sin30, 0.0f, -cos30}}, + }; + static constexpr std::array RearMap{ + ChanPosMap{BackLeft, std::array{-sin30, 0.0f, cos30}}, + ChanPosMap{BackRight, std::array{ sin30, 0.0f, cos30}}, + }; + static constexpr std::array QuadMap{ + ChanPosMap{FrontLeft, std::array{-sin45, 0.0f, -cos45}}, + ChanPosMap{FrontRight, std::array{ sin45, 0.0f, -cos45}}, + ChanPosMap{BackLeft, std::array{-sin45, 0.0f, cos45}}, + ChanPosMap{BackRight, std::array{ sin45, 0.0f, cos45}}, + }; + static constexpr std::array X51Map{ + ChanPosMap{FrontLeft, std::array{-sin30, 0.0f, -cos30}}, + ChanPosMap{FrontRight, std::array{ sin30, 0.0f, -cos30}}, + ChanPosMap{FrontCenter, std::array{ 0.0f, 0.0f, -1.0f}}, + ChanPosMap{LFE, {}}, + ChanPosMap{SideLeft, std::array{-sin110, 0.0f, -cos110}}, + ChanPosMap{SideRight, std::array{ sin110, 0.0f, -cos110}}, + }; + static constexpr std::array X61Map{ + ChanPosMap{FrontLeft, std::array{-sin30, 0.0f, -cos30}}, + ChanPosMap{FrontRight, std::array{ sin30, 0.0f, -cos30}}, + ChanPosMap{FrontCenter, std::array{ 0.0f, 0.0f, -1.0f}}, + ChanPosMap{LFE, {}}, + ChanPosMap{BackCenter, std::array{ 0.0f, 0.0f, 1.0f} }, + ChanPosMap{SideLeft, std::array{-1.0f, 0.0f, 0.0f} }, + ChanPosMap{SideRight, std::array{ 1.0f, 0.0f, 0.0f} }, + }; + static constexpr std::array X71Map{ + ChanPosMap{FrontLeft, std::array{-sin30, 0.0f, -cos30}}, + ChanPosMap{FrontRight, std::array{ sin30, 0.0f, -cos30}}, + ChanPosMap{FrontCenter, std::array{ 0.0f, 0.0f, -1.0f}}, + ChanPosMap{LFE, {}}, + ChanPosMap{BackLeft, std::array{-sin30, 0.0f, cos30}}, + ChanPosMap{BackRight, std::array{ sin30, 0.0f, cos30}}, + ChanPosMap{SideLeft, std::array{ -1.0f, 0.0f, 0.0f}}, + ChanPosMap{SideRight, std::array{ 1.0f, 0.0f, 0.0f}}, }; if(mNumConvolveSegs < 1) UNLIKELY @@ -493,11 +500,11 @@ void ConvolutionState::update(const ContextBase *context, const EffectSlot *slot alu::Vector U{N.cross_product(V)}; U.normalize(); - const float mixmatrix[4][4]{ - {1.0f, 0.0f, 0.0f, 0.0f}, - {0.0f, U[0], -U[1], U[2]}, - {0.0f, -V[0], V[1], -V[2]}, - {0.0f, -N[0], N[1], -N[2]}, + const std::array mixmatrix{ + std::array{1.0f, 0.0f, 0.0f, 0.0f}, + std::array{0.0f, U[0], -U[1], U[2]}, + std::array{0.0f, -V[0], V[1], -V[2]}, + std::array{0.0f, -N[0], N[1], -N[2]}, }; const auto scales = GetAmbiScales(mAmbiScaling); diff --git a/alc/effects/dedicated.cpp b/alc/effects/dedicated.cpp index 69e70847..1b8b3977 100644 --- a/alc/effects/dedicated.cpp +++ b/alc/effects/dedicated.cpp @@ -62,13 +62,13 @@ struct DedicatedState final : public EffectState { void DedicatedState::deviceUpdate(const DeviceBase*, const BufferStorage*) { - std::fill(std::begin(mCurrentGains), std::end(mCurrentGains), 0.0f); + std::fill(mCurrentGains.begin(), mCurrentGains.end(), 0.0f); } void DedicatedState::update(const ContextBase*, const EffectSlot *slot, const EffectProps *props, const EffectTarget target) { - std::fill(std::begin(mTargetGains), std::end(mTargetGains), 0.0f); + std::fill(mTargetGains.begin(), mTargetGains.end(), 0.0f); const float Gain{slot->Gain * props->Dedicated.Gain}; diff --git a/alc/effects/distortion.cpp b/alc/effects/distortion.cpp index 3d77ff35..9ef9de25 100644 --- a/alc/effects/distortion.cpp +++ b/alc/effects/distortion.cpp @@ -45,7 +45,7 @@ namespace { struct DistortionState final : public EffectState { /* Effect gains for each channel */ - float mGain[MaxAmbiChannels]{}; + std::array mGain{}; /* Effect parameters */ BiquadFilter mLowpass; @@ -53,7 +53,7 @@ struct DistortionState final : public EffectState { float mAttenuation{}; float mEdgeCoeff{}; - alignas(16) float mBuffer[2][BufferLineSize]{}; + alignas(16) std::array mBuffer{}; void deviceUpdate(const DeviceBase *device, const BufferStorage *buffer) override; @@ -124,7 +124,7 @@ void DistortionState::process(const size_t samplesToDo, const al::span>= 2; - const float *outgains{mGain}; - for(FloatBufferLine &output : samplesOut) + const float *outgains{mGain.data()}; + for(FloatBufferLine &RESTRICT output : samplesOut) { /* Fourth step, final, do attenuation and perform decimation, * storing only one sample out of four. diff --git a/alc/effects/echo.cpp b/alc/effects/echo.cpp index 714649c9..fe6d8258 100644 --- a/alc/effects/echo.cpp +++ b/alc/effects/echo.cpp @@ -53,21 +53,20 @@ struct EchoState final : public EffectState { // The echo is two tap. The delay is the number of samples from before the // current offset - struct { - size_t delay{0u}; - } mTap[2]; + std::array mDelayTap{}; size_t mOffset{0u}; /* The panning gains for the two taps */ - struct { - float Current[MaxAmbiChannels]{}; - float Target[MaxAmbiChannels]{}; - } mGains[2]; + struct OutGains { + std::array Current{}; + std::array Target{}; + }; + std::array mGains; BiquadFilter mFilter; float mFeedGain{0.0f}; - alignas(16) float mTempBuffer[2][BufferLineSize]; + alignas(16) std::array mTempBuffer; void deviceUpdate(const DeviceBase *device, const BufferStorage *buffer) override; void update(const ContextBase *context, const EffectSlot *slot, const EffectProps *props, @@ -92,8 +91,8 @@ void EchoState::deviceUpdate(const DeviceBase *Device, const BufferStorage*) std::fill(mSampleBuffer.begin(), mSampleBuffer.end(), 0.0f); for(auto &e : mGains) { - std::fill(std::begin(e.Current), std::end(e.Current), 0.0f); - std::fill(std::begin(e.Target), std::end(e.Target), 0.0f); + std::fill(e.Current.begin(), e.Current.end(), 0.0f); + std::fill(e.Target.begin(), e.Target.end(), 0.0f); } } @@ -103,8 +102,8 @@ void EchoState::update(const ContextBase *context, const EffectSlot *slot, const DeviceBase *device{context->mDevice}; const auto frequency = static_cast(device->Frequency); - mTap[0].delay = maxu(float2uint(props->Echo.Delay*frequency + 0.5f), 1); - mTap[1].delay = float2uint(props->Echo.LRDelay*frequency + 0.5f) + mTap[0].delay; + mDelayTap[0] = maxu(float2uint(props->Echo.Delay*frequency + 0.5f), 1); + mDelayTap[1] = float2uint(props->Echo.LRDelay*frequency + 0.5f) + mDelayTap[0]; const float gainhf{maxf(1.0f - props->Echo.Damping, 0.0625f)}; /* Limit -24dB */ mFilter.setParamsFromSlope(BiquadType::HighShelf, LowpassFreqRef/frequency, gainhf, 1.0f); @@ -127,14 +126,13 @@ void EchoState::process(const size_t samplesToDo, const al::span 0); const BiquadFilter filter{mFilter}; - std::tie(z1, z2) = mFilter.getComponents(); + auto [z1, z2] = mFilter.getComponents(); for(size_t i{0u};i < samplesToDo;) { offset &= mask; @@ -161,8 +159,8 @@ void EchoState::process(const size_t samplesToDo, const al::span mFilter; /* Effect gains for each channel */ float mCurrentGain{}; float mTargetGain{}; - } mChans[MaxAmbiChannels]; + }; + std::array mChans; alignas(16) FloatBufferLine mSampleBuffer{}; @@ -114,8 +115,7 @@ void EqualizerState::deviceUpdate(const DeviceBase*, const BufferStorage*) for(auto &e : mChans) { e.mTargetChannel = InvalidChannelIndex; - std::for_each(std::begin(e.mFilter), std::end(e.mFilter), - std::mem_fn(&BiquadFilter::clear)); + std::for_each(e.mFilter.begin(), e.mFilter.end(), std::mem_fn(&BiquadFilter::clear)); e.mCurrentGain = 0.0f; } } @@ -125,7 +125,6 @@ void EqualizerState::update(const ContextBase *context, const EffectSlot *slot, { const DeviceBase *device{context->mDevice}; auto frequency = static_cast(device->Frequency); - float gain, f0norm; /* Calculate coefficients for the each type of filter. Note that the shelf * and peaking filters' gain is for the centerpoint of the transition band, @@ -133,8 +132,8 @@ void EqualizerState::update(const ContextBase *context, const EffectSlot *slot, * property gains need their dB halved (sqrt of linear gain) for the * shelf/peak to reach the provided gain. */ - gain = std::sqrt(props->Equalizer.LowGain); - f0norm = props->Equalizer.LowCutoff / frequency; + float gain{std::sqrt(props->Equalizer.LowGain)}; + float f0norm{props->Equalizer.LowCutoff / frequency}; mChans[0].mFilter[0].setParamsFromSlope(BiquadType::LowShelf, f0norm, gain, 0.75f); gain = std::sqrt(props->Equalizer.Mid1Gain); diff --git a/alc/effects/fshifter.cpp b/alc/effects/fshifter.cpp index d3989e84..d121885b 100644 --- a/alc/effects/fshifter.cpp +++ b/alc/effects/fshifter.cpp @@ -91,10 +91,11 @@ struct FshifterState final : public EffectState { alignas(16) FloatBufferLine mBufferOut{}; /* Effect gains for each output channel */ - struct { - float Current[MaxAmbiChannels]{}; - float Target[MaxAmbiChannels]{}; - } mGains[2]; + struct OutGains { + std::array Current{}; + std::array Target{}; + }; + std::array mGains; void deviceUpdate(const DeviceBase *device, const BufferStorage *buffer) override; @@ -122,8 +123,8 @@ void FshifterState::deviceUpdate(const DeviceBase*, const BufferStorage*) for(auto &gain : mGains) { - std::fill(std::begin(gain.Current), std::end(gain.Current), 0.0f); - std::fill(std::begin(gain.Target), std::end(gain.Target), 0.0f); + gain.Current.fill(0.0f); + gain.Target.fill(0.0f); } } @@ -235,8 +236,8 @@ void FshifterState::process(const size_t samplesToDo, const al::span mChans; void deviceUpdate(const DeviceBase *device, const BufferStorage *buffer) override; diff --git a/alc/effects/pshifter.cpp b/alc/effects/pshifter.cpp index 871e866a..c7d662c7 100644 --- a/alc/effects/pshifter.cpp +++ b/alc/effects/pshifter.cpp @@ -103,8 +103,8 @@ struct PshifterState final : public EffectState { alignas(16) FloatBufferLine mBufferOut; /* Effect gains for each output channel */ - float mCurrentGains[MaxAmbiChannels]; - float mTargetGains[MaxAmbiChannels]; + std::array mCurrentGains; + std::array mTargetGains; void deviceUpdate(const DeviceBase *device, const BufferStorage *buffer) override; @@ -132,8 +132,8 @@ void PshifterState::deviceUpdate(const DeviceBase*, const BufferStorage*) mAnalysisBuffer.fill(FrequencyBin{}); mSynthesisBuffer.fill(FrequencyBin{}); - std::fill(std::begin(mCurrentGains), std::end(mCurrentGains), 0.0f); - std::fill(std::begin(mTargetGains), std::end(mTargetGains), 0.0f); + mCurrentGains.fill(0.0f); + mTargetGains.fill(0.0f); if(!mFft) mFft = PFFFTSetup{StftSize, PFFFT_REAL}; @@ -305,8 +305,8 @@ void PshifterState::process(const size_t samplesToDo, } /* Now, mix the processed sound data to the output. */ - MixSamples({mBufferOut.data(), samplesToDo}, samplesOut, mCurrentGains, mTargetGains, - maxz(samplesToDo, 512), 0); + MixSamples({mBufferOut.data(), samplesToDo}, samplesOut, mCurrentGains.data(), + mTargetGains.data(), maxz(samplesToDo, 512), 0); } diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp index 5157cf72..43451ec8 100644 --- a/alc/effects/reverb.cpp +++ b/alc/effects/reverb.cpp @@ -22,11 +22,11 @@ #include #include +#include #include #include #include #include -#include #include "alc/effects/base.h" #include "almalloc.h" @@ -65,7 +65,7 @@ struct CubicFilter { static constexpr size_t sTableSteps{1 << sTableBits}; static constexpr size_t sTableMask{sTableSteps - 1}; - float mFilter[sTableSteps*2 + 1]{}; + std::array mFilter{}; constexpr CubicFilter() { @@ -85,10 +85,14 @@ struct CubicFilter { } } - constexpr float getCoeff0(size_t i) const noexcept { return mFilter[sTableSteps+i]; } - constexpr float getCoeff1(size_t i) const noexcept { return mFilter[i]; } - constexpr float getCoeff2(size_t i) const noexcept { return mFilter[sTableSteps-i]; } - constexpr float getCoeff3(size_t i) const noexcept { return mFilter[sTableSteps*2-i]; } + [[nodiscard]] constexpr auto getCoeff0(size_t i) const noexcept -> float + { return mFilter[sTableSteps+i]; } + [[nodiscard]] constexpr auto getCoeff1(size_t i) const noexcept -> float + { return mFilter[i]; } + [[nodiscard]] constexpr auto getCoeff2(size_t i) const noexcept -> float + { return mFilter[sTableSteps-i]; } + [[nodiscard]] constexpr auto getCoeff3(size_t i) const noexcept -> float + { return mFilter[sTableSteps*2-i]; } }; constexpr CubicFilter gCubicTable; @@ -119,12 +123,12 @@ constexpr float MODULATION_DEPTH_COEFF{0.05f}; * tetrahedral array of discrete signals (boosted by a factor of sqrt(3), to * reduce the error introduced in the conversion). */ -alignas(16) constexpr float B2A[NUM_LINES][NUM_LINES]{ - { 0.5f, 0.5f, 0.5f, 0.5f }, - { 0.5f, -0.5f, -0.5f, 0.5f }, - { 0.5f, 0.5f, -0.5f, -0.5f }, - { 0.5f, -0.5f, 0.5f, -0.5f } -}; +alignas(16) constexpr std::array,NUM_LINES> B2A{{ + {{ 0.5f, 0.5f, 0.5f, 0.5f }}, + {{ 0.5f, -0.5f, -0.5f, 0.5f }}, + {{ 0.5f, 0.5f, -0.5f, -0.5f }}, + {{ 0.5f, -0.5f, 0.5f, -0.5f }} +}}; /* Converts (W-normalized) A-Format to B-Format for early reflections (scaled * by 1/sqrt(3) to compensate for the boost in the B2A matrix). @@ -364,7 +368,7 @@ struct DelayLineI { struct VecAllpass { DelayLineI Delay; float Coeff{0.0f}; - size_t Offset[NUM_LINES]{}; + std::array Offset{}; void process(const al::span samples, size_t offset, const float xCoeff, const float yCoeff, const size_t todo); @@ -397,12 +401,12 @@ struct EarlyReflections { * reflections. */ DelayLineI Delay; - size_t Offset[NUM_LINES]{}; - float Coeff[NUM_LINES]{}; + std::array Offset{}; + std::array Coeff{}; /* The gain for each output channel based on 3D panning. */ - float CurrentGains[NUM_LINES][MaxAmbiChannels]{}; - float TargetGains[NUM_LINES][MaxAmbiChannels]{}; + std::array,NUM_LINES> CurrentGains{}; + std::array,NUM_LINES> TargetGains{}; void updateLines(const float density_mult, const float diffusion, const float decayTime, const float frequency); @@ -418,7 +422,7 @@ struct Modulation { /* The depth of frequency change, in samples. */ float Depth; - float ModDelays[MAX_UPDATE_SAMPLES]; + std::array ModDelays; void updateModulator(float modTime, float modDepth, float frequency); @@ -428,7 +432,7 @@ struct Modulation { struct LateReverb { /* A recursive delay line is used fill in the reverb tail. */ DelayLineI Delay; - size_t Offset[NUM_LINES]{}; + std::array Offset{}; /* Attenuation to compensate for the modal density and decay rate of the * late lines. @@ -436,7 +440,7 @@ struct LateReverb { float DensityGain{0.0f}; /* T60 decay filters are used to simulate absorption. */ - T60Filter T60[NUM_LINES]; + std::array T60; Modulation Mod; @@ -444,8 +448,8 @@ struct LateReverb { VecAllpass VecAp; /* The gain for each output channel based on 3D panning. */ - float CurrentGains[NUM_LINES][MaxAmbiChannels]{}; - float TargetGains[NUM_LINES][MaxAmbiChannels]{}; + std::array,NUM_LINES> CurrentGains{}; + std::array,NUM_LINES> TargetGains{}; void updateLines(const float density_mult, const float diffusion, const float lfDecayTime, const float mfDecayTime, const float hfDecayTime, const float lf0norm, @@ -460,21 +464,22 @@ struct LateReverb { struct ReverbPipeline { /* Master effect filters */ - struct { + struct FilterPair { BiquadFilter Lp; BiquadFilter Hp; - } mFilter[NUM_LINES]; + }; + std::array mFilter; /* Core delay line (early reflections and late reverb tap from this). */ DelayLineI mEarlyDelayIn; DelayLineI mLateDelayIn; /* Tap points for early reflection delay. */ - size_t mEarlyDelayTap[NUM_LINES][2]{}; - float mEarlyDelayCoeff[NUM_LINES]{}; + std::array,NUM_LINES> mEarlyDelayTap{}; + std::array mEarlyDelayCoeff{}; /* Tap points for late reverb feed and delay. */ - size_t mLateDelayTap[NUM_LINES][2]{}; + std::array,NUM_LINES> mLateDelayTap{}; /* Coefficients for the all-pass and line scattering matrices. */ float mMixX{0.0f}; @@ -548,7 +553,7 @@ struct ReverbState final : public EffectState { PipelineState mPipelineState{DeviceClear}; uint8_t mCurrentPipeline{0}; - ReverbPipeline mPipelines[2]; + std::array mPipelines; /* The current write offset for all delay lines. */ size_t mOffset{}; @@ -577,14 +582,14 @@ struct ReverbState final : public EffectState { for(size_t c{0u};c < NUM_LINES;c++) { const al::span tmpspan{mEarlySamples[c].data(), todo}; - MixSamples(tmpspan, samplesOut, pipeline.mEarly.CurrentGains[c], - pipeline.mEarly.TargetGains[c], todo, 0); + MixSamples(tmpspan, samplesOut, pipeline.mEarly.CurrentGains[c].data(), + pipeline.mEarly.TargetGains[c].data(), todo, 0); } for(size_t c{0u};c < NUM_LINES;c++) { const al::span tmpspan{mLateSamples[c].data(), todo}; - MixSamples(tmpspan, samplesOut, pipeline.mLate.CurrentGains[c], - pipeline.mLate.TargetGains[c], todo, 0); + MixSamples(tmpspan, samplesOut, pipeline.mLate.CurrentGains[c].data(), + pipeline.mLate.TargetGains[c].data(), todo, 0); } } @@ -627,8 +632,8 @@ struct ReverbState final : public EffectState { const float hfscale{(c==0) ? mOrderScales[0] : mOrderScales[1]}; pipeline.mAmbiSplitter[0][c].processHfScale(tmpspan, hfscale); - MixSamples(tmpspan, samplesOut, pipeline.mEarly.CurrentGains[c], - pipeline.mEarly.TargetGains[c], todo, 0); + MixSamples(tmpspan, samplesOut, pipeline.mEarly.CurrentGains[c].data(), + pipeline.mEarly.TargetGains[c].data(), todo, 0); } for(size_t c{0u};c < NUM_LINES;c++) { @@ -637,8 +642,8 @@ struct ReverbState final : public EffectState { const float hfscale{(c==0) ? mOrderScales[0] : mOrderScales[1]}; pipeline.mAmbiSplitter[1][c].processHfScale(tmpspan, hfscale); - MixSamples(tmpspan, samplesOut, pipeline.mLate.CurrentGains[c], - pipeline.mLate.TargetGains[c], todo, 0); + MixSamples(tmpspan, samplesOut, pipeline.mLate.CurrentGains[c].data(), + pipeline.mLate.TargetGains[c].data(), todo, 0); } } @@ -756,17 +761,16 @@ void ReverbState::deviceUpdate(const DeviceBase *device, const BufferStorage*) for(auto &pipeline : mPipelines) { - /* Clear filters and gain coefficients since the delay lines were all just - * cleared (if not reallocated). - */ + /* Clear filters and gain coefficients since the delay lines were all + * just cleared (if not reallocated). + */ for(auto &filter : pipeline.mFilter) { filter.Lp.clear(); filter.Hp.clear(); } - std::fill(std::begin(pipeline.mEarlyDelayCoeff),std::end(pipeline.mEarlyDelayCoeff), 0.0f); - std::fill(std::begin(pipeline.mEarlyDelayCoeff),std::end(pipeline.mEarlyDelayCoeff), 0.0f); + pipeline.mEarlyDelayCoeff.fill(0.0f); pipeline.mLate.DensityGain = 0.0f; for(auto &t60 : pipeline.mLate.T60) @@ -781,13 +785,13 @@ void ReverbState::deviceUpdate(const DeviceBase *device, const BufferStorage*) pipeline.mLate.Mod.Depth = 0.0f; for(auto &gains : pipeline.mEarly.CurrentGains) - std::fill(std::begin(gains), std::end(gains), 0.0f); + gains.fill(0.0f); for(auto &gains : pipeline.mEarly.TargetGains) - std::fill(std::begin(gains), std::end(gains), 0.0f); + gains.fill(0.0f); for(auto &gains : pipeline.mLate.CurrentGains) - std::fill(std::begin(gains), std::end(gains), 0.0f); + gains.fill(0.0f); for(auto &gains : pipeline.mLate.TargetGains) - std::fill(std::begin(gains), std::end(gains), 0.0f); + gains.fill(0.0f); } mPipelineState = DeviceClear; @@ -1071,7 +1075,7 @@ std::array,4> GetTransformFromVector(const al::span norm; float mag{std::sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2])}; if(mag > 1.0f) { @@ -1408,7 +1412,7 @@ void VecAllpass::process(const al::span samples, siz ASSUME(todo > 0); - size_t vap_offset[NUM_LINES]; + std::array vap_offset; for(size_t j{0u};j < NUM_LINES;j++) vap_offset[j] = offset - Offset[j]; for(size_t i{0u};i < todo;) diff --git a/alc/effects/vmorpher.cpp b/alc/effects/vmorpher.cpp index 872c7add..6cf862c2 100644 --- a/alc/effects/vmorpher.cpp +++ b/alc/effects/vmorpher.cpp @@ -57,29 +57,30 @@ namespace { using uint = unsigned int; -#define MAX_UPDATE_SAMPLES 256 -#define NUM_FORMANTS 4 -#define NUM_FILTERS 2 -#define Q_FACTOR 5.0f - -#define VOWEL_A_INDEX 0 -#define VOWEL_B_INDEX 1 +constexpr size_t MaxUpdateSamples{256}; +constexpr size_t NumFormants{4}; +constexpr float QFactor{5.0f}; +enum : size_t { + VowelAIndex, + VowelBIndex, + NumFilters +}; -#define WAVEFORM_FRACBITS 24 -#define WAVEFORM_FRACONE (1<*2.0f / WAVEFORM_FRACONE}; + constexpr float scale{al::numbers::pi_v*2.0f / float{WaveformFracOne}}; return std::sin(static_cast(index) * scale)*0.5f + 0.5f; } inline float Saw(uint index) -{ return static_cast(index) / float{WAVEFORM_FRACONE}; } +{ return static_cast(index) / float{WaveformFracOne}; } inline float Triangle(uint index) -{ return std::fabs(static_cast(index)*(2.0f/WAVEFORM_FRACONE) - 1.0f); } +{ return std::fabs(static_cast(index)*(2.0f/WaveformFracOne) - 1.0f); } inline float Half(uint) { return 0.5f; } @@ -89,13 +90,12 @@ void Oscillate(float *RESTRICT dst, uint index, const uint step, size_t todo) for(size_t i{0u};i < todo;i++) { index += step; - index &= WAVEFORM_FRACMASK; + index &= WaveformFracMask; dst[i] = func(index); } } -struct FormantFilter -{ +struct FormantFilter { float mCoeff{0.0f}; float mGain{1.0f}; float mS1{0.0f}; @@ -106,20 +106,21 @@ struct FormantFilter : mCoeff{std::tan(al::numbers::pi_v * f0norm)}, mGain{gain} { } - inline void process(const float *samplesIn, float *samplesOut, const size_t numInput) + void process(const float *samplesIn, float *samplesOut, const size_t numInput) noexcept { /* A state variable filter from a topology-preserving transform. * Based on a talk given by Ivan Cohen: https://www.youtube.com/watch?v=esjHXGPyrhg */ const float g{mCoeff}; const float gain{mGain}; - const float h{1.0f / (1.0f + (g/Q_FACTOR) + (g*g))}; + const float h{1.0f / (1.0f + (g/QFactor) + (g*g))}; + const float coeff{1.0f/QFactor + g}; float s1{mS1}; float s2{mS2}; for(size_t i{0u};i < numInput;i++) { - const float H{(samplesIn[i] - (1.0f/Q_FACTOR + g)*s1 - s2)*h}; + const float H{(samplesIn[i] - coeff*s1 - s2)*h}; const float B{g*H + s1}; const float L{g*B + s2}; @@ -133,7 +134,7 @@ struct FormantFilter mS2 = s2; } - inline void clear() + void clear() noexcept { mS1 = 0.0f; mS2 = 0.0f; @@ -142,16 +143,17 @@ struct FormantFilter struct VmorpherState final : public EffectState { - struct { + struct OutParams { uint mTargetChannel{InvalidChannelIndex}; /* Effect parameters */ - FormantFilter mFormants[NUM_FILTERS][NUM_FORMANTS]; + std::array,NumFilters> mFormants; /* Effect gains for each channel */ float mCurrentGain{}; float mTargetGain{}; - } mChans[MaxAmbiChannels]; + }; + std::array mChans; void (*mGetSamples)(float*RESTRICT, uint, const uint, size_t){}; @@ -159,9 +161,9 @@ struct VmorpherState final : public EffectState { uint mStep{1}; /* Effects buffers */ - alignas(16) float mSampleBufferA[MAX_UPDATE_SAMPLES]{}; - alignas(16) float mSampleBufferB[MAX_UPDATE_SAMPLES]{}; - alignas(16) float mLfo[MAX_UPDATE_SAMPLES]{}; + alignas(16) std::array mSampleBufferA{}; + alignas(16) std::array mSampleBufferB{}; + alignas(16) std::array mLfo{}; void deviceUpdate(const DeviceBase *device, const BufferStorage *buffer) override; void update(const ContextBase *context, const EffectSlot *slot, const EffectProps *props, @@ -169,14 +171,14 @@ struct VmorpherState final : public EffectState { void process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) override; - static std::array getFiltersByPhoneme(VMorpherPhenome phoneme, - float frequency, float pitch); + static std::array getFiltersByPhoneme(VMorpherPhenome phoneme, + float frequency, float pitch) noexcept; DEF_NEWDEL(VmorpherState) }; -std::array VmorpherState::getFiltersByPhoneme(VMorpherPhenome phoneme, - float frequency, float pitch) +std::array VmorpherState::getFiltersByPhoneme(VMorpherPhenome phoneme, + float frequency, float pitch) noexcept { /* Using soprano formant set of values to * better match mid-range frequency space. @@ -232,9 +234,9 @@ void VmorpherState::deviceUpdate(const DeviceBase*, const BufferStorage*) for(auto &e : mChans) { e.mTargetChannel = InvalidChannelIndex; - std::for_each(std::begin(e.mFormants[VOWEL_A_INDEX]), std::end(e.mFormants[VOWEL_A_INDEX]), + std::for_each(e.mFormants[VowelAIndex].begin(), e.mFormants[VowelAIndex].end(), std::mem_fn(&FormantFilter::clear)); - std::for_each(std::begin(e.mFormants[VOWEL_B_INDEX]), std::end(e.mFormants[VOWEL_B_INDEX]), + std::for_each(e.mFormants[VowelBIndex].begin(), e.mFormants[VowelBIndex].end(), std::mem_fn(&FormantFilter::clear)); e.mCurrentGain = 0.0f; } @@ -246,7 +248,7 @@ void VmorpherState::update(const ContextBase *context, const EffectSlot *slot, const DeviceBase *device{context->mDevice}; const float frequency{static_cast(device->Frequency)}; const float step{props->Vmorpher.Rate / frequency}; - mStep = fastf2u(clampf(step*WAVEFORM_FRACONE, 0.0f, float{WAVEFORM_FRACONE-1})); + mStep = fastf2u(clampf(step*WaveformFracOne, 0.0f, float{WaveformFracOne}-1.0f)); if(mStep == 0) mGetSamples = Oscillate; @@ -268,8 +270,8 @@ void VmorpherState::update(const ContextBase *context, const EffectSlot *slot, /* Copy the filter coefficients to the input channels. */ for(size_t i{0u};i < slot->Wet.Buffer.size();++i) { - std::copy(vowelA.begin(), vowelA.end(), std::begin(mChans[i].mFormants[VOWEL_A_INDEX])); - std::copy(vowelB.begin(), vowelB.end(), std::begin(mChans[i].mFormants[VOWEL_B_INDEX])); + std::copy(vowelA.begin(), vowelA.end(), mChans[i].mFormants[VowelAIndex].begin()); + std::copy(vowelB.begin(), vowelB.end(), mChans[i].mFormants[VowelBIndex].begin()); } mOutTarget = target.Main->Buffer; @@ -288,11 +290,11 @@ void VmorpherState::process(const size_t samplesToDo, const al::span(mStep * td); - mIndex &= WAVEFORM_FRACMASK; + mIndex &= WaveformFracMask; auto chandata = std::begin(mChans); for(const auto &input : samplesIn) @@ -304,30 +306,30 @@ void VmorpherState::process(const size_t samplesToDo, const al::spanmFormants[VOWEL_A_INDEX]; - auto& vowelB = chandata->mFormants[VOWEL_B_INDEX]; + const auto vowelA = al::span{chandata->mFormants[VowelAIndex]}; + const auto vowelB = al::span{chandata->mFormants[VowelBIndex]}; /* Process first vowel. */ std::fill_n(std::begin(mSampleBufferA), td, 0.0f); - vowelA[0].process(&input[base], mSampleBufferA, td); - vowelA[1].process(&input[base], mSampleBufferA, td); - vowelA[2].process(&input[base], mSampleBufferA, td); - vowelA[3].process(&input[base], mSampleBufferA, td); + vowelA[0].process(&input[base], mSampleBufferA.data(), td); + vowelA[1].process(&input[base], mSampleBufferA.data(), td); + vowelA[2].process(&input[base], mSampleBufferA.data(), td); + vowelA[3].process(&input[base], mSampleBufferA.data(), td); /* Process second vowel. */ std::fill_n(std::begin(mSampleBufferB), td, 0.0f); - vowelB[0].process(&input[base], mSampleBufferB, td); - vowelB[1].process(&input[base], mSampleBufferB, td); - vowelB[2].process(&input[base], mSampleBufferB, td); - vowelB[3].process(&input[base], mSampleBufferB, td); + vowelB[0].process(&input[base], mSampleBufferB.data(), td); + vowelB[1].process(&input[base], mSampleBufferB.data(), td); + vowelB[2].process(&input[base], mSampleBufferB.data(), td); + vowelB[3].process(&input[base], mSampleBufferB.data(), td); - alignas(16) float blended[MAX_UPDATE_SAMPLES]; + alignas(16) std::array blended; for(size_t i{0u};i < td;i++) blended[i] = lerpf(mSampleBufferA[i], mSampleBufferB[i], mLfo[i]); /* Now, mix the processed sound data to the output. */ - MixSamples({blended, td}, samplesOut[outidx].data()+base, chandata->mCurrentGain, - chandata->mTargetGain, samplesToDo-base); + MixSamples({blended.data(), td}, samplesOut[outidx].data()+base, + chandata->mCurrentGain, chandata->mTargetGain, samplesToDo-base); ++chandata; } diff --git a/core/effectslot.cpp b/core/effectslot.cpp index 99224225..4d1e14b3 100644 --- a/core/effectslot.cpp +++ b/core/effectslot.cpp @@ -14,6 +14,7 @@ EffectSlotArray *EffectSlot::CreatePtrArray(size_t count) noexcept /* Allocate space for twice as many pointers, so the mixer has scratch * space to store a sorted list during mixing. */ - void *ptr{al_calloc(alignof(EffectSlotArray), EffectSlotArray::Sizeof(count*2))}; - return al::construct_at(static_cast(ptr), count); + if(void *ptr{al_calloc(alignof(EffectSlotArray), EffectSlotArray::Sizeof(count*2))}) + return al::construct_at(static_cast(ptr), count); + return nullptr; } -- cgit v1.2.3 From bc83c874ff15b29fdab9b6c0bf40b268345b3026 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 16 Dec 2023 17:48:33 -0800 Subject: Remove DEF_NEWDEL C++17 provides alignment-aware allocators for us, so we don't need to use our own to make sure classes/structs are properly aligned. --- al/auxeffectslot.h | 3 --- alc/backends/alsa.cpp | 4 ---- alc/backends/coreaudio.cpp | 4 ---- alc/backends/dsound.cpp | 4 ---- alc/backends/jack.cpp | 2 -- alc/backends/loopback.cpp | 2 -- alc/backends/null.cpp | 2 -- alc/backends/opensl.cpp | 4 ---- alc/backends/oss.cpp | 4 ---- alc/backends/pipewire.cpp | 4 ---- alc/backends/portaudio.cpp | 4 ---- alc/backends/pulseaudio.cpp | 4 ---- alc/backends/sdl2.cpp | 2 -- alc/backends/sndio.cpp | 4 ---- alc/backends/solaris.cpp | 2 -- alc/backends/wasapi.cpp | 4 ---- alc/backends/wave.cpp | 2 -- alc/backends/winmm.cpp | 4 ---- alc/context.h | 2 -- alc/device.h | 2 -- alc/effects/autowah.cpp | 2 -- alc/effects/chorus.cpp | 2 -- alc/effects/compressor.cpp | 2 -- alc/effects/convolution.cpp | 2 -- alc/effects/dedicated.cpp | 2 -- alc/effects/distortion.cpp | 2 -- alc/effects/echo.cpp | 2 -- alc/effects/equalizer.cpp | 2 -- alc/effects/fshifter.cpp | 2 -- alc/effects/modulator.cpp | 2 -- alc/effects/null.cpp | 2 -- alc/effects/pshifter.cpp | 2 -- alc/effects/reverb.cpp | 2 -- alc/effects/vmorpher.cpp | 2 -- common/almalloc.h | 13 ------------- core/bformatdec.h | 2 -- core/context.h | 6 ++---- core/device.h | 2 -- core/effectslot.h | 4 ---- core/uhjfilter.h | 10 ---------- core/voice.h | 4 ---- core/voice_change.h | 4 ---- utils/uhjdecoder.cpp | 3 --- utils/uhjencoder.cpp | 3 --- 44 files changed, 2 insertions(+), 140 deletions(-) (limited to 'alc/effects/reverb.cpp') diff --git a/al/auxeffectslot.h b/al/auxeffectslot.h index bfd4038e..fc474bb4 100644 --- a/al/auxeffectslot.h +++ b/al/auxeffectslot.h @@ -81,9 +81,6 @@ struct ALeffectslot { static void SetName(ALCcontext *context, ALuint id, std::string_view name); - /* This can be new'd for the context's default effect slot. */ - DEF_NEWDEL(ALeffectslot) - #ifdef ALSOFT_EAX public: diff --git a/alc/backends/alsa.cpp b/alc/backends/alsa.cpp index fa34e4f9..344c440c 100644 --- a/alc/backends/alsa.cpp +++ b/alc/backends/alsa.cpp @@ -444,8 +444,6 @@ struct AlsaPlayback final : public BackendBase { std::atomic mKillNow{true}; std::thread mThread; - - DEF_NEWDEL(AlsaPlayback) }; AlsaPlayback::~AlsaPlayback() @@ -888,8 +886,6 @@ struct AlsaCapture final : public BackendBase { RingBufferPtr mRing{nullptr}; snd_pcm_sframes_t mLastAvail{0}; - - DEF_NEWDEL(AlsaCapture) }; AlsaCapture::~AlsaCapture() diff --git a/alc/backends/coreaudio.cpp b/alc/backends/coreaudio.cpp index 50e3bc66..86c4b89b 100644 --- a/alc/backends/coreaudio.cpp +++ b/alc/backends/coreaudio.cpp @@ -337,8 +337,6 @@ struct CoreAudioPlayback final : public BackendBase { uint mFrameSize{0u}; AudioStreamBasicDescription mFormat{}; // This is the OpenAL format as a CoreAudio ASBD - - DEF_NEWDEL(CoreAudioPlayback) }; CoreAudioPlayback::~CoreAudioPlayback() @@ -623,8 +621,6 @@ struct CoreAudioCapture final : public BackendBase { std::vector mCaptureData; RingBufferPtr mRing{nullptr}; - - DEF_NEWDEL(CoreAudioCapture) }; CoreAudioCapture::~CoreAudioCapture() diff --git a/alc/backends/dsound.cpp b/alc/backends/dsound.cpp index 08c849e9..59a59a9f 100644 --- a/alc/backends/dsound.cpp +++ b/alc/backends/dsound.cpp @@ -191,8 +191,6 @@ struct DSoundPlayback final : public BackendBase { std::atomic mKillNow{true}; std::thread mThread; - - DEF_NEWDEL(DSoundPlayback) }; DSoundPlayback::~DSoundPlayback() @@ -560,8 +558,6 @@ struct DSoundCapture final : public BackendBase { DWORD mCursor{0u}; RingBufferPtr mRing; - - DEF_NEWDEL(DSoundCapture) }; DSoundCapture::~DSoundCapture() diff --git a/alc/backends/jack.cpp b/alc/backends/jack.cpp index 1a53da17..eb87b0a7 100644 --- a/alc/backends/jack.cpp +++ b/alc/backends/jack.cpp @@ -319,8 +319,6 @@ struct JackPlayback final : public BackendBase { std::atomic mKillNow{true}; std::thread mThread; - - DEF_NEWDEL(JackPlayback) }; JackPlayback::~JackPlayback() diff --git a/alc/backends/loopback.cpp b/alc/backends/loopback.cpp index 2972fc01..e42e35b0 100644 --- a/alc/backends/loopback.cpp +++ b/alc/backends/loopback.cpp @@ -34,8 +34,6 @@ struct LoopbackBackend final : public BackendBase { bool reset() override; void start() override; void stop() override; - - DEF_NEWDEL(LoopbackBackend) }; diff --git a/alc/backends/null.cpp b/alc/backends/null.cpp index c149820c..f28eaa47 100644 --- a/alc/backends/null.cpp +++ b/alc/backends/null.cpp @@ -58,8 +58,6 @@ struct NullBackend final : public BackendBase { std::atomic mKillNow{true}; std::thread mThread; - - DEF_NEWDEL(NullBackend) }; int NullBackend::mixerProc() diff --git a/alc/backends/opensl.cpp b/alc/backends/opensl.cpp index 75b6e30d..6b2de909 100644 --- a/alc/backends/opensl.cpp +++ b/alc/backends/opensl.cpp @@ -190,8 +190,6 @@ struct OpenSLPlayback final : public BackendBase { std::atomic mKillNow{true}; std::thread mThread; - - DEF_NEWDEL(OpenSLPlayback) }; OpenSLPlayback::~OpenSLPlayback() @@ -595,8 +593,6 @@ struct OpenSLCapture final : public BackendBase { uint mSplOffset{0u}; uint mFrameSize{0}; - - DEF_NEWDEL(OpenSLCapture) }; OpenSLCapture::~OpenSLCapture() diff --git a/alc/backends/oss.cpp b/alc/backends/oss.cpp index e6cebec4..8e547497 100644 --- a/alc/backends/oss.cpp +++ b/alc/backends/oss.cpp @@ -240,8 +240,6 @@ struct OSSPlayback final : public BackendBase { std::atomic mKillNow{true}; std::thread mThread; - - DEF_NEWDEL(OSSPlayback) }; OSSPlayback::~OSSPlayback() @@ -457,8 +455,6 @@ struct OSScapture final : public BackendBase { std::atomic mKillNow{true}; std::thread mThread; - - DEF_NEWDEL(OSScapture) }; OSScapture::~OSScapture() diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp index 2c726cbe..9c9323ec 100644 --- a/alc/backends/pipewire.cpp +++ b/alc/backends/pipewire.cpp @@ -1442,8 +1442,6 @@ public: /* Stop the mainloop so the stream can be properly destroyed. */ if(mLoop) mLoop.stop(); } - - DEF_NEWDEL(PipeWirePlayback) }; @@ -1927,8 +1925,6 @@ class PipeWireCapture final : public BackendBase { public: PipeWireCapture(DeviceBase *device) noexcept : BackendBase{device} { } ~PipeWireCapture() final { if(mLoop) mLoop.stop(); } - - DEF_NEWDEL(PipeWireCapture) }; diff --git a/alc/backends/portaudio.cpp b/alc/backends/portaudio.cpp index 554efe9a..dc9725b0 100644 --- a/alc/backends/portaudio.cpp +++ b/alc/backends/portaudio.cpp @@ -95,8 +95,6 @@ struct PortPlayback final : public BackendBase { PaStream *mStream{nullptr}; PaStreamParameters mParams{}; uint mUpdateSize{0u}; - - DEF_NEWDEL(PortPlayback) }; PortPlayback::~PortPlayback() @@ -256,8 +254,6 @@ struct PortCapture final : public BackendBase { PaStreamParameters mParams; RingBufferPtr mRing{nullptr}; - - DEF_NEWDEL(PortCapture) }; PortCapture::~PortCapture() diff --git a/alc/backends/pulseaudio.cpp b/alc/backends/pulseaudio.cpp index b6f0f95d..8533cdb9 100644 --- a/alc/backends/pulseaudio.cpp +++ b/alc/backends/pulseaudio.cpp @@ -664,8 +664,6 @@ struct PulsePlayback final : public BackendBase { pa_stream *mStream{nullptr}; uint mFrameSize{0u}; - - DEF_NEWDEL(PulsePlayback) }; PulsePlayback::~PulsePlayback() @@ -1090,8 +1088,6 @@ struct PulseCapture final : public BackendBase { pa_sample_spec mSpec{}; pa_stream *mStream{nullptr}; - - DEF_NEWDEL(PulseCapture) }; PulseCapture::~PulseCapture() diff --git a/alc/backends/sdl2.cpp b/alc/backends/sdl2.cpp index d7f66d93..49b9713e 100644 --- a/alc/backends/sdl2.cpp +++ b/alc/backends/sdl2.cpp @@ -67,8 +67,6 @@ struct Sdl2Backend final : public BackendBase { DevFmtChannels mFmtChans{}; DevFmtType mFmtType{}; uint mUpdateSize{0u}; - - DEF_NEWDEL(Sdl2Backend) }; Sdl2Backend::~Sdl2Backend() diff --git a/alc/backends/sndio.cpp b/alc/backends/sndio.cpp index d05db2e8..8477ed1f 100644 --- a/alc/backends/sndio.cpp +++ b/alc/backends/sndio.cpp @@ -70,8 +70,6 @@ struct SndioPlayback final : public BackendBase { std::atomic mKillNow{true}; std::thread mThread; - - DEF_NEWDEL(SndioPlayback) }; SndioPlayback::~SndioPlayback() @@ -293,8 +291,6 @@ struct SndioCapture final : public BackendBase { std::atomic mKillNow{true}; std::thread mThread; - - DEF_NEWDEL(SndioCapture) }; SndioCapture::~SndioCapture() diff --git a/alc/backends/solaris.cpp b/alc/backends/solaris.cpp index 2c4a97fd..b29a8cea 100644 --- a/alc/backends/solaris.cpp +++ b/alc/backends/solaris.cpp @@ -75,8 +75,6 @@ struct SolarisBackend final : public BackendBase { std::atomic mKillNow{true}; std::thread mThread; - - DEF_NEWDEL(SolarisBackend) }; SolarisBackend::~SolarisBackend() diff --git a/alc/backends/wasapi.cpp b/alc/backends/wasapi.cpp index 3e9632e0..a164ed24 100644 --- a/alc/backends/wasapi.cpp +++ b/alc/backends/wasapi.cpp @@ -1086,8 +1086,6 @@ struct WasapiPlayback final : public BackendBase, WasapiProxy { std::atomic mKillNow{true}; std::thread mThread; - - DEF_NEWDEL(WasapiPlayback) }; WasapiPlayback::~WasapiPlayback() @@ -2123,8 +2121,6 @@ struct WasapiCapture final : public BackendBase, WasapiProxy { std::atomic mKillNow{true}; std::thread mThread; - - DEF_NEWDEL(WasapiCapture) }; WasapiCapture::~WasapiCapture() diff --git a/alc/backends/wave.cpp b/alc/backends/wave.cpp index f3261ed4..11794608 100644 --- a/alc/backends/wave.cpp +++ b/alc/backends/wave.cpp @@ -109,8 +109,6 @@ struct WaveBackend final : public BackendBase { std::atomic mKillNow{true}; std::thread mThread; - - DEF_NEWDEL(WaveBackend) }; WaveBackend::~WaveBackend() diff --git a/alc/backends/winmm.cpp b/alc/backends/winmm.cpp index 696f7f37..a3d647ec 100644 --- a/alc/backends/winmm.cpp +++ b/alc/backends/winmm.cpp @@ -151,8 +151,6 @@ struct WinMMPlayback final : public BackendBase { std::atomic mKillNow{true}; std::thread mThread; - - DEF_NEWDEL(WinMMPlayback) }; WinMMPlayback::~WinMMPlayback() @@ -389,8 +387,6 @@ struct WinMMCapture final : public BackendBase { std::atomic mKillNow{true}; std::thread mThread; - - DEF_NEWDEL(WinMMCapture) }; WinMMCapture::~WinMMCapture() diff --git a/alc/context.h b/alc/context.h index d923e46e..9f49ceac 100644 --- a/alc/context.h +++ b/alc/context.h @@ -230,8 +230,6 @@ public: /* Default effect that applies to sources that don't have an effect on send 0. */ static ALeffect sDefaultEffect; - DEF_NEWDEL(ALCcontext) - #ifdef ALSOFT_EAX public: bool hasEax() const noexcept { return mEaxIsInitialized; } diff --git a/alc/device.h b/alc/device.h index 66f37a7e..0f36304b 100644 --- a/alc/device.h +++ b/alc/device.h @@ -148,8 +148,6 @@ struct ALCdevice : public al::intrusive_ref, DeviceBase { template inline std::optional configValue(const char *block, const char *key) = delete; - - DEF_NEWDEL(ALCdevice) }; template<> diff --git a/alc/effects/autowah.cpp b/alc/effects/autowah.cpp index 6d66f99f..20c790b6 100644 --- a/alc/effects/autowah.cpp +++ b/alc/effects/autowah.cpp @@ -88,8 +88,6 @@ struct AutowahState final : public EffectState { const EffectTarget target) override; void process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) override; - - DEF_NEWDEL(AutowahState) }; void AutowahState::deviceUpdate(const DeviceBase*, const BufferStorage*) diff --git a/alc/effects/chorus.cpp b/alc/effects/chorus.cpp index 098b33a1..d3bcd394 100644 --- a/alc/effects/chorus.cpp +++ b/alc/effects/chorus.cpp @@ -84,8 +84,6 @@ struct ChorusState final : public EffectState { const EffectTarget target) override; void process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) override; - - DEF_NEWDEL(ChorusState) }; void ChorusState::deviceUpdate(const DeviceBase *Device, const BufferStorage*) diff --git a/alc/effects/compressor.cpp b/alc/effects/compressor.cpp index 47ef64e9..eb8605ce 100644 --- a/alc/effects/compressor.cpp +++ b/alc/effects/compressor.cpp @@ -82,8 +82,6 @@ struct CompressorState final : public EffectState { const EffectTarget target) override; void process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) override; - - DEF_NEWDEL(CompressorState) }; void CompressorState::deviceUpdate(const DeviceBase *device, const BufferStorage*) diff --git a/alc/effects/convolution.cpp b/alc/effects/convolution.cpp index 1fcb419c..f497ebce 100644 --- a/alc/effects/convolution.cpp +++ b/alc/effects/convolution.cpp @@ -233,8 +233,6 @@ struct ConvolutionState final : public EffectState { const EffectTarget target) override; void process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) override; - - DEF_NEWDEL(ConvolutionState) }; void ConvolutionState::NormalMix(const al::span samplesOut, diff --git a/alc/effects/dedicated.cpp b/alc/effects/dedicated.cpp index 1b8b3977..609776ad 100644 --- a/alc/effects/dedicated.cpp +++ b/alc/effects/dedicated.cpp @@ -56,8 +56,6 @@ struct DedicatedState final : public EffectState { const EffectTarget target) override; void process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) override; - - DEF_NEWDEL(DedicatedState) }; void DedicatedState::deviceUpdate(const DeviceBase*, const BufferStorage*) diff --git a/alc/effects/distortion.cpp b/alc/effects/distortion.cpp index 9ef9de25..5e8253e8 100644 --- a/alc/effects/distortion.cpp +++ b/alc/effects/distortion.cpp @@ -61,8 +61,6 @@ struct DistortionState final : public EffectState { const EffectTarget target) override; void process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) override; - - DEF_NEWDEL(DistortionState) }; void DistortionState::deviceUpdate(const DeviceBase*, const BufferStorage*) diff --git a/alc/effects/echo.cpp b/alc/effects/echo.cpp index fe6d8258..8def5e71 100644 --- a/alc/effects/echo.cpp +++ b/alc/effects/echo.cpp @@ -73,8 +73,6 @@ struct EchoState final : public EffectState { const EffectTarget target) override; void process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) override; - - DEF_NEWDEL(EchoState) }; void EchoState::deviceUpdate(const DeviceBase *Device, const BufferStorage*) diff --git a/alc/effects/equalizer.cpp b/alc/effects/equalizer.cpp index a4a1777a..9cb42470 100644 --- a/alc/effects/equalizer.cpp +++ b/alc/effects/equalizer.cpp @@ -106,8 +106,6 @@ struct EqualizerState final : public EffectState { const EffectTarget target) override; void process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) override; - - DEF_NEWDEL(EqualizerState) }; void EqualizerState::deviceUpdate(const DeviceBase*, const BufferStorage*) diff --git a/alc/effects/fshifter.cpp b/alc/effects/fshifter.cpp index d121885b..2add8379 100644 --- a/alc/effects/fshifter.cpp +++ b/alc/effects/fshifter.cpp @@ -103,8 +103,6 @@ struct FshifterState final : public EffectState { const EffectTarget target) override; void process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) override; - - DEF_NEWDEL(FshifterState) }; void FshifterState::deviceUpdate(const DeviceBase*, const BufferStorage*) diff --git a/alc/effects/modulator.cpp b/alc/effects/modulator.cpp index 3c612a6e..29c225e3 100644 --- a/alc/effects/modulator.cpp +++ b/alc/effects/modulator.cpp @@ -105,8 +105,6 @@ struct ModulatorState final : public EffectState { const EffectTarget target) override; void process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) override; - - DEF_NEWDEL(ModulatorState) }; template<> diff --git a/alc/effects/null.cpp b/alc/effects/null.cpp index 12d1688e..964afe47 100644 --- a/alc/effects/null.cpp +++ b/alc/effects/null.cpp @@ -25,8 +25,6 @@ struct NullState final : public EffectState { const EffectTarget target) override; void process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) override; - - DEF_NEWDEL(NullState) }; /* This constructs the effect state. It's called when the object is first diff --git a/alc/effects/pshifter.cpp b/alc/effects/pshifter.cpp index c7d662c7..24171082 100644 --- a/alc/effects/pshifter.cpp +++ b/alc/effects/pshifter.cpp @@ -112,8 +112,6 @@ struct PshifterState final : public EffectState { const EffectTarget target) override; void process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) override; - - DEF_NEWDEL(PshifterState) }; void PshifterState::deviceUpdate(const DeviceBase*, const BufferStorage*) diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp index 43451ec8..4318fa28 100644 --- a/alc/effects/reverb.cpp +++ b/alc/effects/reverb.cpp @@ -662,8 +662,6 @@ struct ReverbState final : public EffectState { const EffectTarget target) override; void process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) override; - - DEF_NEWDEL(ReverbState) }; /************************************** diff --git a/alc/effects/vmorpher.cpp b/alc/effects/vmorpher.cpp index 6cf862c2..adbcdeab 100644 --- a/alc/effects/vmorpher.cpp +++ b/alc/effects/vmorpher.cpp @@ -173,8 +173,6 @@ struct VmorpherState final : public EffectState { static std::array getFiltersByPhoneme(VMorpherPhenome phoneme, float frequency, float pitch) noexcept; - - DEF_NEWDEL(VmorpherState) }; std::array VmorpherState::getFiltersByPhoneme(VMorpherPhenome phoneme, diff --git a/common/almalloc.h b/common/almalloc.h index b3d8dd58..7ac02bf1 100644 --- a/common/almalloc.h +++ b/common/almalloc.h @@ -26,19 +26,6 @@ void *al_calloc(size_t alignment, size_t size); void operator delete(void*) noexcept = delete; \ void operator delete[](void*) noexcept = delete; -#define DEF_NEWDEL(T) \ - void *operator new(size_t size) \ - { \ - static_assert(&operator new == &T::operator new, \ - "Incorrect container type specified"); \ - if(void *ret{al_malloc(alignof(T), size)}) \ - return ret; \ - throw std::bad_alloc(); \ - } \ - void *operator new[](size_t size) { return operator new(size); } \ - void operator delete(void *block) noexcept { al_free(block); } \ - void operator delete[](void *block) noexcept { operator delete(block); } - #define DEF_PLACE_NEWDEL \ void *operator new(size_t) = delete; \ void *operator new[](size_t) = delete; \ diff --git a/core/bformatdec.h b/core/bformatdec.h index 97e7c9e4..35cf20a2 100644 --- a/core/bformatdec.h +++ b/core/bformatdec.h @@ -58,8 +58,6 @@ public: static std::unique_ptr Create(const size_t inchans, const al::span coeffs, const al::span coeffslf, const float xover_f0norm, std::unique_ptr stablizer); - - DEF_NEWDEL(BFormatDec) }; #endif /* CORE_BFORMATDEC_H */ diff --git a/core/context.h b/core/context.h index 15897ff3..0b830205 100644 --- a/core/context.h +++ b/core/context.h @@ -27,9 +27,9 @@ struct VoiceChange; struct VoicePropsItem; -constexpr float SpeedOfSoundMetersPerSec{343.3f}; +inline constexpr float SpeedOfSoundMetersPerSec{343.3f}; -constexpr float AirAbsorbGainHF{0.99426f}; /* -0.05dB */ +inline constexpr float AirAbsorbGainHF{0.99426f}; /* -0.05dB */ enum class DistanceModel : unsigned char { Disable, @@ -57,8 +57,6 @@ struct ContextProps { DistanceModel mDistanceModel; std::atomic next; - - DEF_NEWDEL(ContextProps) }; struct ContextParams { diff --git a/core/device.h b/core/device.h index 93d64aef..d85b9254 100644 --- a/core/device.h +++ b/core/device.h @@ -380,8 +380,6 @@ struct DeviceBase { [[nodiscard]] auto channelIdxByName(Channel chan) const noexcept -> uint8_t { return RealOut.ChannelIndex[chan]; } - DISABLE_ALLOC - private: uint renderSamples(const uint numSamples); }; diff --git a/core/effectslot.h b/core/effectslot.h index 3362ba85..cf8503ff 100644 --- a/core/effectslot.h +++ b/core/effectslot.h @@ -46,8 +46,6 @@ struct EffectSlotProps { al::intrusive_ptr State; std::atomic next; - - DEF_NEWDEL(EffectSlotProps) }; @@ -83,8 +81,6 @@ struct EffectSlot { static EffectSlotArray *CreatePtrArray(size_t count) noexcept; - - DEF_NEWDEL(EffectSlot) }; #endif /* CORE_EFFECTSLOT_H */ diff --git a/core/uhjfilter.h b/core/uhjfilter.h index 29838410..58576beb 100644 --- a/core/uhjfilter.h +++ b/core/uhjfilter.h @@ -110,8 +110,6 @@ struct UhjEncoderIIR final : public UhjEncoderBase { */ void encode(float *LeftOut, float *RightOut, const al::span InSamples, const size_t SamplesToDo) override; - - DEF_NEWDEL(UhjEncoderIIR) }; @@ -158,8 +156,6 @@ struct UhjDecoder final : public DecoderBase { */ void decode(const al::span samples, const size_t samplesToDo, const bool updateState) override; - - DEF_NEWDEL(UhjDecoder) }; struct UhjDecoderIIR final : public DecoderBase { @@ -184,8 +180,6 @@ struct UhjDecoderIIR final : public DecoderBase { void decode(const al::span samples, const size_t samplesToDo, const bool updateState) override; - - DEF_NEWDEL(UhjDecoderIIR) }; template @@ -210,8 +204,6 @@ struct UhjStereoDecoder final : public DecoderBase { */ void decode(const al::span samples, const size_t samplesToDo, const bool updateState) override; - - DEF_NEWDEL(UhjStereoDecoder) }; struct UhjStereoDecoderIIR final : public DecoderBase { @@ -231,8 +223,6 @@ struct UhjStereoDecoderIIR final : public DecoderBase { void decode(const al::span samples, const size_t samplesToDo, const bool updateState) override; - - DEF_NEWDEL(UhjStereoDecoderIIR) }; #endif /* CORE_UHJFILTER_H */ diff --git a/core/voice.h b/core/voice.h index 6c953804..2ecc8148 100644 --- a/core/voice.h +++ b/core/voice.h @@ -160,8 +160,6 @@ struct VoiceProps { struct VoicePropsItem : public VoiceProps { std::atomic next{nullptr}; - - DEF_NEWDEL(VoicePropsItem) }; enum : uint { @@ -271,8 +269,6 @@ struct Voice { void prepare(DeviceBase *device); static void InitMixer(std::optional resampler); - - DEF_NEWDEL(Voice) }; extern Resampler ResamplerDefault; diff --git a/core/voice_change.h b/core/voice_change.h index ddc6186f..e97c48f3 100644 --- a/core/voice_change.h +++ b/core/voice_change.h @@ -3,8 +3,6 @@ #include -#include "almalloc.h" - struct Voice; using uint = unsigned int; @@ -24,8 +22,6 @@ struct VoiceChange { VChangeState mState{}; std::atomic mNext{nullptr}; - - DEF_NEWDEL(VoiceChange) }; #endif /* VOICE_CHANGE_H */ diff --git a/utils/uhjdecoder.cpp b/utils/uhjdecoder.cpp index feca0a35..801425e0 100644 --- a/utils/uhjdecoder.cpp +++ b/utils/uhjdecoder.cpp @@ -35,7 +35,6 @@ #include "albit.h" #include "alcomplex.h" -#include "almalloc.h" #include "alnumbers.h" #include "alspan.h" #include "vector.h" @@ -129,8 +128,6 @@ struct UhjDecoder { const al::span OutSamples, const std::size_t SamplesToDo); void decode2(const float *RESTRICT InSamples, const al::span OutSamples, const std::size_t SamplesToDo); - - DEF_NEWDEL(UhjDecoder) }; const PhaseShifterT PShift{}; diff --git a/utils/uhjencoder.cpp b/utils/uhjencoder.cpp index 8673dd59..6a7b1fa9 100644 --- a/utils/uhjencoder.cpp +++ b/utils/uhjencoder.cpp @@ -33,7 +33,6 @@ #include #include -#include "almalloc.h" #include "alnumbers.h" #include "alspan.h" #include "opthelpers.h" @@ -82,8 +81,6 @@ struct UhjEncoder { void encode(const al::span OutSamples, const al::span InSamples, const size_t SamplesToDo); - - DEF_NEWDEL(UhjEncoder) }; const PhaseShifterT PShift{}; -- cgit v1.2.3 From aa6e04a5562052db172117043165ae999683b052 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 20 Dec 2023 01:53:27 -0800 Subject: Ensure struct members are initialized --- al/source.h | 22 +++++++++---------- alc/backends/portaudio.cpp | 34 +++++++++++++++--------------- alc/backends/pulseaudio.cpp | 4 ++-- alc/backends/sndio.cpp | 2 +- alc/effects/autowah.cpp | 26 +++++++++++------------ alc/effects/chorus.cpp | 4 ++-- alc/effects/dedicated.cpp | 4 ++-- alc/effects/echo.cpp | 2 +- alc/effects/fshifter.cpp | 2 +- alc/effects/pshifter.cpp | 32 ++++++++++++++-------------- alc/effects/reverb.cpp | 6 +++--- common/alsem.h | 2 +- common/polyphase_resampler.h | 2 +- core/bformatdec.h | 6 +++--- core/device.h | 10 ++++----- core/filters/nfc.h | 24 ++++++++++----------- core/hrtf.h | 2 +- core/uhjfilter.h | 2 +- core/voice.h | 50 ++++++++++++++++++++++---------------------- examples/alffplay.cpp | 2 +- examples/alstreamcb.cpp | 2 +- utils/makemhr/makemhr.cpp | 8 +++---- 22 files changed, 124 insertions(+), 124 deletions(-) (limited to 'alc/effects/reverb.cpp') diff --git a/al/source.h b/al/source.h index 69bedda3..1a93d927 100644 --- a/al/source.h +++ b/al/source.h @@ -108,19 +108,19 @@ struct ALsource { /** Direct filter and auxiliary send info. */ struct { - float Gain; - float GainHF; - float HFReference; - float GainLF; - float LFReference; + float Gain{}; + float GainHF{}; + float HFReference{}; + float GainLF{}; + float LFReference{}; } Direct; struct SendData { - ALeffectslot *Slot; - float Gain; - float GainHF; - float HFReference; - float GainLF; - float LFReference; + ALeffectslot *Slot{}; + float Gain{}; + float GainHF{}; + float HFReference{}; + float GainLF{}; + float LFReference{}; }; std::array Send; diff --git a/alc/backends/portaudio.cpp b/alc/backends/portaudio.cpp index dc9725b0..b6013dcc 100644 --- a/alc/backends/portaudio.cpp +++ b/alc/backends/portaudio.cpp @@ -79,13 +79,6 @@ struct PortPlayback final : public BackendBase { int writeCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, const PaStreamCallbackFlags statusFlags) noexcept; - static int writeCallbackC(const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, - const PaStreamCallbackFlags statusFlags, void *userData) noexcept - { - return static_cast(userData)->writeCallback(inputBuffer, outputBuffer, - framesPerBuffer, timeInfo, statusFlags); - } void open(std::string_view name) override; bool reset() override; @@ -156,9 +149,16 @@ void PortPlayback::open(std::string_view name) } retry_open: + static constexpr auto writeCallback = [](const void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, + const PaStreamCallbackFlags statusFlags, void *userData) noexcept + { + return static_cast(userData)->writeCallback(inputBuffer, outputBuffer, + framesPerBuffer, timeInfo, statusFlags); + }; PaStream *stream{}; PaError err{Pa_OpenStream(&stream, nullptr, ¶ms, mDevice->Frequency, mDevice->UpdateSize, - paNoFlag, &PortPlayback::writeCallbackC, this)}; + paNoFlag, writeCallback, this)}; if(err != paNoError) { if(params.sampleFormat == paFloat32) @@ -236,13 +236,6 @@ struct PortCapture final : public BackendBase { int readCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, const PaStreamCallbackFlags statusFlags) noexcept; - static int readCallbackC(const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, - const PaStreamCallbackFlags statusFlags, void *userData) noexcept - { - return static_cast(userData)->readCallback(inputBuffer, outputBuffer, - framesPerBuffer, timeInfo, statusFlags); - } void open(std::string_view name) override; void start() override; @@ -251,7 +244,7 @@ struct PortCapture final : public BackendBase { uint availableSamples() override; PaStream *mStream{nullptr}; - PaStreamParameters mParams; + PaStreamParameters mParams{}; RingBufferPtr mRing{nullptr}; }; @@ -317,8 +310,15 @@ void PortCapture::open(std::string_view name) } mParams.channelCount = static_cast(mDevice->channelsFromFmt()); + static constexpr auto readCallback = [](const void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, + const PaStreamCallbackFlags statusFlags, void *userData) noexcept + { + return static_cast(userData)->readCallback(inputBuffer, outputBuffer, + framesPerBuffer, timeInfo, statusFlags); + }; PaError err{Pa_OpenStream(&mStream, &mParams, nullptr, mDevice->Frequency, - paFramesPerBufferUnspecified, paNoFlag, &PortCapture::readCallbackC, this)}; + paFramesPerBufferUnspecified, paNoFlag, readCallback, this)}; if(err != paNoError) throw al::backend_exception{al::backend_error::NoDevice, "Failed to open stream: %s", Pa_GetErrorText(err)}; diff --git a/alc/backends/pulseaudio.cpp b/alc/backends/pulseaudio.cpp index 8533cdb9..aec91229 100644 --- a/alc/backends/pulseaudio.cpp +++ b/alc/backends/pulseaudio.cpp @@ -658,8 +658,8 @@ struct PulsePlayback final : public BackendBase { std::optional mDeviceName{std::nullopt}; bool mIs51Rear{false}; - pa_buffer_attr mAttr; - pa_sample_spec mSpec; + pa_buffer_attr mAttr{}; + pa_sample_spec mSpec{}; pa_stream *mStream{nullptr}; diff --git a/alc/backends/sndio.cpp b/alc/backends/sndio.cpp index 8477ed1f..2cb577fd 100644 --- a/alc/backends/sndio.cpp +++ b/alc/backends/sndio.cpp @@ -47,7 +47,7 @@ namespace { constexpr char sndio_device[] = "SndIO Default"; struct SioPar : public sio_par { - SioPar() { sio_initpar(this); } + SioPar() : sio_par{} { sio_initpar(this); } void clear() { sio_initpar(this); } }; diff --git a/alc/effects/autowah.cpp b/alc/effects/autowah.cpp index 20c790b6..e9e14e35 100644 --- a/alc/effects/autowah.cpp +++ b/alc/effects/autowah.cpp @@ -50,18 +50,18 @@ constexpr float QFactor{5.0f}; struct AutowahState final : public EffectState { /* Effect parameters */ - float mAttackRate; - float mReleaseRate; - float mResonanceGain; - float mPeakGain; - float mFreqMinNorm; - float mBandwidthNorm; - float mEnvDelay; + float mAttackRate{}; + float mReleaseRate{}; + float mResonanceGain{}; + float mPeakGain{}; + float mFreqMinNorm{}; + float mBandwidthNorm{}; + float mEnvDelay{}; /* Filter components derived from the envelope. */ struct FilterParam { - float cos_w0; - float alpha; + float cos_w0{}; + float alpha{}; }; std::array mEnv; @@ -70,17 +70,17 @@ struct AutowahState final : public EffectState { /* Effect filters' history. */ struct { - float z1, z2; + float z1{}, z2{}; } mFilter; /* Effect gains for each output channel */ - float mCurrentGain; - float mTargetGain; + float mCurrentGain{}; + float mTargetGain{}; }; std::array mChans; /* Effects buffers */ - alignas(16) FloatBufferLine mBufferOut; + alignas(16) FloatBufferLine mBufferOut{}; void deviceUpdate(const DeviceBase *device, const BufferStorage *buffer) override; diff --git a/alc/effects/chorus.cpp b/alc/effects/chorus.cpp index d3bcd394..f56c9f2c 100644 --- a/alc/effects/chorus.cpp +++ b/alc/effects/chorus.cpp @@ -58,10 +58,10 @@ struct ChorusState final : public EffectState { uint mLfoDisp{0}; /* Calculated delays to apply to the left and right outputs. */ - std::array,2> mModDelays; + std::array,2> mModDelays{}; /* Temp storage for the modulated left and right outputs. */ - alignas(16) std::array mBuffer; + alignas(16) std::array mBuffer{}; /* Gains for left and right outputs. */ struct OutGains { diff --git a/alc/effects/dedicated.cpp b/alc/effects/dedicated.cpp index 609776ad..a3d4298d 100644 --- a/alc/effects/dedicated.cpp +++ b/alc/effects/dedicated.cpp @@ -47,8 +47,8 @@ struct DedicatedState final : public EffectState { * gains for all possible output channels and not just the main ambisonic * buffer. */ - std::array mCurrentGains; - std::array mTargetGains; + std::array mCurrentGains{}; + std::array mTargetGains{}; void deviceUpdate(const DeviceBase *device, const BufferStorage *buffer) override; diff --git a/alc/effects/echo.cpp b/alc/effects/echo.cpp index 8def5e71..2f3343e8 100644 --- a/alc/effects/echo.cpp +++ b/alc/effects/echo.cpp @@ -66,7 +66,7 @@ struct EchoState final : public EffectState { BiquadFilter mFilter; float mFeedGain{0.0f}; - alignas(16) std::array mTempBuffer; + alignas(16) std::array mTempBuffer{}; void deviceUpdate(const DeviceBase *device, const BufferStorage *buffer) override; void update(const ContextBase *context, const EffectSlot *slot, const EffectProps *props, diff --git a/alc/effects/fshifter.cpp b/alc/effects/fshifter.cpp index 2add8379..433ebfe4 100644 --- a/alc/effects/fshifter.cpp +++ b/alc/effects/fshifter.cpp @@ -57,7 +57,7 @@ constexpr size_t HilStep{HilSize / OversampleFactor}; /* Define a Hann window, used to filter the HIL input and output. */ struct Windower { - alignas(16) std::array mData; + alignas(16) std::array mData{}; Windower() { diff --git a/alc/effects/pshifter.cpp b/alc/effects/pshifter.cpp index 24171082..9714510f 100644 --- a/alc/effects/pshifter.cpp +++ b/alc/effects/pshifter.cpp @@ -58,7 +58,7 @@ constexpr size_t StftStep{StftSize / OversampleFactor}; /* Define a Hann window, used to filter the STFT input and output. */ struct Windower { - alignas(16) std::array mData; + alignas(16) std::array mData{}; Windower() { @@ -82,29 +82,29 @@ struct FrequencyBin { struct PshifterState final : public EffectState { /* Effect parameters */ - size_t mCount; - size_t mPos; - uint mPitchShiftI; - float mPitchShift; + size_t mCount{}; + size_t mPos{}; + uint mPitchShiftI{}; + float mPitchShift{}; /* Effects buffers */ - std::array mFIFO; - std::array mLastPhase; - std::array mSumPhase; - std::array mOutputAccum; + std::array mFIFO{}; + std::array mLastPhase{}; + std::array mSumPhase{}; + std::array mOutputAccum{}; PFFFTSetup mFft; - alignas(16) std::array mFftBuffer; - alignas(16) std::array mFftWorkBuffer; + alignas(16) std::array mFftBuffer{}; + alignas(16) std::array mFftWorkBuffer{}; - std::array mAnalysisBuffer; - std::array mSynthesisBuffer; + std::array mAnalysisBuffer{}; + std::array mSynthesisBuffer{}; - alignas(16) FloatBufferLine mBufferOut; + alignas(16) FloatBufferLine mBufferOut{}; /* Effect gains for each output channel */ - std::array mCurrentGains; - std::array mTargetGains; + std::array mCurrentGains{}; + std::array mTargetGains{}; void deviceUpdate(const DeviceBase *device, const BufferStorage *buffer) override; diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp index 4318fa28..cc5768e2 100644 --- a/alc/effects/reverb.cpp +++ b/alc/effects/reverb.cpp @@ -417,12 +417,12 @@ struct Modulation { /* The vibrato time is tracked with an index over a (MOD_FRACONE) * normalized range. */ - uint Index, Step; + uint Index{}, Step{}; /* The depth of frequency change, in samples. */ - float Depth; + float Depth{}; - std::array ModDelays; + std::array ModDelays{}; void updateModulator(float modTime, float modDepth, float frequency); diff --git a/common/alsem.h b/common/alsem.h index 9f72d1c6..90b39319 100644 --- a/common/alsem.h +++ b/common/alsem.h @@ -24,7 +24,7 @@ class semaphore { #else using native_type = sem_t; #endif - native_type mSem; + native_type mSem{}; public: semaphore(unsigned int initial=0); diff --git a/common/polyphase_resampler.h b/common/polyphase_resampler.h index 557485bb..764111c9 100644 --- a/common/polyphase_resampler.h +++ b/common/polyphase_resampler.h @@ -40,7 +40,7 @@ struct PPhaseResampler { explicit operator bool() const noexcept { return !mF.empty(); } private: - uint mP, mQ, mM, mL; + uint mP{}, mQ{}, mM{}, mL{}; std::vector mF; }; diff --git a/core/bformatdec.h b/core/bformatdec.h index 35cf20a2..8513db03 100644 --- a/core/bformatdec.h +++ b/core/bformatdec.h @@ -25,15 +25,15 @@ class BFormatDec { static constexpr size_t sNumBands{2}; struct ChannelDecoderSingle { - std::array mGains; + std::array mGains{}; }; struct ChannelDecoderDual { BandSplitter mXOver; - std::array,sNumBands> mGains; + std::array,sNumBands> mGains{}; }; - alignas(16) std::array mSamples; + alignas(16) std::array mSamples{}; const std::unique_ptr mStablizer; diff --git a/core/device.h b/core/device.h index d85b9254..f02700c6 100644 --- a/core/device.h +++ b/core/device.h @@ -237,17 +237,17 @@ struct DeviceBase { static constexpr size_t MixerLineSize{BufferLineSize + DecoderBase::sMaxPadding}; static constexpr size_t MixerChannelsMax{16}; using MixerBufferLine = std::array; - alignas(16) std::array mSampleData; - alignas(16) std::array mResampleData; + alignas(16) std::array mSampleData{}; + alignas(16) std::array mResampleData{}; - alignas(16) std::array FilteredData; + alignas(16) std::array FilteredData{}; union { - alignas(16) std::array HrtfSourceData; + alignas(16) std::array HrtfSourceData{}; alignas(16) std::array NfcSampleData; }; /* Persistent storage for HRTF mixing. */ - alignas(16) std::array HrtfAccumData; + alignas(16) std::array HrtfAccumData{}; /* Mixing buffer used by the Dry mix and Real output. */ al::vector MixBuffer; diff --git a/core/filters/nfc.h b/core/filters/nfc.h index 7d0a7488..9c58f863 100644 --- a/core/filters/nfc.h +++ b/core/filters/nfc.h @@ -8,24 +8,24 @@ struct NfcFilter1 { - float base_gain, gain; - float b1, a1; - std::array z; + float base_gain{1.0f}, gain{1.0f}; + float b1{}, a1{}; + std::array z{}; }; struct NfcFilter2 { - float base_gain, gain; - float b1, b2, a1, a2; - std::array z; + float base_gain{1.0f}, gain{1.0f}; + float b1{}, b2{}, a1{}, a2{}; + std::array z{}; }; struct NfcFilter3 { - float base_gain, gain; - float b1, b2, b3, a1, a2, a3; - std::array z; + float base_gain{1.0f}, gain{1.0f}; + float b1{}, b2{}, b3{}, a1{}, a2{}, a3{}; + std::array z{}; }; struct NfcFilter4 { - float base_gain, gain; - float b1, b2, b3, b4, a1, a2, a3, a4; - std::array z; + float base_gain{1.0f}, gain{1.0f}; + float b1{}, b2{}, b3{}, b4{}, a1{}, a2{}, a3{}, a4{}; + std::array z{}; }; class NfcFilter { diff --git a/core/hrtf.h b/core/hrtf.h index e0263493..7a1a8b69 100644 --- a/core/hrtf.h +++ b/core/hrtf.h @@ -61,7 +61,7 @@ struct AngularPoint { struct DirectHrtfState { - std::array mTemp; + std::array mTemp{}; /* HRTF filter state for dry buffer content */ uint mIrSize{0}; diff --git a/core/uhjfilter.h b/core/uhjfilter.h index 58576beb..74ff2167 100644 --- a/core/uhjfilter.h +++ b/core/uhjfilter.h @@ -25,7 +25,7 @@ extern UhjQualityType UhjEncodeQuality; struct UhjAllPassFilter { struct AllPassState { /* Last two delayed components for direct form II. */ - std::array z; + std::array z{}; }; std::array mState; diff --git a/core/voice.h b/core/voice.h index 2ecc8148..aaf1c5fd 100644 --- a/core/voice.h +++ b/core/voice.h @@ -66,14 +66,14 @@ struct DirectParams { NfcFilter NFCtrlFilter; struct { - HrtfFilter Old; - HrtfFilter Target; - alignas(16) std::array History; + HrtfFilter Old{}; + HrtfFilter Target{}; + alignas(16) std::array History{}; } Hrtf; struct { - std::array Current; - std::array Target; + std::array Current{}; + std::array Target{}; } Gains; }; @@ -82,8 +82,8 @@ struct SendParams { BiquadFilter HighPass; struct { - std::array Current; - std::array Target; + std::array Current{}; + std::array Target{}; } Gains; }; @@ -184,7 +184,7 @@ struct Voice { std::atomic mUpdate{nullptr}; - VoiceProps mProps; + VoiceProps mProps{}; std::atomic mSourceID{0u}; std::atomic mPlayState{Stopped}; @@ -194,30 +194,30 @@ struct Voice { * Source offset in samples, relative to the currently playing buffer, NOT * the whole queue. */ - std::atomic mPosition; + std::atomic mPosition{}; /** Fractional (fixed-point) offset to the next sample. */ - std::atomic mPositionFrac; + std::atomic mPositionFrac{}; /* Current buffer queue item being played. */ - std::atomic mCurrentBuffer; + std::atomic mCurrentBuffer{}; /* Buffer queue item to loop to at end of queue (will be NULL for non- * looping voices). */ - std::atomic mLoopBuffer; + std::atomic mLoopBuffer{}; std::chrono::nanoseconds mStartTime{}; /* Properties for the attached buffer(s). */ - FmtChannels mFmtChannels; - FmtType mFmtType; - uint mFrequency; - uint mFrameStep; /**< In steps of the sample type size. */ - uint mBytesPerBlock; /**< Or for PCM formats, BytesPerFrame. */ - uint mSamplesPerBlock; /**< Always 1 for PCM formats. */ - AmbiLayout mAmbiLayout; - AmbiScaling mAmbiScaling; - uint mAmbiOrder; + FmtChannels mFmtChannels{}; + FmtType mFmtType{}; + uint mFrequency{}; + uint mFrameStep{}; /**< In steps of the sample type size. */ + uint mBytesPerBlock{}; /**< Or for PCM formats, BytesPerFrame. */ + uint mSamplesPerBlock{}; /**< Always 1 for PCM formats. */ + AmbiLayout mAmbiLayout{}; + AmbiScaling mAmbiScaling{}; + uint mAmbiOrder{}; std::unique_ptr mDecoder; uint mDecoderPadding{}; @@ -225,16 +225,16 @@ struct Voice { /** Current target parameters used for mixing. */ uint mStep{0}; - ResamplerFunc mResampler; + ResamplerFunc mResampler{}; - InterpState mResampleState; + InterpState mResampleState{}; std::bitset mFlags{}; uint mNumCallbackBlocks{0}; uint mCallbackBlockBase{0}; struct TargetData { - int FilterType; + int FilterType{}; al::span Buffer; }; TargetData mDirect; @@ -249,7 +249,7 @@ struct Voice { al::vector mPrevSamples{2}; struct ChannelData { - float mAmbiHFScale, mAmbiLFScale; + float mAmbiHFScale{}, mAmbiLFScale{}; BandSplitter mAmbiSplitter; DirectParams mDryParams; diff --git a/examples/alffplay.cpp b/examples/alffplay.cpp index 347d0b14..7a4b7aac 100644 --- a/examples/alffplay.cpp +++ b/examples/alffplay.cpp @@ -322,7 +322,7 @@ struct AudioState { std::mutex mSrcMutex; std::condition_variable mSrcCond; - std::atomic_flag mConnected; + std::atomic_flag mConnected{}; ALuint mSource{0}; std::array mBuffers{}; ALuint mBufferIdx{0}; diff --git a/examples/alstreamcb.cpp b/examples/alstreamcb.cpp index 95f89bbe..1721d367 100644 --- a/examples/alstreamcb.cpp +++ b/examples/alstreamcb.cpp @@ -79,7 +79,7 @@ struct StreamPlayer { size_t mDecoderOffset{0}; /* The format of the callback samples. */ - ALenum mFormat; + ALenum mFormat{}; StreamPlayer() { diff --git a/utils/makemhr/makemhr.cpp b/utils/makemhr/makemhr.cpp index 80e217ee..014b2967 100644 --- a/utils/makemhr/makemhr.cpp +++ b/utils/makemhr/makemhr.cpp @@ -871,10 +871,10 @@ static void SynthesizeHrirs(HrirDataT *hData) */ struct HrirReconstructor { std::vector mIrs; - std::atomic mCurrent; - std::atomic mDone; - uint mFftSize; - uint mIrPoints; + std::atomic mCurrent{}; + std::atomic mDone{}; + uint mFftSize{}; + uint mIrPoints{}; void Worker() { -- cgit v1.2.3 From eb2c7e84b67e23c2a84cf9b2f8db6da2a1d51a2f Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 21 Dec 2023 01:58:55 -0800 Subject: Use a bool for a 0/1 value --- alc/effects/reverb.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'alc/effects/reverb.cpp') diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp index cc5768e2..5eefdfbf 100644 --- a/alc/effects/reverb.cpp +++ b/alc/effects/reverb.cpp @@ -551,7 +551,7 @@ struct ReverbState final : public EffectState { Normal, }; PipelineState mPipelineState{DeviceClear}; - uint8_t mCurrentPipeline{0}; + bool mCurrentPipeline{false}; std::array mPipelines; @@ -1235,7 +1235,7 @@ void ReverbState::update(const ContextBase *Context, const EffectSlot *Slot, mParams.LFReference = props->Reverb.LFReference; mPipelineState = (mPipelineState != DeviceClear) ? StartFade : Normal; - mCurrentPipeline ^= 1; + mCurrentPipeline = !mCurrentPipeline; } auto &pipeline = mPipelines[mCurrentPipeline]; @@ -1671,7 +1671,7 @@ void ReverbState::process(const size_t samplesToDo, const al::span 0); - auto &oldpipeline = mPipelines[mCurrentPipeline^1]; + auto &oldpipeline = mPipelines[!mCurrentPipeline]; auto &pipeline = mPipelines[mCurrentPipeline]; if(mPipelineState >= Fading) @@ -1781,7 +1781,7 @@ void ReverbState::process(const size_t samplesToDo, const al::span Date: Sun, 24 Dec 2023 02:48:20 -0800 Subject: Rework effect property handling To nake EffectProps a variant instead of a union, and avoid manual vtables. --- al/effect.cpp | 231 +++++++++++-------- al/effect.h | 2 - al/effects/autowah.cpp | 102 ++++----- al/effects/chorus.cpp | 194 +++++++--------- al/effects/compressor.cpp | 49 ++-- al/effects/convolution.cpp | 82 ++++--- al/effects/dedicated.cpp | 93 ++++---- al/effects/distortion.cpp | 100 ++++---- al/effects/echo.cpp | 100 ++++---- al/effects/effects.h | 80 ++++--- al/effects/equalizer.cpp | 155 ++++++------- al/effects/fshifter.cpp | 96 ++++---- al/effects/modulator.cpp | 110 +++++---- al/effects/null.cpp | 49 ++-- al/effects/pshifter.cpp | 72 +++--- al/effects/reverb.cpp | 545 +++++++++++++++++++------------------------- al/effects/vmorpher.cpp | 107 ++++----- alc/alu.cpp | 14 +- alc/effects/autowah.cpp | 11 +- alc/effects/chorus.cpp | 15 +- alc/effects/compressor.cpp | 2 +- alc/effects/convolution.cpp | 9 +- alc/effects/dedicated.cpp | 4 +- alc/effects/distortion.cpp | 13 +- alc/effects/echo.cpp | 13 +- alc/effects/equalizer.cpp | 23 +- alc/effects/fshifter.cpp | 9 +- alc/effects/modulator.cpp | 15 +- alc/effects/pshifter.cpp | 5 +- alc/effects/reverb.cpp | 87 ++++--- alc/effects/vmorpher.cpp | 21 +- core/effects/base.h | 38 +-- 32 files changed, 1136 insertions(+), 1310 deletions(-) (limited to 'alc/effects/reverb.cpp') diff --git a/al/effect.cpp b/al/effect.cpp index 005b1557..c33faa2c 100644 --- a/al/effect.cpp +++ b/al/effect.cpp @@ -89,72 +89,34 @@ effect_exception::~effect_exception() = default; namespace { -struct EffectPropsItem { - ALenum Type; - const EffectProps &DefaultProps; - const EffectVtable &Vtable; -}; -constexpr std::array EffectPropsList{ - EffectPropsItem{AL_EFFECT_NULL, NullEffectProps, NullEffectVtable}, - EffectPropsItem{AL_EFFECT_EAXREVERB, ReverbEffectProps, ReverbEffectVtable}, - EffectPropsItem{AL_EFFECT_REVERB, StdReverbEffectProps, StdReverbEffectVtable}, - EffectPropsItem{AL_EFFECT_AUTOWAH, AutowahEffectProps, AutowahEffectVtable}, - EffectPropsItem{AL_EFFECT_CHORUS, ChorusEffectProps, ChorusEffectVtable}, - EffectPropsItem{AL_EFFECT_COMPRESSOR, CompressorEffectProps, CompressorEffectVtable}, - EffectPropsItem{AL_EFFECT_DISTORTION, DistortionEffectProps, DistortionEffectVtable}, - EffectPropsItem{AL_EFFECT_ECHO, EchoEffectProps, EchoEffectVtable}, - EffectPropsItem{AL_EFFECT_EQUALIZER, EqualizerEffectProps, EqualizerEffectVtable}, - EffectPropsItem{AL_EFFECT_FLANGER, FlangerEffectProps, FlangerEffectVtable}, - EffectPropsItem{AL_EFFECT_FREQUENCY_SHIFTER, FshifterEffectProps, FshifterEffectVtable}, - EffectPropsItem{AL_EFFECT_RING_MODULATOR, ModulatorEffectProps, ModulatorEffectVtable}, - EffectPropsItem{AL_EFFECT_PITCH_SHIFTER, PshifterEffectProps, PshifterEffectVtable}, - EffectPropsItem{AL_EFFECT_VOCAL_MORPHER, VmorpherEffectProps, VmorpherEffectVtable}, - EffectPropsItem{AL_EFFECT_DEDICATED_DIALOGUE, DedicatedDialogEffectProps, DedicatedDialogEffectVtable}, - EffectPropsItem{AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT, DedicatedLfeEffectProps, DedicatedLfeEffectVtable}, - EffectPropsItem{AL_EFFECT_CONVOLUTION_SOFT, ConvolutionEffectProps, ConvolutionEffectVtable}, -}; - - -void ALeffect_setParami(ALeffect *effect, ALenum param, int value) -{ effect->vtab->setParami(&effect->Props, param, value); } -void ALeffect_setParamiv(ALeffect *effect, ALenum param, const int *values) -{ effect->vtab->setParamiv(&effect->Props, param, values); } -void ALeffect_setParamf(ALeffect *effect, ALenum param, float value) -{ effect->vtab->setParamf(&effect->Props, param, value); } -void ALeffect_setParamfv(ALeffect *effect, ALenum param, const float *values) -{ effect->vtab->setParamfv(&effect->Props, param, values); } - -void ALeffect_getParami(const ALeffect *effect, ALenum param, int *value) -{ effect->vtab->getParami(&effect->Props, param, value); } -void ALeffect_getParamiv(const ALeffect *effect, ALenum param, int *values) -{ effect->vtab->getParamiv(&effect->Props, param, values); } -void ALeffect_getParamf(const ALeffect *effect, ALenum param, float *value) -{ effect->vtab->getParamf(&effect->Props, param, value); } -void ALeffect_getParamfv(const ALeffect *effect, ALenum param, float *values) -{ effect->vtab->getParamfv(&effect->Props, param, values); } - - -const EffectPropsItem *getEffectPropsItemByType(ALenum type) +auto GetDefaultProps(ALenum type) -> const EffectProps& { - auto iter = std::find_if(EffectPropsList.begin(), EffectPropsList.end(), - [type](const EffectPropsItem &item) noexcept -> bool - { return item.Type == type; }); - return (iter != std::end(EffectPropsList)) ? al::to_address(iter) : nullptr; + switch(type) + { + case AL_EFFECT_NULL: return NullEffectProps; + case AL_EFFECT_EAXREVERB: return ReverbEffectProps; + case AL_EFFECT_REVERB: return StdReverbEffectProps; + case AL_EFFECT_AUTOWAH: return AutowahEffectProps; + case AL_EFFECT_CHORUS: return ChorusEffectProps; + case AL_EFFECT_COMPRESSOR: return CompressorEffectProps; + case AL_EFFECT_DISTORTION: return DistortionEffectProps; + case AL_EFFECT_ECHO: return EchoEffectProps; + case AL_EFFECT_EQUALIZER: return EqualizerEffectProps; + case AL_EFFECT_FLANGER: return FlangerEffectProps; + case AL_EFFECT_FREQUENCY_SHIFTER: return FshifterEffectProps; + case AL_EFFECT_RING_MODULATOR: return ModulatorEffectProps; + case AL_EFFECT_PITCH_SHIFTER: return PshifterEffectProps; + case AL_EFFECT_VOCAL_MORPHER: return VmorpherEffectProps; + case AL_EFFECT_DEDICATED_DIALOGUE: return DedicatedDialogEffectProps; + case AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT: return DedicatedLfeEffectProps; + case AL_EFFECT_CONVOLUTION_SOFT: return ConvolutionEffectProps; + } + return NullEffectProps; } void InitEffectParams(ALeffect *effect, ALenum type) { - const EffectPropsItem *item{getEffectPropsItemByType(type)}; - if(item) - { - effect->Props = item->DefaultProps; - effect->vtab = &item->Vtable; - } - else - { - effect->Props = EffectProps{}; - effect->vtab = &NullEffectVtable; - } + effect->Props = GetDefaultProps(type); effect->type = type; } @@ -342,7 +304,16 @@ FORCE_ALIGN void AL_APIENTRY alEffectiDirect(ALCcontext *context, ALuint effect, else try { /* Call the appropriate handler */ - ALeffect_setParami(aleffect, param, value); + std::visit([aleffect,param,value](auto &arg) + { + using Type = std::remove_cv_t>; + if constexpr(std::is_same_v) + { + if(aleffect->type == AL_EFFECT_REVERB) + return EffectHandler::StdReverbSetParami(arg, param, value); + } + return EffectHandler::SetParami(arg, param, value); + }, aleffect->Props); } catch(effect_exception &e) { context->setError(e.errorCode(), "%s", e.what()); @@ -369,7 +340,16 @@ FORCE_ALIGN void AL_APIENTRY alEffectivDirect(ALCcontext *context, ALuint effect else try { /* Call the appropriate handler */ - ALeffect_setParamiv(aleffect, param, values); + std::visit([aleffect,param,values](auto &arg) + { + using Type = std::remove_cv_t>; + if constexpr(std::is_same_v) + { + if(aleffect->type == AL_EFFECT_REVERB) + return EffectHandler::StdReverbSetParamiv(arg, param, values); + } + return EffectHandler::SetParamiv(arg, param, values); + }, aleffect->Props); } catch(effect_exception &e) { context->setError(e.errorCode(), "%s", e.what()); @@ -389,7 +369,16 @@ FORCE_ALIGN void AL_APIENTRY alEffectfDirect(ALCcontext *context, ALuint effect, else try { /* Call the appropriate handler */ - ALeffect_setParamf(aleffect, param, value); + std::visit([aleffect,param,value](auto &arg) + { + using Type = std::remove_cv_t>; + if constexpr(std::is_same_v) + { + if(aleffect->type == AL_EFFECT_REVERB) + return EffectHandler::StdReverbSetParamf(arg, param, value); + } + return EffectHandler::SetParamf(arg, param, value); + }, aleffect->Props); } catch(effect_exception &e) { context->setError(e.errorCode(), "%s", e.what()); @@ -409,7 +398,16 @@ FORCE_ALIGN void AL_APIENTRY alEffectfvDirect(ALCcontext *context, ALuint effect else try { /* Call the appropriate handler */ - ALeffect_setParamfv(aleffect, param, values); + std::visit([aleffect,param,values](auto &arg) + { + using Type = std::remove_cv_t>; + if constexpr(std::is_same_v) + { + if(aleffect->type == AL_EFFECT_REVERB) + return EffectHandler::StdReverbSetParamfv(arg, param, values); + } + return EffectHandler::SetParamfv(arg, param, values); + }, aleffect->Props); } catch(effect_exception &e) { context->setError(e.errorCode(), "%s", e.what()); @@ -431,7 +429,16 @@ FORCE_ALIGN void AL_APIENTRY alGetEffectiDirect(ALCcontext *context, ALuint effe else try { /* Call the appropriate handler */ - ALeffect_getParami(aleffect, param, value); + std::visit([aleffect,param,value](auto &arg) + { + using Type = std::remove_cv_t>; + if constexpr(std::is_same_v) + { + if(aleffect->type == AL_EFFECT_REVERB) + return EffectHandler::StdReverbGetParami(arg, param, value); + } + return EffectHandler::GetParami(arg, param, value); + }, aleffect->Props); } catch(effect_exception &e) { context->setError(e.errorCode(), "%s", e.what()); @@ -458,7 +465,16 @@ FORCE_ALIGN void AL_APIENTRY alGetEffectivDirect(ALCcontext *context, ALuint eff else try { /* Call the appropriate handler */ - ALeffect_getParamiv(aleffect, param, values); + std::visit([aleffect,param,values](auto &arg) + { + using Type = std::remove_cv_t>; + if constexpr(std::is_same_v) + { + if(aleffect->type == AL_EFFECT_REVERB) + return EffectHandler::StdReverbGetParamiv(arg, param, values); + } + return EffectHandler::GetParamiv(arg, param, values); + }, aleffect->Props); } catch(effect_exception &e) { context->setError(e.errorCode(), "%s", e.what()); @@ -478,7 +494,16 @@ FORCE_ALIGN void AL_APIENTRY alGetEffectfDirect(ALCcontext *context, ALuint effe else try { /* Call the appropriate handler */ - ALeffect_getParamf(aleffect, param, value); + std::visit([aleffect,param,value](auto &arg) + { + using Type = std::remove_cv_t>; + if constexpr(std::is_same_v) + { + if(aleffect->type == AL_EFFECT_REVERB) + return EffectHandler::StdReverbGetParamf(arg, param, value); + } + return EffectHandler::GetParamf(arg, param, value); + }, aleffect->Props); } catch(effect_exception &e) { context->setError(e.errorCode(), "%s", e.what()); @@ -498,7 +523,16 @@ FORCE_ALIGN void AL_APIENTRY alGetEffectfvDirect(ALCcontext *context, ALuint eff else try { /* Call the appropriate handler */ - ALeffect_getParamfv(aleffect, param, values); + std::visit([aleffect,param,values](auto &arg) + { + using Type = std::remove_cv_t>; + if constexpr(std::is_same_v) + { + if(aleffect->type == AL_EFFECT_REVERB) + return EffectHandler::StdReverbGetParamfv(arg, param, values); + } + return EffectHandler::GetParamfv(arg, param, values); + }, aleffect->Props); } catch(effect_exception &e) { context->setError(e.errorCode(), "%s", e.what()); @@ -694,40 +728,39 @@ void LoadReverbPreset(const char *name, ALeffect *effect) InitEffectParams(effect, AL_EFFECT_NULL); for(const auto &reverbitem : reverblist) { - const EFXEAXREVERBPROPERTIES *props; - if(al::strcasecmp(name, reverbitem.name) != 0) continue; TRACE("Loading reverb '%s'\n", reverbitem.name); - props = &reverbitem.props; - effect->Props.Reverb.Density = props->flDensity; - effect->Props.Reverb.Diffusion = props->flDiffusion; - effect->Props.Reverb.Gain = props->flGain; - effect->Props.Reverb.GainHF = props->flGainHF; - effect->Props.Reverb.GainLF = props->flGainLF; - effect->Props.Reverb.DecayTime = props->flDecayTime; - effect->Props.Reverb.DecayHFRatio = props->flDecayHFRatio; - effect->Props.Reverb.DecayLFRatio = props->flDecayLFRatio; - effect->Props.Reverb.ReflectionsGain = props->flReflectionsGain; - effect->Props.Reverb.ReflectionsDelay = props->flReflectionsDelay; - effect->Props.Reverb.ReflectionsPan[0] = props->flReflectionsPan[0]; - effect->Props.Reverb.ReflectionsPan[1] = props->flReflectionsPan[1]; - effect->Props.Reverb.ReflectionsPan[2] = props->flReflectionsPan[2]; - effect->Props.Reverb.LateReverbGain = props->flLateReverbGain; - effect->Props.Reverb.LateReverbDelay = props->flLateReverbDelay; - effect->Props.Reverb.LateReverbPan[0] = props->flLateReverbPan[0]; - effect->Props.Reverb.LateReverbPan[1] = props->flLateReverbPan[1]; - effect->Props.Reverb.LateReverbPan[2] = props->flLateReverbPan[2]; - effect->Props.Reverb.EchoTime = props->flEchoTime; - effect->Props.Reverb.EchoDepth = props->flEchoDepth; - effect->Props.Reverb.ModulationTime = props->flModulationTime; - effect->Props.Reverb.ModulationDepth = props->flModulationDepth; - effect->Props.Reverb.AirAbsorptionGainHF = props->flAirAbsorptionGainHF; - effect->Props.Reverb.HFReference = props->flHFReference; - effect->Props.Reverb.LFReference = props->flLFReference; - effect->Props.Reverb.RoomRolloffFactor = props->flRoomRolloffFactor; - effect->Props.Reverb.DecayHFLimit = props->iDecayHFLimit ? AL_TRUE : AL_FALSE; + const auto &props = reverbitem.props; + auto &dst = std::get(effect->Props); + dst.Density = props.flDensity; + dst.Diffusion = props.flDiffusion; + dst.Gain = props.flGain; + dst.GainHF = props.flGainHF; + dst.GainLF = props.flGainLF; + dst.DecayTime = props.flDecayTime; + dst.DecayHFRatio = props.flDecayHFRatio; + dst.DecayLFRatio = props.flDecayLFRatio; + dst.ReflectionsGain = props.flReflectionsGain; + dst.ReflectionsDelay = props.flReflectionsDelay; + dst.ReflectionsPan[0] = props.flReflectionsPan[0]; + dst.ReflectionsPan[1] = props.flReflectionsPan[1]; + dst.ReflectionsPan[2] = props.flReflectionsPan[2]; + dst.LateReverbGain = props.flLateReverbGain; + dst.LateReverbDelay = props.flLateReverbDelay; + dst.LateReverbPan[0] = props.flLateReverbPan[0]; + dst.LateReverbPan[1] = props.flLateReverbPan[1]; + dst.LateReverbPan[2] = props.flLateReverbPan[2]; + dst.EchoTime = props.flEchoTime; + dst.EchoDepth = props.flEchoDepth; + dst.ModulationTime = props.flModulationTime; + dst.ModulationDepth = props.flModulationDepth; + dst.AirAbsorptionGainHF = props.flAirAbsorptionGainHF; + dst.HFReference = props.flHFReference; + dst.LFReference = props.flLFReference; + dst.RoomRolloffFactor = props.flRoomRolloffFactor; + dst.DecayHFLimit = props.iDecayHFLimit ? AL_TRUE : AL_FALSE; return; } diff --git a/al/effect.h b/al/effect.h index 71fe9c87..820c7d28 100644 --- a/al/effect.h +++ b/al/effect.h @@ -47,8 +47,6 @@ struct ALeffect { EffectProps Props{}; - const EffectVtable *vtab{nullptr}; - /* Self ID */ ALuint id{0u}; diff --git a/al/effects/autowah.cpp b/al/effects/autowah.cpp index c0f845ac..68704c11 100644 --- a/al/effects/autowah.cpp +++ b/al/effects/autowah.cpp @@ -20,100 +20,87 @@ namespace { -void Autowah_setParamf(EffectProps *props, ALenum param, float val) +EffectProps genDefaultProps() noexcept +{ + AutowahProps props{}; + props.AttackTime = AL_AUTOWAH_DEFAULT_ATTACK_TIME; + props.ReleaseTime = AL_AUTOWAH_DEFAULT_RELEASE_TIME; + props.Resonance = AL_AUTOWAH_DEFAULT_RESONANCE; + props.PeakGain = AL_AUTOWAH_DEFAULT_PEAK_GAIN; + return props; +} + +} // namespace + +const EffectProps AutowahEffectProps{genDefaultProps()}; + +void EffectHandler::SetParami(AutowahProps&, ALenum param, int) +{ throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer property 0x%04x", param}; } +void EffectHandler::SetParamiv(AutowahProps&, ALenum param, const int*) +{ + throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer vector property 0x%04x", + param}; +} + +void EffectHandler::SetParamf(AutowahProps &props, ALenum param, float val) { switch(param) { case AL_AUTOWAH_ATTACK_TIME: if(!(val >= AL_AUTOWAH_MIN_ATTACK_TIME && val <= AL_AUTOWAH_MAX_ATTACK_TIME)) throw effect_exception{AL_INVALID_VALUE, "Autowah attack time out of range"}; - props->Autowah.AttackTime = val; + props.AttackTime = val; break; case AL_AUTOWAH_RELEASE_TIME: if(!(val >= AL_AUTOWAH_MIN_RELEASE_TIME && val <= AL_AUTOWAH_MAX_RELEASE_TIME)) throw effect_exception{AL_INVALID_VALUE, "Autowah release time out of range"}; - props->Autowah.ReleaseTime = val; + props.ReleaseTime = val; break; case AL_AUTOWAH_RESONANCE: if(!(val >= AL_AUTOWAH_MIN_RESONANCE && val <= AL_AUTOWAH_MAX_RESONANCE)) throw effect_exception{AL_INVALID_VALUE, "Autowah resonance out of range"}; - props->Autowah.Resonance = val; + props.Resonance = val; break; case AL_AUTOWAH_PEAK_GAIN: if(!(val >= AL_AUTOWAH_MIN_PEAK_GAIN && val <= AL_AUTOWAH_MAX_PEAK_GAIN)) throw effect_exception{AL_INVALID_VALUE, "Autowah peak gain out of range"}; - props->Autowah.PeakGain = val; + props.PeakGain = val; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid autowah float property 0x%04x", param}; } } -void Autowah_setParamfv(EffectProps *props, ALenum param, const float *vals) -{ Autowah_setParamf(props, param, vals[0]); } +void EffectHandler::SetParamfv(AutowahProps &props, ALenum param, const float *vals) +{ SetParamf(props, param, vals[0]); } -void Autowah_setParami(EffectProps*, ALenum param, int) +void EffectHandler::GetParami(const AutowahProps&, ALenum param, int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer property 0x%04x", param}; } -void Autowah_setParamiv(EffectProps*, ALenum param, const int*) +void EffectHandler::GetParamiv(const AutowahProps&, ALenum param, int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer vector property 0x%04x", param}; } -void Autowah_getParamf(const EffectProps *props, ALenum param, float *val) +void EffectHandler::GetParamf(const AutowahProps &props, ALenum param, float *val) { switch(param) { - case AL_AUTOWAH_ATTACK_TIME: - *val = props->Autowah.AttackTime; - break; - - case AL_AUTOWAH_RELEASE_TIME: - *val = props->Autowah.ReleaseTime; - break; - - case AL_AUTOWAH_RESONANCE: - *val = props->Autowah.Resonance; - break; - - case AL_AUTOWAH_PEAK_GAIN: - *val = props->Autowah.PeakGain; - break; + case AL_AUTOWAH_ATTACK_TIME: *val = props.AttackTime; break; + case AL_AUTOWAH_RELEASE_TIME: *val = props.ReleaseTime; break; + case AL_AUTOWAH_RESONANCE: *val = props.Resonance; break; + case AL_AUTOWAH_PEAK_GAIN: *val = props.PeakGain; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid autowah float property 0x%04x", param}; } } -void Autowah_getParamfv(const EffectProps *props, ALenum param, float *vals) -{ Autowah_getParamf(props, param, vals); } - -void Autowah_getParami(const EffectProps*, ALenum param, int*) -{ throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer property 0x%04x", param}; } -void Autowah_getParamiv(const EffectProps*, ALenum param, int*) -{ - throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer vector property 0x%04x", - param}; -} - -EffectProps genDefaultProps() noexcept -{ - EffectProps props{}; - props.Autowah.AttackTime = AL_AUTOWAH_DEFAULT_ATTACK_TIME; - props.Autowah.ReleaseTime = AL_AUTOWAH_DEFAULT_RELEASE_TIME; - props.Autowah.Resonance = AL_AUTOWAH_DEFAULT_RESONANCE; - props.Autowah.PeakGain = AL_AUTOWAH_DEFAULT_PEAK_GAIN; - return props; -} - -} // namespace - -DEFINE_ALEFFECT_VTABLE(Autowah); - -const EffectProps AutowahEffectProps{genDefaultProps()}; +void EffectHandler::GetParamfv(const AutowahProps &props, ALenum param, float *vals) +{ GetParamf(props, param, vals); } #ifdef ALSOFT_EAX namespace { @@ -195,11 +182,14 @@ bool EaxAutowahCommitter::commit(const EAXAUTOWAHPROPERTIES &props) return false; mEaxProps = props; - - mAlProps.Autowah.AttackTime = props.flAttackTime; - mAlProps.Autowah.ReleaseTime = props.flReleaseTime; - mAlProps.Autowah.Resonance = level_mb_to_gain(static_cast(props.lResonance)); - mAlProps.Autowah.PeakGain = level_mb_to_gain(static_cast(props.lPeakLevel)); + mAlProps = [&]{ + AutowahProps ret{}; + ret.AttackTime = props.flAttackTime; + ret.ReleaseTime = props.flReleaseTime; + ret.Resonance = level_mb_to_gain(static_cast(props.lResonance)); + ret.PeakGain = level_mb_to_gain(static_cast(props.lPeakLevel)); + return ret; + }(); return true; } diff --git a/al/effects/chorus.cpp b/al/effects/chorus.cpp index 24aa0a49..dba59d1d 100644 --- a/al/effects/chorus.cpp +++ b/al/effects/chorus.cpp @@ -46,13 +46,41 @@ inline ALenum EnumFromWaveform(ChorusWaveform type) throw std::runtime_error{"Invalid chorus waveform: "+std::to_string(static_cast(type))}; } -void Chorus_setParami(EffectProps *props, ALenum param, int val) +EffectProps genDefaultChorusProps() noexcept +{ + ChorusProps props{}; + props.Waveform = *WaveformFromEnum(AL_CHORUS_DEFAULT_WAVEFORM); + props.Phase = AL_CHORUS_DEFAULT_PHASE; + props.Rate = AL_CHORUS_DEFAULT_RATE; + props.Depth = AL_CHORUS_DEFAULT_DEPTH; + props.Feedback = AL_CHORUS_DEFAULT_FEEDBACK; + props.Delay = AL_CHORUS_DEFAULT_DELAY; + return props; +} + +EffectProps genDefaultFlangerProps() noexcept +{ + FlangerProps props{}; + props.Waveform = *WaveformFromEnum(AL_FLANGER_DEFAULT_WAVEFORM); + props.Phase = AL_FLANGER_DEFAULT_PHASE; + props.Rate = AL_FLANGER_DEFAULT_RATE; + props.Depth = AL_FLANGER_DEFAULT_DEPTH; + props.Feedback = AL_FLANGER_DEFAULT_FEEDBACK; + props.Delay = AL_FLANGER_DEFAULT_DELAY; + return props; +} + +} // namespace + +const EffectProps ChorusEffectProps{genDefaultChorusProps()}; + +void EffectHandler::SetParami(ChorusProps &props, ALenum param, int val) { switch(param) { case AL_CHORUS_WAVEFORM: if(auto formopt = WaveformFromEnum(val)) - props->Chorus.Waveform = *formopt; + props.Waveform = *formopt; else throw effect_exception{AL_INVALID_VALUE, "Invalid chorus waveform: 0x%04x", val}; break; @@ -60,115 +88,89 @@ void Chorus_setParami(EffectProps *props, ALenum param, int val) case AL_CHORUS_PHASE: if(!(val >= AL_CHORUS_MIN_PHASE && val <= AL_CHORUS_MAX_PHASE)) throw effect_exception{AL_INVALID_VALUE, "Chorus phase out of range: %d", val}; - props->Chorus.Phase = val; + props.Phase = val; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid chorus integer property 0x%04x", param}; } } -void Chorus_setParamiv(EffectProps *props, ALenum param, const int *vals) -{ Chorus_setParami(props, param, vals[0]); } -void Chorus_setParamf(EffectProps *props, ALenum param, float val) +void EffectHandler::SetParamiv(ChorusProps &props, ALenum param, const int *vals) +{ SetParami(props, param, vals[0]); } +void EffectHandler::SetParamf(ChorusProps &props, ALenum param, float val) { switch(param) { case AL_CHORUS_RATE: if(!(val >= AL_CHORUS_MIN_RATE && val <= AL_CHORUS_MAX_RATE)) throw effect_exception{AL_INVALID_VALUE, "Chorus rate out of range: %f", val}; - props->Chorus.Rate = val; + props.Rate = val; break; case AL_CHORUS_DEPTH: if(!(val >= AL_CHORUS_MIN_DEPTH && val <= AL_CHORUS_MAX_DEPTH)) throw effect_exception{AL_INVALID_VALUE, "Chorus depth out of range: %f", val}; - props->Chorus.Depth = val; + props.Depth = val; break; case AL_CHORUS_FEEDBACK: if(!(val >= AL_CHORUS_MIN_FEEDBACK && val <= AL_CHORUS_MAX_FEEDBACK)) throw effect_exception{AL_INVALID_VALUE, "Chorus feedback out of range: %f", val}; - props->Chorus.Feedback = val; + props.Feedback = val; break; case AL_CHORUS_DELAY: if(!(val >= AL_CHORUS_MIN_DELAY && val <= AL_CHORUS_MAX_DELAY)) throw effect_exception{AL_INVALID_VALUE, "Chorus delay out of range: %f", val}; - props->Chorus.Delay = val; + props.Delay = val; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid chorus float property 0x%04x", param}; } } -void Chorus_setParamfv(EffectProps *props, ALenum param, const float *vals) -{ Chorus_setParamf(props, param, vals[0]); } +void EffectHandler::SetParamfv(ChorusProps &props, ALenum param, const float *vals) +{ SetParamf(props, param, vals[0]); } -void Chorus_getParami(const EffectProps *props, ALenum param, int *val) +void EffectHandler::GetParami(const ChorusProps &props, ALenum param, int *val) { switch(param) { - case AL_CHORUS_WAVEFORM: - *val = EnumFromWaveform(props->Chorus.Waveform); - break; - - case AL_CHORUS_PHASE: - *val = props->Chorus.Phase; - break; + case AL_CHORUS_WAVEFORM: *val = EnumFromWaveform(props.Waveform); break; + case AL_CHORUS_PHASE: *val = props.Phase; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid chorus integer property 0x%04x", param}; } } -void Chorus_getParamiv(const EffectProps *props, ALenum param, int *vals) -{ Chorus_getParami(props, param, vals); } -void Chorus_getParamf(const EffectProps *props, ALenum param, float *val) +void EffectHandler::GetParamiv(const ChorusProps &props, ALenum param, int *vals) +{ GetParami(props, param, vals); } +void EffectHandler::GetParamf(const ChorusProps &props, ALenum param, float *val) { switch(param) { - case AL_CHORUS_RATE: - *val = props->Chorus.Rate; - break; - - case AL_CHORUS_DEPTH: - *val = props->Chorus.Depth; - break; - - case AL_CHORUS_FEEDBACK: - *val = props->Chorus.Feedback; - break; - - case AL_CHORUS_DELAY: - *val = props->Chorus.Delay; - break; + case AL_CHORUS_RATE: *val = props.Rate; break; + case AL_CHORUS_DEPTH: *val = props.Depth; break; + case AL_CHORUS_FEEDBACK: *val = props.Feedback; break; + case AL_CHORUS_DELAY: *val = props.Delay; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid chorus float property 0x%04x", param}; } } -void Chorus_getParamfv(const EffectProps *props, ALenum param, float *vals) -{ Chorus_getParamf(props, param, vals); } +void EffectHandler::GetParamfv(const ChorusProps &props, ALenum param, float *vals) +{ GetParamf(props, param, vals); } -EffectProps genDefaultChorusProps() noexcept -{ - EffectProps props{}; - props.Chorus.Waveform = *WaveformFromEnum(AL_CHORUS_DEFAULT_WAVEFORM); - props.Chorus.Phase = AL_CHORUS_DEFAULT_PHASE; - props.Chorus.Rate = AL_CHORUS_DEFAULT_RATE; - props.Chorus.Depth = AL_CHORUS_DEFAULT_DEPTH; - props.Chorus.Feedback = AL_CHORUS_DEFAULT_FEEDBACK; - props.Chorus.Delay = AL_CHORUS_DEFAULT_DELAY; - return props; -} +const EffectProps FlangerEffectProps{genDefaultFlangerProps()}; -void Flanger_setParami(EffectProps *props, ALenum param, int val) +void EffectHandler::SetParami(FlangerProps &props, ALenum param, int val) { switch(param) { case AL_FLANGER_WAVEFORM: if(auto formopt = WaveformFromEnum(val)) - props->Flanger.Waveform = *formopt; + props.Waveform = *formopt; else throw effect_exception{AL_INVALID_VALUE, "Invalid flanger waveform: 0x%04x", val}; break; @@ -176,116 +178,78 @@ void Flanger_setParami(EffectProps *props, ALenum param, int val) case AL_FLANGER_PHASE: if(!(val >= AL_FLANGER_MIN_PHASE && val <= AL_FLANGER_MAX_PHASE)) throw effect_exception{AL_INVALID_VALUE, "Flanger phase out of range: %d", val}; - props->Flanger.Phase = val; + props.Phase = val; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid flanger integer property 0x%04x", param}; } } -void Flanger_setParamiv(EffectProps *props, ALenum param, const int *vals) -{ Flanger_setParami(props, param, vals[0]); } -void Flanger_setParamf(EffectProps *props, ALenum param, float val) +void EffectHandler::SetParamiv(FlangerProps &props, ALenum param, const int *vals) +{ SetParami(props, param, vals[0]); } +void EffectHandler::SetParamf(FlangerProps &props, ALenum param, float val) { switch(param) { case AL_FLANGER_RATE: if(!(val >= AL_FLANGER_MIN_RATE && val <= AL_FLANGER_MAX_RATE)) throw effect_exception{AL_INVALID_VALUE, "Flanger rate out of range: %f", val}; - props->Flanger.Rate = val; + props.Rate = val; break; case AL_FLANGER_DEPTH: if(!(val >= AL_FLANGER_MIN_DEPTH && val <= AL_FLANGER_MAX_DEPTH)) throw effect_exception{AL_INVALID_VALUE, "Flanger depth out of range: %f", val}; - props->Flanger.Depth = val; + props.Depth = val; break; case AL_FLANGER_FEEDBACK: if(!(val >= AL_FLANGER_MIN_FEEDBACK && val <= AL_FLANGER_MAX_FEEDBACK)) throw effect_exception{AL_INVALID_VALUE, "Flanger feedback out of range: %f", val}; - props->Flanger.Feedback = val; + props.Feedback = val; break; case AL_FLANGER_DELAY: if(!(val >= AL_FLANGER_MIN_DELAY && val <= AL_FLANGER_MAX_DELAY)) throw effect_exception{AL_INVALID_VALUE, "Flanger delay out of range: %f", val}; - props->Flanger.Delay = val; + props.Delay = val; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid flanger float property 0x%04x", param}; } } -void Flanger_setParamfv(EffectProps *props, ALenum param, const float *vals) -{ Flanger_setParamf(props, param, vals[0]); } +void EffectHandler::SetParamfv(FlangerProps &props, ALenum param, const float *vals) +{ SetParamf(props, param, vals[0]); } -void Flanger_getParami(const EffectProps *props, ALenum param, int *val) +void EffectHandler::GetParami(const FlangerProps &props, ALenum param, int *val) { switch(param) { - case AL_FLANGER_WAVEFORM: - *val = EnumFromWaveform(props->Flanger.Waveform); - break; - - case AL_FLANGER_PHASE: - *val = props->Flanger.Phase; - break; + case AL_FLANGER_WAVEFORM: *val = EnumFromWaveform(props.Waveform); break; + case AL_FLANGER_PHASE: *val = props.Phase; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid flanger integer property 0x%04x", param}; } } -void Flanger_getParamiv(const EffectProps *props, ALenum param, int *vals) -{ Flanger_getParami(props, param, vals); } -void Flanger_getParamf(const EffectProps *props, ALenum param, float *val) +void EffectHandler::GetParamiv(const FlangerProps &props, ALenum param, int *vals) +{ GetParami(props, param, vals); } +void EffectHandler::GetParamf(const FlangerProps &props, ALenum param, float *val) { switch(param) { - case AL_FLANGER_RATE: - *val = props->Flanger.Rate; - break; - - case AL_FLANGER_DEPTH: - *val = props->Flanger.Depth; - break; - - case AL_FLANGER_FEEDBACK: - *val = props->Flanger.Feedback; - break; - - case AL_FLANGER_DELAY: - *val = props->Flanger.Delay; - break; + case AL_FLANGER_RATE: *val = props.Rate; break; + case AL_FLANGER_DEPTH: *val = props.Depth; break; + case AL_FLANGER_FEEDBACK: *val = props.Feedback; break; + case AL_FLANGER_DELAY: *val = props.Delay; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid flanger float property 0x%04x", param}; } } -void Flanger_getParamfv(const EffectProps *props, ALenum param, float *vals) -{ Flanger_getParamf(props, param, vals); } - -EffectProps genDefaultFlangerProps() noexcept -{ - EffectProps props{}; - props.Flanger.Waveform = *WaveformFromEnum(AL_FLANGER_DEFAULT_WAVEFORM); - props.Flanger.Phase = AL_FLANGER_DEFAULT_PHASE; - props.Flanger.Rate = AL_FLANGER_DEFAULT_RATE; - props.Flanger.Depth = AL_FLANGER_DEFAULT_DEPTH; - props.Flanger.Feedback = AL_FLANGER_DEFAULT_FEEDBACK; - props.Flanger.Delay = AL_FLANGER_DEFAULT_DELAY; - return props; -} - -} // namespace - -DEFINE_ALEFFECT_VTABLE(Chorus); - -const EffectProps ChorusEffectProps{genDefaultChorusProps()}; - -DEFINE_ALEFFECT_VTABLE(Flanger); - -const EffectProps FlangerEffectProps{genDefaultFlangerProps()}; +void EffectHandler::GetParamfv(const FlangerProps &props, ALenum param, float *vals) +{ GetParamf(props, param, vals); } #ifdef ALSOFT_EAX @@ -626,7 +590,7 @@ template<> bool EaxChorusCommitter::commit(const EAXCHORUSPROPERTIES &props) { using Committer = ChorusFlangerEffect; - return Committer::Commit(props, mEaxProps, mAlProps.Chorus); + return Committer::Commit(props, mEaxProps, mAlProps.emplace()); } void EaxChorusCommitter::SetDefaults(EaxEffectProps &props) @@ -663,7 +627,7 @@ template<> bool EaxFlangerCommitter::commit(const EAXFLANGERPROPERTIES &props) { using Committer = ChorusFlangerEffect; - return Committer::Commit(props, mEaxProps, mAlProps.Flanger); + return Committer::Commit(props, mEaxProps, mAlProps.emplace()); } void EaxFlangerCommitter::SetDefaults(EaxEffectProps &props) diff --git a/al/effects/compressor.cpp b/al/effects/compressor.cpp index 9c4308f4..9fcc8c61 100644 --- a/al/effects/compressor.cpp +++ b/al/effects/compressor.cpp @@ -16,14 +16,25 @@ namespace { -void Compressor_setParami(EffectProps *props, ALenum param, int val) +EffectProps genDefaultProps() noexcept +{ + CompressorProps props{}; + props.OnOff = AL_COMPRESSOR_DEFAULT_ONOFF; + return props; +} + +} // namespace + +const EffectProps CompressorEffectProps{genDefaultProps()}; + +void EffectHandler::SetParami(CompressorProps &props, ALenum param, int val) { switch(param) { case AL_COMPRESSOR_ONOFF: if(!(val >= AL_COMPRESSOR_MIN_ONOFF && val <= AL_COMPRESSOR_MAX_ONOFF)) throw effect_exception{AL_INVALID_VALUE, "Compressor state out of range"}; - props->Compressor.OnOff = (val != AL_FALSE); + props.OnOff = (val != AL_FALSE); break; default: @@ -31,22 +42,22 @@ void Compressor_setParami(EffectProps *props, ALenum param, int val) param}; } } -void Compressor_setParamiv(EffectProps *props, ALenum param, const int *vals) -{ Compressor_setParami(props, param, vals[0]); } -void Compressor_setParamf(EffectProps*, ALenum param, float) +void EffectHandler::SetParamiv(CompressorProps &props, ALenum param, const int *vals) +{ SetParami(props, param, vals[0]); } +void EffectHandler::SetParamf(CompressorProps&, ALenum param, float) { throw effect_exception{AL_INVALID_ENUM, "Invalid compressor float property 0x%04x", param}; } -void Compressor_setParamfv(EffectProps*, ALenum param, const float*) +void EffectHandler::SetParamfv(CompressorProps&, ALenum param, const float*) { throw effect_exception{AL_INVALID_ENUM, "Invalid compressor float-vector property 0x%04x", param}; } -void Compressor_getParami(const EffectProps *props, ALenum param, int *val) +void EffectHandler::GetParami(const CompressorProps &props, ALenum param, int *val) { switch(param) { case AL_COMPRESSOR_ONOFF: - *val = props->Compressor.OnOff; + *val = props.OnOff; break; default: @@ -54,28 +65,16 @@ void Compressor_getParami(const EffectProps *props, ALenum param, int *val) param}; } } -void Compressor_getParamiv(const EffectProps *props, ALenum param, int *vals) -{ Compressor_getParami(props, param, vals); } -void Compressor_getParamf(const EffectProps*, ALenum param, float*) +void EffectHandler::GetParamiv(const CompressorProps &props, ALenum param, int *vals) +{ GetParami(props, param, vals); } +void EffectHandler::GetParamf(const CompressorProps&, ALenum param, float*) { throw effect_exception{AL_INVALID_ENUM, "Invalid compressor float property 0x%04x", param}; } -void Compressor_getParamfv(const EffectProps*, ALenum param, float*) +void EffectHandler::GetParamfv(const CompressorProps&, ALenum param, float*) { throw effect_exception{AL_INVALID_ENUM, "Invalid compressor float-vector property 0x%04x", param}; } -EffectProps genDefaultProps() noexcept -{ - EffectProps props{}; - props.Compressor.OnOff = AL_COMPRESSOR_DEFAULT_ONOFF; - return props; -} - -} // namespace - -DEFINE_ALEFFECT_VTABLE(Compressor); - -const EffectProps CompressorEffectProps{genDefaultProps()}; #ifdef ALSOFT_EAX namespace { @@ -121,8 +120,8 @@ bool EaxCompressorCommitter::commit(const EAXAGCCOMPRESSORPROPERTIES &props) return false; mEaxProps = props; + mAlProps = CompressorProps{props.ulOnOff != 0}; - mAlProps.Compressor.OnOff = props.ulOnOff != 0; return true; } diff --git a/al/effects/convolution.cpp b/al/effects/convolution.cpp index 9c091e53..1f8d1111 100644 --- a/al/effects/convolution.cpp +++ b/al/effects/convolution.cpp @@ -12,33 +12,45 @@ namespace { -void Convolution_setParami(EffectProps* /*props*/, ALenum param, int /*val*/) +EffectProps genDefaultProps() noexcept +{ + ConvolutionProps props{}; + props.OrientAt = {0.0f, 0.0f, -1.0f}; + props.OrientUp = {0.0f, 1.0f, 0.0f}; + return props; +} + +} // namespace + +const EffectProps ConvolutionEffectProps{genDefaultProps()}; + +void EffectHandler::SetParami(ConvolutionProps& /*props*/, ALenum param, int /*val*/) { switch(param) { default: - throw effect_exception{AL_INVALID_ENUM, "Invalid null effect integer property 0x%04x", + throw effect_exception{AL_INVALID_ENUM, "Invalid convolution effect integer property 0x%04x", param}; } } -void Convolution_setParamiv(EffectProps *props, ALenum param, const int *vals) +void EffectHandler::SetParamiv(ConvolutionProps &props, ALenum param, const int *vals) { switch(param) { default: - Convolution_setParami(props, param, vals[0]); + SetParami(props, param, vals[0]); } } -void Convolution_setParamf(EffectProps* /*props*/, ALenum param, float /*val*/) +void EffectHandler::SetParamf(ConvolutionProps& /*props*/, ALenum param, float /*val*/) { switch(param) { default: - throw effect_exception{AL_INVALID_ENUM, "Invalid null effect float property 0x%04x", + throw effect_exception{AL_INVALID_ENUM, "Invalid convolution effect float property 0x%04x", param}; } } -void Convolution_setParamfv(EffectProps *props, ALenum param, const float *values) +void EffectHandler::SetParamfv(ConvolutionProps &props, ALenum param, const float *values) { switch(param) { @@ -47,73 +59,59 @@ void Convolution_setParamfv(EffectProps *props, ALenum param, const float *value && std::isfinite(values[3]) && std::isfinite(values[4]) && std::isfinite(values[5]))) throw effect_exception{AL_INVALID_VALUE, "Property 0x%04x value out of range", param}; - props->Convolution.OrientAt[0] = values[0]; - props->Convolution.OrientAt[1] = values[1]; - props->Convolution.OrientAt[2] = values[2]; - props->Convolution.OrientUp[0] = values[3]; - props->Convolution.OrientUp[1] = values[4]; - props->Convolution.OrientUp[2] = values[5]; + props.OrientAt[0] = values[0]; + props.OrientAt[1] = values[1]; + props.OrientAt[2] = values[2]; + props.OrientUp[0] = values[3]; + props.OrientUp[1] = values[4]; + props.OrientUp[2] = values[5]; break; default: - Convolution_setParamf(props, param, values[0]); + SetParamf(props, param, values[0]); } } -void Convolution_getParami(const EffectProps* /*props*/, ALenum param, int* /*val*/) +void EffectHandler::GetParami(const ConvolutionProps& /*props*/, ALenum param, int* /*val*/) { switch(param) { default: - throw effect_exception{AL_INVALID_ENUM, "Invalid null effect integer property 0x%04x", + throw effect_exception{AL_INVALID_ENUM, "Invalid convolution effect integer property 0x%04x", param}; } } -void Convolution_getParamiv(const EffectProps *props, ALenum param, int *vals) +void EffectHandler::GetParamiv(const ConvolutionProps &props, ALenum param, int *vals) { switch(param) { default: - Convolution_getParami(props, param, vals); + GetParami(props, param, vals); } } -void Convolution_getParamf(const EffectProps* /*props*/, ALenum param, float* /*val*/) +void EffectHandler::GetParamf(const ConvolutionProps& /*props*/, ALenum param, float* /*val*/) { switch(param) { default: - throw effect_exception{AL_INVALID_ENUM, "Invalid null effect float property 0x%04x", + throw effect_exception{AL_INVALID_ENUM, "Invalid convolution effect float property 0x%04x", param}; } } -void Convolution_getParamfv(const EffectProps *props, ALenum param, float *values) +void EffectHandler::GetParamfv(const ConvolutionProps &props, ALenum param, float *values) { switch(param) { case AL_CONVOLUTION_ORIENTATION_SOFT: - values[0] = props->Convolution.OrientAt[0]; - values[1] = props->Convolution.OrientAt[1]; - values[2] = props->Convolution.OrientAt[2]; - values[3] = props->Convolution.OrientUp[0]; - values[4] = props->Convolution.OrientUp[1]; - values[5] = props->Convolution.OrientUp[2]; + values[0] = props.OrientAt[0]; + values[1] = props.OrientAt[1]; + values[2] = props.OrientAt[2]; + values[3] = props.OrientUp[0]; + values[4] = props.OrientUp[1]; + values[5] = props.OrientUp[2]; break; default: - Convolution_getParamf(props, param, values); + GetParamf(props, param, values); } } - -EffectProps genDefaultProps() noexcept -{ - EffectProps props{}; - props.Convolution.OrientAt = {0.0f, 0.0f, -1.0f}; - props.Convolution.OrientUp = {0.0f, 1.0f, 0.0f}; - return props; -} - -} // namespace - -DEFINE_ALEFFECT_VTABLE(Convolution); - -const EffectProps ConvolutionEffectProps{genDefaultProps()}; diff --git a/al/effects/dedicated.cpp b/al/effects/dedicated.cpp index f5edfd51..518c224c 100644 --- a/al/effects/dedicated.cpp +++ b/al/effects/dedicated.cpp @@ -12,120 +12,115 @@ namespace { -void DedicatedDialog_setParami(EffectProps*, ALenum param, int) +EffectProps genDefaultDialogProps() noexcept +{ + DedicatedDialogProps props{}; + props.Gain = 1.0f; + return props; +} + +EffectProps genDefaultLfeProps() noexcept +{ + DedicatedLfeProps props{}; + props.Gain = 1.0f; + return props; +} + +} // namespace + +const EffectProps DedicatedDialogEffectProps{genDefaultDialogProps()}; + +void EffectHandler::SetParami(DedicatedDialogProps&, ALenum param, int) { throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer property 0x%04x", param}; } -void DedicatedDialog_setParamiv(EffectProps*, ALenum param, const int*) +void EffectHandler::SetParamiv(DedicatedDialogProps&, ALenum param, const int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer-vector property 0x%04x", param}; } -void DedicatedDialog_setParamf(EffectProps *props, ALenum param, float val) +void EffectHandler::SetParamf(DedicatedDialogProps &props, ALenum param, float val) { switch(param) { case AL_DEDICATED_GAIN: if(!(val >= 0.0f && std::isfinite(val))) throw effect_exception{AL_INVALID_VALUE, "Dedicated gain out of range"}; - props->DedicatedDialog.Gain = val; + props.Gain = val; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated float property 0x%04x", param}; } } -void DedicatedDialog_setParamfv(EffectProps *props, ALenum param, const float *vals) -{ DedicatedDialog_setParamf(props, param, vals[0]); } +void EffectHandler::SetParamfv(DedicatedDialogProps &props, ALenum param, const float *vals) +{ SetParamf(props, param, vals[0]); } -void DedicatedDialog_getParami(const EffectProps*, ALenum param, int*) +void EffectHandler::GetParami(const DedicatedDialogProps&, ALenum param, int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer property 0x%04x", param}; } -void DedicatedDialog_getParamiv(const EffectProps*, ALenum param, int*) +void EffectHandler::GetParamiv(const DedicatedDialogProps&, ALenum param, int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer-vector property 0x%04x", param}; } -void DedicatedDialog_getParamf(const EffectProps *props, ALenum param, float *val) +void EffectHandler::GetParamf(const DedicatedDialogProps &props, ALenum param, float *val) { switch(param) { case AL_DEDICATED_GAIN: - *val = props->DedicatedDialog.Gain; + *val = props.Gain; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated float property 0x%04x", param}; } } -void DedicatedDialog_getParamfv(const EffectProps *props, ALenum param, float *vals) -{ DedicatedDialog_getParamf(props, param, vals); } +void EffectHandler::GetParamfv(const DedicatedDialogProps &props, ALenum param, float *vals) +{ GetParamf(props, param, vals); } -void DedicatedLfe_setParami(EffectProps*, ALenum param, int) +const EffectProps DedicatedLfeEffectProps{genDefaultLfeProps()}; + +void EffectHandler::SetParami(DedicatedLfeProps&, ALenum param, int) { throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer property 0x%04x", param}; } -void DedicatedLfe_setParamiv(EffectProps*, ALenum param, const int*) +void EffectHandler::SetParamiv(DedicatedLfeProps&, ALenum param, const int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer-vector property 0x%04x", param}; } -void DedicatedLfe_setParamf(EffectProps *props, ALenum param, float val) +void EffectHandler::SetParamf(DedicatedLfeProps &props, ALenum param, float val) { switch(param) { case AL_DEDICATED_GAIN: if(!(val >= 0.0f && std::isfinite(val))) throw effect_exception{AL_INVALID_VALUE, "Dedicated gain out of range"}; - props->DedicatedLfe.Gain = val; + props.Gain = val; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated float property 0x%04x", param}; } } -void DedicatedLfe_setParamfv(EffectProps *props, ALenum param, const float *vals) -{ DedicatedLfe_setParamf(props, param, vals[0]); } +void EffectHandler::SetParamfv(DedicatedLfeProps &props, ALenum param, const float *vals) +{ SetParamf(props, param, vals[0]); } -void DedicatedLfe_getParami(const EffectProps*, ALenum param, int*) +void EffectHandler::GetParami(const DedicatedLfeProps&, ALenum param, int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer property 0x%04x", param}; } -void DedicatedLfe_getParamiv(const EffectProps*, ALenum param, int*) +void EffectHandler::GetParamiv(const DedicatedLfeProps&, ALenum param, int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer-vector property 0x%04x", param}; } -void DedicatedLfe_getParamf(const EffectProps *props, ALenum param, float *val) +void EffectHandler::GetParamf(const DedicatedLfeProps &props, ALenum param, float *val) { switch(param) { case AL_DEDICATED_GAIN: - *val = props->DedicatedLfe.Gain; + *val = props.Gain; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated float property 0x%04x", param}; } } -void DedicatedLfe_getParamfv(const EffectProps *props, ALenum param, float *vals) -{ DedicatedLfe_getParamf(props, param, vals); } - - -EffectProps genDefaultDialogProps() noexcept -{ - EffectProps props{}; - props.DedicatedDialog.Gain = 1.0f; - return props; -} - -EffectProps genDefaultLfeProps() noexcept -{ - EffectProps props{}; - props.DedicatedLfe.Gain = 1.0f; - return props; -} - -} // namespace - -DEFINE_ALEFFECT_VTABLE(DedicatedDialog); - -const EffectProps DedicatedDialogEffectProps{genDefaultDialogProps()}; - -DEFINE_ALEFFECT_VTABLE(DedicatedLfe); - -const EffectProps DedicatedLfeEffectProps{genDefaultLfeProps()}; +void EffectHandler::GetParamfv(const DedicatedLfeProps &props, ALenum param, float *vals) +{ GetParamf(props, param, vals); } diff --git a/al/effects/distortion.cpp b/al/effects/distortion.cpp index bec2af53..534b6c24 100644 --- a/al/effects/distortion.cpp +++ b/al/effects/distortion.cpp @@ -16,108 +16,93 @@ namespace { -void Distortion_setParami(EffectProps*, ALenum param, int) +EffectProps genDefaultProps() noexcept +{ + DistortionProps props{}; + props.Edge = AL_DISTORTION_DEFAULT_EDGE; + props.Gain = AL_DISTORTION_DEFAULT_GAIN; + props.LowpassCutoff = AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF; + props.EQCenter = AL_DISTORTION_DEFAULT_EQCENTER; + props.EQBandwidth = AL_DISTORTION_DEFAULT_EQBANDWIDTH; + return props; +} + +} // namespace + +const EffectProps DistortionEffectProps{genDefaultProps()}; + +void EffectHandler::SetParami(DistortionProps&, ALenum param, int) { throw effect_exception{AL_INVALID_ENUM, "Invalid distortion integer property 0x%04x", param}; } -void Distortion_setParamiv(EffectProps*, ALenum param, const int*) +void EffectHandler::SetParamiv(DistortionProps&, ALenum param, const int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid distortion integer-vector property 0x%04x", param}; } -void Distortion_setParamf(EffectProps *props, ALenum param, float val) +void EffectHandler::SetParamf(DistortionProps &props, ALenum param, float val) { switch(param) { case AL_DISTORTION_EDGE: if(!(val >= AL_DISTORTION_MIN_EDGE && val <= AL_DISTORTION_MAX_EDGE)) throw effect_exception{AL_INVALID_VALUE, "Distortion edge out of range"}; - props->Distortion.Edge = val; + props.Edge = val; break; case AL_DISTORTION_GAIN: if(!(val >= AL_DISTORTION_MIN_GAIN && val <= AL_DISTORTION_MAX_GAIN)) throw effect_exception{AL_INVALID_VALUE, "Distortion gain out of range"}; - props->Distortion.Gain = val; + props.Gain = val; break; case AL_DISTORTION_LOWPASS_CUTOFF: if(!(val >= AL_DISTORTION_MIN_LOWPASS_CUTOFF && val <= AL_DISTORTION_MAX_LOWPASS_CUTOFF)) throw effect_exception{AL_INVALID_VALUE, "Distortion low-pass cutoff out of range"}; - props->Distortion.LowpassCutoff = val; + props.LowpassCutoff = val; break; case AL_DISTORTION_EQCENTER: if(!(val >= AL_DISTORTION_MIN_EQCENTER && val <= AL_DISTORTION_MAX_EQCENTER)) throw effect_exception{AL_INVALID_VALUE, "Distortion EQ center out of range"}; - props->Distortion.EQCenter = val; + props.EQCenter = val; break; case AL_DISTORTION_EQBANDWIDTH: if(!(val >= AL_DISTORTION_MIN_EQBANDWIDTH && val <= AL_DISTORTION_MAX_EQBANDWIDTH)) throw effect_exception{AL_INVALID_VALUE, "Distortion EQ bandwidth out of range"}; - props->Distortion.EQBandwidth = val; + props.EQBandwidth = val; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid distortion float property 0x%04x", param}; } } -void Distortion_setParamfv(EffectProps *props, ALenum param, const float *vals) -{ Distortion_setParamf(props, param, vals[0]); } +void EffectHandler::SetParamfv(DistortionProps &props, ALenum param, const float *vals) +{ SetParamf(props, param, vals[0]); } -void Distortion_getParami(const EffectProps*, ALenum param, int*) +void EffectHandler::GetParami(const DistortionProps&, ALenum param, int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid distortion integer property 0x%04x", param}; } -void Distortion_getParamiv(const EffectProps*, ALenum param, int*) +void EffectHandler::GetParamiv(const DistortionProps&, ALenum param, int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid distortion integer-vector property 0x%04x", param}; } -void Distortion_getParamf(const EffectProps *props, ALenum param, float *val) +void EffectHandler::GetParamf(const DistortionProps &props, ALenum param, float *val) { switch(param) { - case AL_DISTORTION_EDGE: - *val = props->Distortion.Edge; - break; - - case AL_DISTORTION_GAIN: - *val = props->Distortion.Gain; - break; - - case AL_DISTORTION_LOWPASS_CUTOFF: - *val = props->Distortion.LowpassCutoff; - break; - - case AL_DISTORTION_EQCENTER: - *val = props->Distortion.EQCenter; - break; - - case AL_DISTORTION_EQBANDWIDTH: - *val = props->Distortion.EQBandwidth; - break; + case AL_DISTORTION_EDGE: *val = props.Edge; break; + case AL_DISTORTION_GAIN: *val = props.Gain; break; + case AL_DISTORTION_LOWPASS_CUTOFF: *val = props.LowpassCutoff; break; + case AL_DISTORTION_EQCENTER: *val = props.EQCenter; break; + case AL_DISTORTION_EQBANDWIDTH: *val = props.EQBandwidth; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid distortion float property 0x%04x", param}; } } -void Distortion_getParamfv(const EffectProps *props, ALenum param, float *vals) -{ Distortion_getParamf(props, param, vals); } +void EffectHandler::GetParamfv(const DistortionProps &props, ALenum param, float *vals) +{ GetParamf(props, param, vals); } -EffectProps genDefaultProps() noexcept -{ - EffectProps props{}; - props.Distortion.Edge = AL_DISTORTION_DEFAULT_EDGE; - props.Distortion.Gain = AL_DISTORTION_DEFAULT_GAIN; - props.Distortion.LowpassCutoff = AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF; - props.Distortion.EQCenter = AL_DISTORTION_DEFAULT_EQCENTER; - props.Distortion.EQBandwidth = AL_DISTORTION_DEFAULT_EQBANDWIDTH; - return props; -} - -} // namespace - -DEFINE_ALEFFECT_VTABLE(Distortion); - -const EffectProps DistortionEffectProps{genDefaultProps()}; #ifdef ALSOFT_EAX namespace { @@ -210,12 +195,15 @@ bool EaxDistortionCommitter::commit(const EAXDISTORTIONPROPERTIES &props) return false; mEaxProps = props; - - mAlProps.Distortion.Edge = props.flEdge; - mAlProps.Distortion.Gain = level_mb_to_gain(static_cast(props.lGain)); - mAlProps.Distortion.LowpassCutoff = props.flLowPassCutOff; - mAlProps.Distortion.EQCenter = props.flEQCenter; - mAlProps.Distortion.EQBandwidth = props.flEdge; + mAlProps = [&]{ + DistortionProps ret{}; + ret.Edge = props.flEdge; + ret.Gain = level_mb_to_gain(static_cast(props.lGain)); + ret.LowpassCutoff = props.flLowPassCutOff; + ret.EQCenter = props.flEQCenter; + ret.EQBandwidth = props.flEdge; + return ret; + }(); return true; } diff --git a/al/effects/echo.cpp b/al/effects/echo.cpp index 90f109da..9412039b 100644 --- a/al/effects/echo.cpp +++ b/al/effects/echo.cpp @@ -19,102 +19,87 @@ namespace { static_assert(EchoMaxDelay >= AL_ECHO_MAX_DELAY, "Echo max delay too short"); static_assert(EchoMaxLRDelay >= AL_ECHO_MAX_LRDELAY, "Echo max left-right delay too short"); -void Echo_setParami(EffectProps*, ALenum param, int) +EffectProps genDefaultProps() noexcept +{ + EchoProps props{}; + props.Delay = AL_ECHO_DEFAULT_DELAY; + props.LRDelay = AL_ECHO_DEFAULT_LRDELAY; + props.Damping = AL_ECHO_DEFAULT_DAMPING; + props.Feedback = AL_ECHO_DEFAULT_FEEDBACK; + props.Spread = AL_ECHO_DEFAULT_SPREAD; + return props; +} + +} // namespace + +const EffectProps EchoEffectProps{genDefaultProps()}; + +void EffectHandler::SetParami(EchoProps&, ALenum param, int) { throw effect_exception{AL_INVALID_ENUM, "Invalid echo integer property 0x%04x", param}; } -void Echo_setParamiv(EffectProps*, ALenum param, const int*) +void EffectHandler::SetParamiv(EchoProps&, ALenum param, const int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid echo integer-vector property 0x%04x", param}; } -void Echo_setParamf(EffectProps *props, ALenum param, float val) +void EffectHandler::SetParamf(EchoProps &props, ALenum param, float val) { switch(param) { case AL_ECHO_DELAY: if(!(val >= AL_ECHO_MIN_DELAY && val <= AL_ECHO_MAX_DELAY)) throw effect_exception{AL_INVALID_VALUE, "Echo delay out of range"}; - props->Echo.Delay = val; + props.Delay = val; break; case AL_ECHO_LRDELAY: if(!(val >= AL_ECHO_MIN_LRDELAY && val <= AL_ECHO_MAX_LRDELAY)) throw effect_exception{AL_INVALID_VALUE, "Echo LR delay out of range"}; - props->Echo.LRDelay = val; + props.LRDelay = val; break; case AL_ECHO_DAMPING: if(!(val >= AL_ECHO_MIN_DAMPING && val <= AL_ECHO_MAX_DAMPING)) throw effect_exception{AL_INVALID_VALUE, "Echo damping out of range"}; - props->Echo.Damping = val; + props.Damping = val; break; case AL_ECHO_FEEDBACK: if(!(val >= AL_ECHO_MIN_FEEDBACK && val <= AL_ECHO_MAX_FEEDBACK)) throw effect_exception{AL_INVALID_VALUE, "Echo feedback out of range"}; - props->Echo.Feedback = val; + props.Feedback = val; break; case AL_ECHO_SPREAD: if(!(val >= AL_ECHO_MIN_SPREAD && val <= AL_ECHO_MAX_SPREAD)) throw effect_exception{AL_INVALID_VALUE, "Echo spread out of range"}; - props->Echo.Spread = val; + props.Spread = val; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid echo float property 0x%04x", param}; } } -void Echo_setParamfv(EffectProps *props, ALenum param, const float *vals) -{ Echo_setParamf(props, param, vals[0]); } +void EffectHandler::SetParamfv(EchoProps &props, ALenum param, const float *vals) +{ SetParamf(props, param, vals[0]); } -void Echo_getParami(const EffectProps*, ALenum param, int*) +void EffectHandler::GetParami(const EchoProps&, ALenum param, int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid echo integer property 0x%04x", param}; } -void Echo_getParamiv(const EffectProps*, ALenum param, int*) +void EffectHandler::GetParamiv(const EchoProps&, ALenum param, int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid echo integer-vector property 0x%04x", param}; } -void Echo_getParamf(const EffectProps *props, ALenum param, float *val) +void EffectHandler::GetParamf(const EchoProps &props, ALenum param, float *val) { switch(param) { - case AL_ECHO_DELAY: - *val = props->Echo.Delay; - break; - - case AL_ECHO_LRDELAY: - *val = props->Echo.LRDelay; - break; - - case AL_ECHO_DAMPING: - *val = props->Echo.Damping; - break; - - case AL_ECHO_FEEDBACK: - *val = props->Echo.Feedback; - break; - - case AL_ECHO_SPREAD: - *val = props->Echo.Spread; - break; + case AL_ECHO_DELAY: *val = props.Delay; break; + case AL_ECHO_LRDELAY: *val = props.LRDelay; break; + case AL_ECHO_DAMPING: *val = props.Damping; break; + case AL_ECHO_FEEDBACK: *val = props.Feedback; break; + case AL_ECHO_SPREAD: *val = props.Spread; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid echo float property 0x%04x", param}; } } -void Echo_getParamfv(const EffectProps *props, ALenum param, float *vals) -{ Echo_getParamf(props, param, vals); } +void EffectHandler::GetParamfv(const EchoProps &props, ALenum param, float *vals) +{ GetParamf(props, param, vals); } -EffectProps genDefaultProps() noexcept -{ - EffectProps props{}; - props.Echo.Delay = AL_ECHO_DEFAULT_DELAY; - props.Echo.LRDelay = AL_ECHO_DEFAULT_LRDELAY; - props.Echo.Damping = AL_ECHO_DEFAULT_DAMPING; - props.Echo.Feedback = AL_ECHO_DEFAULT_FEEDBACK; - props.Echo.Spread = AL_ECHO_DEFAULT_SPREAD; - return props; -} - -} // namespace - -DEFINE_ALEFFECT_VTABLE(Echo); - -const EffectProps EchoEffectProps{genDefaultProps()}; #ifdef ALSOFT_EAX namespace { @@ -207,12 +192,15 @@ bool EaxEchoCommitter::commit(const EAXECHOPROPERTIES &props) return false; mEaxProps = props; - - mAlProps.Echo.Delay = props.flDelay; - mAlProps.Echo.LRDelay = props.flLRDelay; - mAlProps.Echo.Damping = props.flDamping; - mAlProps.Echo.Feedback = props.flFeedback; - mAlProps.Echo.Spread = props.flSpread; + mAlProps = [&]{ + EchoProps ret{}; + ret.Delay = props.flDelay; + ret.LRDelay = props.flLRDelay; + ret.Damping = props.flDamping; + ret.Feedback = props.flFeedback; + ret.Spread = props.flSpread; + return ret; + }(); return true; } diff --git a/al/effects/effects.h b/al/effects/effects.h index 2e49eb00..38d47f86 100644 --- a/al/effects/effects.h +++ b/al/effects/effects.h @@ -3,14 +3,52 @@ #include "AL/al.h" +#include "core/effects/base.h" #include "core/except.h" #ifdef ALSOFT_EAX #include "al/eax/effect.h" #endif // ALSOFT_EAX -union EffectProps; +struct EffectHandler { +#define DECL_HANDLER(T) \ + static void SetParami(T &props, ALenum param, int val); \ + static void SetParamiv(T &props, ALenum param, const int *vals); \ + static void SetParamf(T &props, ALenum param, float val); \ + static void SetParamfv(T &props, ALenum param, const float *vals); \ + static void GetParami(const T &props, ALenum param, int *val); \ + static void GetParamiv(const T &props, ALenum param, int *vals); \ + static void GetParamf(const T &props, ALenum param, float *val); \ + static void GetParamfv(const T &props, ALenum param, float *vals); + + DECL_HANDLER(std::monostate) + DECL_HANDLER(ReverbProps) + DECL_HANDLER(ChorusProps) + DECL_HANDLER(AutowahProps) + DECL_HANDLER(CompressorProps) + DECL_HANDLER(ConvolutionProps) + DECL_HANDLER(DedicatedDialogProps) + DECL_HANDLER(DedicatedLfeProps) + DECL_HANDLER(DistortionProps) + DECL_HANDLER(EchoProps) + DECL_HANDLER(EqualizerProps) + DECL_HANDLER(FlangerProps) + DECL_HANDLER(FshifterProps) + DECL_HANDLER(ModulatorProps) + DECL_HANDLER(PshifterProps) + DECL_HANDLER(VmorpherProps) +#undef DECL_HANDLER + + static void StdReverbSetParami(ReverbProps &props, ALenum param, int val); + static void StdReverbSetParamiv(ReverbProps &props, ALenum param, const int *vals); + static void StdReverbSetParamf(ReverbProps &props, ALenum param, float val); + static void StdReverbSetParamfv(ReverbProps &props, ALenum param, const float *vals); + static void StdReverbGetParami(const ReverbProps &props, ALenum param, int *val); + static void StdReverbGetParamiv(const ReverbProps &props, ALenum param, int *vals); + static void StdReverbGetParamf(const ReverbProps &props, ALenum param, float *val); + static void StdReverbGetParamfv(const ReverbProps &props, ALenum param, float *vals); +}; class effect_exception final : public al::base_exception { ALenum mErrorCode; @@ -28,27 +66,6 @@ public: }; -struct EffectVtable { - void (*const setParami)(EffectProps *props, ALenum param, int val); - void (*const setParamiv)(EffectProps *props, ALenum param, const int *vals); - void (*const setParamf)(EffectProps *props, ALenum param, float val); - void (*const setParamfv)(EffectProps *props, ALenum param, const float *vals); - - void (*const getParami)(const EffectProps *props, ALenum param, int *val); - void (*const getParamiv)(const EffectProps *props, ALenum param, int *vals); - void (*const getParamf)(const EffectProps *props, ALenum param, float *val); - void (*const getParamfv)(const EffectProps *props, ALenum param, float *vals); -}; - -#define DEFINE_ALEFFECT_VTABLE(T) \ -const EffectVtable T##EffectVtable = { \ - T##_setParami, T##_setParamiv, \ - T##_setParamf, T##_setParamfv, \ - T##_getParami, T##_getParamiv, \ - T##_getParamf, T##_getParamfv, \ -} - - /* Default properties for the given effect types. */ extern const EffectProps NullEffectProps; extern const EffectProps ReverbEffectProps; @@ -68,23 +85,4 @@ extern const EffectProps DedicatedDialogEffectProps; extern const EffectProps DedicatedLfeEffectProps; extern const EffectProps ConvolutionEffectProps; -/* Vtables to get/set properties for the given effect types. */ -extern const EffectVtable NullEffectVtable; -extern const EffectVtable ReverbEffectVtable; -extern const EffectVtable StdReverbEffectVtable; -extern const EffectVtable AutowahEffectVtable; -extern const EffectVtable ChorusEffectVtable; -extern const EffectVtable CompressorEffectVtable; -extern const EffectVtable DistortionEffectVtable; -extern const EffectVtable EchoEffectVtable; -extern const EffectVtable EqualizerEffectVtable; -extern const EffectVtable FlangerEffectVtable; -extern const EffectVtable FshifterEffectVtable; -extern const EffectVtable ModulatorEffectVtable; -extern const EffectVtable PshifterEffectVtable; -extern const EffectVtable VmorpherEffectVtable; -extern const EffectVtable DedicatedDialogEffectVtable; -extern const EffectVtable DedicatedLfeEffectVtable; -extern const EffectVtable ConvolutionEffectVtable; - #endif /* AL_EFFECTS_EFFECTS_H */ diff --git a/al/effects/equalizer.cpp b/al/effects/equalizer.cpp index 921d1090..74fc43fc 100644 --- a/al/effects/equalizer.cpp +++ b/al/effects/equalizer.cpp @@ -16,163 +16,133 @@ namespace { -void Equalizer_setParami(EffectProps*, ALenum param, int) +EffectProps genDefaultProps() noexcept +{ + EqualizerProps props{}; + props.LowCutoff = AL_EQUALIZER_DEFAULT_LOW_CUTOFF; + props.LowGain = AL_EQUALIZER_DEFAULT_LOW_GAIN; + props.Mid1Center = AL_EQUALIZER_DEFAULT_MID1_CENTER; + props.Mid1Gain = AL_EQUALIZER_DEFAULT_MID1_GAIN; + props.Mid1Width = AL_EQUALIZER_DEFAULT_MID1_WIDTH; + props.Mid2Center = AL_EQUALIZER_DEFAULT_MID2_CENTER; + props.Mid2Gain = AL_EQUALIZER_DEFAULT_MID2_GAIN; + props.Mid2Width = AL_EQUALIZER_DEFAULT_MID2_WIDTH; + props.HighCutoff = AL_EQUALIZER_DEFAULT_HIGH_CUTOFF; + props.HighGain = AL_EQUALIZER_DEFAULT_HIGH_GAIN; + return props; +} + +} // namespace + +const EffectProps EqualizerEffectProps{genDefaultProps()}; + +void EffectHandler::SetParami(EqualizerProps&, ALenum param, int) { throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer integer property 0x%04x", param}; } -void Equalizer_setParamiv(EffectProps*, ALenum param, const int*) +void EffectHandler::SetParamiv(EqualizerProps&, ALenum param, const int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer integer-vector property 0x%04x", param}; } -void Equalizer_setParamf(EffectProps *props, ALenum param, float val) +void EffectHandler::SetParamf(EqualizerProps &props, ALenum param, float val) { switch(param) { case AL_EQUALIZER_LOW_GAIN: if(!(val >= AL_EQUALIZER_MIN_LOW_GAIN && val <= AL_EQUALIZER_MAX_LOW_GAIN)) throw effect_exception{AL_INVALID_VALUE, "Equalizer low-band gain out of range"}; - props->Equalizer.LowGain = val; + props.LowGain = val; break; case AL_EQUALIZER_LOW_CUTOFF: if(!(val >= AL_EQUALIZER_MIN_LOW_CUTOFF && val <= AL_EQUALIZER_MAX_LOW_CUTOFF)) throw effect_exception{AL_INVALID_VALUE, "Equalizer low-band cutoff out of range"}; - props->Equalizer.LowCutoff = val; + props.LowCutoff = val; break; case AL_EQUALIZER_MID1_GAIN: if(!(val >= AL_EQUALIZER_MIN_MID1_GAIN && val <= AL_EQUALIZER_MAX_MID1_GAIN)) throw effect_exception{AL_INVALID_VALUE, "Equalizer mid1-band gain out of range"}; - props->Equalizer.Mid1Gain = val; + props.Mid1Gain = val; break; case AL_EQUALIZER_MID1_CENTER: if(!(val >= AL_EQUALIZER_MIN_MID1_CENTER && val <= AL_EQUALIZER_MAX_MID1_CENTER)) throw effect_exception{AL_INVALID_VALUE, "Equalizer mid1-band center out of range"}; - props->Equalizer.Mid1Center = val; + props.Mid1Center = val; break; case AL_EQUALIZER_MID1_WIDTH: if(!(val >= AL_EQUALIZER_MIN_MID1_WIDTH && val <= AL_EQUALIZER_MAX_MID1_WIDTH)) throw effect_exception{AL_INVALID_VALUE, "Equalizer mid1-band width out of range"}; - props->Equalizer.Mid1Width = val; + props.Mid1Width = val; break; case AL_EQUALIZER_MID2_GAIN: if(!(val >= AL_EQUALIZER_MIN_MID2_GAIN && val <= AL_EQUALIZER_MAX_MID2_GAIN)) throw effect_exception{AL_INVALID_VALUE, "Equalizer mid2-band gain out of range"}; - props->Equalizer.Mid2Gain = val; + props.Mid2Gain = val; break; case AL_EQUALIZER_MID2_CENTER: if(!(val >= AL_EQUALIZER_MIN_MID2_CENTER && val <= AL_EQUALIZER_MAX_MID2_CENTER)) throw effect_exception{AL_INVALID_VALUE, "Equalizer mid2-band center out of range"}; - props->Equalizer.Mid2Center = val; + props.Mid2Center = val; break; case AL_EQUALIZER_MID2_WIDTH: if(!(val >= AL_EQUALIZER_MIN_MID2_WIDTH && val <= AL_EQUALIZER_MAX_MID2_WIDTH)) throw effect_exception{AL_INVALID_VALUE, "Equalizer mid2-band width out of range"}; - props->Equalizer.Mid2Width = val; + props.Mid2Width = val; break; case AL_EQUALIZER_HIGH_GAIN: if(!(val >= AL_EQUALIZER_MIN_HIGH_GAIN && val <= AL_EQUALIZER_MAX_HIGH_GAIN)) throw effect_exception{AL_INVALID_VALUE, "Equalizer high-band gain out of range"}; - props->Equalizer.HighGain = val; + props.HighGain = val; break; case AL_EQUALIZER_HIGH_CUTOFF: if(!(val >= AL_EQUALIZER_MIN_HIGH_CUTOFF && val <= AL_EQUALIZER_MAX_HIGH_CUTOFF)) throw effect_exception{AL_INVALID_VALUE, "Equalizer high-band cutoff out of range"}; - props->Equalizer.HighCutoff = val; + props.HighCutoff = val; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer float property 0x%04x", param}; } } -void Equalizer_setParamfv(EffectProps *props, ALenum param, const float *vals) -{ Equalizer_setParamf(props, param, vals[0]); } +void EffectHandler::SetParamfv(EqualizerProps &props, ALenum param, const float *vals) +{ SetParamf(props, param, vals[0]); } -void Equalizer_getParami(const EffectProps*, ALenum param, int*) +void EffectHandler::GetParami(const EqualizerProps&, ALenum param, int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer integer property 0x%04x", param}; } -void Equalizer_getParamiv(const EffectProps*, ALenum param, int*) +void EffectHandler::GetParamiv(const EqualizerProps&, ALenum param, int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer integer-vector property 0x%04x", param}; } -void Equalizer_getParamf(const EffectProps *props, ALenum param, float *val) +void EffectHandler::GetParamf(const EqualizerProps &props, ALenum param, float *val) { switch(param) { - case AL_EQUALIZER_LOW_GAIN: - *val = props->Equalizer.LowGain; - break; - - case AL_EQUALIZER_LOW_CUTOFF: - *val = props->Equalizer.LowCutoff; - break; - - case AL_EQUALIZER_MID1_GAIN: - *val = props->Equalizer.Mid1Gain; - break; - - case AL_EQUALIZER_MID1_CENTER: - *val = props->Equalizer.Mid1Center; - break; - - case AL_EQUALIZER_MID1_WIDTH: - *val = props->Equalizer.Mid1Width; - break; - - case AL_EQUALIZER_MID2_GAIN: - *val = props->Equalizer.Mid2Gain; - break; - - case AL_EQUALIZER_MID2_CENTER: - *val = props->Equalizer.Mid2Center; - break; - - case AL_EQUALIZER_MID2_WIDTH: - *val = props->Equalizer.Mid2Width; - break; - - case AL_EQUALIZER_HIGH_GAIN: - *val = props->Equalizer.HighGain; - break; - - case AL_EQUALIZER_HIGH_CUTOFF: - *val = props->Equalizer.HighCutoff; - break; + case AL_EQUALIZER_LOW_GAIN: *val = props.LowGain; break; + case AL_EQUALIZER_LOW_CUTOFF: *val = props.LowCutoff; break; + case AL_EQUALIZER_MID1_GAIN: *val = props.Mid1Gain; break; + case AL_EQUALIZER_MID1_CENTER: *val = props.Mid1Center; break; + case AL_EQUALIZER_MID1_WIDTH: *val = props.Mid1Width; break; + case AL_EQUALIZER_MID2_GAIN: *val = props.Mid2Gain; break; + case AL_EQUALIZER_MID2_CENTER: *val = props.Mid2Center; break; + case AL_EQUALIZER_MID2_WIDTH: *val = props.Mid2Width; break; + case AL_EQUALIZER_HIGH_GAIN: *val = props.HighGain; break; + case AL_EQUALIZER_HIGH_CUTOFF: *val = props.HighCutoff; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer float property 0x%04x", param}; } } -void Equalizer_getParamfv(const EffectProps *props, ALenum param, float *vals) -{ Equalizer_getParamf(props, param, vals); } - -EffectProps genDefaultProps() noexcept -{ - EffectProps props{}; - props.Equalizer.LowCutoff = AL_EQUALIZER_DEFAULT_LOW_CUTOFF; - props.Equalizer.LowGain = AL_EQUALIZER_DEFAULT_LOW_GAIN; - props.Equalizer.Mid1Center = AL_EQUALIZER_DEFAULT_MID1_CENTER; - props.Equalizer.Mid1Gain = AL_EQUALIZER_DEFAULT_MID1_GAIN; - props.Equalizer.Mid1Width = AL_EQUALIZER_DEFAULT_MID1_WIDTH; - props.Equalizer.Mid2Center = AL_EQUALIZER_DEFAULT_MID2_CENTER; - props.Equalizer.Mid2Gain = AL_EQUALIZER_DEFAULT_MID2_GAIN; - props.Equalizer.Mid2Width = AL_EQUALIZER_DEFAULT_MID2_WIDTH; - props.Equalizer.HighCutoff = AL_EQUALIZER_DEFAULT_HIGH_CUTOFF; - props.Equalizer.HighGain = AL_EQUALIZER_DEFAULT_HIGH_GAIN; - return props; -} +void EffectHandler::GetParamfv(const EqualizerProps &props, ALenum param, float *vals) +{ GetParamf(props, param, vals); } -} // namespace - -DEFINE_ALEFFECT_VTABLE(Equalizer); - -const EffectProps EqualizerEffectProps{genDefaultProps()}; #ifdef ALSOFT_EAX namespace { @@ -325,17 +295,20 @@ bool EaxEqualizerCommitter::commit(const EAXEQUALIZERPROPERTIES &props) return false; mEaxProps = props; - - mAlProps.Equalizer.LowGain = level_mb_to_gain(static_cast(props.lLowGain)); - mAlProps.Equalizer.LowCutoff = props.flLowCutOff; - mAlProps.Equalizer.Mid1Gain = level_mb_to_gain(static_cast(props.lMid1Gain)); - mAlProps.Equalizer.Mid1Center = props.flMid1Center; - mAlProps.Equalizer.Mid1Width = props.flMid1Width; - mAlProps.Equalizer.Mid2Gain = level_mb_to_gain(static_cast(props.lMid2Gain)); - mAlProps.Equalizer.Mid2Center = props.flMid2Center; - mAlProps.Equalizer.Mid2Width = props.flMid2Width; - mAlProps.Equalizer.HighGain = level_mb_to_gain(static_cast(props.lHighGain)); - mAlProps.Equalizer.HighCutoff = props.flHighCutOff; + mAlProps = [&]{ + EqualizerProps ret{}; + ret.LowGain = level_mb_to_gain(static_cast(props.lLowGain)); + ret.LowCutoff = props.flLowCutOff; + ret.Mid1Gain = level_mb_to_gain(static_cast(props.lMid1Gain)); + ret.Mid1Center = props.flMid1Center; + ret.Mid1Width = props.flMid1Width; + ret.Mid2Gain = level_mb_to_gain(static_cast(props.lMid2Gain)); + ret.Mid2Center = props.flMid2Center; + ret.Mid2Width = props.flMid2Width; + ret.HighGain = level_mb_to_gain(static_cast(props.lHighGain)); + ret.HighCutoff = props.flHighCutOff; + return ret; + }(); return true; } diff --git a/al/effects/fshifter.cpp b/al/effects/fshifter.cpp index a6b3c86c..6f19e0dd 100644 --- a/al/effects/fshifter.cpp +++ b/al/effects/fshifter.cpp @@ -41,31 +41,26 @@ ALenum EnumFromDirection(FShifterDirection dir) throw std::runtime_error{"Invalid direction: "+std::to_string(static_cast(dir))}; } -void Fshifter_setParamf(EffectProps *props, ALenum param, float val) +EffectProps genDefaultProps() noexcept { - switch(param) - { - case AL_FREQUENCY_SHIFTER_FREQUENCY: - if(!(val >= AL_FREQUENCY_SHIFTER_MIN_FREQUENCY && val <= AL_FREQUENCY_SHIFTER_MAX_FREQUENCY)) - throw effect_exception{AL_INVALID_VALUE, "Frequency shifter frequency out of range"}; - props->Fshifter.Frequency = val; - break; - - default: - throw effect_exception{AL_INVALID_ENUM, "Invalid frequency shifter float property 0x%04x", - param}; - } + FshifterProps props{}; + props.Frequency = AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY; + props.LeftDirection = *DirectionFromEmum(AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION); + props.RightDirection = *DirectionFromEmum(AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION); + return props; } -void Fshifter_setParamfv(EffectProps *props, ALenum param, const float *vals) -{ Fshifter_setParamf(props, param, vals[0]); } -void Fshifter_setParami(EffectProps *props, ALenum param, int val) +} // namespace + +const EffectProps FshifterEffectProps{genDefaultProps()}; + +void EffectHandler::SetParami(FshifterProps &props, ALenum param, int val) { switch(param) { case AL_FREQUENCY_SHIFTER_LEFT_DIRECTION: if(auto diropt = DirectionFromEmum(val)) - props->Fshifter.LeftDirection = *diropt; + props.LeftDirection = *diropt; else throw effect_exception{AL_INVALID_VALUE, "Unsupported frequency shifter left direction: 0x%04x", val}; @@ -73,7 +68,7 @@ void Fshifter_setParami(EffectProps *props, ALenum param, int val) case AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION: if(auto diropt = DirectionFromEmum(val)) - props->Fshifter.RightDirection = *diropt; + props.RightDirection = *diropt; else throw effect_exception{AL_INVALID_VALUE, "Unsupported frequency shifter right direction: 0x%04x", val}; @@ -84,33 +79,52 @@ void Fshifter_setParami(EffectProps *props, ALenum param, int val) "Invalid frequency shifter integer property 0x%04x", param}; } } -void Fshifter_setParamiv(EffectProps *props, ALenum param, const int *vals) -{ Fshifter_setParami(props, param, vals[0]); } +void EffectHandler::SetParamiv(FshifterProps &props, ALenum param, const int *vals) +{ SetParami(props, param, vals[0]); } + +void EffectHandler::SetParamf(FshifterProps &props, ALenum param, float val) +{ + switch(param) + { + case AL_FREQUENCY_SHIFTER_FREQUENCY: + if(!(val >= AL_FREQUENCY_SHIFTER_MIN_FREQUENCY && val <= AL_FREQUENCY_SHIFTER_MAX_FREQUENCY)) + throw effect_exception{AL_INVALID_VALUE, "Frequency shifter frequency out of range"}; + props.Frequency = val; + break; + + default: + throw effect_exception{AL_INVALID_ENUM, "Invalid frequency shifter float property 0x%04x", + param}; + } +} +void EffectHandler::SetParamfv(FshifterProps &props, ALenum param, const float *vals) +{ SetParamf(props, param, vals[0]); } -void Fshifter_getParami(const EffectProps *props, ALenum param, int *val) +void EffectHandler::GetParami(const FshifterProps &props, ALenum param, int *val) { switch(param) { case AL_FREQUENCY_SHIFTER_LEFT_DIRECTION: - *val = EnumFromDirection(props->Fshifter.LeftDirection); + *val = EnumFromDirection(props.LeftDirection); break; case AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION: - *val = EnumFromDirection(props->Fshifter.RightDirection); + *val = EnumFromDirection(props.RightDirection); break; + default: throw effect_exception{AL_INVALID_ENUM, "Invalid frequency shifter integer property 0x%04x", param}; } } -void Fshifter_getParamiv(const EffectProps *props, ALenum param, int *vals) -{ Fshifter_getParami(props, param, vals); } +void EffectHandler::GetParamiv(const FshifterProps &props, ALenum param, int *vals) +{ GetParami(props, param, vals); } -void Fshifter_getParamf(const EffectProps *props, ALenum param, float *val) +void EffectHandler::GetParamf(const FshifterProps &props, ALenum param, float *val) { switch(param) { case AL_FREQUENCY_SHIFTER_FREQUENCY: - *val = props->Fshifter.Frequency; + *val = props.Frequency; break; default: @@ -118,23 +132,9 @@ void Fshifter_getParamf(const EffectProps *props, ALenum param, float *val) param}; } } -void Fshifter_getParamfv(const EffectProps *props, ALenum param, float *vals) -{ Fshifter_getParamf(props, param, vals); } +void EffectHandler::GetParamfv(const FshifterProps &props, ALenum param, float *vals) +{ GetParamf(props, param, vals); } -EffectProps genDefaultProps() noexcept -{ - EffectProps props{}; - props.Fshifter.Frequency = AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY; - props.Fshifter.LeftDirection = *DirectionFromEmum(AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION); - props.Fshifter.RightDirection = *DirectionFromEmum(AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION); - return props; -} - -} // namespace - -DEFINE_ALEFFECT_VTABLE(Fshifter); - -const EffectProps FshifterEffectProps{genDefaultProps()}; #ifdef ALSOFT_EAX namespace { @@ -213,9 +213,13 @@ bool EaxFrequencyShifterCommitter::commit(const EAXFREQUENCYSHIFTERPROPERTIES &p return FShifterDirection::Off; }; - mAlProps.Fshifter.Frequency = props.flFrequency; - mAlProps.Fshifter.LeftDirection = get_direction(props.ulLeftDirection); - mAlProps.Fshifter.RightDirection = get_direction(props.ulRightDirection); + mAlProps = [&]{ + FshifterProps ret{}; + ret.Frequency = props.flFrequency; + ret.LeftDirection = get_direction(props.ulLeftDirection); + ret.RightDirection = get_direction(props.ulRightDirection); + return ret; + }(); return true; } diff --git a/al/effects/modulator.cpp b/al/effects/modulator.cpp index d0a2df02..566b333e 100644 --- a/al/effects/modulator.cpp +++ b/al/effects/modulator.cpp @@ -42,40 +42,31 @@ ALenum EnumFromWaveform(ModulatorWaveform type) std::to_string(static_cast(type))}; } -void Modulator_setParamf(EffectProps *props, ALenum param, float val) +EffectProps genDefaultProps() noexcept { - switch(param) - { - case AL_RING_MODULATOR_FREQUENCY: - if(!(val >= AL_RING_MODULATOR_MIN_FREQUENCY && val <= AL_RING_MODULATOR_MAX_FREQUENCY)) - throw effect_exception{AL_INVALID_VALUE, "Modulator frequency out of range: %f", val}; - props->Modulator.Frequency = val; - break; + ModulatorProps props{}; + props.Frequency = AL_RING_MODULATOR_DEFAULT_FREQUENCY; + props.HighPassCutoff = AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF; + props.Waveform = *WaveformFromEmum(AL_RING_MODULATOR_DEFAULT_WAVEFORM); + return props; +} - case AL_RING_MODULATOR_HIGHPASS_CUTOFF: - if(!(val >= AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF && val <= AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF)) - throw effect_exception{AL_INVALID_VALUE, "Modulator high-pass cutoff out of range: %f", val}; - props->Modulator.HighPassCutoff = val; - break; +} // namespace - default: - throw effect_exception{AL_INVALID_ENUM, "Invalid modulator float property 0x%04x", param}; - } -} -void Modulator_setParamfv(EffectProps *props, ALenum param, const float *vals) -{ Modulator_setParamf(props, param, vals[0]); } -void Modulator_setParami(EffectProps *props, ALenum param, int val) +const EffectProps ModulatorEffectProps{genDefaultProps()}; + +void EffectHandler::SetParami(ModulatorProps &props, ALenum param, int val) { switch(param) { case AL_RING_MODULATOR_FREQUENCY: case AL_RING_MODULATOR_HIGHPASS_CUTOFF: - Modulator_setParamf(props, param, static_cast(val)); + SetParamf(props, param, static_cast(val)); break; case AL_RING_MODULATOR_WAVEFORM: if(auto formopt = WaveformFromEmum(val)) - props->Modulator.Waveform = *formopt; + props.Waveform = *formopt; else throw effect_exception{AL_INVALID_VALUE, "Invalid modulator waveform: 0x%04x", val}; break; @@ -85,62 +76,61 @@ void Modulator_setParami(EffectProps *props, ALenum param, int val) param}; } } -void Modulator_setParamiv(EffectProps *props, ALenum param, const int *vals) -{ Modulator_setParami(props, param, vals[0]); } +void EffectHandler::SetParamiv(ModulatorProps &props, ALenum param, const int *vals) +{ SetParami(props, param, vals[0]); } -void Modulator_getParami(const EffectProps *props, ALenum param, int *val) +void EffectHandler::SetParamf(ModulatorProps &props, ALenum param, float val) { switch(param) { case AL_RING_MODULATOR_FREQUENCY: - *val = static_cast(props->Modulator.Frequency); + if(!(val >= AL_RING_MODULATOR_MIN_FREQUENCY && val <= AL_RING_MODULATOR_MAX_FREQUENCY)) + throw effect_exception{AL_INVALID_VALUE, "Modulator frequency out of range: %f", val}; + props.Frequency = val; break; + case AL_RING_MODULATOR_HIGHPASS_CUTOFF: - *val = static_cast(props->Modulator.HighPassCutoff); - break; - case AL_RING_MODULATOR_WAVEFORM: - *val = EnumFromWaveform(props->Modulator.Waveform); + if(!(val >= AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF && val <= AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF)) + throw effect_exception{AL_INVALID_VALUE, "Modulator high-pass cutoff out of range: %f", val}; + props.HighPassCutoff = val; break; + default: + throw effect_exception{AL_INVALID_ENUM, "Invalid modulator float property 0x%04x", param}; + } +} +void EffectHandler::SetParamfv(ModulatorProps &props, ALenum param, const float *vals) +{ SetParamf(props, param, vals[0]); } + +void EffectHandler::GetParami(const ModulatorProps &props, ALenum param, int *val) +{ + switch(param) + { + case AL_RING_MODULATOR_FREQUENCY: *val = static_cast(props.Frequency); break; + case AL_RING_MODULATOR_HIGHPASS_CUTOFF: *val = static_cast(props.HighPassCutoff); break; + case AL_RING_MODULATOR_WAVEFORM: *val = EnumFromWaveform(props.Waveform); break; + default: throw effect_exception{AL_INVALID_ENUM, "Invalid modulator integer property 0x%04x", param}; } } -void Modulator_getParamiv(const EffectProps *props, ALenum param, int *vals) -{ Modulator_getParami(props, param, vals); } -void Modulator_getParamf(const EffectProps *props, ALenum param, float *val) +void EffectHandler::GetParamiv(const ModulatorProps &props, ALenum param, int *vals) +{ GetParami(props, param, vals); } +void EffectHandler::GetParamf(const ModulatorProps &props, ALenum param, float *val) { switch(param) { - case AL_RING_MODULATOR_FREQUENCY: - *val = props->Modulator.Frequency; - break; - case AL_RING_MODULATOR_HIGHPASS_CUTOFF: - *val = props->Modulator.HighPassCutoff; - break; + case AL_RING_MODULATOR_FREQUENCY: *val = props.Frequency; break; + case AL_RING_MODULATOR_HIGHPASS_CUTOFF: *val = props.HighPassCutoff; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid modulator float property 0x%04x", param}; } } -void Modulator_getParamfv(const EffectProps *props, ALenum param, float *vals) -{ Modulator_getParamf(props, param, vals); } - -EffectProps genDefaultProps() noexcept -{ - EffectProps props{}; - props.Modulator.Frequency = AL_RING_MODULATOR_DEFAULT_FREQUENCY; - props.Modulator.HighPassCutoff = AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF; - props.Modulator.Waveform = *WaveformFromEmum(AL_RING_MODULATOR_DEFAULT_WAVEFORM); - return props; -} - -} // namespace +void EffectHandler::GetParamfv(const ModulatorProps &props, ALenum param, float *vals) +{ GetParamf(props, param, vals); } -DEFINE_ALEFFECT_VTABLE(Modulator); - -const EffectProps ModulatorEffectProps{genDefaultProps()}; #ifdef ALSOFT_EAX namespace { @@ -221,9 +211,13 @@ bool EaxModulatorCommitter::commit(const EAXRINGMODULATORPROPERTIES &props) return ModulatorWaveform::Sinusoid; }; - mAlProps.Modulator.Frequency = props.flFrequency; - mAlProps.Modulator.HighPassCutoff = props.flHighPassCutOff; - mAlProps.Modulator.Waveform = get_waveform(props.ulWaveform); + mAlProps = [&]{ + ModulatorProps ret{}; + ret.Frequency = props.flFrequency; + ret.HighPassCutoff = props.flHighPassCutOff; + ret.Waveform = get_waveform(props.ulWaveform); + return ret; + }(); return true; } diff --git a/al/effects/null.cpp b/al/effects/null.cpp index 4b68a28f..4b00ef4f 100644 --- a/al/effects/null.cpp +++ b/al/effects/null.cpp @@ -14,7 +14,17 @@ namespace { -void Null_setParami(EffectProps* /*props*/, ALenum param, int /*val*/) +EffectProps genDefaultProps() noexcept +{ + EffectProps props{}; + return props; +} + +} // namespace + +const EffectProps NullEffectProps{genDefaultProps()}; + +void EffectHandler::SetParami(std::monostate& /*props*/, ALenum param, int /*val*/) { switch(param) { @@ -23,15 +33,15 @@ void Null_setParami(EffectProps* /*props*/, ALenum param, int /*val*/) param}; } } -void Null_setParamiv(EffectProps *props, ALenum param, const int *vals) +void EffectHandler::SetParamiv(std::monostate &props, ALenum param, const int *vals) { switch(param) { default: - Null_setParami(props, param, vals[0]); + SetParami(props, param, vals[0]); } } -void Null_setParamf(EffectProps* /*props*/, ALenum param, float /*val*/) +void EffectHandler::SetParamf(std::monostate& /*props*/, ALenum param, float /*val*/) { switch(param) { @@ -40,16 +50,16 @@ void Null_setParamf(EffectProps* /*props*/, ALenum param, float /*val*/) param}; } } -void Null_setParamfv(EffectProps *props, ALenum param, const float *vals) +void EffectHandler::SetParamfv(std::monostate &props, ALenum param, const float *vals) { switch(param) { default: - Null_setParamf(props, param, vals[0]); + SetParamf(props, param, vals[0]); } } -void Null_getParami(const EffectProps* /*props*/, ALenum param, int* /*val*/) +void EffectHandler::GetParami(const std::monostate& /*props*/, ALenum param, int* /*val*/) { switch(param) { @@ -58,15 +68,15 @@ void Null_getParami(const EffectProps* /*props*/, ALenum param, int* /*val*/) param}; } } -void Null_getParamiv(const EffectProps *props, ALenum param, int *vals) +void EffectHandler::GetParamiv(const std::monostate &props, ALenum param, int *vals) { switch(param) { default: - Null_getParami(props, param, vals); + GetParami(props, param, vals); } } -void Null_getParamf(const EffectProps* /*props*/, ALenum param, float* /*val*/) +void EffectHandler::GetParamf(const std::monostate& /*props*/, ALenum param, float* /*val*/) { switch(param) { @@ -75,27 +85,15 @@ void Null_getParamf(const EffectProps* /*props*/, ALenum param, float* /*val*/) param}; } } -void Null_getParamfv(const EffectProps *props, ALenum param, float *vals) +void EffectHandler::GetParamfv(const std::monostate &props, ALenum param, float *vals) { switch(param) { default: - Null_getParamf(props, param, vals); + GetParamf(props, param, vals); } } -EffectProps genDefaultProps() noexcept -{ - EffectProps props{}; - return props; -} - -} // namespace - -DEFINE_ALEFFECT_VTABLE(Null); - -const EffectProps NullEffectProps{genDefaultProps()}; - #ifdef ALSOFT_EAX namespace { @@ -121,12 +119,13 @@ bool EaxNullCommitter::commit(const std::monostate &props) { const bool ret{std::holds_alternative(mEaxProps)}; mEaxProps = props; + mAlProps = std::monostate{}; return ret; } void EaxNullCommitter::SetDefaults(EaxEffectProps &props) { - props.emplace(); + props = std::monostate{}; } void EaxNullCommitter::Get(const EaxCall &call, const std::monostate&) diff --git a/al/effects/pshifter.cpp b/al/effects/pshifter.cpp index f29a3593..b36fe034 100644 --- a/al/effects/pshifter.cpp +++ b/al/effects/pshifter.cpp @@ -16,28 +16,32 @@ namespace { -void Pshifter_setParamf(EffectProps*, ALenum param, float) -{ throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float property 0x%04x", param}; } -void Pshifter_setParamfv(EffectProps*, ALenum param, const float*) +EffectProps genDefaultProps() noexcept { - throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float-vector property 0x%04x", - param}; + PshifterProps props{}; + props.CoarseTune = AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE; + props.FineTune = AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE; + return props; } -void Pshifter_setParami(EffectProps *props, ALenum param, int val) +} // namespace + +const EffectProps PshifterEffectProps{genDefaultProps()}; + +void EffectHandler::SetParami(PshifterProps &props, ALenum param, int val) { switch(param) { case AL_PITCH_SHIFTER_COARSE_TUNE: if(!(val >= AL_PITCH_SHIFTER_MIN_COARSE_TUNE && val <= AL_PITCH_SHIFTER_MAX_COARSE_TUNE)) throw effect_exception{AL_INVALID_VALUE, "Pitch shifter coarse tune out of range"}; - props->Pshifter.CoarseTune = val; + props.CoarseTune = val; break; case AL_PITCH_SHIFTER_FINE_TUNE: if(!(val >= AL_PITCH_SHIFTER_MIN_FINE_TUNE && val <= AL_PITCH_SHIFTER_MAX_FINE_TUNE)) throw effect_exception{AL_INVALID_VALUE, "Pitch shifter fine tune out of range"}; - props->Pshifter.FineTune = val; + props.FineTune = val; break; default: @@ -45,49 +49,40 @@ void Pshifter_setParami(EffectProps *props, ALenum param, int val) param}; } } -void Pshifter_setParamiv(EffectProps *props, ALenum param, const int *vals) -{ Pshifter_setParami(props, param, vals[0]); } +void EffectHandler::SetParamiv(PshifterProps &props, ALenum param, const int *vals) +{ SetParami(props, param, vals[0]); } + +void EffectHandler::SetParamf(PshifterProps&, ALenum param, float) +{ throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float property 0x%04x", param}; } +void EffectHandler::SetParamfv(PshifterProps&, ALenum param, const float*) +{ + throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float-vector property 0x%04x", + param}; +} -void Pshifter_getParami(const EffectProps *props, ALenum param, int *val) +void EffectHandler::GetParami(const PshifterProps &props, ALenum param, int *val) { switch(param) { - case AL_PITCH_SHIFTER_COARSE_TUNE: - *val = props->Pshifter.CoarseTune; - break; - case AL_PITCH_SHIFTER_FINE_TUNE: - *val = props->Pshifter.FineTune; - break; + case AL_PITCH_SHIFTER_COARSE_TUNE: *val = props.CoarseTune; break; + case AL_PITCH_SHIFTER_FINE_TUNE: *val = props.FineTune; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter integer property 0x%04x", param}; } } -void Pshifter_getParamiv(const EffectProps *props, ALenum param, int *vals) -{ Pshifter_getParami(props, param, vals); } +void EffectHandler::GetParamiv(const PshifterProps &props, ALenum param, int *vals) +{ GetParami(props, param, vals); } -void Pshifter_getParamf(const EffectProps*, ALenum param, float*) +void EffectHandler::GetParamf(const PshifterProps&, ALenum param, float*) { throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float property 0x%04x", param}; } -void Pshifter_getParamfv(const EffectProps*, ALenum param, float*) +void EffectHandler::GetParamfv(const PshifterProps&, ALenum param, float*) { throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float vector-property 0x%04x", param}; } -EffectProps genDefaultProps() noexcept -{ - EffectProps props{}; - props.Pshifter.CoarseTune = AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE; - props.Pshifter.FineTune = AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE; - return props; -} - -} // namespace - -DEFINE_ALEFFECT_VTABLE(Pshifter); - -const EffectProps PshifterEffectProps{genDefaultProps()}; #ifdef ALSOFT_EAX namespace { @@ -144,9 +139,12 @@ bool EaxPitchShifterCommitter::commit(const EAXPITCHSHIFTERPROPERTIES &props) return false; mEaxProps = props; - - mAlProps.Pshifter.CoarseTune = static_cast(props.lCoarseTune); - mAlProps.Pshifter.FineTune = static_cast(props.lFineTune); + mAlProps = [&]{ + PshifterProps ret{}; + ret.CoarseTune = static_cast(props.lCoarseTune); + ret.FineTune = static_cast(props.lFineTune); + return ret; + }(); return true; } diff --git a/al/effects/reverb.cpp b/al/effects/reverb.cpp index 7f549f04..f0df51b2 100644 --- a/al/effects/reverb.cpp +++ b/al/effects/reverb.cpp @@ -20,14 +20,80 @@ namespace { -void Reverb_setParami(EffectProps *props, ALenum param, int val) +EffectProps genDefaultProps() noexcept +{ + ReverbProps props{}; + props.Density = AL_EAXREVERB_DEFAULT_DENSITY; + props.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION; + props.Gain = AL_EAXREVERB_DEFAULT_GAIN; + props.GainHF = AL_EAXREVERB_DEFAULT_GAINHF; + props.GainLF = AL_EAXREVERB_DEFAULT_GAINLF; + props.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME; + props.DecayHFRatio = AL_EAXREVERB_DEFAULT_DECAY_HFRATIO; + props.DecayLFRatio = AL_EAXREVERB_DEFAULT_DECAY_LFRATIO; + props.ReflectionsGain = AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN; + props.ReflectionsDelay = AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY; + props.ReflectionsPan[0] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; + props.ReflectionsPan[1] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; + props.ReflectionsPan[2] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; + props.LateReverbGain = AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN; + props.LateReverbDelay = AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY; + props.LateReverbPan[0] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; + props.LateReverbPan[1] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; + props.LateReverbPan[2] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; + props.EchoTime = AL_EAXREVERB_DEFAULT_ECHO_TIME; + props.EchoDepth = AL_EAXREVERB_DEFAULT_ECHO_DEPTH; + props.ModulationTime = AL_EAXREVERB_DEFAULT_MODULATION_TIME; + props.ModulationDepth = AL_EAXREVERB_DEFAULT_MODULATION_DEPTH; + props.AirAbsorptionGainHF = AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF; + props.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE; + props.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE; + props.RoomRolloffFactor = AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR; + props.DecayHFLimit = AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT; + return props; +} + +EffectProps genDefaultStdProps() noexcept +{ + ReverbProps props{}; + props.Density = AL_REVERB_DEFAULT_DENSITY; + props.Diffusion = AL_REVERB_DEFAULT_DIFFUSION; + props.Gain = AL_REVERB_DEFAULT_GAIN; + props.GainHF = AL_REVERB_DEFAULT_GAINHF; + props.GainLF = 1.0f; + props.DecayTime = AL_REVERB_DEFAULT_DECAY_TIME; + props.DecayHFRatio = AL_REVERB_DEFAULT_DECAY_HFRATIO; + props.DecayLFRatio = 1.0f; + props.ReflectionsGain = AL_REVERB_DEFAULT_REFLECTIONS_GAIN; + props.ReflectionsDelay = AL_REVERB_DEFAULT_REFLECTIONS_DELAY; + props.ReflectionsPan = {0.0f, 0.0f, 0.0f}; + props.LateReverbGain = AL_REVERB_DEFAULT_LATE_REVERB_GAIN; + props.LateReverbDelay = AL_REVERB_DEFAULT_LATE_REVERB_DELAY; + props.LateReverbPan = {0.0f, 0.0f, 0.0f}; + props.EchoTime = 0.25f; + props.EchoDepth = 0.0f; + props.ModulationTime = 0.25f; + props.ModulationDepth = 0.0f; + props.AirAbsorptionGainHF = AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF; + props.HFReference = 5000.0f; + props.LFReference = 250.0f; + props.RoomRolloffFactor = AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR; + props.DecayHFLimit = AL_REVERB_DEFAULT_DECAY_HFLIMIT; + return props; +} + +} // namespace + +const EffectProps ReverbEffectProps{genDefaultProps()}; + +void EffectHandler::SetParami(ReverbProps &props, ALenum param, int val) { switch(param) { case AL_EAXREVERB_DECAY_HFLIMIT: if(!(val >= AL_EAXREVERB_MIN_DECAY_HFLIMIT && val <= AL_EAXREVERB_MAX_DECAY_HFLIMIT)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hflimit out of range"}; - props->Reverb.DecayHFLimit = val != AL_FALSE; + props.DecayHFLimit = val != AL_FALSE; break; default: @@ -35,167 +101,167 @@ void Reverb_setParami(EffectProps *props, ALenum param, int val) param}; } } -void Reverb_setParamiv(EffectProps *props, ALenum param, const int *vals) -{ Reverb_setParami(props, param, vals[0]); } -void Reverb_setParamf(EffectProps *props, ALenum param, float val) +void EffectHandler::SetParamiv(ReverbProps &props, ALenum param, const int *vals) +{ SetParami(props, param, vals[0]); } +void EffectHandler::SetParamf(ReverbProps &props, ALenum param, float val) { switch(param) { case AL_EAXREVERB_DENSITY: if(!(val >= AL_EAXREVERB_MIN_DENSITY && val <= AL_EAXREVERB_MAX_DENSITY)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb density out of range"}; - props->Reverb.Density = val; + props.Density = val; break; case AL_EAXREVERB_DIFFUSION: if(!(val >= AL_EAXREVERB_MIN_DIFFUSION && val <= AL_EAXREVERB_MAX_DIFFUSION)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb diffusion out of range"}; - props->Reverb.Diffusion = val; + props.Diffusion = val; break; case AL_EAXREVERB_GAIN: if(!(val >= AL_EAXREVERB_MIN_GAIN && val <= AL_EAXREVERB_MAX_GAIN)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gain out of range"}; - props->Reverb.Gain = val; + props.Gain = val; break; case AL_EAXREVERB_GAINHF: if(!(val >= AL_EAXREVERB_MIN_GAINHF && val <= AL_EAXREVERB_MAX_GAINHF)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gainhf out of range"}; - props->Reverb.GainHF = val; + props.GainHF = val; break; case AL_EAXREVERB_GAINLF: if(!(val >= AL_EAXREVERB_MIN_GAINLF && val <= AL_EAXREVERB_MAX_GAINLF)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gainlf out of range"}; - props->Reverb.GainLF = val; + props.GainLF = val; break; case AL_EAXREVERB_DECAY_TIME: if(!(val >= AL_EAXREVERB_MIN_DECAY_TIME && val <= AL_EAXREVERB_MAX_DECAY_TIME)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay time out of range"}; - props->Reverb.DecayTime = val; + props.DecayTime = val; break; case AL_EAXREVERB_DECAY_HFRATIO: if(!(val >= AL_EAXREVERB_MIN_DECAY_HFRATIO && val <= AL_EAXREVERB_MAX_DECAY_HFRATIO)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hfratio out of range"}; - props->Reverb.DecayHFRatio = val; + props.DecayHFRatio = val; break; case AL_EAXREVERB_DECAY_LFRATIO: if(!(val >= AL_EAXREVERB_MIN_DECAY_LFRATIO && val <= AL_EAXREVERB_MAX_DECAY_LFRATIO)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay lfratio out of range"}; - props->Reverb.DecayLFRatio = val; + props.DecayLFRatio = val; break; case AL_EAXREVERB_REFLECTIONS_GAIN: if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_GAIN && val <= AL_EAXREVERB_MAX_REFLECTIONS_GAIN)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections gain out of range"}; - props->Reverb.ReflectionsGain = val; + props.ReflectionsGain = val; break; case AL_EAXREVERB_REFLECTIONS_DELAY: if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_DELAY && val <= AL_EAXREVERB_MAX_REFLECTIONS_DELAY)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections delay out of range"}; - props->Reverb.ReflectionsDelay = val; + props.ReflectionsDelay = val; break; case AL_EAXREVERB_LATE_REVERB_GAIN: if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_GAIN && val <= AL_EAXREVERB_MAX_LATE_REVERB_GAIN)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb gain out of range"}; - props->Reverb.LateReverbGain = val; + props.LateReverbGain = val; break; case AL_EAXREVERB_LATE_REVERB_DELAY: if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_DELAY && val <= AL_EAXREVERB_MAX_LATE_REVERB_DELAY)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb delay out of range"}; - props->Reverb.LateReverbDelay = val; + props.LateReverbDelay = val; break; case AL_EAXREVERB_ECHO_TIME: if(!(val >= AL_EAXREVERB_MIN_ECHO_TIME && val <= AL_EAXREVERB_MAX_ECHO_TIME)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb echo time out of range"}; - props->Reverb.EchoTime = val; + props.EchoTime = val; break; case AL_EAXREVERB_ECHO_DEPTH: if(!(val >= AL_EAXREVERB_MIN_ECHO_DEPTH && val <= AL_EAXREVERB_MAX_ECHO_DEPTH)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb echo depth out of range"}; - props->Reverb.EchoDepth = val; + props.EchoDepth = val; break; case AL_EAXREVERB_MODULATION_TIME: if(!(val >= AL_EAXREVERB_MIN_MODULATION_TIME && val <= AL_EAXREVERB_MAX_MODULATION_TIME)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb modulation time out of range"}; - props->Reverb.ModulationTime = val; + props.ModulationTime = val; break; case AL_EAXREVERB_MODULATION_DEPTH: if(!(val >= AL_EAXREVERB_MIN_MODULATION_DEPTH && val <= AL_EAXREVERB_MAX_MODULATION_DEPTH)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb modulation depth out of range"}; - props->Reverb.ModulationDepth = val; + props.ModulationDepth = val; break; case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: if(!(val >= AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb air absorption gainhf out of range"}; - props->Reverb.AirAbsorptionGainHF = val; + props.AirAbsorptionGainHF = val; break; case AL_EAXREVERB_HFREFERENCE: if(!(val >= AL_EAXREVERB_MIN_HFREFERENCE && val <= AL_EAXREVERB_MAX_HFREFERENCE)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb hfreference out of range"}; - props->Reverb.HFReference = val; + props.HFReference = val; break; case AL_EAXREVERB_LFREFERENCE: if(!(val >= AL_EAXREVERB_MIN_LFREFERENCE && val <= AL_EAXREVERB_MAX_LFREFERENCE)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb lfreference out of range"}; - props->Reverb.LFReference = val; + props.LFReference = val; break; case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: if(!(val >= AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR)) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb room rolloff factor out of range"}; - props->Reverb.RoomRolloffFactor = val; + props.RoomRolloffFactor = val; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param}; } } -void Reverb_setParamfv(EffectProps *props, ALenum param, const float *vals) +void EffectHandler::SetParamfv(ReverbProps &props, ALenum param, const float *vals) { switch(param) { case AL_EAXREVERB_REFLECTIONS_PAN: if(!(std::isfinite(vals[0]) && std::isfinite(vals[1]) && std::isfinite(vals[2]))) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections pan out of range"}; - props->Reverb.ReflectionsPan[0] = vals[0]; - props->Reverb.ReflectionsPan[1] = vals[1]; - props->Reverb.ReflectionsPan[2] = vals[2]; + props.ReflectionsPan[0] = vals[0]; + props.ReflectionsPan[1] = vals[1]; + props.ReflectionsPan[2] = vals[2]; break; case AL_EAXREVERB_LATE_REVERB_PAN: if(!(std::isfinite(vals[0]) && std::isfinite(vals[1]) && std::isfinite(vals[2]))) throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb pan out of range"}; - props->Reverb.LateReverbPan[0] = vals[0]; - props->Reverb.LateReverbPan[1] = vals[1]; - props->Reverb.LateReverbPan[2] = vals[2]; + props.LateReverbPan[0] = vals[0]; + props.LateReverbPan[1] = vals[1]; + props.LateReverbPan[2] = vals[2]; break; default: - Reverb_setParamf(props, param, vals[0]); + SetParamf(props, param, vals[0]); break; } } -void Reverb_getParami(const EffectProps *props, ALenum param, int *val) +void EffectHandler::GetParami(const ReverbProps &props, ALenum param, int *val) { switch(param) { case AL_EAXREVERB_DECAY_HFLIMIT: - *val = props->Reverb.DecayHFLimit; + *val = props.DecayHFLimit; break; default: @@ -203,365 +269,214 @@ void Reverb_getParami(const EffectProps *props, ALenum param, int *val) param}; } } -void Reverb_getParamiv(const EffectProps *props, ALenum param, int *vals) -{ Reverb_getParami(props, param, vals); } -void Reverb_getParamf(const EffectProps *props, ALenum param, float *val) +void EffectHandler::GetParamiv(const ReverbProps &props, ALenum param, int *vals) +{ GetParami(props, param, vals); } +void EffectHandler::GetParamf(const ReverbProps &props, ALenum param, float *val) { switch(param) { - case AL_EAXREVERB_DENSITY: - *val = props->Reverb.Density; - break; - - case AL_EAXREVERB_DIFFUSION: - *val = props->Reverb.Diffusion; - break; - - case AL_EAXREVERB_GAIN: - *val = props->Reverb.Gain; - break; - - case AL_EAXREVERB_GAINHF: - *val = props->Reverb.GainHF; - break; - - case AL_EAXREVERB_GAINLF: - *val = props->Reverb.GainLF; - break; - - case AL_EAXREVERB_DECAY_TIME: - *val = props->Reverb.DecayTime; - break; - - case AL_EAXREVERB_DECAY_HFRATIO: - *val = props->Reverb.DecayHFRatio; - break; - - case AL_EAXREVERB_DECAY_LFRATIO: - *val = props->Reverb.DecayLFRatio; - break; - - case AL_EAXREVERB_REFLECTIONS_GAIN: - *val = props->Reverb.ReflectionsGain; - break; - - case AL_EAXREVERB_REFLECTIONS_DELAY: - *val = props->Reverb.ReflectionsDelay; - break; - - case AL_EAXREVERB_LATE_REVERB_GAIN: - *val = props->Reverb.LateReverbGain; - break; - - case AL_EAXREVERB_LATE_REVERB_DELAY: - *val = props->Reverb.LateReverbDelay; - break; - - case AL_EAXREVERB_ECHO_TIME: - *val = props->Reverb.EchoTime; - break; - - case AL_EAXREVERB_ECHO_DEPTH: - *val = props->Reverb.EchoDepth; - break; - - case AL_EAXREVERB_MODULATION_TIME: - *val = props->Reverb.ModulationTime; - break; - - case AL_EAXREVERB_MODULATION_DEPTH: - *val = props->Reverb.ModulationDepth; - break; - - case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: - *val = props->Reverb.AirAbsorptionGainHF; - break; - - case AL_EAXREVERB_HFREFERENCE: - *val = props->Reverb.HFReference; - break; - - case AL_EAXREVERB_LFREFERENCE: - *val = props->Reverb.LFReference; - break; - - case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: - *val = props->Reverb.RoomRolloffFactor; - break; + case AL_EAXREVERB_DENSITY: *val = props.Density; break; + case AL_EAXREVERB_DIFFUSION: *val = props.Diffusion; break; + case AL_EAXREVERB_GAIN: *val = props.Gain; break; + case AL_EAXREVERB_GAINHF: *val = props.GainHF; break; + case AL_EAXREVERB_GAINLF: *val = props.GainLF; break; + case AL_EAXREVERB_DECAY_TIME: *val = props.DecayTime; break; + case AL_EAXREVERB_DECAY_HFRATIO: *val = props.DecayHFRatio; break; + case AL_EAXREVERB_DECAY_LFRATIO: *val = props.DecayLFRatio; break; + case AL_EAXREVERB_REFLECTIONS_GAIN: *val = props.ReflectionsGain; break; + case AL_EAXREVERB_REFLECTIONS_DELAY: *val = props.ReflectionsDelay; break; + case AL_EAXREVERB_LATE_REVERB_GAIN: *val = props.LateReverbGain; break; + case AL_EAXREVERB_LATE_REVERB_DELAY: *val = props.LateReverbDelay; break; + case AL_EAXREVERB_ECHO_TIME: *val = props.EchoTime; break; + case AL_EAXREVERB_ECHO_DEPTH: *val = props.EchoDepth; break; + case AL_EAXREVERB_MODULATION_TIME: *val = props.ModulationTime; break; + case AL_EAXREVERB_MODULATION_DEPTH: *val = props.ModulationDepth; break; + case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: *val = props.AirAbsorptionGainHF; break; + case AL_EAXREVERB_HFREFERENCE: *val = props.HFReference; break; + case AL_EAXREVERB_LFREFERENCE: *val = props.LFReference; break; + case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: *val = props.RoomRolloffFactor; break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param}; } } -void Reverb_getParamfv(const EffectProps *props, ALenum param, float *vals) +void EffectHandler::GetParamfv(const ReverbProps &props, ALenum param, float *vals) { switch(param) { case AL_EAXREVERB_REFLECTIONS_PAN: - vals[0] = props->Reverb.ReflectionsPan[0]; - vals[1] = props->Reverb.ReflectionsPan[1]; - vals[2] = props->Reverb.ReflectionsPan[2]; + vals[0] = props.ReflectionsPan[0]; + vals[1] = props.ReflectionsPan[1]; + vals[2] = props.ReflectionsPan[2]; break; case AL_EAXREVERB_LATE_REVERB_PAN: - vals[0] = props->Reverb.LateReverbPan[0]; - vals[1] = props->Reverb.LateReverbPan[1]; - vals[2] = props->Reverb.LateReverbPan[2]; + vals[0] = props.LateReverbPan[0]; + vals[1] = props.LateReverbPan[1]; + vals[2] = props.LateReverbPan[2]; break; default: - Reverb_getParamf(props, param, vals); + GetParamf(props, param, vals); break; } } -EffectProps genDefaultProps() noexcept -{ - EffectProps props{}; - props.Reverb.Density = AL_EAXREVERB_DEFAULT_DENSITY; - props.Reverb.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION; - props.Reverb.Gain = AL_EAXREVERB_DEFAULT_GAIN; - props.Reverb.GainHF = AL_EAXREVERB_DEFAULT_GAINHF; - props.Reverb.GainLF = AL_EAXREVERB_DEFAULT_GAINLF; - props.Reverb.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME; - props.Reverb.DecayHFRatio = AL_EAXREVERB_DEFAULT_DECAY_HFRATIO; - props.Reverb.DecayLFRatio = AL_EAXREVERB_DEFAULT_DECAY_LFRATIO; - props.Reverb.ReflectionsGain = AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN; - props.Reverb.ReflectionsDelay = AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY; - props.Reverb.ReflectionsPan[0] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; - props.Reverb.ReflectionsPan[1] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; - props.Reverb.ReflectionsPan[2] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; - props.Reverb.LateReverbGain = AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN; - props.Reverb.LateReverbDelay = AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY; - props.Reverb.LateReverbPan[0] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; - props.Reverb.LateReverbPan[1] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; - props.Reverb.LateReverbPan[2] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; - props.Reverb.EchoTime = AL_EAXREVERB_DEFAULT_ECHO_TIME; - props.Reverb.EchoDepth = AL_EAXREVERB_DEFAULT_ECHO_DEPTH; - props.Reverb.ModulationTime = AL_EAXREVERB_DEFAULT_MODULATION_TIME; - props.Reverb.ModulationDepth = AL_EAXREVERB_DEFAULT_MODULATION_DEPTH; - props.Reverb.AirAbsorptionGainHF = AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF; - props.Reverb.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE; - props.Reverb.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE; - props.Reverb.RoomRolloffFactor = AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR; - props.Reverb.DecayHFLimit = AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT; - return props; -} +const EffectProps StdReverbEffectProps{genDefaultStdProps()}; -void StdReverb_setParami(EffectProps *props, ALenum param, int val) +void EffectHandler::StdReverbSetParami(ReverbProps &props, ALenum param, int val) { switch(param) { case AL_REVERB_DECAY_HFLIMIT: if(!(val >= AL_REVERB_MIN_DECAY_HFLIMIT && val <= AL_REVERB_MAX_DECAY_HFLIMIT)) - throw effect_exception{AL_INVALID_VALUE, "Reverb decay hflimit out of range"}; - props->Reverb.DecayHFLimit = val != AL_FALSE; + throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hflimit out of range"}; + props.DecayHFLimit = val != AL_FALSE; break; default: - throw effect_exception{AL_INVALID_ENUM, "Invalid reverb integer property 0x%04x", param}; + throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x", + param}; } } -void StdReverb_setParamiv(EffectProps *props, ALenum param, const int *vals) -{ StdReverb_setParami(props, param, vals[0]); } -void StdReverb_setParamf(EffectProps *props, ALenum param, float val) +void EffectHandler::StdReverbSetParamiv(ReverbProps &props, ALenum param, const int *vals) +{ StdReverbSetParami(props, param, vals[0]); } +void EffectHandler::StdReverbSetParamf(ReverbProps &props, ALenum param, float val) { switch(param) { case AL_REVERB_DENSITY: if(!(val >= AL_REVERB_MIN_DENSITY && val <= AL_REVERB_MAX_DENSITY)) - throw effect_exception{AL_INVALID_VALUE, "Reverb density out of range"}; - props->Reverb.Density = val; + throw effect_exception{AL_INVALID_VALUE, "EAX Reverb density out of range"}; + props.Density = val; break; case AL_REVERB_DIFFUSION: if(!(val >= AL_REVERB_MIN_DIFFUSION && val <= AL_REVERB_MAX_DIFFUSION)) - throw effect_exception{AL_INVALID_VALUE, "Reverb diffusion out of range"}; - props->Reverb.Diffusion = val; + throw effect_exception{AL_INVALID_VALUE, "EAX Reverb diffusion out of range"}; + props.Diffusion = val; break; case AL_REVERB_GAIN: if(!(val >= AL_REVERB_MIN_GAIN && val <= AL_REVERB_MAX_GAIN)) - throw effect_exception{AL_INVALID_VALUE, "Reverb gain out of range"}; - props->Reverb.Gain = val; + throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gain out of range"}; + props.Gain = val; break; case AL_REVERB_GAINHF: if(!(val >= AL_REVERB_MIN_GAINHF && val <= AL_REVERB_MAX_GAINHF)) - throw effect_exception{AL_INVALID_VALUE, "Reverb gainhf out of range"}; - props->Reverb.GainHF = val; + throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gainhf out of range"}; + props.GainHF = val; break; case AL_REVERB_DECAY_TIME: if(!(val >= AL_REVERB_MIN_DECAY_TIME && val <= AL_REVERB_MAX_DECAY_TIME)) - throw effect_exception{AL_INVALID_VALUE, "Reverb decay time out of range"}; - props->Reverb.DecayTime = val; + throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay time out of range"}; + props.DecayTime = val; break; case AL_REVERB_DECAY_HFRATIO: if(!(val >= AL_REVERB_MIN_DECAY_HFRATIO && val <= AL_REVERB_MAX_DECAY_HFRATIO)) - throw effect_exception{AL_INVALID_VALUE, "Reverb decay hfratio out of range"}; - props->Reverb.DecayHFRatio = val; + throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hfratio out of range"}; + props.DecayHFRatio = val; break; case AL_REVERB_REFLECTIONS_GAIN: if(!(val >= AL_REVERB_MIN_REFLECTIONS_GAIN && val <= AL_REVERB_MAX_REFLECTIONS_GAIN)) - throw effect_exception{AL_INVALID_VALUE, "Reverb reflections gain out of range"}; - props->Reverb.ReflectionsGain = val; + throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections gain out of range"}; + props.ReflectionsGain = val; break; case AL_REVERB_REFLECTIONS_DELAY: if(!(val >= AL_REVERB_MIN_REFLECTIONS_DELAY && val <= AL_REVERB_MAX_REFLECTIONS_DELAY)) - throw effect_exception{AL_INVALID_VALUE, "Reverb reflections delay out of range"}; - props->Reverb.ReflectionsDelay = val; + throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections delay out of range"}; + props.ReflectionsDelay = val; break; case AL_REVERB_LATE_REVERB_GAIN: if(!(val >= AL_REVERB_MIN_LATE_REVERB_GAIN && val <= AL_REVERB_MAX_LATE_REVERB_GAIN)) - throw effect_exception{AL_INVALID_VALUE, "Reverb late reverb gain out of range"}; - props->Reverb.LateReverbGain = val; + throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb gain out of range"}; + props.LateReverbGain = val; break; case AL_REVERB_LATE_REVERB_DELAY: if(!(val >= AL_REVERB_MIN_LATE_REVERB_DELAY && val <= AL_REVERB_MAX_LATE_REVERB_DELAY)) - throw effect_exception{AL_INVALID_VALUE, "Reverb late reverb delay out of range"}; - props->Reverb.LateReverbDelay = val; + throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb delay out of range"}; + props.LateReverbDelay = val; break; case AL_REVERB_AIR_ABSORPTION_GAINHF: if(!(val >= AL_REVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_REVERB_MAX_AIR_ABSORPTION_GAINHF)) - throw effect_exception{AL_INVALID_VALUE, "Reverb air absorption gainhf out of range"}; - props->Reverb.AirAbsorptionGainHF = val; + throw effect_exception{AL_INVALID_VALUE, "EAX Reverb air absorption gainhf out of range"}; + props.AirAbsorptionGainHF = val; break; case AL_REVERB_ROOM_ROLLOFF_FACTOR: if(!(val >= AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR)) - throw effect_exception{AL_INVALID_VALUE, "Reverb room rolloff factor out of range"}; - props->Reverb.RoomRolloffFactor = val; + throw effect_exception{AL_INVALID_VALUE, "EAX Reverb room rolloff factor out of range"}; + props.RoomRolloffFactor = val; break; default: - throw effect_exception{AL_INVALID_ENUM, "Invalid reverb float property 0x%04x", param}; + throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param}; + } +} +void EffectHandler::StdReverbSetParamfv(ReverbProps &props, ALenum param, const float *vals) +{ + switch(param) + { + default: + StdReverbSetParamf(props, param, vals[0]); + break; } } -void StdReverb_setParamfv(EffectProps *props, ALenum param, const float *vals) -{ StdReverb_setParamf(props, param, vals[0]); } -void StdReverb_getParami(const EffectProps *props, ALenum param, int *val) +void EffectHandler::StdReverbGetParami(const ReverbProps &props, ALenum param, int *val) { switch(param) { case AL_REVERB_DECAY_HFLIMIT: - *val = props->Reverb.DecayHFLimit; + *val = props.DecayHFLimit; break; default: - throw effect_exception{AL_INVALID_ENUM, "Invalid reverb integer property 0x%04x", param}; + throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x", + param}; } } -void StdReverb_getParamiv(const EffectProps *props, ALenum param, int *vals) -{ StdReverb_getParami(props, param, vals); } -void StdReverb_getParamf(const EffectProps *props, ALenum param, float *val) +void EffectHandler::StdReverbGetParamiv(const ReverbProps &props, ALenum param, int *vals) +{ StdReverbGetParami(props, param, vals); } +void EffectHandler::StdReverbGetParamf(const ReverbProps &props, ALenum param, float *val) { switch(param) { - case AL_REVERB_DENSITY: - *val = props->Reverb.Density; - break; - - case AL_REVERB_DIFFUSION: - *val = props->Reverb.Diffusion; - break; - - case AL_REVERB_GAIN: - *val = props->Reverb.Gain; - break; - - case AL_REVERB_GAINHF: - *val = props->Reverb.GainHF; - break; - - case AL_REVERB_DECAY_TIME: - *val = props->Reverb.DecayTime; - break; - - case AL_REVERB_DECAY_HFRATIO: - *val = props->Reverb.DecayHFRatio; - break; - - case AL_REVERB_REFLECTIONS_GAIN: - *val = props->Reverb.ReflectionsGain; - break; - - case AL_REVERB_REFLECTIONS_DELAY: - *val = props->Reverb.ReflectionsDelay; - break; - - case AL_REVERB_LATE_REVERB_GAIN: - *val = props->Reverb.LateReverbGain; - break; - - case AL_REVERB_LATE_REVERB_DELAY: - *val = props->Reverb.LateReverbDelay; - break; - - case AL_REVERB_AIR_ABSORPTION_GAINHF: - *val = props->Reverb.AirAbsorptionGainHF; - break; - - case AL_REVERB_ROOM_ROLLOFF_FACTOR: - *val = props->Reverb.RoomRolloffFactor; - break; + case AL_REVERB_DENSITY: *val = props.Density; break; + case AL_REVERB_DIFFUSION: *val = props.Diffusion; break; + case AL_REVERB_GAIN: *val = props.Gain; break; + case AL_REVERB_GAINHF: *val = props.GainHF; break; + case AL_REVERB_DECAY_TIME: *val = props.DecayTime; break; + case AL_REVERB_DECAY_HFRATIO: *val = props.DecayHFRatio; break; + case AL_REVERB_REFLECTIONS_GAIN: *val = props.ReflectionsGain; break; + case AL_REVERB_REFLECTIONS_DELAY: *val = props.ReflectionsDelay; break; + case AL_REVERB_LATE_REVERB_GAIN: *val = props.LateReverbGain; break; + case AL_REVERB_LATE_REVERB_DELAY: *val = props.LateReverbDelay; break; + case AL_REVERB_AIR_ABSORPTION_GAINHF: *val = props.AirAbsorptionGainHF; break; + case AL_REVERB_ROOM_ROLLOFF_FACTOR: *val = props.RoomRolloffFactor; break; default: - throw effect_exception{AL_INVALID_ENUM, "Invalid reverb float property 0x%04x", param}; + throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param}; } } -void StdReverb_getParamfv(const EffectProps *props, ALenum param, float *vals) -{ StdReverb_getParamf(props, param, vals); } - -EffectProps genDefaultStdProps() noexcept +void EffectHandler::StdReverbGetParamfv(const ReverbProps &props, ALenum param, float *vals) { - EffectProps props{}; - props.Reverb.Density = AL_REVERB_DEFAULT_DENSITY; - props.Reverb.Diffusion = AL_REVERB_DEFAULT_DIFFUSION; - props.Reverb.Gain = AL_REVERB_DEFAULT_GAIN; - props.Reverb.GainHF = AL_REVERB_DEFAULT_GAINHF; - props.Reverb.GainLF = 1.0f; - props.Reverb.DecayTime = AL_REVERB_DEFAULT_DECAY_TIME; - props.Reverb.DecayHFRatio = AL_REVERB_DEFAULT_DECAY_HFRATIO; - props.Reverb.DecayLFRatio = 1.0f; - props.Reverb.ReflectionsGain = AL_REVERB_DEFAULT_REFLECTIONS_GAIN; - props.Reverb.ReflectionsDelay = AL_REVERB_DEFAULT_REFLECTIONS_DELAY; - props.Reverb.ReflectionsPan[0] = 0.0f; - props.Reverb.ReflectionsPan[1] = 0.0f; - props.Reverb.ReflectionsPan[2] = 0.0f; - props.Reverb.LateReverbGain = AL_REVERB_DEFAULT_LATE_REVERB_GAIN; - props.Reverb.LateReverbDelay = AL_REVERB_DEFAULT_LATE_REVERB_DELAY; - props.Reverb.LateReverbPan[0] = 0.0f; - props.Reverb.LateReverbPan[1] = 0.0f; - props.Reverb.LateReverbPan[2] = 0.0f; - props.Reverb.EchoTime = 0.25f; - props.Reverb.EchoDepth = 0.0f; - props.Reverb.ModulationTime = 0.25f; - props.Reverb.ModulationDepth = 0.0f; - props.Reverb.AirAbsorptionGainHF = AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF; - props.Reverb.HFReference = 5000.0f; - props.Reverb.LFReference = 250.0f; - props.Reverb.RoomRolloffFactor = AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR; - props.Reverb.DecayHFLimit = AL_REVERB_DEFAULT_DECAY_HFLIMIT; - return props; + switch(param) + { + default: + StdReverbGetParamf(props, param, vals); + break; + } } -} // namespace - -DEFINE_ALEFFECT_VTABLE(Reverb); - -const EffectProps ReverbEffectProps{genDefaultProps()}; - -DEFINE_ALEFFECT_VTABLE(StdReverb); - -const EffectProps StdReverbEffectProps{genDefaultStdProps()}; #ifdef ALSOFT_EAX namespace { @@ -1138,33 +1053,35 @@ bool EaxReverbCommitter::commit(const EAXREVERBPROPERTIES &props) const auto size = props.flEnvironmentSize; const auto density = (size * size * size) / 16.0f; - mAlProps.Reverb.Density = std::min(density, AL_EAXREVERB_MAX_DENSITY); - mAlProps.Reverb.Diffusion = props.flEnvironmentDiffusion; - mAlProps.Reverb.Gain = level_mb_to_gain(static_cast(props.lRoom)); - mAlProps.Reverb.GainHF = level_mb_to_gain(static_cast(props.lRoomHF)); - mAlProps.Reverb.GainLF = level_mb_to_gain(static_cast(props.lRoomLF)); - mAlProps.Reverb.DecayTime = props.flDecayTime; - mAlProps.Reverb.DecayHFRatio = props.flDecayHFRatio; - mAlProps.Reverb.DecayLFRatio = props.flDecayLFRatio; - mAlProps.Reverb.ReflectionsGain = level_mb_to_gain(static_cast(props.lReflections)); - mAlProps.Reverb.ReflectionsDelay = props.flReflectionsDelay; - mAlProps.Reverb.ReflectionsPan[0] = props.vReflectionsPan.x; - mAlProps.Reverb.ReflectionsPan[1] = props.vReflectionsPan.y; - mAlProps.Reverb.ReflectionsPan[2] = props.vReflectionsPan.z; - mAlProps.Reverb.LateReverbGain = level_mb_to_gain(static_cast(props.lReverb)); - mAlProps.Reverb.LateReverbDelay = props.flReverbDelay; - mAlProps.Reverb.LateReverbPan[0] = props.vReverbPan.x; - mAlProps.Reverb.LateReverbPan[1] = props.vReverbPan.y; - mAlProps.Reverb.LateReverbPan[2] = props.vReverbPan.z; - mAlProps.Reverb.EchoTime = props.flEchoTime; - mAlProps.Reverb.EchoDepth = props.flEchoDepth; - mAlProps.Reverb.ModulationTime = props.flModulationTime; - mAlProps.Reverb.ModulationDepth = props.flModulationDepth; - mAlProps.Reverb.AirAbsorptionGainHF = level_mb_to_gain(props.flAirAbsorptionHF); - mAlProps.Reverb.HFReference = props.flHFReference; - mAlProps.Reverb.LFReference = props.flLFReference; - mAlProps.Reverb.RoomRolloffFactor = props.flRoomRolloffFactor; - mAlProps.Reverb.DecayHFLimit = ((props.ulFlags & EAXREVERBFLAGS_DECAYHFLIMIT) != 0); + mAlProps = [&]{ + ReverbProps ret{}; + ret.Density = std::min(density, AL_EAXREVERB_MAX_DENSITY); + ret.Diffusion = props.flEnvironmentDiffusion; + ret.Gain = level_mb_to_gain(static_cast(props.lRoom)); + ret.GainHF = level_mb_to_gain(static_cast(props.lRoomHF)); + ret.GainLF = level_mb_to_gain(static_cast(props.lRoomLF)); + ret.DecayTime = props.flDecayTime; + ret.DecayHFRatio = props.flDecayHFRatio; + ret.DecayLFRatio = props.flDecayLFRatio; + ret.ReflectionsGain = level_mb_to_gain(static_cast(props.lReflections)); + ret.ReflectionsDelay = props.flReflectionsDelay; + ret.ReflectionsPan = {props.vReflectionsPan.x, props.vReflectionsPan.y, + props.vReflectionsPan.z}; + ret.LateReverbGain = level_mb_to_gain(static_cast(props.lReverb)); + ret.LateReverbDelay = props.flReverbDelay; + ret.LateReverbPan = {props.vReverbPan.x, props.vReverbPan.y, props.vReverbPan.z}; + ret.EchoTime = props.flEchoTime; + ret.EchoDepth = props.flEchoDepth; + ret.ModulationTime = props.flModulationTime; + ret.ModulationDepth = props.flModulationDepth; + ret.AirAbsorptionGainHF = level_mb_to_gain(props.flAirAbsorptionHF); + ret.HFReference = props.flHFReference; + ret.LFReference = props.flLFReference; + ret.RoomRolloffFactor = props.flRoomRolloffFactor; + ret.DecayHFLimit = ((props.ulFlags & EAXREVERBFLAGS_DECAYHFLIMIT) != 0); + return ret; + }(); + return true; } diff --git a/al/effects/vmorpher.cpp b/al/effects/vmorpher.cpp index 240c7b54..a986ddf7 100644 --- a/al/effects/vmorpher.cpp +++ b/al/effects/vmorpher.cpp @@ -122,13 +122,29 @@ ALenum EnumFromWaveform(VMorpherWaveform type) std::to_string(static_cast(type))}; } -void Vmorpher_setParami(EffectProps *props, ALenum param, int val) +EffectProps genDefaultProps() noexcept +{ + VmorpherProps props{}; + props.Rate = AL_VOCAL_MORPHER_DEFAULT_RATE; + props.PhonemeA = *PhenomeFromEnum(AL_VOCAL_MORPHER_DEFAULT_PHONEMEA); + props.PhonemeB = *PhenomeFromEnum(AL_VOCAL_MORPHER_DEFAULT_PHONEMEB); + props.PhonemeACoarseTuning = AL_VOCAL_MORPHER_DEFAULT_PHONEMEA_COARSE_TUNING; + props.PhonemeBCoarseTuning = AL_VOCAL_MORPHER_DEFAULT_PHONEMEB_COARSE_TUNING; + props.Waveform = *WaveformFromEmum(AL_VOCAL_MORPHER_DEFAULT_WAVEFORM); + return props; +} + +} // namespace + +const EffectProps VmorpherEffectProps{genDefaultProps()}; + +void EffectHandler::SetParami(VmorpherProps &props, ALenum param, int val) { switch(param) { case AL_VOCAL_MORPHER_PHONEMEA: if(auto phenomeopt = PhenomeFromEnum(val)) - props->Vmorpher.PhonemeA = *phenomeopt; + props.PhonemeA = *phenomeopt; else throw effect_exception{AL_INVALID_VALUE, "Vocal morpher phoneme-a out of range: 0x%04x", val}; break; @@ -136,12 +152,12 @@ void Vmorpher_setParami(EffectProps *props, ALenum param, int val) case AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING: if(!(val >= AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING && val <= AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING)) throw effect_exception{AL_INVALID_VALUE, "Vocal morpher phoneme-a coarse tuning out of range"}; - props->Vmorpher.PhonemeACoarseTuning = val; + props.PhonemeACoarseTuning = val; break; case AL_VOCAL_MORPHER_PHONEMEB: if(auto phenomeopt = PhenomeFromEnum(val)) - props->Vmorpher.PhonemeB = *phenomeopt; + props.PhonemeB = *phenomeopt; else throw effect_exception{AL_INVALID_VALUE, "Vocal morpher phoneme-b out of range: 0x%04x", val}; break; @@ -149,12 +165,12 @@ void Vmorpher_setParami(EffectProps *props, ALenum param, int val) case AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING: if(!(val >= AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING && val <= AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING)) throw effect_exception{AL_INVALID_VALUE, "Vocal morpher phoneme-b coarse tuning out of range"}; - props->Vmorpher.PhonemeBCoarseTuning = val; + props.PhonemeBCoarseTuning = val; break; case AL_VOCAL_MORPHER_WAVEFORM: if(auto formopt = WaveformFromEmum(val)) - props->Vmorpher.Waveform = *formopt; + props.Waveform = *formopt; else throw effect_exception{AL_INVALID_VALUE, "Vocal morpher waveform out of range: 0x%04x", val}; break; @@ -164,19 +180,19 @@ void Vmorpher_setParami(EffectProps *props, ALenum param, int val) param}; } } -void Vmorpher_setParamiv(EffectProps*, ALenum param, const int*) +void EffectHandler::SetParamiv(VmorpherProps&, ALenum param, const int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher integer-vector property 0x%04x", param}; } -void Vmorpher_setParamf(EffectProps *props, ALenum param, float val) +void EffectHandler::SetParamf(VmorpherProps &props, ALenum param, float val) { switch(param) { case AL_VOCAL_MORPHER_RATE: if(!(val >= AL_VOCAL_MORPHER_MIN_RATE && val <= AL_VOCAL_MORPHER_MAX_RATE)) throw effect_exception{AL_INVALID_VALUE, "Vocal morpher rate out of range"}; - props->Vmorpher.Rate = val; + props.Rate = val; break; default: @@ -184,49 +200,35 @@ void Vmorpher_setParamf(EffectProps *props, ALenum param, float val) param}; } } -void Vmorpher_setParamfv(EffectProps *props, ALenum param, const float *vals) -{ Vmorpher_setParamf(props, param, vals[0]); } +void EffectHandler::SetParamfv(VmorpherProps &props, ALenum param, const float *vals) +{ SetParamf(props, param, vals[0]); } -void Vmorpher_getParami(const EffectProps *props, ALenum param, int* val) +void EffectHandler::GetParami(const VmorpherProps &props, ALenum param, int* val) { switch(param) { - case AL_VOCAL_MORPHER_PHONEMEA: - *val = EnumFromPhenome(props->Vmorpher.PhonemeA); - break; - - case AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING: - *val = props->Vmorpher.PhonemeACoarseTuning; - break; - - case AL_VOCAL_MORPHER_PHONEMEB: - *val = EnumFromPhenome(props->Vmorpher.PhonemeB); - break; - - case AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING: - *val = props->Vmorpher.PhonemeBCoarseTuning; - break; - - case AL_VOCAL_MORPHER_WAVEFORM: - *val = EnumFromWaveform(props->Vmorpher.Waveform); - break; + case AL_VOCAL_MORPHER_PHONEMEA: *val = EnumFromPhenome(props.PhonemeA); break; + case AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING: *val = props.PhonemeACoarseTuning; break; + case AL_VOCAL_MORPHER_PHONEMEB: *val = EnumFromPhenome(props.PhonemeB); break; + case AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING: *val = props.PhonemeBCoarseTuning; break; + case AL_VOCAL_MORPHER_WAVEFORM: *val = EnumFromWaveform(props.Waveform); break; default: throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher integer property 0x%04x", param}; } } -void Vmorpher_getParamiv(const EffectProps*, ALenum param, int*) +void EffectHandler::GetParamiv(const VmorpherProps&, ALenum param, int*) { throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher integer-vector property 0x%04x", param}; } -void Vmorpher_getParamf(const EffectProps *props, ALenum param, float *val) +void EffectHandler::GetParamf(const VmorpherProps &props, ALenum param, float *val) { switch(param) { case AL_VOCAL_MORPHER_RATE: - *val = props->Vmorpher.Rate; + *val = props.Rate; break; default: @@ -234,26 +236,9 @@ void Vmorpher_getParamf(const EffectProps *props, ALenum param, float *val) param}; } } -void Vmorpher_getParamfv(const EffectProps *props, ALenum param, float *vals) -{ Vmorpher_getParamf(props, param, vals); } - -EffectProps genDefaultProps() noexcept -{ - EffectProps props{}; - props.Vmorpher.Rate = AL_VOCAL_MORPHER_DEFAULT_RATE; - props.Vmorpher.PhonemeA = *PhenomeFromEnum(AL_VOCAL_MORPHER_DEFAULT_PHONEMEA); - props.Vmorpher.PhonemeB = *PhenomeFromEnum(AL_VOCAL_MORPHER_DEFAULT_PHONEMEB); - props.Vmorpher.PhonemeACoarseTuning = AL_VOCAL_MORPHER_DEFAULT_PHONEMEA_COARSE_TUNING; - props.Vmorpher.PhonemeBCoarseTuning = AL_VOCAL_MORPHER_DEFAULT_PHONEMEB_COARSE_TUNING; - props.Vmorpher.Waveform = *WaveformFromEmum(AL_VOCAL_MORPHER_DEFAULT_WAVEFORM); - return props; -} - -} // namespace - -DEFINE_ALEFFECT_VTABLE(Vmorpher); +void EffectHandler::GetParamfv(const VmorpherProps &props, ALenum param, float *vals) +{ GetParamf(props, param, vals); } -const EffectProps VmorpherEffectProps{genDefaultProps()}; #ifdef ALSOFT_EAX namespace { @@ -406,12 +391,16 @@ bool EaxVocalMorpherCommitter::commit(const EAXVOCALMORPHERPROPERTIES &props) return VMorpherWaveform::Sinusoid; }; - mAlProps.Vmorpher.PhonemeA = get_phoneme(props.ulPhonemeA); - mAlProps.Vmorpher.PhonemeACoarseTuning = static_cast(props.lPhonemeACoarseTuning); - mAlProps.Vmorpher.PhonemeB = get_phoneme(props.ulPhonemeB); - mAlProps.Vmorpher.PhonemeBCoarseTuning = static_cast(props.lPhonemeBCoarseTuning); - mAlProps.Vmorpher.Waveform = get_waveform(props.ulWaveform); - mAlProps.Vmorpher.Rate = props.flRate; + mAlProps = [&]{ + VmorpherProps ret{}; + ret.PhonemeA = get_phoneme(props.ulPhonemeA); + ret.PhonemeACoarseTuning = static_cast(props.lPhonemeACoarseTuning); + ret.PhonemeB = get_phoneme(props.ulPhonemeB); + ret.PhonemeBCoarseTuning = static_cast(props.lPhonemeBCoarseTuning); + ret.Waveform = get_waveform(props.ulWaveform); + ret.Rate = props.flRate; + return ret; + }(); return true; } diff --git a/alc/alu.cpp b/alc/alu.cpp index 3b4c659f..eb3dee5f 100644 --- a/alc/alu.cpp +++ b/alc/alu.cpp @@ -450,14 +450,14 @@ bool CalcEffectSlotParams(EffectSlot *slot, EffectSlot **sorted_slots, ContextBa slot->Target = props->Target; slot->EffectType = props->Type; slot->mEffectProps = props->Props; - if(props->Type == EffectSlotType::Reverb || props->Type == EffectSlotType::EAXReverb) + if(auto *reverbprops = std::get_if(&props->Props)) { - slot->RoomRolloff = props->Props.Reverb.RoomRolloffFactor; - slot->DecayTime = props->Props.Reverb.DecayTime; - slot->DecayLFRatio = props->Props.Reverb.DecayLFRatio; - slot->DecayHFRatio = props->Props.Reverb.DecayHFRatio; - slot->DecayHFLimit = props->Props.Reverb.DecayHFLimit; - slot->AirAbsorptionGainHF = props->Props.Reverb.AirAbsorptionGainHF; + slot->RoomRolloff = reverbprops->RoomRolloffFactor; + slot->DecayTime = reverbprops->DecayTime; + slot->DecayLFRatio = reverbprops->DecayLFRatio; + slot->DecayHFRatio = reverbprops->DecayHFRatio; + slot->DecayHFLimit = reverbprops->DecayHFLimit; + slot->AirAbsorptionGainHF = reverbprops->AirAbsorptionGainHF; } else { diff --git a/alc/effects/autowah.cpp b/alc/effects/autowah.cpp index e9e14e35..424230e8 100644 --- a/alc/effects/autowah.cpp +++ b/alc/effects/autowah.cpp @@ -118,18 +118,19 @@ void AutowahState::deviceUpdate(const DeviceBase*, const BufferStorage*) } void AutowahState::update(const ContextBase *context, const EffectSlot *slot, - const EffectProps *props, const EffectTarget target) + const EffectProps *props_, const EffectTarget target) { + auto &props = std::get(*props_); const DeviceBase *device{context->mDevice}; const auto frequency = static_cast(device->Frequency); - const float ReleaseTime{clampf(props->Autowah.ReleaseTime, 0.001f, 1.0f)}; + const float ReleaseTime{clampf(props.ReleaseTime, 0.001f, 1.0f)}; - mAttackRate = std::exp(-1.0f / (props->Autowah.AttackTime*frequency)); + mAttackRate = std::exp(-1.0f / (props.AttackTime*frequency)); mReleaseRate = std::exp(-1.0f / (ReleaseTime*frequency)); /* 0-20dB Resonance Peak gain */ - mResonanceGain = std::sqrt(std::log10(props->Autowah.Resonance)*10.0f / 3.0f); - mPeakGain = 1.0f - std::log10(props->Autowah.PeakGain / GainScale); + mResonanceGain = std::sqrt(std::log10(props.Resonance)*10.0f / 3.0f); + mPeakGain = 1.0f - std::log10(props.PeakGain / GainScale); mFreqMinNorm = MinFreq / frequency; mBandwidthNorm = (MaxFreq-MinFreq) / frequency; diff --git a/alc/effects/chorus.cpp b/alc/effects/chorus.cpp index 52aaa9a6..bc6ddaf0 100644 --- a/alc/effects/chorus.cpp +++ b/alc/effects/chorus.cpp @@ -93,11 +93,12 @@ struct ChorusState : public EffectState { void deviceUpdate(const DeviceBase *device, const BufferStorage*) override { deviceUpdate(device, ChorusMaxDelay); } - void update(const ContextBase *context, const EffectSlot *slot, const EffectProps *props, + void update(const ContextBase *context, const EffectSlot *slot, const EffectProps *props_, const EffectTarget target) override { - update(context, slot, props->Chorus.Waveform, props->Chorus.Delay, props->Chorus.Depth, - props->Chorus.Feedback, props->Chorus.Rate, props->Chorus.Phase, target); + auto &props = std::get(*props_); + update(context, slot, props.Waveform, props.Delay, props.Depth, props.Feedback, props.Rate, + props.Phase, target); } void process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) final; @@ -106,12 +107,12 @@ struct ChorusState : public EffectState { struct FlangerState final : public ChorusState { void deviceUpdate(const DeviceBase *device, const BufferStorage*) final { ChorusState::deviceUpdate(device, FlangerMaxDelay); } - void update(const ContextBase *context, const EffectSlot *slot, const EffectProps *props, + void update(const ContextBase *context, const EffectSlot *slot, const EffectProps *props_, const EffectTarget target) final { - ChorusState::update(context, slot, props->Flanger.Waveform, props->Flanger.Delay, - props->Flanger.Depth, props->Flanger.Feedback, props->Flanger.Rate, - props->Flanger.Phase, target); + auto &props = std::get(*props_); + ChorusState::update(context, slot, props.Waveform, props.Delay, props.Depth, + props.Feedback, props.Rate, props.Phase, target); } }; diff --git a/alc/effects/compressor.cpp b/alc/effects/compressor.cpp index eb8605ce..717b6dd2 100644 --- a/alc/effects/compressor.cpp +++ b/alc/effects/compressor.cpp @@ -102,7 +102,7 @@ void CompressorState::deviceUpdate(const DeviceBase *device, const BufferStorage void CompressorState::update(const ContextBase*, const EffectSlot *slot, const EffectProps *props, const EffectTarget target) { - mEnabled = props->Compressor.OnOff; + mEnabled = std::get(*props).OnOff; mOutTarget = target.Main->Buffer; auto set_channel = [this](size_t idx, uint outchan, float outgain) diff --git a/alc/effects/convolution.cpp b/alc/effects/convolution.cpp index f497ebce..3f3e157c 100644 --- a/alc/effects/convolution.cpp +++ b/alc/effects/convolution.cpp @@ -401,7 +401,7 @@ void ConvolutionState::deviceUpdate(const DeviceBase *device, const BufferStorag void ConvolutionState::update(const ContextBase *context, const EffectSlot *slot, - const EffectProps *props, const EffectTarget target) + const EffectProps *props_, const EffectTarget target) { /* TODO: LFE is not mixed to output. This will require each buffer channel * to have its own output target since the main mixing buffer won't have an @@ -455,6 +455,7 @@ void ConvolutionState::update(const ContextBase *context, const EffectSlot *slot if(mNumConvolveSegs < 1) UNLIKELY return; + auto &props = std::get(*props_); mMix = &ConvolutionState::NormalMix; for(auto &chan : mChans) @@ -488,11 +489,9 @@ void ConvolutionState::update(const ContextBase *context, const EffectSlot *slot } mOutTarget = target.Main->Buffer; - alu::Vector N{props->Convolution.OrientAt[0], props->Convolution.OrientAt[1], - props->Convolution.OrientAt[2], 0.0f}; + alu::Vector N{props.OrientAt[0], props.OrientAt[1], props.OrientAt[2], 0.0f}; N.normalize(); - alu::Vector V{props->Convolution.OrientUp[0], props->Convolution.OrientUp[1], - props->Convolution.OrientUp[2], 0.0f}; + alu::Vector V{props.OrientUp[0], props.OrientUp[1], props.OrientUp[2], 0.0f}; V.normalize(); /* Build and normalize right-vector */ alu::Vector U{N.cross_product(V)}; diff --git a/alc/effects/dedicated.cpp b/alc/effects/dedicated.cpp index 1629aaea..23ac4d1a 100644 --- a/alc/effects/dedicated.cpp +++ b/alc/effects/dedicated.cpp @@ -73,7 +73,7 @@ void DedicatedState::update(const ContextBase*, const EffectSlot *slot, { std::fill(mTargetGains.begin(), mTargetGains.end(), 0.0f); - const float Gain{slot->Gain * props->DedicatedDialog.Gain}; + const float Gain{slot->Gain * std::get(*props).Gain}; /* Dialog goes to the front-center speaker if it exists, otherwise it plays * from the front-center location. @@ -99,7 +99,7 @@ void DedicatedLfeState::update(const ContextBase*, const EffectSlot *slot, { std::fill(mTargetGains.begin(), mTargetGains.end(), 0.0f); - const float Gain{slot->Gain * props->DedicatedLfe.Gain}; + const float Gain{slot->Gain * std::get(*props).Gain}; const size_t idx{target.RealOut ? target.RealOut->ChannelIndex[LFE] : InvalidChannelIndex}; if(idx != InvalidChannelIndex) diff --git a/alc/effects/distortion.cpp b/alc/effects/distortion.cpp index 5e8253e8..d0946971 100644 --- a/alc/effects/distortion.cpp +++ b/alc/effects/distortion.cpp @@ -70,16 +70,17 @@ void DistortionState::deviceUpdate(const DeviceBase*, const BufferStorage*) } void DistortionState::update(const ContextBase *context, const EffectSlot *slot, - const EffectProps *props, const EffectTarget target) + const EffectProps *props_, const EffectTarget target) { + auto &props = std::get(*props_); const DeviceBase *device{context->mDevice}; /* Store waveshaper edge settings. */ - const float edge{minf(std::sin(al::numbers::pi_v*0.5f * props->Distortion.Edge), + const float edge{minf(std::sin(al::numbers::pi_v*0.5f * props.Edge), 0.99f)}; mEdgeCoeff = 2.0f * edge / (1.0f-edge); - float cutoff{props->Distortion.LowpassCutoff}; + float cutoff{props.LowpassCutoff}; /* Bandwidth value is constant in octaves. */ float bandwidth{(cutoff / 2.0f) / (cutoff * 0.67f)}; /* Divide normalized frequency by the amount of oversampling done during @@ -88,15 +89,15 @@ void DistortionState::update(const ContextBase *context, const EffectSlot *slot, auto frequency = static_cast(device->Frequency); mLowpass.setParamsFromBandwidth(BiquadType::LowPass, cutoff/frequency/4.0f, 1.0f, bandwidth); - cutoff = props->Distortion.EQCenter; + cutoff = props.EQCenter; /* Convert bandwidth in Hz to octaves. */ - bandwidth = props->Distortion.EQBandwidth / (cutoff * 0.67f); + bandwidth = props.EQBandwidth / (cutoff * 0.67f); mBandpass.setParamsFromBandwidth(BiquadType::BandPass, cutoff/frequency/4.0f, 1.0f, bandwidth); static constexpr auto coeffs = CalcDirectionCoeffs(std::array{0.0f, 0.0f, -1.0f}); mOutTarget = target.Main->Buffer; - ComputePanGains(target.Main, coeffs, slot->Gain*props->Distortion.Gain, mGain); + ComputePanGains(target.Main, coeffs, slot->Gain*props.Gain, mGain); } void DistortionState::process(const size_t samplesToDo, const al::span samplesIn, const al::span samplesOut) diff --git a/alc/effects/echo.cpp b/alc/effects/echo.cpp index 2f3343e8..a5bfa6a5 100644 --- a/alc/effects/echo.cpp +++ b/alc/effects/echo.cpp @@ -95,21 +95,22 @@ void EchoState::deviceUpdate(const DeviceBase *Device, const BufferStorage*) } void EchoState::update(const ContextBase *context, const EffectSlot *slot, - const EffectProps *props, const EffectTarget target) + const EffectProps *props_, const EffectTarget target) { + auto &props = std::get(*props_); const DeviceBase *device{context->mDevice}; const auto frequency = static_cast(device->Frequency); - mDelayTap[0] = maxu(float2uint(props->Echo.Delay*frequency + 0.5f), 1); - mDelayTap[1] = float2uint(props->Echo.LRDelay*frequency + 0.5f) + mDelayTap[0]; + mDelayTap[0] = maxu(float2uint(props.Delay*frequency + 0.5f), 1); + mDelayTap[1] = float2uint(props.LRDelay*frequency + 0.5f) + mDelayTap[0]; - const float gainhf{maxf(1.0f - props->Echo.Damping, 0.0625f)}; /* Limit -24dB */ + const float gainhf{maxf(1.0f - props.Damping, 0.0625f)}; /* Limit -24dB */ mFilter.setParamsFromSlope(BiquadType::HighShelf, LowpassFreqRef/frequency, gainhf, 1.0f); - mFeedGain = props->Echo.Feedback; + mFeedGain = props.Feedback; /* Convert echo spread (where 0 = center, +/-1 = sides) to angle. */ - const float angle{std::asin(props->Echo.Spread)}; + const float angle{std::asin(props.Spread)}; const auto coeffs0 = CalcAngleCoeffs(-angle, 0.0f, 0.0f); const auto coeffs1 = CalcAngleCoeffs( angle, 0.0f, 0.0f); diff --git a/alc/effects/equalizer.cpp b/alc/effects/equalizer.cpp index 9cb42470..165d00f2 100644 --- a/alc/effects/equalizer.cpp +++ b/alc/effects/equalizer.cpp @@ -119,8 +119,9 @@ void EqualizerState::deviceUpdate(const DeviceBase*, const BufferStorage*) } void EqualizerState::update(const ContextBase *context, const EffectSlot *slot, - const EffectProps *props, const EffectTarget target) + const EffectProps *props_, const EffectTarget target) { + auto &props = std::get(*props_); const DeviceBase *device{context->mDevice}; auto frequency = static_cast(device->Frequency); @@ -130,22 +131,22 @@ void EqualizerState::update(const ContextBase *context, const EffectSlot *slot, * property gains need their dB halved (sqrt of linear gain) for the * shelf/peak to reach the provided gain. */ - float gain{std::sqrt(props->Equalizer.LowGain)}; - float f0norm{props->Equalizer.LowCutoff / frequency}; + float gain{std::sqrt(props.LowGain)}; + float f0norm{props.LowCutoff / frequency}; mChans[0].mFilter[0].setParamsFromSlope(BiquadType::LowShelf, f0norm, gain, 0.75f); - gain = std::sqrt(props->Equalizer.Mid1Gain); - f0norm = props->Equalizer.Mid1Center / frequency; + gain = std::sqrt(props.Mid1Gain); + f0norm = props.Mid1Center / frequency; mChans[0].mFilter[1].setParamsFromBandwidth(BiquadType::Peaking, f0norm, gain, - props->Equalizer.Mid1Width); + props.Mid1Width); - gain = std::sqrt(props->Equalizer.Mid2Gain); - f0norm = props->Equalizer.Mid2Center / frequency; + gain = std::sqrt(props.Mid2Gain); + f0norm = props.Mid2Center / frequency; mChans[0].mFilter[2].setParamsFromBandwidth(BiquadType::Peaking, f0norm, gain, - props->Equalizer.Mid2Width); + props.Mid2Width); - gain = std::sqrt(props->Equalizer.HighGain); - f0norm = props->Equalizer.HighCutoff / frequency; + gain = std::sqrt(props.HighGain); + f0norm = props.HighCutoff / frequency; mChans[0].mFilter[3].setParamsFromSlope(BiquadType::HighShelf, f0norm, gain, 0.75f); /* Copy the filter coefficients for the other input channels. */ diff --git a/alc/effects/fshifter.cpp b/alc/effects/fshifter.cpp index 433ebfe4..076661cf 100644 --- a/alc/effects/fshifter.cpp +++ b/alc/effects/fshifter.cpp @@ -127,14 +127,15 @@ void FshifterState::deviceUpdate(const DeviceBase*, const BufferStorage*) } void FshifterState::update(const ContextBase *context, const EffectSlot *slot, - const EffectProps *props, const EffectTarget target) + const EffectProps *props_, const EffectTarget target) { + auto &props = std::get(*props_); const DeviceBase *device{context->mDevice}; - const float step{props->Fshifter.Frequency / static_cast(device->Frequency)}; + const float step{props.Frequency / static_cast(device->Frequency)}; mPhaseStep[0] = mPhaseStep[1] = fastf2u(minf(step, 1.0f) * MixerFracOne); - switch(props->Fshifter.LeftDirection) + switch(props.LeftDirection) { case FShifterDirection::Down: mSign[0] = -1.0; @@ -148,7 +149,7 @@ void FshifterState::update(const ContextBase *context, const EffectSlot *slot, break; } - switch(props->Fshifter.RightDirection) + switch(props.RightDirection) { case FShifterDirection::Down: mSign[1] = -1.0; diff --git a/alc/effects/modulator.cpp b/alc/effects/modulator.cpp index 8144061a..7350ca5a 100644 --- a/alc/effects/modulator.cpp +++ b/alc/effects/modulator.cpp @@ -125,8 +125,9 @@ void ModulatorState::deviceUpdate(const DeviceBase*, const BufferStorage*) } void ModulatorState::update(const ContextBase *context, const EffectSlot *slot, - const EffectProps *props, const EffectTarget target) + const EffectProps *props_, const EffectTarget target) { + auto &props = std::get(*props_); const DeviceBase *device{context->mDevice}; /* The effective frequency will be adjusted to have a whole number of @@ -136,8 +137,8 @@ void ModulatorState::update(const ContextBase *context, const EffectSlot *slot, * but that may need a more efficient sin function since it needs to do * many iterations per sample. */ - const float samplesPerCycle{props->Modulator.Frequency > 0.0f - ? static_cast(device->Frequency)/props->Modulator.Frequency + 0.5f + const float samplesPerCycle{props.Frequency > 0.0f + ? static_cast(device->Frequency)/props.Frequency + 0.5f : 1.0f}; const uint range{static_cast(clampf(samplesPerCycle, 1.0f, static_cast(device->Frequency)))}; @@ -149,17 +150,17 @@ void ModulatorState::update(const ContextBase *context, const EffectSlot *slot, mIndexScale = 0.0f; mGenModSamples = &ModulatorState::Modulate; } - else if(props->Modulator.Waveform == ModulatorWaveform::Sinusoid) + else if(props.Waveform == ModulatorWaveform::Sinusoid) { mIndexScale = al::numbers::pi_v*2.0f / static_cast(mRange); mGenModSamples = &ModulatorState::Modulate; } - else if(props->Modulator.Waveform == ModulatorWaveform::Sawtooth) + else if(props.Waveform == ModulatorWaveform::Sawtooth) { mIndexScale = 2.0f / static_cast(mRange-1); mGenModSamples = &ModulatorState::Modulate; } - else /*if(props->Modulator.Waveform == ModulatorWaveform::Square)*/ + else /*if(props.Waveform == ModulatorWaveform::Square)*/ { /* For square wave, the range should be even (there should be an equal * number of high and low samples). An odd number of samples per cycle @@ -170,7 +171,7 @@ void ModulatorState::update(const ContextBase *context, const EffectSlot *slot, mGenModSamples = &ModulatorState::Modulate; } - float f0norm{props->Modulator.HighPassCutoff / static_cast(device->Frequency)}; + float f0norm{props.HighPassCutoff / static_cast(device->Frequency)}; f0norm = clampf(f0norm, 1.0f/512.0f, 0.49f); /* Bandwidth value is constant in octaves. */ mChans[0].mFilter.setParamsFromBandwidth(BiquadType::HighPass, f0norm, 1.0f, 0.75f); diff --git a/alc/effects/pshifter.cpp b/alc/effects/pshifter.cpp index 9714510f..1cc1a18c 100644 --- a/alc/effects/pshifter.cpp +++ b/alc/effects/pshifter.cpp @@ -138,9 +138,10 @@ void PshifterState::deviceUpdate(const DeviceBase*, const BufferStorage*) } void PshifterState::update(const ContextBase*, const EffectSlot *slot, - const EffectProps *props, const EffectTarget target) + const EffectProps *props_, const EffectTarget target) { - const int tune{props->Pshifter.CoarseTune*100 + props->Pshifter.FineTune}; + auto &props = std::get(*props_); + const int tune{props.CoarseTune*100 + props.FineTune}; const float pitch{std::pow(2.0f, static_cast(tune) / 1200.0f)}; mPitchShiftI = clampu(fastf2u(pitch*MixerFracOne), MixerFracHalf, MixerFracOne*2); mPitchShift = static_cast(mPitchShiftI) * float{1.0f/MixerFracOne}; diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp index 5eefdfbf..ac599e41 100644 --- a/alc/effects/reverb.cpp +++ b/alc/effects/reverb.cpp @@ -1182,57 +1182,56 @@ void ReverbPipeline::update3DPanning(const al::span ReflectionsPa } void ReverbState::update(const ContextBase *Context, const EffectSlot *Slot, - const EffectProps *props, const EffectTarget target) + const EffectProps *props_, const EffectTarget target) { + auto &props = std::get(*props_); const DeviceBase *Device{Context->mDevice}; const auto frequency = static_cast(Device->Frequency); /* If the HF limit parameter is flagged, calculate an appropriate limit * based on the air absorption parameter. */ - float hfRatio{props->Reverb.DecayHFRatio}; - if(props->Reverb.DecayHFLimit && props->Reverb.AirAbsorptionGainHF < 1.0f) - hfRatio = CalcLimitedHfRatio(hfRatio, props->Reverb.AirAbsorptionGainHF, - props->Reverb.DecayTime); + float hfRatio{props.DecayHFRatio}; + if(props.DecayHFLimit && props.AirAbsorptionGainHF < 1.0f) + hfRatio = CalcLimitedHfRatio(hfRatio, props.AirAbsorptionGainHF, props.DecayTime); /* Calculate the LF/HF decay times. */ constexpr float MinDecayTime{0.1f}, MaxDecayTime{20.0f}; - const float lfDecayTime{clampf(props->Reverb.DecayTime*props->Reverb.DecayLFRatio, - MinDecayTime, MaxDecayTime)}; - const float hfDecayTime{clampf(props->Reverb.DecayTime*hfRatio, MinDecayTime, MaxDecayTime)}; + const float lfDecayTime{clampf(props.DecayTime*props.DecayLFRatio, MinDecayTime,MaxDecayTime)}; + const float hfDecayTime{clampf(props.DecayTime*hfRatio, MinDecayTime, MaxDecayTime)}; /* Determine if a full update is required. */ const bool fullUpdate{mPipelineState == DeviceClear || /* Density is essentially a master control for the feedback delays, so * changes the offsets of many delay lines. */ - mParams.Density != props->Reverb.Density || + mParams.Density != props.Density || /* Diffusion and decay times influences the decay rate (gain) of the * late reverb T60 filter. */ - mParams.Diffusion != props->Reverb.Diffusion || - mParams.DecayTime != props->Reverb.DecayTime || + mParams.Diffusion != props.Diffusion || + mParams.DecayTime != props.DecayTime || mParams.HFDecayTime != hfDecayTime || mParams.LFDecayTime != lfDecayTime || /* Modulation time and depth both require fading the modulation delay. */ - mParams.ModulationTime != props->Reverb.ModulationTime || - mParams.ModulationDepth != props->Reverb.ModulationDepth || + mParams.ModulationTime != props.ModulationTime || + mParams.ModulationDepth != props.ModulationDepth || /* HF/LF References control the weighting used to calculate the density * gain. */ - mParams.HFReference != props->Reverb.HFReference || - mParams.LFReference != props->Reverb.LFReference}; + mParams.HFReference != props.HFReference || + mParams.LFReference != props.LFReference}; if(fullUpdate) { - mParams.Density = props->Reverb.Density; - mParams.Diffusion = props->Reverb.Diffusion; - mParams.DecayTime = props->Reverb.DecayTime; + mParams.Density = props.Density; + mParams.Diffusion = props.Diffusion; + mParams.DecayTime = props.DecayTime; mParams.HFDecayTime = hfDecayTime; mParams.LFDecayTime = lfDecayTime; - mParams.ModulationTime = props->Reverb.ModulationTime; - mParams.ModulationDepth = props->Reverb.ModulationDepth; - mParams.HFReference = props->Reverb.HFReference; - mParams.LFReference = props->Reverb.LFReference; + mParams.ModulationTime = props.ModulationTime; + mParams.ModulationDepth = props.ModulationDepth; + mParams.HFReference = props.HFReference; + mParams.LFReference = props.LFReference; mPipelineState = (mPipelineState != DeviceClear) ? StartFade : Normal; mCurrentPipeline = !mCurrentPipeline; @@ -1241,16 +1240,15 @@ void ReverbState::update(const ContextBase *Context, const EffectSlot *Slot, /* Update early and late 3D panning. */ mOutTarget = target.Main->Buffer; - const float gain{props->Reverb.Gain * Slot->Gain * ReverbBoost}; - pipeline.update3DPanning(props->Reverb.ReflectionsPan, props->Reverb.LateReverbPan, - props->Reverb.ReflectionsGain*gain, props->Reverb.LateReverbGain*gain, mUpmixOutput, - target.Main); + const float gain{props.Gain * Slot->Gain * ReverbBoost}; + pipeline.update3DPanning(props.ReflectionsPan, props.LateReverbPan, props.ReflectionsGain*gain, + props.LateReverbGain*gain, mUpmixOutput, target.Main); /* Calculate the master filters */ - float hf0norm{minf(props->Reverb.HFReference/frequency, 0.49f)}; - pipeline.mFilter[0].Lp.setParamsFromSlope(BiquadType::HighShelf, hf0norm, props->Reverb.GainHF, 1.0f); - float lf0norm{minf(props->Reverb.LFReference/frequency, 0.49f)}; - pipeline.mFilter[0].Hp.setParamsFromSlope(BiquadType::LowShelf, lf0norm, props->Reverb.GainLF, 1.0f); + float hf0norm{minf(props.HFReference/frequency, 0.49f)}; + pipeline.mFilter[0].Lp.setParamsFromSlope(BiquadType::HighShelf, hf0norm, props.GainHF, 1.0f); + float lf0norm{minf(props.LFReference/frequency, 0.49f)}; + pipeline.mFilter[0].Hp.setParamsFromSlope(BiquadType::LowShelf, lf0norm, props.GainLF, 1.0f); for(size_t i{1u};i < NUM_LINES;i++) { pipeline.mFilter[i].Lp.copyParamsFrom(pipeline.mFilter[0].Lp); @@ -1258,34 +1256,32 @@ void ReverbState::update(const ContextBase *Context, const EffectSlot *Slot, } /* The density-based room size (delay length) multiplier. */ - const float density_mult{CalcDelayLengthMult(props->Reverb.Density)}; + const float density_mult{CalcDelayLengthMult(props.Density)}; /* Update the main effect delay and associated taps. */ - pipeline.updateDelayLine(props->Reverb.ReflectionsDelay, props->Reverb.LateReverbDelay, - density_mult, props->Reverb.DecayTime, frequency); + pipeline.updateDelayLine(props.ReflectionsDelay, props.LateReverbDelay, density_mult, + props.DecayTime, frequency); if(fullUpdate) { /* Update the early lines. */ - pipeline.mEarly.updateLines(density_mult, props->Reverb.Diffusion, props->Reverb.DecayTime, - frequency); + pipeline.mEarly.updateLines(density_mult, props.Diffusion, props.DecayTime, frequency); /* Get the mixing matrix coefficients. */ - CalcMatrixCoeffs(props->Reverb.Diffusion, &pipeline.mMixX, &pipeline.mMixY); + CalcMatrixCoeffs(props.Diffusion, &pipeline.mMixX, &pipeline.mMixY); /* Update the modulator rate and depth. */ - pipeline.mLate.Mod.updateModulator(props->Reverb.ModulationTime, - props->Reverb.ModulationDepth, frequency); + pipeline.mLate.Mod.updateModulator(props.ModulationTime, props.ModulationDepth, frequency); /* Update the late lines. */ - pipeline.mLate.updateLines(density_mult, props->Reverb.Diffusion, lfDecayTime, - props->Reverb.DecayTime, hfDecayTime, lf0norm, hf0norm, frequency); + pipeline.mLate.updateLines(density_mult, props.Diffusion, lfDecayTime, props.DecayTime, + hfDecayTime, lf0norm, hf0norm, frequency); } /* Calculate the gain at the start of the late reverb stage, and the gain * difference from the decay target (0.001, or -60dB). */ - const float decayBase{props->Reverb.ReflectionsGain * props->Reverb.LateReverbGain}; + const float decayBase{props.ReflectionsGain * props.LateReverbGain}; const float decayDiff{ReverbDecayGain / decayBase}; if(decayDiff < 1.0f) @@ -1294,10 +1290,10 @@ void ReverbState::update(const ContextBase *Context, const EffectSlot *Slot, * by -60dB), calculate the time to decay to -60dB from the start of * the late reverb. */ - const float diffTime{std::log10(decayDiff)*(20.0f / -60.0f) * props->Reverb.DecayTime}; + const float diffTime{std::log10(decayDiff)*(20.0f / -60.0f) * props.DecayTime}; - const float decaySamples{(props->Reverb.ReflectionsDelay + props->Reverb.LateReverbDelay - + diffTime) * frequency}; + const float decaySamples{(props.ReflectionsDelay+props.LateReverbDelay+diffTime) + * frequency}; /* Limit to 100,000 samples (a touch over 2 seconds at 48khz) to * avoid excessive double-processing. */ @@ -1308,8 +1304,7 @@ void ReverbState::update(const ContextBase *Context, const EffectSlot *Slot, /* Otherwise, if the late reverb already starts at -60dB or less, only * include the time to get to the late reverb. */ - const float decaySamples{(props->Reverb.ReflectionsDelay + props->Reverb.LateReverbDelay) - * frequency}; + const float decaySamples{(props.ReflectionsDelay+props.LateReverbDelay) * frequency}; pipeline.mFadeSampleCount = static_cast(minf(decaySamples, 100'000.0f)); } } diff --git a/alc/effects/vmorpher.cpp b/alc/effects/vmorpher.cpp index adbcdeab..eaf30d07 100644 --- a/alc/effects/vmorpher.cpp +++ b/alc/effects/vmorpher.cpp @@ -241,29 +241,28 @@ void VmorpherState::deviceUpdate(const DeviceBase*, const BufferStorage*) } void VmorpherState::update(const ContextBase *context, const EffectSlot *slot, - const EffectProps *props, const EffectTarget target) + const EffectProps *props_, const EffectTarget target) { + auto &props = std::get(*props_); const DeviceBase *device{context->mDevice}; const float frequency{static_cast(device->Frequency)}; - const float step{props->Vmorpher.Rate / frequency}; + const float step{props.Rate / frequency}; mStep = fastf2u(clampf(step*WaveformFracOne, 0.0f, float{WaveformFracOne}-1.0f)); if(mStep == 0) mGetSamples = Oscillate; - else if(props->Vmorpher.Waveform == VMorpherWaveform::Sinusoid) + else if(props.Waveform == VMorpherWaveform::Sinusoid) mGetSamples = Oscillate; - else if(props->Vmorpher.Waveform == VMorpherWaveform::Triangle) + else if(props.Waveform == VMorpherWaveform::Triangle) mGetSamples = Oscillate; - else /*if(props->Vmorpher.Waveform == VMorpherWaveform::Sawtooth)*/ + else /*if(props.Waveform == VMorpherWaveform::Sawtooth)*/ mGetSamples = Oscillate; - const float pitchA{std::pow(2.0f, - static_cast(props->Vmorpher.PhonemeACoarseTuning) / 12.0f)}; - const float pitchB{std::pow(2.0f, - static_cast(props->Vmorpher.PhonemeBCoarseTuning) / 12.0f)}; + const float pitchA{std::pow(2.0f, static_cast(props.PhonemeACoarseTuning) / 12.0f)}; + const float pitchB{std::pow(2.0f, static_cast(props.PhonemeBCoarseTuning) / 12.0f)}; - auto vowelA = getFiltersByPhoneme(props->Vmorpher.PhonemeA, frequency, pitchA); - auto vowelB = getFiltersByPhoneme(props->Vmorpher.PhonemeB, frequency, pitchB); + auto vowelA = getFiltersByPhoneme(props.PhonemeA, frequency, pitchA); + auto vowelB = getFiltersByPhoneme(props.PhonemeB, frequency, pitchB); /* Copy the filter coefficients to the input channels. */ for(size_t i{0u};i < slot->Wet.Buffer.size();++i) diff --git a/core/effects/base.h b/core/effects/base.h index 66182bf5..df4eb129 100644 --- a/core/effects/base.h +++ b/core/effects/base.h @@ -2,7 +2,8 @@ #define CORE_EFFECTS_BASE_H #include -#include +#include +#include #include "almalloc.h" #include "alspan.h" @@ -145,7 +146,7 @@ struct EqualizerProps { float HighGain; }; -struct FshiterProps { +struct FshifterProps { float Frequency; FShifterDirection LeftDirection; FShifterDirection RightDirection; @@ -184,23 +185,22 @@ struct ConvolutionProps { std::array OrientUp; }; -union EffectProps { - ReverbProps Reverb; - AutowahProps Autowah; - ChorusProps Chorus; - FlangerProps Flanger; - CompressorProps Compressor; - DistortionProps Distortion; - EchoProps Echo; - EqualizerProps Equalizer; - FshiterProps Fshifter; - ModulatorProps Modulator; - PshifterProps Pshifter; - VmorpherProps Vmorpher; - DedicatedDialogProps DedicatedDialog; - DedicatedLfeProps DedicatedLfe; - ConvolutionProps Convolution; -}; +using EffectProps = std::variant; struct EffectTarget { -- cgit v1.2.3 From e9c7a8602530d73dd34af11172af79b7d58a3b49 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 30 Dec 2023 03:50:49 -0800 Subject: Don't apply the T60 filter on the initial late reverb input --- alc/effects/reverb.cpp | 83 ++++++++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 37 deletions(-) (limited to 'alc/effects/reverb.cpp') diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp index ac599e41..047dca6c 100644 --- a/alc/effects/reverb.cpp +++ b/alc/effects/reverb.cpp @@ -1587,16 +1587,51 @@ void ReverbPipeline::processLate(size_t offset, const size_t samplesToDo, /* First, calculate the modulated delays for the late feedback. */ mLate.Mod.calcDelays(todo); - /* Next, load decorrelated samples from the main and feedback delay - * lines. Filter the signal to apply its frequency-dependent decay. + /* Now load samples from the feedback delay lines. Filter the signal to + * apply its frequency-dependent decay. */ + for(size_t j{0u};j < NUM_LINES;++j) + { + size_t late_feedb_tap{offset - mLate.Offset[j]}; + const float midGain{mLate.T60[j].MidGain}; + + for(size_t i{0u};i < todo;++i) + { + /* Calculate the read offset and offset between it and the next + * sample. + */ + const float fdelay{mLate.Mod.ModDelays[i]}; + const size_t idelay{float2uint(fdelay * float{gCubicTable.sTableSteps})}; + const size_t delay{late_feedb_tap - (idelay>>gCubicTable.sTableBits)}; + const size_t delayoffset{idelay & gCubicTable.sTableMask}; + ++late_feedb_tap; + + /* Get the samples around by the delayed offset. */ + const float out0{late_delay.Line[(delay ) & late_delay.Mask][j]}; + const float out1{late_delay.Line[(delay-1) & late_delay.Mask][j]}; + const float out2{late_delay.Line[(delay-2) & late_delay.Mask][j]}; + const float out3{late_delay.Line[(delay-3) & late_delay.Mask][j]}; + + /* The output is obtained by interpolating the four samples + * that were acquired above, and combined with the main delay + * tap. + */ + const float out{out0*gCubicTable.getCoeff0(delayoffset) + + out1*gCubicTable.getCoeff1(delayoffset) + + out2*gCubicTable.getCoeff2(delayoffset) + + out3*gCubicTable.getCoeff3(delayoffset)}; + tempSamples[j][i] = out * midGain; + } + + mLate.T60[j].process({tempSamples[j].data(), todo}); + } + + /* Next load decorrelated samples from the main delay lines. */ const float fadeStep{1.0f / static_cast(todo)}; - for(size_t j{0u};j < NUM_LINES;j++) + for(size_t j{0u};j < NUM_LINES;++j) { size_t late_delay_tap0{offset - mLateDelayTap[j][0]}; size_t late_delay_tap1{offset - mLateDelayTap[j][1]}; - size_t late_feedb_tap{offset - mLate.Offset[j]}; - const float midGain{mLate.T60[j].MidGain}; const float densityGain{mLate.DensityGain}; const float densityStep{late_delay_tap0 != late_delay_tap1 ? densityGain*fadeStep : 0.0f}; @@ -1608,48 +1643,22 @@ void ReverbPipeline::processLate(size_t offset, const size_t samplesToDo, late_delay_tap1 &= in_delay.Mask; size_t td{minz(todo-i, in_delay.Mask+1 - maxz(late_delay_tap0, late_delay_tap1))}; do { - /* Calculate the read offset and offset between it and the - * next sample. - */ - const float fdelay{mLate.Mod.ModDelays[i]}; - const size_t idelay{float2uint(fdelay * float{gCubicTable.sTableSteps})}; - const size_t delay{late_feedb_tap - (idelay>>gCubicTable.sTableBits)}; - const size_t delayoffset{idelay & gCubicTable.sTableMask}; - ++late_feedb_tap; - - /* Get the samples around by the delayed offset. */ - const float out0{late_delay.Line[(delay ) & late_delay.Mask][j]}; - const float out1{late_delay.Line[(delay-1) & late_delay.Mask][j]}; - const float out2{late_delay.Line[(delay-2) & late_delay.Mask][j]}; - const float out3{late_delay.Line[(delay-3) & late_delay.Mask][j]}; - - /* The output is obtained by interpolating the four samples - * that were acquired above, and combined with the main - * delay tap. - */ - const float out{out0*gCubicTable.getCoeff0(delayoffset) - + out1*gCubicTable.getCoeff1(delayoffset) - + out2*gCubicTable.getCoeff2(delayoffset) - + out3*gCubicTable.getCoeff3(delayoffset)}; const float fade0{densityGain - densityStep*fadeCount}; const float fade1{densityStep*fadeCount}; fadeCount += 1.0f; - tempSamples[j][i] = (out + - in_delay.Line[late_delay_tap0++][j]*fade0 + - in_delay.Line[late_delay_tap1++][j]*fade1) * midGain; + tempSamples[j][i] += in_delay.Line[late_delay_tap0++][j]*fade0 + + in_delay.Line[late_delay_tap1++][j]*fade1; ++i; } while(--td); } mLateDelayTap[j][0] = mLateDelayTap[j][1]; - - mLate.T60[j].process({tempSamples[j].data(), todo}); } /* Apply a vector all-pass to improve micro-surface diffusion, and * write out the results for mixing. */ mLate.VecAp.process(tempSamples, offset, mixX, mixY, todo); - for(size_t j{0u};j < NUM_LINES;j++) + for(size_t j{0u};j < NUM_LINES;++j) std::copy_n(tempSamples[j].begin(), todo, outSamples[j].begin()+base); /* Finally, scatter and bounce the results to refeed the feedback buffer. */ @@ -1674,7 +1683,7 @@ void ReverbState::process(const size_t samplesToDo, const al::span tmpspan{al::assume_aligned<16>(mTempLine.data()), samplesToDo}; - for(size_t c{0u};c < NUM_LINES;c++) + for(size_t c{0u};c < NUM_LINES;++c) { std::fill(tmpspan.begin(), tmpspan.end(), 0.0f); for(size_t i{0};i < numInput;++i) @@ -1715,7 +1724,7 @@ void ReverbState::process(const size_t samplesToDo, const al::span tmpspan{al::assume_aligned<16>(mTempLine.data()), samplesToDo}; const float fadeStep{1.0f / static_cast(samplesToDo)}; - for(size_t c{0u};c < NUM_LINES;c++) + for(size_t c{0u};c < NUM_LINES;++c) { std::fill(tmpspan.begin(), tmpspan.end(), 0.0f); for(size_t i{0};i < numInput;++i) @@ -1739,7 +1748,7 @@ void ReverbState::process(const size_t samplesToDo, const al::span Date: Wed, 3 Jan 2024 20:54:50 -0800 Subject: Avoid a union for storing a temporary value --- alc/effects/reverb.cpp | 70 ++++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 33 deletions(-) (limited to 'alc/effects/reverb.cpp') diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp index 047dca6c..2d884500 100644 --- a/alc/effects/reverb.cpp +++ b/alc/effects/reverb.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -289,20 +290,16 @@ struct DelayLineI { * of 2 to allow the use of bit-masking instead of a modulus for wrapping. */ size_t Mask{0u}; - union { - uintptr_t LineOffset{0u}; - std::array *Line; - }; + std::array *Line; /* Given the allocated sample buffer, this function updates each delay line * offset. */ void realizeLineOffset(std::array *sampleBuffer) noexcept - { Line = sampleBuffer + LineOffset; } + { Line = sampleBuffer; } /* Calculate the length of a delay line and store its mask and offset. */ - uint calcLineLength(const float length, const uintptr_t offset, const float frequency, - const uint extra) + size_t calcLineLength(const float length, const float frequency, const uint extra) { /* All line lengths are powers of 2, calculated from their lengths in * seconds, rounded up. @@ -312,7 +309,6 @@ struct DelayLineI { /* All lines share a single sample buffer. */ Mask = samples - 1; - LineOffset = offset; /* Return the sample count for accumulation. */ return samples; @@ -676,11 +672,6 @@ inline float CalcDelayLengthMult(float density) */ void ReverbState::allocLines(const float frequency) { - /* All delay line lengths are calculated to accommodate the full range of - * lengths given their respective parameters. - */ - size_t totalSamples{0u}; - /* Multiplier for the maximum density value, i.e. density=1, which is * actually the least density... */ @@ -690,8 +681,12 @@ void ReverbState::allocLines(const float frequency) * time and depth coefficient, and halfed for the low-to-high frequency * swing. */ - constexpr float max_mod_delay{MaxModulationTime*MODULATION_DEPTH_COEFF / 2.0f}; + static constexpr float max_mod_delay{MaxModulationTime*MODULATION_DEPTH_COEFF / 2.0f}; + + std::array lineoffsets{}; + size_t oidx{0}; + size_t totalSamples{0u}; for(auto &pipeline : mPipelines) { /* The main delay length includes the maximum early reflection delay, @@ -700,37 +695,45 @@ void ReverbState::allocLines(const float frequency) * update size (BufferLineSize) for block processing. */ float length{ReverbMaxReflectionsDelay + EARLY_TAP_LENGTHS.back()*multiplier}; - totalSamples += pipeline.mEarlyDelayIn.calcLineLength(length, totalSamples, frequency, - BufferLineSize); + size_t count{pipeline.mEarlyDelayIn.calcLineLength(length, frequency, BufferLineSize)}; + lineoffsets[oidx++] = totalSamples; + totalSamples += count; - constexpr float LateLineDiffAvg{(LATE_LINE_LENGTHS.back()-LATE_LINE_LENGTHS.front()) / + static constexpr float LateDiffAvg{(LATE_LINE_LENGTHS.back()-LATE_LINE_LENGTHS.front()) / float{NUM_LINES}}; - length = ReverbMaxLateReverbDelay + LateLineDiffAvg*multiplier; - totalSamples += pipeline.mLateDelayIn.calcLineLength(length, totalSamples, frequency, - BufferLineSize); + length = ReverbMaxLateReverbDelay + LateDiffAvg*multiplier; + count = pipeline.mLateDelayIn.calcLineLength(length, frequency, BufferLineSize); + lineoffsets[oidx++] = totalSamples; + totalSamples += count; /* The early vector all-pass line. */ length = EARLY_ALLPASS_LENGTHS.back() * multiplier; - totalSamples += pipeline.mEarly.VecAp.Delay.calcLineLength(length, totalSamples, frequency, - 0); + count = pipeline.mEarly.VecAp.Delay.calcLineLength(length, frequency, 0); + lineoffsets[oidx++] = totalSamples; + totalSamples += count; /* The early reflection line. */ length = EARLY_LINE_LENGTHS.back() * multiplier; - totalSamples += pipeline.mEarly.Delay.calcLineLength(length, totalSamples, frequency, - MAX_UPDATE_SAMPLES); + count = pipeline.mEarly.Delay.calcLineLength(length, frequency, MAX_UPDATE_SAMPLES); + lineoffsets[oidx++] = totalSamples; + totalSamples += count; /* The late vector all-pass line. */ length = LATE_ALLPASS_LENGTHS.back() * multiplier; - totalSamples += pipeline.mLate.VecAp.Delay.calcLineLength(length, totalSamples, frequency, - 0); + count = pipeline.mLate.VecAp.Delay.calcLineLength(length, frequency, 0); + lineoffsets[oidx++] = totalSamples; + totalSamples += count; /* The late delay lines are calculated from the largest maximum density * line length, and the maximum modulation delay. Four additional * samples are needed for resampling the modulator delay. */ length = LATE_LINE_LENGTHS.back()*multiplier + max_mod_delay; - totalSamples += pipeline.mLate.Delay.calcLineLength(length, totalSamples, frequency, 4); + count = pipeline.mLate.Delay.calcLineLength(length, frequency, 4); + lineoffsets[oidx++] = totalSamples; + totalSamples += count; } + assert(oidx == lineoffsets.size()); if(totalSamples != mSampleBuffer.size()) decltype(mSampleBuffer)(totalSamples).swap(mSampleBuffer); @@ -739,14 +742,15 @@ void ReverbState::allocLines(const float frequency) std::fill(mSampleBuffer.begin(), mSampleBuffer.end(), decltype(mSampleBuffer)::value_type{}); /* Update all delays to reflect the new sample buffer. */ + oidx = 0; for(auto &pipeline : mPipelines) { - pipeline.mEarlyDelayIn.realizeLineOffset(mSampleBuffer.data()); - pipeline.mLateDelayIn.realizeLineOffset(mSampleBuffer.data()); - pipeline.mEarly.VecAp.Delay.realizeLineOffset(mSampleBuffer.data()); - pipeline.mEarly.Delay.realizeLineOffset(mSampleBuffer.data()); - pipeline.mLate.VecAp.Delay.realizeLineOffset(mSampleBuffer.data()); - pipeline.mLate.Delay.realizeLineOffset(mSampleBuffer.data()); + pipeline.mEarlyDelayIn.realizeLineOffset(mSampleBuffer.data() + lineoffsets[oidx++]); + pipeline.mLateDelayIn.realizeLineOffset(mSampleBuffer.data() + lineoffsets[oidx++]); + pipeline.mEarly.VecAp.Delay.realizeLineOffset(mSampleBuffer.data() + lineoffsets[oidx++]); + pipeline.mEarly.Delay.realizeLineOffset(mSampleBuffer.data() + lineoffsets[oidx++]); + pipeline.mLate.VecAp.Delay.realizeLineOffset(mSampleBuffer.data() + lineoffsets[oidx++]); + pipeline.mLate.Delay.realizeLineOffset(mSampleBuffer.data() + lineoffsets[oidx++]); } } -- cgit v1.2.3 From b82cd2e60edb8fbe5fdd3567105ae76a016a554c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 4 Jan 2024 19:14:59 -0800 Subject: Don't scale the early reflection output The secondary reflections are spatially reflected and scaled by time already, so an average of the primary and secondary doesn't make sense. --- alc/effects/reverb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'alc/effects/reverb.cpp') diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp index 2d884500..45bfaf0f 100644 --- a/alc/effects/reverb.cpp +++ b/alc/effects/reverb.cpp @@ -1522,7 +1522,7 @@ void ReverbPipeline::processEarly(size_t offset, const size_t samplesToDo, size_t td{minz(early_delay.Mask+1 - feedb_tap, todo - i)}; do { float sample{early_delay.Line[feedb_tap++][j]}; - out[i] = (tempSamples[j][i] + sample*feedb_coeff) * 0.5f; + out[i] = tempSamples[j][i] + sample*feedb_coeff; tempSamples[j][i] = sample; ++i; } while(--td); -- cgit v1.2.3