Files
FluidSim/Core/SoundProcessor.cs
2026-05-07 23:55:02 +02:00

76 lines
2.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)
// ---------- 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 { 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)
{
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);
}
/// <summary>
/// Process one sample. The OpenEndLink provides the instantaneous
/// exitplane mass flow.
/// </summary>
public float Process(OpenEndLink openEnd)
{
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;
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;
}
}
}