#pragma once #include "FluidSim/AudioProcessing.hpp" #include "FluidSim/Engine.hpp" #include "FluidSim/Fluid.hpp" #include "FluidSim/MechanicalSoundProcessor.hpp" #include "FluidSim/OutdoorExhaustReverb.hpp" #include "FluidSim/Solver.hpp" #include "FluidSim/Vehicle.hpp" #include #include #include #include namespace fluidsim::port { struct ScenarioSnapshot { float rpm{}, speed_kmh{}, kinetic_energy{}, average_power{}, average_torque{}; float cylinder_pressure1{}, cylinder_pressure2{}; float cylinder_temperature1{}, cylinder_temperature2{}; float cylinder_piston_fraction1{}, cylinder_piston_fraction2{}; float valve1_intake_area{}, valve1_exhaust_area{}, valve2_intake_area{}, valve2_exhaust_area{}; float intake_pressure{}, exhaust_pressure{}; float throttle{}, clutch{}, intake_flow{}, exhaust_flow{}; int gear{}; bool rev_limit1{}, rev_limit2{}, mechanical_sound_enabled{}; std::array, 6> pipe_states; }; // Active C# SingleCylScenario topology: a 600 cc parallel twin, independent // intake runners, separate short exhaust headers, shared collector and tailpipe. class FourStrokeTwinScenario { public: explicit FourStrokeTwinScenario(int sample_rate = 44100); AudioFrame process(); void set_controls(float throttle_value, float load_value, float clutch_value); void toggle_mechanical_sound(); void shift_up(); void shift_down(); void set_neutral(); void set_first_gear(); ScenarioSnapshot snapshot() const; float throttle{}; float load{}; float clutch{1.0f}; bool mechanical_sound_enabled{}; float mechanical_mix{0.02f}, reverb_send_gain{1.0f}; float exhaust_send{0.5f}, intake_send{0.5f}, mechanical_send{}; Crankshaft crankshaft{}; FourStrokeCylinder cylinder1{}, cylinder2{}; Vehicle vehicle{}; Volume0D intake_plenum{1.0e-3f, 101325.0f, 300.0f}; Volume0D exhaust_collector{0.15e-3f, 101325.0f, 700.0f}; std::vector pipes; float intake_flow{}, exhaust_flow{}; float last_mix_l{}, last_mix_r{}; std::uint64_t sample_count{}; private: Port* throttle_port_{}; Port* runner_feed1_{}; Port* runner_feed2_{}; Port* collector_in1_{}; Port* collector_in2_{}; Port* collector_out_{}; float throttle_area_{}, runner_area_{}, valve1_in_{}, valve2_in_{}; float valve1_out_{}, valve2_out_{}, header_area_{}, tail_area_{}; float dt_{}; BoundarySystem boundaries_; Solver solver_; RadiationSource intake_radiation_; RadiationSource exhaust_radiation_; OutdoorExhaustReverb reverb_; MechanicalSoundProcessor mechanical_sound_; mutable std::mutex mutex_; static float area_for_diameter(float diameter); static std::vector create_pipes(); }; } // namespace fluidsim::port