annotate branches/carfac_cpp/src/AGC.cpp @ 706:f8e90b5d85fd tip

Delete CARFAC code from this repository. It has been moved to https://github.com/google/carfac Please email me with your github username to get access. I've also created a new mailing list to discuss CARFAC development: https://groups.google.com/forum/#!forum/carfac-dev
author ronw@google.com
date Thu, 18 Jul 2013 20:56:51 +0000
parents f3dde307f4b8
children
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@586 6 AGC_parameters::AGC_parameters():
Ulf@586 7 n_stages_(4),
Ulf@586 8 time_constants_({0.002*1, 0.002*4, 0.002*16, 0.002*64}),
Ulf@586 9 agc_stage_gain_(2),
Ulf@586 10 decimation_({8, 2, 2, 2}),
Ulf@586 11 agc1_scales_({1.0, 1.4, 2.0, 2.8}),
Ulf@586 12 agc2_scales_({1.6, 2.25, 3.2, 4.5}),
Ulf@586 13 detect_scale_(0.25),
Ulf@586 14 agc_mix_coeff_(0.5)
Ulf@586 15 {
Ulf@586 16 // do nothing more
Ulf@586 17 }
Ulf@586 18
Ulf@564 19 AGC_coefficients::AGC_coefficients(AGC_parameters* AGC_params_p,
Ulf@545 20 float fs, int n_ch){
pfh1976@554 21 float decim = 1.0;
pfh1976@554 22 float total_DC_gain = 0.0;
pfh1976@554 23 float tau, ntimes, delay, spread_sq, u, p, dp;
pfh1976@554 24 int n_taps = 0, n_iterations = 1;
Ulf@557 25
pfh1976@554 26 n_ch_ = n_ch;
Ulf@564 27 n_agc_stages_ = AGC_params_p->n_stages_;
Ulf@564 28 agc_stage_gain_ = AGC_params_p->agc_stage_gain_;
pfh1976@554 29
pfh1976@554 30 // FloatArray initialization using assign method - dont know if this is good enough
pfh1976@554 31 agc_epsilon_.assign(n_agc_stages_, 0.0); //the 1/(tau*fs) roughly
pfh1976@554 32 agc_polez1_ = agc_epsilon_;
pfh1976@554 33 agc_polez2_ = agc_epsilon_;
pfh1976@554 34 agc_spatial_iterations_ = agc_epsilon_;
pfh1976@554 35 agc_spatial_n_taps_ = agc_epsilon_;
pfh1976@554 36 agc_mix_coeffs_ = agc_epsilon_;
Ulf@564 37 FloatArray agc1_scales = AGC_params_p->agc1_scales_;
Ulf@564 38 FloatArray agc2_scales = AGC_params_p->agc2_scales_;
pfh1976@554 39 FloatArray agc_spatial_FIR;
Ulf@564 40 decimation_ = AGC_params_p->decimation_;
pfh1976@554 41
pfh1976@554 42 for(int stage=0; stage < n_agc_stages_; stage++){
Ulf@564 43 tau = AGC_params_p->time_constants_[stage];
Ulf@564 44 decim *= AGC_params_p->decimation_[stage];
pfh1976@554 45 agc_epsilon_[stage] = 1.0 - exp(-decim/(tau*fs));
pfh1976@554 46 ntimes = tau * (fs/decim);
pfh1976@554 47 delay = (agc2_scales[stage]-agc1_scales[stage])/ntimes;
pfh1976@554 48 spread_sq = (agc1_scales[stage]*agc1_scales[stage] + agc2_scales[stage]*agc2_scales[stage])/ntimes;
pfh1976@554 49
pfh1976@554 50 u = 1.0 + 1.0/spread_sq;
pfh1976@554 51 p = u - sqrt(u*u-1);
pfh1976@554 52 dp = delay*(1 - 2*p + p*p)*0.5;
pfh1976@554 53 agc_polez1_[stage] = p - dp;
pfh1976@554 54 agc_polez2_[stage] = p + dp;
Ulf@557 55
Ulf@557 56 agc_spatial_FIR = Build_FIR_coeffs(spread_sq, delay, &n_iterations, &n_taps);
Ulf@557 57
pfh1976@554 58 agc_spatial_iterations_[stage] = (float) n_iterations;
pfh1976@554 59 agc_spatial_n_taps_[stage] = (float) n_taps;
pfh1976@554 60 agc_spatial_fir_.push_back(FloatArray());
pfh1976@554 61
pfh1976@554 62 for(int i =0; i < 3; i++)
pfh1976@554 63 agc_spatial_fir_[stage].push_back(agc_spatial_FIR[i]);
pfh1976@554 64
Ulf@564 65 total_DC_gain += pow(AGC_params_p->agc_stage_gain_,stage);
pfh1976@554 66
pfh1976@554 67 if(stage == 0)
pfh1976@554 68 agc_mix_coeffs_[stage] = 0.0;
pfh1976@554 69 else
Ulf@564 70 agc_mix_coeffs_[stage] = AGC_params_p->agc_mix_coeff_/(tau * (fs/decim));
pfh1976@554 71 }
pfh1976@554 72 agc_gain_ = total_DC_gain;
Ulf@564 73 detect_scale_ = AGC_params_p->detect_scale_/total_DC_gain;
Ulf@538 74 }
pfh1976@554 75
Ulf@557 76 FloatArray AGC_coefficients::Build_FIR_coeffs(float var, float mn, int* ptr_iters, int* ptr_taps){
pfh1976@554 77 float a, b;
pfh1976@554 78 FloatArray FIR(3);
Ulf@557 79
Ulf@557 80 // Try with 3 FIR taps
Ulf@557 81 a = (var + mn*mn - mn)/2;
Ulf@557 82 b = (var + mn*mn + mn)/2;
Ulf@557 83 FIR[0] = a;
Ulf@557 84 FIR[1] = 1.0 - a - b;
Ulf@557 85 FIR[2] = b;
Ulf@557 86
Ulf@557 87 if(FIR[1] >= 0.2){
Ulf@557 88 *ptr_taps = 3;
Ulf@557 89 return FIR;
pfh1976@554 90 }
Ulf@557 91 else //Try with 5 FIR taps
Ulf@557 92 {
Ulf@557 93 for(int n_iter = 1; n_iter<16; n_iter++){
Ulf@557 94 mn /= n_iter;
Ulf@557 95 var /= n_iter;
Ulf@557 96
Ulf@557 97 a = ((var + mn*mn)*2/5 - mn*2/3)/2;
Ulf@557 98 b = ((var + mn*mn)*2/5 + mn*2/3)/2;
Ulf@557 99 FIR[0] = a/2;
Ulf@557 100 FIR[1] = 1.0 - a - b;
Ulf@557 101 FIR[2] = b;
Ulf@557 102
Ulf@557 103 *ptr_iters = n_iter;
Ulf@557 104
Ulf@557 105 if(FIR[1] >= 0.1){
Ulf@557 106 *ptr_taps = 5;
Ulf@557 107 return FIR;
Ulf@557 108 }
Ulf@557 109 }
Ulf@557 110 //TODO: discuss how we handle errors
Ulf@557 111 printf("Too many iterations in FIR_coeffs\n");
Ulf@557 112 FIR = {0, 0, 0};
Ulf@557 113 return FIR;
Ulf@557 114 }
pfh1976@554 115 }