sdrangel/sdrbase/dsp/agc.h

135 lines
3.0 KiB
C
Raw Normal View History

2015-05-12 06:12:13 -04:00
/*
* kissagc.h
*
* Created on: May 12, 2015
* Author: f4exb
*/
#ifndef INCLUDE_GPL_DSP_AGC_H_
#define INCLUDE_GPL_DSP_AGC_H_
#include "movingaverage.h"
2015-09-07 17:31:34 -04:00
class AGC
2015-06-20 03:28:57 -04:00
{
public:
2015-09-07 17:31:34 -04:00
AGC(int historySize, Real R);
virtual ~AGC();
2015-09-07 17:31:34 -04:00
void resize(int historySize, Real R);
Real getValue();
2015-09-12 10:34:57 -04:00
Real getAverage();
2015-09-07 17:31:34 -04:00
virtual void feed(Complex& ci) = 0;
2015-09-07 17:31:34 -04:00
protected:
double m_u0;
double m_R; // objective mag
MovingAverage<double> m_moving_average; // Averaging engine. The stack length conditions the smoothness of AGC.
int m_historySize;
int m_count;
};
2015-09-07 17:31:34 -04:00
class MagSquaredAGC : public AGC
{
public:
MagSquaredAGC(int historySize, double R, double threshold);
2015-09-07 17:31:34 -04:00
virtual ~MagSquaredAGC();
virtual void feed(Complex& ci);
double feedAndGetValue(const Complex& ci);
double getMagSq() const { return m_magsq; }
2017-07-25 15:21:48 -04:00
void setThreshold(double threshold) { m_threshold = threshold; }
void setGate(int gate) { m_gate = gate; }
private:
double m_magsq;
2017-07-25 15:21:48 -04:00
double m_threshold; //!< squelch on magsq average with transition from +3dB
int m_gate;
int m_stepCounter;
int m_gateCounter;
2015-09-07 17:31:34 -04:00
};
2015-09-07 17:31:34 -04:00
class MagAGC : public AGC
{
public:
MagAGC(int historySize, double R, double threshold);
2015-09-07 17:31:34 -04:00
virtual ~MagAGC();
virtual void feed(Complex& ci);
double feedAndGetValue(const Complex& ci);
Real getMagSq() const { return m_magsq; }
2017-07-25 15:21:48 -04:00
void setThreshold(double threshold) { m_threshold = threshold; }
void setGate(int gate) { m_gate = gate; }
private:
double m_magsq;
2017-07-25 15:21:48 -04:00
double m_threshold; //!< squelch on magsq average
int m_gate;
int m_stepCounter;
int m_gateCounter;
2015-09-07 17:31:34 -04:00
};
2015-06-20 03:28:57 -04:00
2015-09-07 17:31:34 -04:00
class AlphaAGC : public AGC
{
public:
AlphaAGC(int historySize, Real R);
AlphaAGC(int historySize, Real R, Real alpha);
virtual ~AlphaAGC();
void resize(int historySize, Real R, Real alpha);
virtual void feed(Complex& ci);
Real getMagSq() const { return m_magsq; }
2015-06-20 03:28:57 -04:00
private:
2015-09-07 17:31:34 -04:00
Real m_alpha;
Real m_magsq;
2015-09-07 17:31:34 -04:00
bool m_squelchOpen;
2015-06-20 03:28:57 -04:00
};
2015-09-07 17:31:34 -04:00
class SimpleAGC
2015-06-20 03:28:57 -04:00
{
public:
2015-09-07 17:31:34 -04:00
SimpleAGC(int historySize, Real initial, Real cutoff=0, Real clip=0) :
m_squelchOpen(false),
m_fill(initial),
m_cutoff(cutoff),
m_clip(clip),
m_moving_average(historySize, initial)
2015-06-20 03:28:57 -04:00
{}
2015-09-07 17:31:34 -04:00
void resize(int historySize, Real initial, Real cutoff=0, Real clip=0)
2015-06-20 03:28:57 -04:00
{
2015-09-07 17:31:34 -04:00
m_fill = initial;
m_cutoff = cutoff;
m_clip = clip;
m_moving_average.resize(historySize, initial);
2015-06-20 03:28:57 -04:00
}
void fill(double value)
{
m_moving_average.fill(value);
}
2015-06-20 03:28:57 -04:00
Real getValue()
{
2015-09-07 17:31:34 -04:00
if (m_moving_average.average() > m_clip)
{
return m_moving_average.average();
} else
{
return m_clip;
}
}
void feed(Real value)
{
if (value > m_cutoff)
{
m_moving_average.feed(value);
}
}
2015-06-20 03:28:57 -04:00
private:
2015-09-07 17:31:34 -04:00
bool m_squelchOpen; // open for processing
Real m_fill; // refill average at this level
Real m_cutoff; // consider samples only above this level
Real m_clip; // never go below this level
MovingAverage<double> m_moving_average; // Averaging engine. The stack length conditions the smoothness of AGC.
2015-05-12 06:12:13 -04:00
};
#endif /* INCLUDE_GPL_DSP_AGC_H_ */