48 lines
1.5 KiB
C#
48 lines
1.5 KiB
C#
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;
|
||
}
|
||
}
|
||
} |