Mercurial > hg > aimc
view branches/carfac_cpp/src/AGC.cpp @ 557:0fde611fcd10
* SUGGESTED re-factor of the FIR_coeffs calls (old code remains in commented out form for easy comparison).
* Minor changes to CARFAC and IHC corresponding to MATLAB refactoring
author | Ulf.Hammarqvist@gmail.com |
---|---|
date | Mon, 09 Apr 2012 09:43:02 +0000 |
parents | d18ff10b5559 |
children | 8ca6eb401a03 |
line wrap: on
line source
#include "AGC.h" #include <cmath> #include <stdlib.h> #include <stdio.h> AGC_coefficients::AGC_coefficients(AGC_parameters* AGC_params, float fs, int n_ch){ float decim = 1.0; float total_DC_gain = 0.0; float tau, ntimes, delay, spread_sq, u, p, dp; int n_taps = 0, n_iterations = 1; // bool FIR_OK = false; n_ch_ = n_ch; n_agc_stages_ = AGC_params->n_stages_; agc_stage_gain_ = AGC_params->agc_stage_gain_; // FloatArray initialization using assign method - dont know if this is good enough agc_epsilon_.assign(n_agc_stages_, 0.0); //the 1/(tau*fs) roughly agc_polez1_ = agc_epsilon_; agc_polez2_ = agc_epsilon_; agc_spatial_iterations_ = agc_epsilon_; agc_spatial_n_taps_ = agc_epsilon_; agc_mix_coeffs_ = agc_epsilon_; FloatArray agc1_scales = AGC_params->agc1_scales_; FloatArray agc2_scales = AGC_params->agc2_scales_; FloatArray agc_spatial_FIR; decimation_ = AGC_params->decimation_; for(int stage=0; stage < n_agc_stages_; stage++){ tau = AGC_params->time_constants_[stage]; decim *= AGC_params->decimation_[stage]; agc_epsilon_[stage] = 1.0 - exp(-decim/(tau*fs)); ntimes = tau * (fs/decim); delay = (agc2_scales[stage]-agc1_scales[stage])/ntimes; spread_sq = (agc1_scales[stage]*agc1_scales[stage] + agc2_scales[stage]*agc2_scales[stage])/ntimes; u = 1.0 + 1.0/spread_sq; p = u - sqrt(u*u-1); dp = delay*(1 - 2*p + p*p)*0.5; agc_polez1_[stage] = p - dp; agc_polez2_[stage] = p + dp; // while(!FIR_OK){ // switch(n_taps){ // case 0: // n_taps = 3; // break; // case 3: // n_taps = 5; // break; // case 5: // n_iterations++; // if(n_iterations > 16){ // printf("Too many n_iterations in CARFAC_DesignAGC\n"); // exit(1); // } // break; // default: // printf("Bad n_taps in CARFAC_DesignAGC\n"); // exit(1); // } // agc_spatial_FIR = FIR_coeffs(n_taps, spread_sq, delay, n_iterations, &FIR_OK); // } agc_spatial_FIR = Build_FIR_coeffs(spread_sq, delay, &n_iterations, &n_taps); agc_spatial_iterations_[stage] = (float) n_iterations; agc_spatial_n_taps_[stage] = (float) n_taps; agc_spatial_fir_.push_back(FloatArray()); for(int i =0; i < 3; i++) agc_spatial_fir_[stage].push_back(agc_spatial_FIR[i]); total_DC_gain += pow(AGC_params->agc_stage_gain_,stage); if(stage == 0) agc_mix_coeffs_[stage] = 0.0; else agc_mix_coeffs_[stage] = AGC_params->agc_mix_coeff_/(tau * (fs/decim)); } agc_gain_ = total_DC_gain; // TODO Computation of the detect_scale_ member } AGC_coefficients::~AGC_coefficients(){ // TODO Auto-generated destructor stub } //FloatArray AGC_coefficients::FIR_coeffs(int n_taps, float var, float mn, int n_iter, bool* ptr_FIR_OK) //{ // float a, b; // FloatArray FIR(3); // mn /= n_iter; // var /= n_iter; // // switch(n_taps){ // case 3: // a = (var + mn*mn - mn)/2; // b = (var + mn*mn + mn)/2; // FIR[0] = a; // FIR[1] = 1.0 - a - b; // FIR[2] = b; // if(FIR[1] >= 0.2) // *ptr_FIR_OK = true; // break; // case 5: // a = ((var + mn*mn)*2/5 - mn*2/3)/2; // b = ((var + mn*mn)*2/5 + mn*2/3)/2; // FIR[0] = a/2; // FIR[1] = 1.0 - a - b; // FIR[2] = b; // if(FIR[1] >= 0.1) // *ptr_FIR_OK = true; // break; // default: // printf("Bad n_taps in AGC_spatial_FIR\n"); // exit(1); // } // // return FIR; //} FloatArray AGC_coefficients::Build_FIR_coeffs(float var, float mn, int* ptr_iters, int* ptr_taps){ float a, b; FloatArray FIR(3); // Try with 3 FIR taps a = (var + mn*mn - mn)/2; b = (var + mn*mn + mn)/2; FIR[0] = a; FIR[1] = 1.0 - a - b; FIR[2] = b; if(FIR[1] >= 0.2){ *ptr_taps = 3; return FIR; } else //Try with 5 FIR taps { for(int n_iter = 1; n_iter<16; n_iter++){ mn /= n_iter; var /= n_iter; a = ((var + mn*mn)*2/5 - mn*2/3)/2; b = ((var + mn*mn)*2/5 + mn*2/3)/2; FIR[0] = a/2; FIR[1] = 1.0 - a - b; FIR[2] = b; *ptr_iters = n_iter; if(FIR[1] >= 0.1){ *ptr_taps = 5; return FIR; } } //TODO: discuss how we handle errors printf("Too many iterations in FIR_coeffs\n"); FIR = {0, 0, 0}; return FIR; } }