2015-05-12 10:12:13 +00: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"
|
2018-02-03 16:06:16 +00:00
|
|
|
#include "util/movingaverage.h"
|
2018-03-20 12:49:21 +00:00
|
|
|
#include "export.h"
|
2015-05-12 10:12:13 +00:00
|
|
|
|
2018-03-03 19:23:38 +00:00
|
|
|
class SDRBASE_API AGC
|
2015-06-20 07:28:57 +00:00
|
|
|
{
|
|
|
|
public:
|
2017-08-05 21:11:05 +00:00
|
|
|
AGC(int historySize, double R);
|
2015-09-07 21:31:34 +00:00
|
|
|
virtual ~AGC();
|
2015-09-07 07:32:29 +00:00
|
|
|
|
2017-08-05 21:11:05 +00:00
|
|
|
void resize(int historySize, double R);
|
|
|
|
void setOrder(double R) { m_R = R; }
|
2015-09-07 21:31:34 +00:00
|
|
|
Real getValue();
|
2015-09-12 14:34:57 +00:00
|
|
|
Real getAverage();
|
2015-09-07 21:31:34 +00:00
|
|
|
virtual void feed(Complex& ci) = 0;
|
2015-09-07 07:32:29 +00:00
|
|
|
|
2015-09-07 21:31:34 +00:00
|
|
|
protected:
|
2017-08-05 17:08:33 +00:00
|
|
|
double m_u0; //!< AGC factor
|
2017-08-05 22:02:16 +00:00
|
|
|
double m_R; //!< ordered magnitude
|
2017-08-05 17:08:33 +00:00
|
|
|
MovingAverage<double> m_moving_average; //!< Averaging engine. The stack length conditions the smoothness of AGC.
|
|
|
|
int m_historySize; //!< Averaging length (attack)
|
|
|
|
int m_count; //!< Samples counter
|
2015-09-07 07:32:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2018-03-03 19:23:38 +00:00
|
|
|
class SDRBASE_API MagAGC : public AGC
|
2015-09-07 21:31:34 +00:00
|
|
|
{
|
|
|
|
public:
|
2017-07-24 22:58:16 +00:00
|
|
|
MagAGC(int historySize, double R, double threshold);
|
2015-09-07 21:31:34 +00:00
|
|
|
virtual ~MagAGC();
|
2017-07-27 08:50:41 +00:00
|
|
|
void setSquared(bool squared) { m_squared = squared; }
|
2018-05-06 00:39:39 +00:00
|
|
|
void resize(int historySize, int stepLength, Real R);
|
2017-08-05 21:11:05 +00:00
|
|
|
void setOrder(double R);
|
2015-09-07 21:31:34 +00:00
|
|
|
virtual void feed(Complex& ci);
|
2017-07-24 22:58:16 +00:00
|
|
|
double feedAndGetValue(const Complex& ci);
|
2017-08-05 21:11:05 +00:00
|
|
|
double getMagSq() const { return m_magsq; }
|
2017-07-25 19:21:48 +00:00
|
|
|
void setThreshold(double threshold) { m_threshold = threshold; }
|
2017-07-27 08:50:41 +00:00
|
|
|
void setThresholdEnable(bool enable);
|
2017-07-25 21:39:27 +00:00
|
|
|
void setGate(int gate) { m_gate = gate; }
|
2017-08-05 17:08:33 +00:00
|
|
|
void setStepDownDelay(int stepDownDelay) { m_stepDownDelay = stepDownDelay; }
|
|
|
|
void setClamping(bool clamping) { m_clamping = clamping; }
|
|
|
|
void setClampMax(double clampMax) { m_clampMax = clampMax; }
|
2018-04-22 07:37:34 +00:00
|
|
|
int getStepDownDelay() const { return m_stepDownDelay; }
|
|
|
|
float getStepDownValue() const;
|
2018-05-06 00:39:39 +00:00
|
|
|
float getStepValue() const;
|
2018-04-22 07:37:34 +00:00
|
|
|
|
2015-10-04 04:26:06 +00:00
|
|
|
private:
|
2017-07-27 08:50:41 +00:00
|
|
|
bool m_squared; //!< use squared magnitude (power) to compute AGC value
|
|
|
|
double m_magsq; //!< current squared magnitude (power)
|
2017-07-26 06:39:20 +00:00
|
|
|
double m_threshold; //!< squelch on magsq average
|
2017-07-27 08:50:41 +00:00
|
|
|
bool m_thresholdEnable; //!< enable squelch on power threshold
|
2017-07-26 06:39:20 +00:00
|
|
|
int m_gate; //!< power threshold gate in number of samples
|
|
|
|
int m_stepLength; //!< transition step length in number of samples
|
2017-07-26 14:23:34 +00:00
|
|
|
double m_stepDelta; //!< transition step unit by sample
|
2017-07-26 06:39:20 +00:00
|
|
|
int m_stepUpCounter; //!< step up transition samples counter
|
|
|
|
int m_stepDownCounter; //!< step down transition samples counter
|
|
|
|
int m_gateCounter; //!< threshold gate samples counter
|
2017-08-05 17:08:33 +00:00
|
|
|
int m_stepDownDelay; //!< delay in samples before cutoff (release)
|
|
|
|
bool m_clamping; //!< clamping active
|
2017-08-05 22:02:16 +00:00
|
|
|
double m_R2; //!< square of ordered magnitude
|
|
|
|
double m_clampMax; //!< maximum to clamp to as power value
|
2015-09-07 21:31:34 +00:00
|
|
|
};
|
2015-06-20 07:28:57 +00:00
|
|
|
|
2018-02-03 16:06:16 +00:00
|
|
|
template<uint32_t AvgSize>
|
2015-09-07 21:31:34 +00:00
|
|
|
class SimpleAGC
|
2015-06-20 07:28:57 +00:00
|
|
|
{
|
|
|
|
public:
|
2018-02-15 23:43:21 +00:00
|
|
|
SimpleAGC(Real initial, Real cutoff=0, Real clip=0) :
|
2018-02-03 16:06:16 +00:00
|
|
|
m_cutoff(cutoff),
|
2018-02-15 23:43:21 +00:00
|
|
|
m_clip(clip),
|
|
|
|
m_moving_average(AvgSize, initial)
|
|
|
|
{
|
|
|
|
}
|
2015-06-20 07:28:57 +00:00
|
|
|
|
2018-02-15 23:43:21 +00:00
|
|
|
void resize(Real initial, Real cutoff=0, Real clip=0)
|
2017-05-12 14:38:58 +00:00
|
|
|
{
|
2018-02-03 16:06:16 +00:00
|
|
|
m_cutoff = cutoff;
|
|
|
|
m_clip = clip;
|
2018-02-15 23:43:21 +00:00
|
|
|
m_moving_average.resize(AvgSize, initial);
|
2017-05-12 14:38:58 +00:00
|
|
|
}
|
|
|
|
|
2018-05-13 20:30:50 +00:00
|
|
|
void resizeNew(uint32_t newSize, Real initial, Real cutoff=0, Real clip=0)
|
|
|
|
{
|
|
|
|
m_cutoff = cutoff;
|
|
|
|
m_clip = clip;
|
|
|
|
m_moving_average.resize(newSize, initial);
|
|
|
|
}
|
|
|
|
|
2018-02-15 23:43:21 +00:00
|
|
|
void fill(double value)
|
|
|
|
{
|
|
|
|
m_moving_average.fill(value);
|
|
|
|
}
|
|
|
|
|
2015-06-20 07:28:57 +00:00
|
|
|
Real getValue()
|
|
|
|
{
|
2018-02-15 23:43:21 +00:00
|
|
|
if ((Real) m_moving_average.average() > m_clip) {
|
|
|
|
return (Real) m_moving_average.average();
|
|
|
|
} else {
|
2018-02-03 16:06:16 +00:00
|
|
|
return m_clip;
|
|
|
|
}
|
2015-09-07 21:31:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void feed(Real value)
|
|
|
|
{
|
2018-02-15 23:43:21 +00:00
|
|
|
if (value > m_cutoff) {
|
|
|
|
m_moving_average.feed(value);
|
2018-02-03 16:06:16 +00:00
|
|
|
}
|
2015-09-07 21:31:34 +00:00
|
|
|
}
|
|
|
|
|
2015-06-20 07:28:57 +00:00
|
|
|
private:
|
2015-09-07 21:31:34 +00:00
|
|
|
Real m_cutoff; // consider samples only above this level
|
|
|
|
Real m_clip; // never go below this level
|
2018-02-15 23:43:21 +00:00
|
|
|
MovingAverage<double> m_moving_average; // Averaging engine. The stack length conditions the smoothness of AGC.
|
|
|
|
//MovingAverageUtil<Real, double, AvgSize> m_moving_average;
|
2015-05-12 10:12:13 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* INCLUDE_GPL_DSP_AGC_H_ */
|