Files
FluidSim/Program.cs

96 lines
3.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using SFML.Graphics;
using SFML.Window;
using SFML.System;
using System.Diagnostics;
using FluidSim.Scenarios;
using FluidSim.Audio;
namespace FluidSim;
public class Program
{
private const int SampleRate = 44100;
private static volatile bool running = true;
// Global step counter incremented every simulation step
private static long stepCount = 0;
public static void Main()
{
var mode = new VideoMode(new Vector2u(1280, 720));
var window = new RenderWindow(mode, "Fluid Simulation");
window.SetVerticalSyncEnabled(true);
window.Closed += (_, _) => { running = false; window.Close(); };
var soundEngine = new SoundEngine(bufferCapacity: 2048);
soundEngine.Volume = 70;
soundEngine.Start();
var stopwatch = Stopwatch.StartNew();
// --- Warmup: fill audio buffer with silence ---
int warmupSamples = SampleRate / 2; // 0.5 s
float[] warmup = new float[warmupSamples];
for (int i = 0; i < warmupSamples; i++)
warmup[i] = 0;
soundEngine.WriteSamples(warmup, warmupSamples);
// Reset timer after warmup this is the “realtime zero”
stopwatch.Restart();
stepCount = 0; // simulation steps start now
// --- Initialise the simulation scenario ---
Simulation.Initialize(SampleRate);
const int chunkSize = 2048;
float[] buffer = new float[chunkSize];
double lastLogTime = 0.0; // for periodic speed printout
while (window.IsOpen)
{
window.DispatchEvents();
// --- Compute how many audio samples are needed since last frame ---
double currentTime = stopwatch.Elapsed.TotalSeconds;
double elapsed = currentTime; // since stopwatch was reset
int samplesNeeded = (int)(elapsed * SampleRate) - (int)(stepCount);
// (stepCount is total generated samples, so we just need the remainder)
// --- Generate the required number of simulation steps ---
while (samplesNeeded > 0 && running)
{
int toGenerate = Math.Min(samplesNeeded, chunkSize);
for (int i = 0; i < toGenerate; i++)
{
buffer[i] = Simulation.Process();
stepCount++;
}
soundEngine.WriteSamples(buffer, toGenerate);
samplesNeeded -= toGenerate;
}
// --- Display speed ---
double simTime = stepCount / (double)SampleRate;
double wallTime = stopwatch.Elapsed.TotalSeconds;
double speed = (wallTime > 0) ? simTime / wallTime : 0.0;
// Update window title with instant speed
window.SetTitle($"FluidSim | Speed: {speed:F3}× | Steps: {stepCount}");
// Console log once per second
if (wallTime - lastLogTime >= 1.0)
{
Console.WriteLine($"Speed: {speed:F3}× ({stepCount} steps, {wallTime:F2}s wall)");
lastLogTime = wallTime;
}
// --- Rendering (placeholder) ---
window.Clear(Color.Black);
window.Display();
}
// --- Cleanup ---
soundEngine.Dispose();
window.Dispose();
}
}