Helmholtz testing (no decay bug)

This commit is contained in:
max
2026-05-09 01:44:35 +02:00
parent 9c9e23147a
commit 77ef4753a3
23 changed files with 1811 additions and 2118 deletions

View File

@@ -1,76 +1,34 @@
using System;
using FluidSim.Core;
namespace FluidSim.Core
{
/// <summary>
/// Synthesises farfield exhaust sound using the monopole model
/// of Jones (1978). The radiated pressure is proportional to the
/// time derivative of the mass flow at the pipe exit.
///
/// Reference:
/// Jones, A.D. (1978) "Noise characteristics and exhaust process
/// gas dynamics of a small 2-stroke engine", PhD thesis, Univ. Adelaide.
/// </summary>
public class SoundProcessor
{
private readonly double dt;
private readonly double r; // listener distance (m)
private readonly double scaleFactor; // 1 / (4π r) (free-field monopole)
private readonly float dt;
private readonly float scaleFactor; // 1 / (4π r)
private float flowLP, prevMassFlowOut, smoothDMdt;
private readonly float lpAlpha, alpha;
// ---------- Massflow derivative (identical to original) ----------
private double flowLP;
private readonly double lpAlpha;
private double prevMassFlowOut;
private double smoothDMdt;
private readonly double alpha;
public float Gain = 1f;
public float Gain { get; set; } = 1.0f;
/// <summary>
/// </summary>
/// <param name="sampleRate">Audio sample rate (Hz).</param>
/// <param name="listenerDistanceMeters">Listener distance (m).</param>
/// <param name="pipeDiameterMeters">Ignored in this model; kept for compatibility.</param>
public SoundProcessor(int sampleRate,
double listenerDistanceMeters = 1.0,
double pipeDiameterMeters = 0.0217)
public SoundProcessor(int sampleRate, float listenerDistance = 1f)
{
dt = 1.0 / sampleRate;
r = listenerDistanceMeters;
scaleFactor = 1.0 / (4.0 * Math.PI * r); // freefield monopole
// ---- Smoothing time constants (unchanged) ----
double tau = 0.02; // 2 ms for derivative
alpha = Math.Exp(-dt / tau);
double tauLP = 0.00001; // 5 ms lowpass on mass flow
lpAlpha = Math.Exp(-dt / tauLP);
dt = 1f / sampleRate;
scaleFactor = 1f / (4f * MathF.PI * listenerDistance);
float tau = 0.02f;
alpha = MathF.Exp(-dt / tau);
float tauLP = 0.005f;
lpAlpha = MathF.Exp(-dt / tauLP);
}
/// <summary>
/// Process one sample. The OpenEndLink provides the instantaneous
/// exitplane mass flow.
/// </summary>
public float Process(OpenEndLink openEnd)
public float Process(float massFlowOut)
{
double flowOut = openEnd.LastMassFlowRate; // kg/s, positive = leaving pipe
// Lowpass the mass flow signal
flowLP = lpAlpha * flowLP + (1.0 - lpAlpha) * flowOut;
// Derivative of the smoothed mass flow
double rawDerivative = (flowLP - prevMassFlowOut) / dt;
flowLP = lpAlpha * flowLP + (1f - lpAlpha) * massFlowOut;
float rawDerivative = (flowLP - prevMassFlowOut) / dt;
prevMassFlowOut = flowLP;
// Smooth the derivative
smoothDMdt = alpha * smoothDMdt + (1.0 - alpha) * rawDerivative;
// Farfield monopole pressure (freefield, Jones eq. 2.15 adapted)
double pressure = smoothDMdt * scaleFactor * Gain;
// Soft clip to ±1
return (float)pressure;
smoothDMdt = alpha * smoothDMdt + (1f - alpha) * rawDerivative;
float pressure = smoothDMdt * scaleFactor * Gain;
return MathF.Tanh(pressure);
}
}
}