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 }
|