Load engines from TOML and improve scenario audio and carb tuning

Migrate 32 engine definitions into validated startup-loaded TOML files and separate configuration and snapshots from scenario assembly. Add camera-based stereo propagation from shared pipe geometry, preserve exhaust character, tune carburetor mixtures and idle, use ignition cuts for carb engines, and support returning to the scenario menu.

Validation: full Windows build and all 14 CTest checks passed.
This commit is contained in:
max
2026-10-24 03:24:35 +02:00
parent 5607dcf2b5
commit bf8621ad39
82 changed files with 24084 additions and 648 deletions

View File

@@ -25,7 +25,7 @@ struct OutdoorAudioConfig {
float monitor_cutoff_hz{6000.0f}; // Second-order acquisition/rendering filter.
};
// Static geometric direct/first-order reflection paths plus an explicitly
// Moving geometric direct/first-order reflection paths plus an explicitly
// approximate diffuse tail. No feedback into the fluid/combustion simulation.
class OutdoorAudio {
public:
@@ -35,6 +35,9 @@ public:
AudioFrame process(float intake_mass_flow, float exhaust_mass_flow, float second_exhaust_mass_flow = 0);
void set_scene(OutdoorScene scene) { requested_scene_.store(scene, std::memory_order_relaxed); }
OutdoorScene scene() const { return requested_scene_.load(std::memory_order_relaxed); }
// Call on the simulation thread or under the scenario's simulation lock.
void set_listener(AudioListener listener);
void set_source_positions(const std::array<Vec3,3>& positions);
void set_monitor_filter(bool enabled) { monitor_filter_ = enabled; } // Set before playback/capture.
AudioFrame dry_frame() const { return last_dry_; }
AudioFrame unfiltered_frame() const { return last_raw_; }
@@ -45,8 +48,8 @@ private:
float process(float x);
};
struct Path {
std::size_t delay_left{}, delay_right{};
float fraction_left{}, fraction_right{}, gain_left{}, gain_right{}, alpha{1};
float delay_left{}, delay_right{}, gain_left{}, gain_right{}, alpha{1};
float target_delay_left{}, target_delay_right{}, target_gain_left{}, target_gain_right{};
float state_left{}, state_right{};
int group{}; // direct, ground, wall, trees, tunnel
};
@@ -55,6 +58,7 @@ private:
std::vector<Path> paths;
std::size_t position{};
float previous_flow{};
float center_delay{}, target_center_delay{}, center_gain{}, target_center_gain{};
LowPass filter;
};
int rate_{};
@@ -66,8 +70,10 @@ private:
OutdoorExhaustReverb late_reverb_;
std::array<float, 5> weights_{1, 0, 0, 0, 0};
float scene_alpha_{}, tail_mix_{};
float geometry_alpha_{}, reverb_input_{};
AudioFrame last_dry_{}, last_raw_{};
void configure_emitter(Emitter &emitter, Vec3 position);
void update_geometry();
AudioFrame render(Emitter &emitter, float flow, AudioFrame &dry, AudioFrame &raw);
};
} // namespace fluidsim::port