GNU Radio v3.6.2-149-ga6d285d9 C++ API
agc2.h
Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 /*
00003  * Copyright 2006,2012 Free Software Foundation, Inc.
00004  *
00005  * This file is part of GNU Radio
00006  *
00007  * GNU Radio is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 3, or (at your option)
00010  * any later version.
00011  *
00012  * GNU Radio is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with GNU Radio; see the file COPYING.  If not, write to
00019  * the Free Software Foundation, Inc., 51 Franklin Street,
00020  * Boston, MA 02110-1301, USA.
00021  */
00022 
00023 #ifndef INCLUDED_ANALOG_AGC2_H
00024 #define INCLUDED_ANALOG_AGC2_H
00025 
00026 #include <analog/api.h>
00027 #include <gr_complex.h>
00028 #include <math.h>
00029 
00030 namespace gr {
00031   namespace analog {
00032     namespace kernel {
00033 
00034       /*!
00035        * \brief high performance Automatic Gain Control class
00036        *
00037        * For Power the absolute value of the complex number is used.
00038        */
00039       class ANALOG_API agc2_cc
00040       {
00041       public:
00042         agc2_cc(float attack_rate = 1e-1, float decay_rate = 1e-2,
00043                 float reference = 1.0,
00044                 float gain = 1.0, float max_gain = 0.0)
00045           : _attack_rate(attack_rate), _decay_rate(decay_rate),
00046           _reference(reference),
00047           _gain(gain), _max_gain(max_gain) {};
00048 
00049         float decay_rate() const  { return _decay_rate; }
00050         float attack_rate() const { return _attack_rate; }
00051         float reference() const   { return _reference; }
00052         float gain() const        { return _gain;  }
00053         float max_gain() const     { return _max_gain; }
00054 
00055         void set_decay_rate(float rate) { _decay_rate = rate; }
00056         void set_attack_rate(float rate) { _attack_rate = rate; }
00057         void set_reference(float reference) { _reference = reference; }
00058         void set_gain(float gain) { _gain = gain; }
00059         void set_max_gain(float max_gain) { _max_gain = max_gain; }
00060 
00061         gr_complex scale(gr_complex input)
00062         {
00063           gr_complex output = input * _gain;
00064 
00065           float tmp = -_reference + sqrt(output.real()*output.real() +
00066                                          output.imag()*output.imag());
00067           float rate = _decay_rate;
00068           if((tmp) > _gain) {
00069             rate = _attack_rate;
00070           }
00071           _gain -= tmp*rate;
00072 
00073           // Not sure about this; will blow up if _gain < 0 (happens
00074           // when rates are too high), but is this the solution?
00075           if(_gain < 0.0)
00076             _gain = 10e-5;
00077 
00078           if(_max_gain > 0.0 && _gain > _max_gain) {
00079             _gain = _max_gain;
00080           }
00081           return output;
00082         }
00083 
00084         void scaleN(gr_complex output[], const gr_complex input[], unsigned n)
00085         {
00086           for(unsigned i = 0; i < n; i++)
00087             output[i] = scale (input[i]);
00088         }
00089 
00090       protected:
00091         float _attack_rate;     // attack rate for fast changing signals
00092         float _decay_rate;      // decay rate for slow changing signals
00093         float _reference;       // reference value
00094         float _gain;            // current gain
00095         float _max_gain;        // max allowable gain
00096       };
00097 
00098 
00099       class ANALOG_API agc2_ff
00100       {
00101       public:
00102         agc2_ff(float attack_rate = 1e-1, float decay_rate = 1e-2,
00103                 float reference = 1.0,
00104                 float gain = 1.0, float max_gain = 0.0)
00105           : _attack_rate(attack_rate), _decay_rate(decay_rate),
00106           _reference(reference),
00107           _gain(gain), _max_gain(max_gain) {};
00108 
00109         float attack_rate() const { return _attack_rate; }
00110         float decay_rate() const  { return _decay_rate; }
00111         float reference() const   { return _reference; }
00112         float gain() const        { return _gain;  }
00113         float max_gain() const    { return _max_gain; }
00114 
00115         void set_attack_rate(float rate) { _attack_rate = rate; }
00116         void set_decay_rate(float rate) { _decay_rate = rate; }
00117         void set_reference(float reference) { _reference = reference; }
00118         void set_gain(float gain) { _gain = gain; }
00119         void set_max_gain(float max_gain) { _max_gain = max_gain; }
00120 
00121         float scale(float input)
00122         {
00123           float output = input * _gain;
00124 
00125           float tmp = (fabsf(output)) - _reference;
00126           float rate = _decay_rate;
00127           if(fabsf(tmp) > _gain) {
00128             rate = _attack_rate;
00129           }
00130           _gain -= tmp*rate;
00131 
00132           // Not sure about this
00133           if(_gain < 0.0)
00134             _gain = 10e-5;
00135 
00136           if(_max_gain > 0.0 && _gain > _max_gain) {
00137             _gain = _max_gain;
00138           }
00139           return output;
00140         }
00141 
00142         void scaleN(float output[], const float input[], unsigned n)
00143         {
00144           for(unsigned i = 0; i < n; i++)
00145             output[i] = scale (input[i]);
00146         }
00147 
00148       protected:
00149         float _attack_rate;     // attack_rate for fast changing signals
00150         float _decay_rate;      // decay rate for slow changing signals
00151         float _reference;       // reference value
00152         float _gain;            // current gain
00153         float _max_gain;        // maximum gain
00154       };
00155       
00156     } /* namespace kernel */
00157   } /* namespace analog */
00158 } /* namespace gr */
00159 
00160 #endif /* INCLUDED_ANALOG_AGC2_H */