SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
agc.cpp
Go to the documentation of this file.
1 /*
2  * agc.cpp
3  *
4  * Created on: Sep 7, 2015
5  * Author: f4exb
6  */
7 
8 #include <algorithm>
9 #include "dsp/agc.h"
10 
11 #include "util/stepfunctions.h"
12 
13 AGC::AGC(int historySize, double R) :
14  m_u0(1.0),
15  m_R(R),
16  m_moving_average(historySize, m_R),
17  m_historySize(historySize),
18  m_count(0)
19 {}
20 
22 {}
23 
24 void AGC::resize(int historySize, double R)
25 {
26  m_R = R;
27  m_moving_average.resize(historySize, R);
28  m_historySize = historySize;
29  m_count = 0;
30 }
31 
33 {
34  return m_u0;
35 }
36 
38 {
39  return m_moving_average.average();
40 }
41 
42 
43 MagAGC::MagAGC(int historySize, double R, double threshold) :
44  AGC(historySize, R),
45  m_squared(false),
46  m_magsq(0.0),
47  m_threshold(threshold),
48  m_thresholdEnable(true),
49  m_gate(0),
50  m_stepLength(std::min(2400, historySize/2)), // max 50 ms (at 48 kHz)
51  m_stepDelta(1.0/m_stepLength),
52  m_stepUpCounter(0),
53  m_stepDownCounter(0),
54  m_gateCounter(0),
55  m_stepDownDelay(historySize),
56  m_clamping(false),
57  m_R2(R*R),
58  m_clampMax(1.0),
59  m_hardLimiting(false)
60 {}
61 
63 {}
64 
65 void MagAGC::resize(int historySize, int stepLength, Real R)
66 {
67  m_R2 = R*R;
68  m_stepLength = stepLength;
69  m_stepDelta = 1.0 / m_stepLength;
70  m_stepUpCounter = 0;
72  AGC::resize(historySize, R);
74 }
75 
76 void MagAGC::setOrder(double R)
77 {
78  m_R2 = R*R;
79  AGC::setOrder(R);
81 }
82 
83 void MagAGC::setThresholdEnable(bool enable)
84 {
85  if (m_thresholdEnable != enable)
86  {
87  m_stepUpCounter = 0;
89  }
90 
91  m_thresholdEnable = enable;
92 }
93 
95 {
96  ci *= feedAndGetValue(ci);
97 }
98 
99 double MagAGC::hardLimiter(double multiplier, double magsq)
100 {
101  if ((m_hardLimiting) && (multiplier*multiplier*magsq > 1.0)) {
102  return 1.0 / (multiplier*sqrt(magsq));
103  } else {
104  return multiplier;
105  }
106 }
107 
109 {
110  m_magsq = ci.real()*ci.real() + ci.imag()*ci.imag();
112 
113  if (m_clamping)
114  {
115  if (m_squared)
116  {
117  if (m_magsq > m_clampMax) {
118  m_u0 = m_clampMax / m_magsq;
119  } else {
121  }
122  }
123  else
124  {
125  if (sqrt(m_magsq) > m_clampMax) {
127  } else {
129  }
130  }
131  }
132  else
133  {
135  }
136 
137  if (m_thresholdEnable)
138  {
139  bool open = false;
140 
141  if (m_magsq > m_threshold)
142  {
143  if (m_gateCounter < m_gate) {
144  m_gateCounter++;
145  } else {
146  open = true;
147  }
148  }
149  else
150  {
151  m_gateCounter = 0;
152  }
153 
154  if (open)
155  {
156  m_count = m_stepDownDelay; // delay before step down (grace delay)
157  }
158  else
159  {
160  m_count--;
161  m_gateCounter = m_gate; // keep gate open during grace
162  }
163 
164  if (m_count > 0) // up phase
165  {
166  m_stepDownCounter = m_stepUpCounter; // prepare for step down
167 
168  if (m_stepUpCounter < m_stepLength) // step up
169  {
170  m_stepUpCounter++;
172  }
173  else // steady open
174  {
175  return hardLimiter(m_u0, m_magsq);
176  }
177  }
178  else // down phase
179  {
180  m_stepUpCounter = m_stepDownCounter; // prepare for step up
181 
182  if (m_stepDownCounter > 0) // step down
183  {
186  }
187  else // steady closed
188  {
189  return 0.0;
190  }
191  }
192  }
193  else
194  {
195  return hardLimiter(m_u0, m_magsq);
196  }
197 }
198 
199 float MagAGC::getStepValue() const
200 {
201  if (m_count > 0) // up phase
202  {
204  }
205  else // down phase
206  {
208  }
209 }
int m_gate
power threshold gate in number of samples
Definition: agc.h:62
int m_stepDownCounter
step down transition samples counter
Definition: agc.h:66
void feed(Type value)
Definition: movingaverage.h:24
void setThresholdEnable(bool enable)
Definition: agc.cpp:83
double m_u0
AGC factor.
Definition: agc.h:28
Real getAverage()
Definition: agc.cpp:37
double m_threshold
squelch on magsq average
Definition: agc.h:60
int m_historySize
Averaging length (attack)
Definition: agc.h:31
void fill(Type value)
Definition: movingaverage.h:37
static float smootherstep(float x)
Definition: stepfunctions.h:24
Type average() const
Definition: movingaverage.h:43
int m_count
Samples counter.
Definition: agc.h:32
double feedAndGetValue(const Complex &ci)
Definition: agc.cpp:108
double m_R2
square of ordered magnitude
Definition: agc.h:70
MagAGC(int historySize, double R, double threshold)
Definition: agc.cpp:43
double hardLimiter(double multiplier, double magsq)
Definition: agc.cpp:99
void resize(int historySize, int stepLength, Real R)
Definition: agc.cpp:65
double m_clampMax
maximum to clamp to as power value
Definition: agc.h:71
void resize(int historySize, double R)
Definition: agc.cpp:24
bool m_clamping
clamping active
Definition: agc.h:69
void setOrder(double R)
Definition: agc.cpp:76
MovingAverage< double > m_moving_average
Averaging engine. The stack length conditions the smoothness of AGC.
Definition: agc.h:30
double m_R
ordered magnitude
Definition: agc.h:29
virtual void feed(Complex &ci)
Definition: agc.cpp:94
int m_gateCounter
threshold gate samples counter
Definition: agc.h:67
int m_stepLength
transition step length in number of samples
Definition: agc.h:63
Fixed< IntType, IntBits > sqrt(Fixed< IntType, IntBits > const &x)
Definition: fixed.h:2283
AGC(int historySize, double R)
Definition: agc.cpp:13
bool m_squared
use squared magnitude (power) to compute AGC value
Definition: agc.h:58
double m_magsq
current squared magnitude (power)
Definition: agc.h:59
Definition: agc.h:15
double m_stepDelta
transition step unit by sample
Definition: agc.h:64
void setOrder(double R)
Definition: agc.h:22
virtual ~AGC()
Definition: agc.cpp:21
virtual ~MagAGC()
Definition: agc.cpp:62
Real getValue()
Definition: agc.cpp:32
int m_stepDownDelay
delay in samples before cutoff (release)
Definition: agc.h:68
int m_stepUpCounter
step up transition samples counter
Definition: agc.h:65
float getStepValue() const
Definition: agc.cpp:199
std::complex< Real > Complex
Definition: dsptypes.h:43
float Real
Definition: dsptypes.h:42
void resize(int historySize, Type initial)
Definition: movingaverage.h:16
bool m_thresholdEnable
enable squelch on power threshold
Definition: agc.h:61
bool m_hardLimiting
hard limit multiplier so that resulting sample magnitude does not exceed 1.0
Definition: agc.h:72
T min(const T &x, const T &y)
Definition: framework.h:440