using System; using FluidSim.Core; namespace FluidSim.Core { public class SoundProcessor { private readonly double dt; private readonly double scaleFactor; // 1 / (4π r) private double prevMassFlowOut; private double smoothDMdt; private readonly double alpha; // New: low‑pass the mass flow signal before derivative private double flowLP; private readonly double lpAlpha; 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 for the derivative: 10 ms (much smoother) double tau = 0.005; // 10 ms alpha = Math.Exp(-dt / tau); // Low‑pass time constant for the mass flow: 5 ms (kneecap high‑freq directly) double tauLP = 0.005; lpAlpha = Math.Exp(-dt / tauLP); } public float Process(OpenEndLink openEnd) { double flowOut = openEnd.LastMassFlowRate; // Low‑pass the mass flow signal flowLP = lpAlpha * flowLP + (1.0 - lpAlpha) * flowOut; // Derivative of the smoothed mass flow double rawDerivative = (flowLP - prevMassFlowOut) / dt; prevMassFlowOut = flowLP; // Smooth the derivative smoothDMdt = alpha * smoothDMdt + (1.0 - alpha) * rawDerivative; // Far‑field monopole pressure double pressure = smoothDMdt * scaleFactor * Gain; // Soft clip to ±1 (should rarely trigger now) return (float)pressure; } } }