Helmholtz testing (no decay bug)
This commit is contained in:
@@ -1,76 +1,34 @@
|
||||
using System;
|
||||
using FluidSim.Core;
|
||||
|
||||
namespace FluidSim.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Synthesises far‑field 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;
|
||||
|
||||
// ---------- Mass‑flow 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); // free‑field monopole
|
||||
|
||||
// ---- Smoothing time constants (unchanged) ----
|
||||
double tau = 0.02; // 2 ms for derivative
|
||||
alpha = Math.Exp(-dt / tau);
|
||||
|
||||
double tauLP = 0.00001; // 5 ms low‑pass 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
|
||||
/// exit‑plane mass flow.
|
||||
/// </summary>
|
||||
public float Process(OpenEndLink openEnd)
|
||||
public float Process(float massFlowOut)
|
||||
{
|
||||
double flowOut = openEnd.LastMassFlowRate; // kg/s, positive = leaving pipe
|
||||
|
||||
// Low‑pass 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;
|
||||
|
||||
// Far‑field monopole pressure (free‑field, 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user