MVH/NAudio-2.2.1/NAudio.Core/Dsp/SimpleCompressor.cs
2024-06-07 00:47:07 +02:00

84 lines
2.7 KiB
C#

// based on SimpleComp v1.10 © 2006, ChunkWare Music Software, OPEN-SOURCE
using System;
using NAudio.Utils;
namespace NAudio.Dsp
{
class SimpleCompressor : AttRelEnvelope
{
// runtime variables
private double envdB; // over-threshold envelope (dB)
public SimpleCompressor(double attackTime, double releaseTime, double sampleRate)
: base(attackTime, releaseTime, sampleRate)
{
this.Threshold = 0.0;
this.Ratio = 1.0;
this.MakeUpGain = 0.0;
this.envdB = DC_OFFSET;
}
public SimpleCompressor()
: this(10.0, 10.0, 44100.0)
{
}
public double MakeUpGain { get; set; }
public double Threshold { get; set; }
public double Ratio { get; set; }
// call before runtime (in resume())
public void InitRuntime()
{
this.envdB = DC_OFFSET;
}
// // compressor runtime process
public void Process(ref double in1, ref double in2)
{
// sidechain
// rectify input
double rect1 = Math.Abs(in1); // n.b. was fabs
double rect2 = Math.Abs(in2); // n.b. was fabs
// if desired, one could use another EnvelopeDetector to smooth
// the rectified signal.
double link = Math.Max( rect1, rect2 ); // link channels with greater of 2
link += DC_OFFSET; // add DC offset to avoid log( 0 )
double keydB = Decibels.LinearToDecibels(link); // convert linear -> dB
// threshold
double overdB = keydB - Threshold; // delta over threshold
if (overdB < 0.0)
overdB = 0.0;
// attack/release
overdB += DC_OFFSET; // add DC offset to avoid denormal
envdB = Run(overdB, envdB); // run attack/release envelope
overdB = envdB - DC_OFFSET; // subtract DC offset
// Regarding the DC offset: In this case, since the offset is added before
// the attack/release processes, the envelope will never fall below the offset,
// thereby avoiding denormals. However, to prevent the offset from causing
// constant gain reduction, we must subtract it from the envelope, yielding
// a minimum value of 0dB.
// transfer function
double gr = overdB * (Ratio - 1.0); // gain reduction (dB)
gr = Decibels.DecibelsToLinear(gr) * Decibels.DecibelsToLinear(MakeUpGain); // convert dB -> linear
// output gain
in1 *= gr; // apply gain reduction to input
in2 *= gr;
}
}
}