-Added SidechainGain class

This commit is contained in:
Harry van Haaren 2013-08-16 00:57:44 +01:00
parent 7c30d2a6eb
commit c7ea67f8b0
4 changed files with 135 additions and 0 deletions

View file

@ -0,0 +1,83 @@
#include "dsp_sidechain_gain.hxx"
// for pow()
#include <cmath>
SidechainGain::SidechainGain(int rate) :
/// filter state init
w(10.0f / (rate * 0.02)),
a(0.07f),
b(1.0f / (1.0f - a)),
g1(0.0f),
g2(0.0f),
peakFrameCounter(0),
peakCountDuration( rate / 4 ),
currentTarget(0)
{
}
void SidechainGain::process(unsigned int n_samples, float** inputs, float** outputs)
{
/// audio inputs
float* inL = inputs[0];
float* inR = inputs[1];
float* side = inputs[2];
float* outL = outputs[0];
float* outR = outputs[0];
/// control inputs
float threshold = controlThreshold;
float reduction = controlReduction;
float releaseTime = controlReleaseTime;
/// analyse sidechain input for peak
float sum = 0.f;
for( unsigned int i = 0; i < n_samples; i++ )
{
if ( *side > 0.000001 )
sum += *side++;
else
sum += -*side++;
}
currentTarget = 0.f;
/// check for peak level (offset to avoid "always on" peak)
if ( sum / n_samples > threshold + 0.05 )
{
peakFrameCounter = peakCountDuration * releaseTime;
currentTarget = 1.f - reduction;
}
else if ( peakFrameCounter < 0 )
{
currentTarget = 1.f;
}
else
{
currentTarget = 1.f - reduction;
}
if ( currentTarget < 0.f )
currentTarget = 0.f;
peakFrameCounter -= n_samples;
for( unsigned int i = 0; i < n_samples; i++ )
{
/// smoothing algo is a lowpass, to de-zip the fades
/// x^^4 approximates linear volume increase for human ears
g1 += w * ( pow ( currentTarget, 4.f ) - g1 - a * g2 - 1e-20f);
g2 += w * (b * g1 - g2 + 1e-20f);
float gain = g2;
*outL++ = *inL++ * gain;
*outR++ = *inR++ * gain;
}
/// update output value
controlSidechainAmp = currentTarget;
}

View file

@ -0,0 +1,49 @@
#ifndef OPENAV_DSP_SIDECHAIN_GAIN_H
#define OPENAV_DSP_SIDECHAIN_GAIN_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
class SidechainGain
{
public:
SidechainGain(int rate);
~SidechainGain(){}
void threshold(float t){controlThreshold = t;}
void reduction(float r){controlReduction = r;}
void time (float t){controlReleaseTime = t;}
void process(unsigned int n_samples, float** inputs, float** outputs);
private:
/// audio buffers
float* audioInputL;
float* audioInputR;
float* audioSidechain;
float* audioOutputL;
float* audioOutputR;
/// control signals
float controlThreshold;
float controlReduction;
float controlReleaseTime;
float controlSidechainAmp;
/// filter state
float w, a, b, g1, g2;
/// last peak history
bool nowIsAPeak;
long peakFrameCounter;
/// nframes available for countdown
long peakCountDuration;
/// control output
float currentTarget;
};
#endif // OPENAV_DSP_SIDECHAIN_GAIN_H

View file

@ -20,6 +20,7 @@
#include "dsp/dsp_reverb.hxx"
#include "dsp/dsp_dbmeter.hxx"
#include "dsp/dsp_sidechain_gain.hxx"
using namespace std;

View file

@ -39,6 +39,8 @@ def build(bld):
'src/controller/apc.cxx',
'src/controller/gui.cxx',
'src/dsp/dsp_sidechain_gain.cxx',
'src/eventhandlergui.cxx',
'src/eventhandlerdsp.cxx']