#pragma once #include "FluidSim/AudioProcessing.hpp" #include namespace fluidsim::port { // Eight-line frequency-dependent feedback delay network with early reflections // and transient bloom, ported from Core/OutdoorExhaustReverb.cs. class OutdoorExhaustReverb { public: float dry_mix{1.00f}, early_mix{0.10f}, tail_mix{0.28f}; float pre_delay_ms{5.0f}, ground_delay_ms{9.0f}, wall_delay_ms{45.0f}; float low_decay_seconds{1.50f}, mid_decay_seconds{0.70f}, high_decay_seconds{0.20f}; float band_low_hz{300.0f}, band_high_hz{3000.0f}; float transient_feedback_boost{0.35f}, transient_hf_boost{3.0f}; float transient_decay_ms{110.0f}, saturation_drive{1.2f}; explicit OutdoorExhaustReverb(int sample_rate = 44100); AudioFrame process_stereo(float input); float process(float input); private: class DelayLine { public: explicit DelayLine(std::size_t size = 1); float read() const; float read_write(float value); void write(float value); private: std::vector buffer_; std::size_t position_{}; }; class OnePoleLowPass { public: OnePoleLowPass(float cutoff_hz, int sample_rate); float process(float value); private: float alpha_{}, state_{}; }; int sample_rate_{}; float dt_{}, gain_low_{}, gain_mid_{}, gain_high_{}; std::vector fdn_; std::vector low_filters_, mid_filters_; std::vector read_buffer_, mix_buffer_; DelayLine pre_delay_, ground_left_, ground_right_, wall_left_, wall_right_; OnePoleLowPass ground_filter_left_, ground_filter_right_, wall_filter_left_, wall_filter_right_; float fast_envelope_{}, slow_envelope_{}, bloom_{}; float fast_attack_{}, fast_release_{}, slow_attack_{}, slow_release_{}, bloom_decay_{}; static std::size_t delay_samples(int sample_rate, float milliseconds); }; } // namespace fluidsim::port