Files
FluidSimCpp/include/FluidSim/MechanicalSoundProcessor.hpp
2026-10-22 23:52:20 +02:00

50 lines
1.7 KiB
C++

#pragma once
#include "FluidSim/Engine.hpp"
#include <random>
namespace fluidsim::port {
// Synthetic valve, piston, combustion, chain, and gear sounds driven by live
// engine state; direct port of Core/MechanicalSoundProcessor.cs.
class MechanicalSoundProcessor {
public:
float master_gain{0.6f}, valve_tick_gain{0.9f}, piston_slap_gain{1.2f};
float combustion_gain{0.5f}, gear_whine_gain{0.12f}, cam_chain_gain{0.25f};
explicit MechanicalSoundProcessor(int sample_rate = 44100);
float process(const Crankshaft& crank, const EngineCylinder& cylinder, float load);
private:
class Resonator {
public:
Resonator(float frequency_hz, float q, float sample_rate);
float process(float input);
private:
float b1_{}, b2_{}, gain_{}, y1_{}, y2_{};
};
class OnePoleLowPass {
public:
OnePoleLowPass(float cutoff_hz, float sample_rate);
float process(float input);
private:
float alpha_{}, state_{};
};
float dt_{};
Resonator intake_tick_, exhaust_tick_;
OnePoleLowPass slap_filter_, combustion_filter_, chain_filter_;
float slap_envelope_{}, combustion_envelope_{}, chain_envelope_{};
float slap_decay_{}, combustion_decay_{}, chain_decay_{};
float gear_phase1_{}, gear_phase2_{}, gear_phase3_{};
float previous_intake_area_{}, previous_exhaust_area_{}, previous_pressure_{};
float previous_cycle_position_{-1.0f}, previous_crank_fraction_{-1.0f};
std::mt19937 random_{0x5EEDu};
std::uniform_real_distribution<float> unit_{-1.0f, 1.0f};
float random_sample();
static bool crossed_fraction(float previous, float current, float target);
};
} // namespace fluidsim::port