using SFML.Graphics; using SFML.Window; using SFML.System; using System.Diagnostics; using FluidSim.Core; namespace FluidSim; public class Program { private const int SampleRate = 44100; private static volatile bool running = true; 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(); double lastAudioTime = 0.0; var stopwatch = Stopwatch.StartNew(); int warmupSamples = SampleRate / 2; float[] warmup = new float[warmupSamples]; for (int i = 0; i < warmupSamples; i++) warmup[i] = 0; soundEngine.WriteSamples(warmup, warmupSamples); lastAudioTime = stopwatch.Elapsed.TotalSeconds; const int chunkSize = 2048; float[] buffer = new float[chunkSize]; Simulation.Initialize(SampleRate); while (window.IsOpen) { window.DispatchEvents(); double currentTime = stopwatch.Elapsed.TotalSeconds; double elapsed = currentTime - lastAudioTime; int samplesNeeded = (int)(elapsed * SampleRate); while (samplesNeeded > 0 && running) { int toGenerate = Math.Min(samplesNeeded, chunkSize); for (int i = 0; i < toGenerate; i++) { buffer[i] = Simulation.Process(); } soundEngine.WriteSamples(buffer, toGenerate); samplesNeeded -= toGenerate; } lastAudioTime = currentTime; window.Clear(Color.Black); window.Display(); } soundEngine.Dispose(); window.Dispose(); } }