Add American V8 preset, carb fuel transport, and adaptive desktop audio

This commit is contained in:
2026-10-23 12:43:57 +02:00
parent 7a5c77c1c8
commit 85d4fb828a
36 changed files with 805 additions and 144 deletions

View File

@@ -12,9 +12,17 @@ int main() {
bool reed_open_seen = false, reed_closed_seen = false, above_old_limit = false;
DynoCurve dyno;
float peak = 0, maximum_rpm = 0;
std::uint64_t release_firings = 0, one_second_coast_firings = 0;
float release_rpm = 0;
for (int sample = 0; sample < 14 * 44100; ++sample) {
scenario.set_throttle(sample >= 2 * 44100 && sample < 6 * 44100 ? .6f : 0.f);
const auto audio = scenario.process();
if (sample == 6 * 44100) {
release_firings = scenario.cylinder.combustion_count();
release_rpm = scenario.snapshot().rpm;
} else if (sample == 7 * 44100) {
one_second_coast_firings = scenario.cylinder.combustion_count() - release_firings;
}
if (!std::isfinite(audio.left) || !std::isfinite(audio.right))
throw std::runtime_error("Nonfinite two-stroke audio");
peak = std::max({peak, std::abs(audio.left), std::abs(audio.right)});
@@ -31,6 +39,8 @@ int main() {
throw std::runtime_error("Two-stroke cut fuel with the pedal open");
above_old_limit |= state.rpm > 10200;
}
if (sample >= 6 * 44100 && sample < 7 * 44100 && state.rpm > 5000 && state.fuel_cut)
throw std::runtime_error("Carbureted two-stroke cut fuel on overrun");
dyno.update(state.rpm, scenario.crankshaft.average_power / 1000,
scenario.crankshaft.average_torque);
reed_open_seen |= state.reed_open;
@@ -39,11 +49,16 @@ int main() {
}
const auto final = scenario.snapshot();
if (!above_old_limit)
throw std::runtime_error("Two-stroke did not exceed the old rev limit");
throw std::runtime_error("Two-stroke did not exceed the old rev limit: peak=" +
std::to_string(maximum_rpm) + ", idle=" + std::to_string(final.rpm));
if (!reed_open_seen || !reed_closed_seen)
throw std::runtime_error("Reed did not open and close");
if (final.rpm < 2000 || final.rpm > 4000)
throw std::runtime_error("Two-stroke idle did not recover after throttle release");
throw std::runtime_error("Two-stroke idle did not recover after throttle release: " +
std::to_string(final.rpm) + " RPM, coast firings=" +
std::to_string(one_second_coast_firings) + ", carb AFR=" +
std::to_string(scenario.carburetor.indicated_afr()) +
", cylinder fuel=" + std::to_string(scenario.cylinder.fuel_mass));
if (peak >= 1)
throw std::runtime_error("Two-stroke audio exceeds device range");
for (const auto &pipe : scenario.pipes)
@@ -83,5 +98,6 @@ int main() {
throw std::runtime_error("Motorcycle launch required pipe positivity repairs");
std::cout << "Two-stroke regression passed: peak=" << peak << ", maximum RPM=" << maximum_rpm
<< ", recovered RPM=" << final.rpm << ", bike speed=" << scenario.vehicle.speed * 3.6f
<< " km/h\n";
<< " km/h, release RPM=" << release_rpm
<< ", first coast-second firings=" << one_second_coast_firings << '\n';
}