annotate 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
rev   line source
Ulf@538 1 #include "AGC.h"
pfh1976@554 2 #include <cmath>
pfh1976@554 3 #include <stdlib.h>
pfh1976@554 4 #include <stdio.h>
Ulf@538 5
Ulf@545 6 AGC_coefficients::AGC_coefficients(AGC_parameters* AGC_params,
Ulf@545 7 float fs, int n_ch){
pfh1976@554 8 float decim = 1.0;
pfh1976@554 9 float total_DC_gain = 0.0;
pfh1976@554 10 float tau, ntimes, delay, spread_sq, u, p, dp;
pfh1976@554 11 int n_taps = 0, n_iterations = 1;
Ulf@557 12 // bool FIR_OK = false;
Ulf@557 13
pfh1976@554 14 n_ch_ = n_ch;
pfh1976@554 15 n_agc_stages_ = AGC_params->n_stages_;
pfh1976@554 16 agc_stage_gain_ = AGC_params->agc_stage_gain_;
pfh1976@554 17
pfh1976@554 18 // FloatArray initialization using assign method - dont know if this is good enough
pfh1976@554 19 agc_epsilon_.assign(n_agc_stages_, 0.0); //the 1/(tau*fs) roughly
pfh1976@554 20 agc_polez1_ = agc_epsilon_;
pfh1976@554 21 agc_polez2_ = agc_epsilon_;
pfh1976@554 22 agc_spatial_iterations_ = agc_epsilon_;
pfh1976@554 23 agc_spatial_n_taps_ = agc_epsilon_;
pfh1976@554 24 agc_mix_coeffs_ = agc_epsilon_;
pfh1976@554 25 FloatArray agc1_scales = AGC_params->agc1_scales_;
pfh1976@554 26 FloatArray agc2_scales = AGC_params->agc2_scales_;
pfh1976@554 27 FloatArray agc_spatial_FIR;
pfh1976@554 28 decimation_ = AGC_params->decimation_;
pfh1976@554 29
pfh1976@554 30 for(int stage=0; stage < n_agc_stages_; stage++){
pfh1976@554 31 tau = AGC_params->time_constants_[stage];
pfh1976@554 32 decim *= AGC_params->decimation_[stage];
pfh1976@554 33 agc_epsilon_[stage] = 1.0 - exp(-decim/(tau*fs));
pfh1976@554 34 ntimes = tau * (fs/decim);
pfh1976@554 35 delay = (agc2_scales[stage]-agc1_scales[stage])/ntimes;
pfh1976@554 36 spread_sq = (agc1_scales[stage]*agc1_scales[stage] + agc2_scales[stage]*agc2_scales[stage])/ntimes;
pfh1976@554 37
pfh1976@554 38 u = 1.0 + 1.0/spread_sq;
pfh1976@554 39 p = u - sqrt(u*u-1);
pfh1976@554 40 dp = delay*(1 - 2*p + p*p)*0.5;
pfh1976@554 41 agc_polez1_[stage] = p - dp;
pfh1976@554 42 agc_polez2_[stage] = p + dp;
Ulf@557 43
Ulf@557 44 // while(!FIR_OK){
Ulf@557 45 // switch(n_taps){
Ulf@557 46 // case 0:
Ulf@557 47 // n_taps = 3;
Ulf@557 48 // break;
Ulf@557 49 // case 3:
Ulf@557 50 // n_taps = 5;
Ulf@557 51 // break;
Ulf@557 52 // case 5:
Ulf@557 53 // n_iterations++;
Ulf@557 54 // if(n_iterations > 16){
Ulf@557 55 // printf("Too many n_iterations in CARFAC_DesignAGC\n");
Ulf@557 56 // exit(1);
Ulf@557 57 // }
Ulf@557 58 // break;
Ulf@557 59 // default:
Ulf@557 60 // printf("Bad n_taps in CARFAC_DesignAGC\n");
Ulf@557 61 // exit(1);
Ulf@557 62 // }
Ulf@557 63 // agc_spatial_FIR = FIR_coeffs(n_taps, spread_sq, delay, n_iterations, &FIR_OK);
Ulf@557 64 // }
Ulf@557 65
Ulf@557 66 agc_spatial_FIR = Build_FIR_coeffs(spread_sq, delay, &n_iterations, &n_taps);
Ulf@557 67
pfh1976@554 68 agc_spatial_iterations_[stage] = (float) n_iterations;
pfh1976@554 69 agc_spatial_n_taps_[stage] = (float) n_taps;
pfh1976@554 70 agc_spatial_fir_.push_back(FloatArray());
pfh1976@554 71
pfh1976@554 72 for(int i =0; i < 3; i++)
pfh1976@554 73 agc_spatial_fir_[stage].push_back(agc_spatial_FIR[i]);
pfh1976@554 74
pfh1976@554 75 total_DC_gain += pow(AGC_params->agc_stage_gain_,stage);
pfh1976@554 76
pfh1976@554 77 if(stage == 0)
pfh1976@554 78 agc_mix_coeffs_[stage] = 0.0;
pfh1976@554 79 else
pfh1976@554 80 agc_mix_coeffs_[stage] = AGC_params->agc_mix_coeff_/(tau * (fs/decim));
pfh1976@554 81 }
pfh1976@554 82 agc_gain_ = total_DC_gain;
pfh1976@554 83
pfh1976@554 84 // TODO Computation of the detect_scale_ member
Ulf@538 85 }
Ulf@545 86 AGC_coefficients::~AGC_coefficients(){
Ulf@544 87 // TODO Auto-generated destructor stub
Ulf@538 88 }
pfh1976@554 89
Ulf@557 90 //FloatArray AGC_coefficients::FIR_coeffs(int n_taps, float var, float mn, int n_iter, bool* ptr_FIR_OK)
Ulf@557 91 //{
Ulf@557 92 // float a, b;
Ulf@557 93 // FloatArray FIR(3);
Ulf@557 94 // mn /= n_iter;
Ulf@557 95 // var /= n_iter;
Ulf@557 96 //
Ulf@557 97 // switch(n_taps){
Ulf@557 98 // case 3:
Ulf@557 99 // a = (var + mn*mn - mn)/2;
Ulf@557 100 // b = (var + mn*mn + mn)/2;
Ulf@557 101 // FIR[0] = a;
Ulf@557 102 // FIR[1] = 1.0 - a - b;
Ulf@557 103 // FIR[2] = b;
Ulf@557 104 // if(FIR[1] >= 0.2)
Ulf@557 105 // *ptr_FIR_OK = true;
Ulf@557 106 // break;
Ulf@557 107 // case 5:
Ulf@557 108 // a = ((var + mn*mn)*2/5 - mn*2/3)/2;
Ulf@557 109 // b = ((var + mn*mn)*2/5 + mn*2/3)/2;
Ulf@557 110 // FIR[0] = a/2;
Ulf@557 111 // FIR[1] = 1.0 - a - b;
Ulf@557 112 // FIR[2] = b;
Ulf@557 113 // if(FIR[1] >= 0.1)
Ulf@557 114 // *ptr_FIR_OK = true;
Ulf@557 115 // break;
Ulf@557 116 // default:
Ulf@557 117 // printf("Bad n_taps in AGC_spatial_FIR\n");
Ulf@557 118 // exit(1);
Ulf@557 119 // }
Ulf@557 120 //
Ulf@557 121 // return FIR;
Ulf@557 122 //}
Ulf@557 123
Ulf@557 124 FloatArray AGC_coefficients::Build_FIR_coeffs(float var, float mn, int* ptr_iters, int* ptr_taps){
pfh1976@554 125 float a, b;
pfh1976@554 126 FloatArray FIR(3);
Ulf@557 127
Ulf@557 128 // Try with 3 FIR taps
Ulf@557 129 a = (var + mn*mn - mn)/2;
Ulf@557 130 b = (var + mn*mn + mn)/2;
Ulf@557 131 FIR[0] = a;
Ulf@557 132 FIR[1] = 1.0 - a - b;
Ulf@557 133 FIR[2] = b;
Ulf@557 134
Ulf@557 135 if(FIR[1] >= 0.2){
Ulf@557 136 *ptr_taps = 3;
Ulf@557 137 return FIR;
pfh1976@554 138 }
Ulf@557 139 else //Try with 5 FIR taps
Ulf@557 140 {
Ulf@557 141 for(int n_iter = 1; n_iter<16; n_iter++){
Ulf@557 142 mn /= n_iter;
Ulf@557 143 var /= n_iter;
Ulf@557 144
Ulf@557 145 a = ((var + mn*mn)*2/5 - mn*2/3)/2;
Ulf@557 146 b = ((var + mn*mn)*2/5 + mn*2/3)/2;
Ulf@557 147 FIR[0] = a/2;
Ulf@557 148 FIR[1] = 1.0 - a - b;
Ulf@557 149 FIR[2] = b;
Ulf@557 150
Ulf@557 151 *ptr_iters = n_iter;
Ulf@557 152
Ulf@557 153 if(FIR[1] >= 0.1){
Ulf@557 154 *ptr_taps = 5;
Ulf@557 155 return FIR;
Ulf@557 156 }
Ulf@557 157 }
Ulf@557 158 //TODO: discuss how we handle errors
Ulf@557 159 printf("Too many iterations in FIR_coeffs\n");
Ulf@557 160 FIR = {0, 0, 0};
Ulf@557 161 return FIR;
Ulf@557 162 }
pfh1976@554 163 }