96 lines
3.4 KiB
C#
96 lines
3.4 KiB
C#
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 “real‑time 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();
|
||
}
|
||
} |