Changeset 2432

Show
Ignore:
Timestamp:
12/20/06 17:13:16 (6 years ago)
Author:
jgaeddert
Message:

SigProc::agc is now functional

Location:
SigProc/trunk/SigProc
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • SigProc/trunk/SigProc/SigProc.h

    r2393 r2432  
    4747    agc(); 
    4848 
    49     // intialize constructor 
    50     agc(float _elo, 
    51         float _ehi, 
    52         float _ka, 
    53         float _kr, 
    54         float _gmin, 
    55         float _gmax); 
    56  
     49    // set signal processing values 
     50    void set_values( 
     51            float _elo, 
     52            float _ehi, 
     53            float _ka, 
     54            float _kr, 
     55            float _gmin, 
     56            float _gmax); 
     57 
     58    // get signal processing values 
     59    void get_values( 
     60            float & _elo, 
     61            float & _ehi, 
     62            float & _ka, 
     63            float & _kr, 
     64            float & _gmin, 
     65            float & _gmax); 
     66     
     67    // get status 
     68    void get_status(float & _gain, float & _energy); 
     69     
    5770    // destructor 
    5871    ~agc(); 
     
    8093    float zeta;       // low-pass filter coefficient for 
    8194                      //   estimating average energy 
     95 
     96    float energy_av;  // average energy threshold for 
     97                      // smoother tracking 
    8298}; 
    8399 
  • SigProc/trunk/SigProc/sources.cpp

    r2393 r2432  
    3434SigProc::agc::agc() 
    3535{ 
    36     energy_lo = 8192; 
    37     energy_hi = 8192; 
    38     ka = 0.5f; 
    39     kr = 0.05f; 
     36    energy_lo = 8192.0f; 
     37    energy_hi = 8192.0f; 
     38    energy_av = 8192.0f; 
     39    ka = 0.0001f; 
     40    kr = 0.000025f; 
    4041    gmin = 0.0f; 
    4142    gmax = 32768.0f; 
     
    4344    gain = 1.0f; 
    4445    energy = 0.0f; 
    45  
    4646    zeta = 0.001; 
    4747} 
    4848 
    49 // intialize constructor 
    50 SigProc::agc::agc( 
     49// destructor 
     50SigProc::agc::~agc() 
     51{ 
     52} 
     53 
     54// set signal processing values 
     55void SigProc::agc::set_values( 
    5156  float _elo, 
    5257  float _ehi, 
     
    6368    gmax = (_gmax>32768.0f) ? 32768.0f : _gmax; 
    6469 
    65     gain = 1.0f; 
    66     energy = 0.0f; 
    67  
    68     zeta = 0.001; 
    69 } 
    70  
    71 // destructor 
    72 SigProc::agc::~agc() 
    73 { 
     70    if ( gmin > gmax ) 
     71    { 
     72        std::cout << "WARNING: SigProc::agc: minimum gain " 
     73                  << "must be less than maximum gain" 
     74                  << std::endl; 
     75    } 
     76 
     77    if ( energy_lo > energy_hi ) 
     78    { 
     79        std::cout << "WARNING: SigProc::agc: low energy threshold " 
     80                  << "must be less than high energy threshold" 
     81                  << std::endl; 
     82    } 
     83     
     84    energy_av = 0.5*( energy_hi + energy_lo ); 
     85} 
     86 
     87// get signal processing values 
     88void SigProc::agc::get_values( 
     89  float & _elo, 
     90  float & _ehi, 
     91  float & _ka, 
     92  float & _kr, 
     93  float & _gmin, 
     94  float & _gmax) 
     95{ 
     96    _elo = energy_lo; 
     97    _ehi = energy_hi; 
     98    _ka = ka; 
     99    _kr = kr; 
     100    _gmin = gmin; 
     101    _gmax = gmax; 
     102} 
     103 
     104// get status 
     105void SigProc::agc::get_status(float & _gain, float & _energy) 
     106{ 
     107    _gain = gain; 
     108    _energy = energy; 
    74109} 
    75110 
     
    78113{ 
    79114    // update energy value 
    80     energy = (1-zeta)*energy + zeta*abs(I); 
     115    // TODO: implement IIR low-pass filter 
     116    energy = (1-zeta)*energy + zeta*gain*abs(I); 
    81117     
    82118    // update gain value 
     
    91127{ 
    92128    short abs_I, abs_Q; 
    93     float energy_this; 
     129    float energy_this, I_tmp, Q_tmp; 
    94130     
    95131    // update energy 
     132    // TODO: implement IIR low-pass filter 
     133    // NOTE: A good approximation to A=sqrt(I^2 + Q^2) is 
     134    //   A ~= max(|I|,|Q|) + 0.30059*min(|I|,|Q|) 
     135    // This yields a MSE of about -30dB 
    96136    abs_I = abs(I); 
    97137    abs_Q = abs(Q); 
     
    101141        energy_this = float(abs_Q) + 0.30059f*float(abs_I); 
    102142     
    103     energy = (1-zeta)*energy + zeta*energy_this; 
     143    energy = (1-zeta)*energy + zeta*gain*energy_this; 
    104144 
    105145    // update gain value 
    106146    compute_gain(); 
    107147 
    108     // apply gain 
    109     I = short( I*gain ); 
    110     Q = short( Q*gain ); 
     148    // apply gain to I-channel, prevent clipping 
     149    I_tmp = float(I)*gain; 
     150    if ( I_tmp > float(SHRT_MAX) ) 
     151        I = SHRT_MAX; 
     152    else if ( I_tmp < -float(SHRT_MAX) ) 
     153        I = -SHRT_MAX; 
     154    else 
     155        I = short(I_tmp); 
     156     
     157    // apply gain to Q-channel, prevent clipping 
     158    Q_tmp = float(Q)*gain; 
     159    if ( Q_tmp > float(SHRT_MAX) ) 
     160        Q = SHRT_MAX; 
     161    else if ( Q_tmp < -float(SHRT_MAX) ) 
     162        Q = -SHRT_MAX; 
     163    else 
     164        Q = short(Q_tmp); 
     165     
    111166} 
    112167 
     
    124179        gain *= 1 + kr*(energy_hi - energy)/energy_hi; 
    125180    } 
     181    else if ( energy > energy_av ) 
     182    { 
     183        gain *= 1 - ka*(energy - energy_av)/energy_av; 
     184    } 
     185    else if ( energy < energy_av ) 
     186    { 
     187        gain *= 1 + kr*(energy_av - energy)/energy_av; 
     188    } 
    126189    else 
    127190    { 
     
    129192    } 
    130193 
     194    // hard limit gain values 
    131195    gain = (gain>gmax) ? gmax : gain; 
    132196    gain = (gain<gmin) ? gmin : gain;