summaryrefslogtreecommitdiff
path: root/gr-analog/lib/agc3_cc_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gr-analog/lib/agc3_cc_impl.cc')
-rw-r--r--gr-analog/lib/agc3_cc_impl.cc38
1 files changed, 25 insertions, 13 deletions
diff --git a/gr-analog/lib/agc3_cc_impl.cc b/gr-analog/lib/agc3_cc_impl.cc
index 286c6be2a2..21c9f471ea 100644
--- a/gr-analog/lib/agc3_cc_impl.cc
+++ b/gr-analog/lib/agc3_cc_impl.cc
@@ -32,19 +32,22 @@ namespace gr {
namespace analog {
agc3_cc::sptr
- agc3_cc::make(float attack_rate, float decay_rate, float reference)
+ agc3_cc::make(float attack_rate, float decay_rate,
+ float reference, float gain)
{
return gnuradio::get_initial_sptr
- (new agc3_cc_impl(attack_rate, decay_rate, reference));
+ (new agc3_cc_impl(attack_rate, decay_rate,
+ reference, gain));
}
- agc3_cc_impl::agc3_cc_impl(float attack_rate, float decay_rate, float reference)
- : sync_block("agc3_cc",
- io_signature::make(1, 1, sizeof(gr_complex)),
- io_signature::make(1, 1, sizeof(gr_complex))),
- d_attack(attack_rate), d_decay(decay_rate),
- d_reference(reference), d_gain(1.0),
- d_reset(true)
+ agc3_cc_impl::agc3_cc_impl(float attack_rate, float decay_rate,
+ float reference, float gain)
+ : sync_block("agc3_cc",
+ io_signature::make(1, 1, sizeof(gr_complex)),
+ io_signature::make(1, 1, sizeof(gr_complex))),
+ d_attack(attack_rate), d_decay(decay_rate),
+ d_reference(reference), d_gain(gain), d_max_gain(2e16),
+ d_reset(true)
{
const int alignment_multiple =
volk_get_alignment() / sizeof(gr_complex);
@@ -70,20 +73,29 @@ namespace gr {
#endif
volk_32fc_magnitude_32f(mags, &in[0], noutput_items);
// Compute a linear average on reset (no expected)
- if(__builtin_expect (d_reset, false)){
+ if(__builtin_expect(d_reset, false)) {
float mag;
- for(int i=0; i<noutput_items; i++){
+ for(int i=0; i<noutput_items; i++) {
mag += mags[i];
}
d_gain = d_reference * (noutput_items/mag);
+
+ if(d_gain < 0.0)
+ d_gain = 10e-5;
+
+ if(d_max_gain > 0.0 && d_gain > d_max_gain) {
+ d_gain = d_max_gain;
+ }
+
// scale output values
for(int i=0; i<noutput_items; i++){
out[i] = in[i] * d_gain;
}
d_reset = false;
- } else {
+ }
+ else {
// Otherwise perform a normal iir update
- for(int i=0; i<noutput_items; i++){
+ for(int i=0; i<noutput_items; i++) {
float newlevel = mags[i]; // abs(in[i]);
float rate = (newlevel > d_reference/d_gain)?d_attack:d_decay;
d_gain = (d_gain*(1-rate)) + (d_reference/newlevel)*rate;