diff options
Diffstat (limited to 'al/source.cpp')
-rw-r--r-- | al/source.cpp | 83 |
1 files changed, 63 insertions, 20 deletions
diff --git a/al/source.cpp b/al/source.cpp index e5241a39..8856bafc 100644 --- a/al/source.cpp +++ b/al/source.cpp @@ -3996,6 +3996,9 @@ float ALsource::eax_calculate_dst_occlusion_mb( float path_ratio, float lf_ratio) noexcept { + if(src_occlusion_mb == 0) + return 0.0f; + const auto ratio_1 = path_ratio + lf_ratio - 1.0F; const auto ratio_2 = path_ratio * lf_ratio; const auto ratio = (ratio_2 > ratio_1) ? ratio_2 : ratio_1; @@ -4013,26 +4016,44 @@ EaxAlLowPassParam ALsource::eax_create_direct_filter_param() const noexcept eax_.source.flOcclusionDirectRatio, eax_.source.flOcclusionLFRatio); + const auto has_source_occlusion = (eax_.source.lOcclusion != 0); + auto gain_hf_mb = static_cast<float>(eax_.source.lDirectHF) + - static_cast<float>(eax_.source.lObstruction) + - (static_cast<float>(eax_.source.lOcclusion) * eax_.source.flOcclusionDirectRatio); + static_cast<float>(eax_.source.lObstruction); for (auto i = std::size_t{}; i < EAX_MAX_FXSLOTS; ++i) { - if (!eax_active_fx_slots_[i]) - { + if(!eax_active_fx_slots_[i]) continue; + + if(has_source_occlusion) { + const auto& fx_slot = eax_al_context_->eax_get_fx_slot(i); + const auto& fx_slot_eax = fx_slot.eax_get_eax_fx_slot(); + const auto is_environmental_fx = ((fx_slot_eax.ulFlags & EAXFXSLOTFLAGS_ENVIRONMENT) != 0); + const auto is_primary = (eax_primary_fx_slot_id_.value_or(-1) == fx_slot.eax_get_index()); + const auto is_listener_environment = (is_environmental_fx && is_primary); + + if(is_listener_environment) { + gain_mb += eax_calculate_dst_occlusion_mb( + eax_.source.lOcclusion, + eax_.source.flOcclusionDirectRatio, + eax_.source.flOcclusionLFRatio); + + gain_hf_mb += static_cast<float>(eax_.source.lOcclusion) * eax_.source.flOcclusionDirectRatio; + } } const auto& send = eax_.sends[i]; - gain_mb += eax_calculate_dst_occlusion_mb( - send.lOcclusion, - send.flOcclusionDirectRatio, - send.flOcclusionLFRatio); + if(send.lOcclusion != 0) { + gain_mb += eax_calculate_dst_occlusion_mb( + send.lOcclusion, + send.flOcclusionDirectRatio, + send.flOcclusionLFRatio); - gain_hf_mb += static_cast<float>(send.lOcclusion) * send.flOcclusionDirectRatio; + gain_hf_mb += static_cast<float>(send.lOcclusion) * send.flOcclusionDirectRatio; + } } const auto al_low_pass_param = EaxAlLowPassParam{ @@ -4047,25 +4068,38 @@ EaxAlLowPassParam ALsource::eax_create_room_filter_param( const EAXSOURCEALLSENDPROPERTIES& send) const noexcept { const auto& fx_slot_eax = fx_slot.eax_get_eax_fx_slot(); + const auto is_environmental_fx = ((fx_slot_eax.ulFlags & EAXFXSLOTFLAGS_ENVIRONMENT) != 0); + const auto is_primary = (eax_primary_fx_slot_id_.value_or(-1) == fx_slot.eax_get_index()); + const auto is_listener_environment = (is_environmental_fx && is_primary); const auto gain_mb = - static_cast<float>(eax_.source.lRoom + send.lSend) + - eax_calculate_dst_occlusion_mb( - eax_.source.lOcclusion, - eax_.source.flOcclusionRoomRatio, - eax_.source.flOcclusionLFRatio) + + (static_cast<float>(fx_slot_eax.lOcclusion) * fx_slot_eax.flOcclusionLFRatio) + + static_cast<float>((is_environmental_fx ? eax_.source.lRoom : 0) + send.lSend) + + (is_listener_environment ? + eax_calculate_dst_occlusion_mb( + eax_.source.lOcclusion, + eax_.source.flOcclusionRoomRatio, + eax_.source.flOcclusionLFRatio) : + 0.0f) + eax_calculate_dst_occlusion_mb( send.lOcclusion, send.flOcclusionRoomRatio, send.flOcclusionLFRatio) + - (static_cast<float>(eax_.source.lExclusion) * eax_.source.flExclusionLFRatio) + + (is_listener_environment ? + (static_cast<float>(eax_.source.lExclusion) * eax_.source.flExclusionLFRatio) : + 0.0f) + (static_cast<float>(send.lExclusion) * send.flExclusionLFRatio); const auto gain_hf_mb = - static_cast<float>(eax_.source.lRoomHF + send.lSendHF) + - (static_cast<float>(fx_slot_eax.lOcclusion + eax_.source.lOcclusion) * eax_.source.flOcclusionRoomRatio) + + static_cast<float>(fx_slot_eax.lOcclusion) + + static_cast<float>((is_environmental_fx ? eax_.source.lRoomHF : 0) + send.lSendHF) + + (is_listener_environment ? + ((static_cast<float>(eax_.source.lOcclusion) * eax_.source.flOcclusionRoomRatio)) : + 0.0f) + (static_cast<float>(send.lOcclusion) * send.flOcclusionRoomRatio) + - static_cast<float>(eax_.source.lExclusion + send.lExclusion); + (is_listener_environment ? + static_cast<float>(eax_.source.lExclusion + send.lExclusion) : + 0.0f); const auto al_low_pass_param = EaxAlLowPassParam{ level_mb_to_gain(gain_mb), @@ -4486,6 +4520,15 @@ void ALsource::eax_set(const EaxCall& call) eax_version_ = eax_version; } +void ALsource::eax_get_active_fx_slot_id(const EaxCall& call, const GUID* ids, int max_count) +{ + assert(ids != nullptr); + assert(max_count == EAX40_MAX_ACTIVE_FXSLOTS || max_count == EAX50_MAX_ACTIVE_FXSLOTS); + const auto dst_ids = call.get_values<GUID>(max_count); + const auto count = dst_ids.size(); + std::uninitialized_copy_n(ids, count, dst_ids.begin()); +} + void ALsource::eax1_get(const EaxCall& call, const Eax1Props& props) { switch (call.get_property_id()) { @@ -4731,7 +4774,7 @@ void ALsource::eax4_get(const EaxCall& call, const Eax4Props& props) break; case EAXSOURCE_ACTIVEFXSLOTID: - call.set_value<Exception>(props.active_fx_slots); + eax_get_active_fx_slot_id(call, props.active_fx_slots.guidActiveFXSlots, EAX40_MAX_ACTIVE_FXSLOTS); break; default: @@ -4803,7 +4846,7 @@ void ALsource::eax5_get(const EaxCall& call, const Eax5Props& props) break; case EAXSOURCE_ACTIVEFXSLOTID: - call.set_value<Exception>(props.active_fx_slots); + eax_get_active_fx_slot_id(call, props.active_fx_slots.guidActiveFXSlots, EAX50_MAX_ACTIVE_FXSLOTS); break; case EAXSOURCE_MACROFXFACTOR: |