using System; using FluidSim.Interfaces; namespace FluidSim.Core { public class SoundProcessor { private readonly double dt; private readonly double scaleFactor; // 1 / (4π r) and a user gain private double prevMassFlowOut; // Simple low‑pass for derivative smoothing (≈ 2‑3 ms) private double smoothDMdt; private readonly double alpha; public float Gain { get; set; } = 1.0f; public SoundProcessor(int sampleRate, double listenerDistanceMeters = 1.0) { dt = 1.0 / sampleRate; scaleFactor = 1.0 / (4.0 * Math.PI * listenerDistanceMeters); // Smoothing time constant ~ 2 ms, blocks single‑sample spikes double tau = 0.002; alpha = Math.Exp(-dt / tau); } public float Process(Port port) { // Outflow mass flow (positive = leaving pipe) double flowOut = -port.MassFlowRate; // Derivative double rawDerivative = (flowOut - prevMassFlowOut) / dt; prevMassFlowOut = flowOut; // Smooth the derivative to kill isolated spikes smoothDMdt = alpha * smoothDMdt + (1.0 - alpha) * rawDerivative; // Far‑field monopole pressure double pressure = smoothDMdt * scaleFactor * Gain; // Soft clip to ±1 for audio output (safe limit) float sample = (float)Math.Tanh(pressure); return sample; } } }