100 lines
2.6 KiB
C#
100 lines
2.6 KiB
C#
// based on EnvelopeDetector.cpp v1.10 © 2006, ChunkWare Music Software, OPEN-SOURCE
|
|
using System;
|
|
|
|
namespace NAudio.Dsp
|
|
{
|
|
class EnvelopeDetector
|
|
{
|
|
private double sampleRate;
|
|
private double ms;
|
|
private double coeff;
|
|
|
|
public EnvelopeDetector() : this(1.0, 44100.0)
|
|
{
|
|
}
|
|
|
|
public EnvelopeDetector( double ms, double sampleRate )
|
|
{
|
|
System.Diagnostics.Debug.Assert( sampleRate > 0.0 );
|
|
System.Diagnostics.Debug.Assert( ms > 0.0 );
|
|
this.sampleRate = sampleRate;
|
|
this.ms = ms;
|
|
SetCoef();
|
|
}
|
|
|
|
public double TimeConstant
|
|
{
|
|
get => ms;
|
|
set
|
|
{
|
|
System.Diagnostics.Debug.Assert( value > 0.0 );
|
|
this.ms = value;
|
|
SetCoef();
|
|
}
|
|
}
|
|
|
|
public double SampleRate
|
|
{
|
|
get => sampleRate;
|
|
set
|
|
{
|
|
System.Diagnostics.Debug.Assert( value > 0.0 );
|
|
this.sampleRate = value;
|
|
SetCoef();
|
|
}
|
|
}
|
|
|
|
public double Run( double inValue, double state )
|
|
{
|
|
return inValue + coeff * (state - inValue);
|
|
}
|
|
|
|
private void SetCoef()
|
|
{
|
|
coeff = Math.Exp(-1.0 / (0.001 * ms * sampleRate));
|
|
}
|
|
}
|
|
|
|
class AttRelEnvelope
|
|
{
|
|
// DC offset to prevent denormal
|
|
protected const double DC_OFFSET = 1.0E-25;
|
|
|
|
private readonly EnvelopeDetector attack;
|
|
private readonly EnvelopeDetector release;
|
|
|
|
public AttRelEnvelope( double attackMilliseconds, double releaseMilliseconds, double sampleRate )
|
|
{
|
|
attack = new EnvelopeDetector(attackMilliseconds,sampleRate);
|
|
release = new EnvelopeDetector(releaseMilliseconds,sampleRate);
|
|
}
|
|
|
|
public double Attack
|
|
{
|
|
get => attack.TimeConstant;
|
|
set => attack.TimeConstant = value;
|
|
}
|
|
|
|
public double Release
|
|
{
|
|
get => release.TimeConstant;
|
|
set => release.TimeConstant = value;
|
|
}
|
|
|
|
public double SampleRate
|
|
{
|
|
get => attack.SampleRate;
|
|
set => attack.SampleRate = release.SampleRate = value;
|
|
}
|
|
|
|
public double Run(double inValue, double state)
|
|
{
|
|
// assumes that:
|
|
// positive delta = attack
|
|
// negative delta = release
|
|
// good for linear & log values
|
|
return inValue > state ? attack.Run( inValue, state ) : release.Run( inValue, state );
|
|
}
|
|
}
|
|
}
|