I am trying to translate the Automatic Gain Control block from Matlab's communications toolbox. Here is the documentation but the relevant parts are summarized below:
The block diagram
Where
And
This is the code I've written:
double AGC_Detector(int N, float complex* input, int ndx)
{
double samp = 0;
for(int i = ndx*N; i < (ndx+1)*(N-1); i++)
{
samp += cabs(input[i])*cabs(input[i]);
}
samp = samp/N;
return samp;
}
void use_AGC(float complex* input,
float complex* output,
double step,
double desired_pwr,
int avrg_len,
int max_pwr,
int len)
{
double z = 0;
double e = 0;
double g = 0;
double prev_g = 0;
double dtctr = 0;
for(int i = 0; i < len; i++)
{
dtctr = AGC_Detector(avrg_len,input,i);
z = dtctr * exp(2*prev_g);
e = desired_pwr - log(z);
g = prev_g + step*e;
if(g > max_pwr)
{
g = max_pwr;
}
prev_g = g;
output[i] = input[i] * exp(prev_g);
}
}
But I am not getting the same output I get for the same values in Matlab. What am I doing wrong?
Thank You!
I figured it out. Code below gives same output as matlab for a given set of complex data.
double AGC_Detector(double complex input, double* sum, double state[], unsigned int* idx, int N)
{
unsigned int first;
unsigned int nth;
double output;
double val = cabs(input)*cabs(input);
*sum += val;
output = (*sum)*(1.0/N);
*sum -= state[*idx-1];
if(*sum < 0.0){*sum = 0.0;}
state[*idx-1] = val;
first = *idx;
nth = first + 1;
if(nth < first){nth = 0xFFFFFFFF;}
*idx = nth;
if(*idx > N-1){*idx = 1;}
return output;
}
void use_AGC(double complex* input, double complex* output, double step, double desired_pwr, int avrg_len, int max_pwr, int len)
{
unsigned int idx = 1;
int filt_len = avrg_len-1;
double K = step;
double g = 0;
double sum = 0;
double dtctr = 0;
double filterState[filt_len];
for(int i = 0; i < filt_len; i++){filterState[i] = 0;}
for(int i = 0; i < avrg_len; i++)
{
dtctr = AGC_Detector(input[i], &sum, filterState, &idx, avrg_len);
output[i] = input[i] * exp(g);
dtctr = log(dtctr);
g += K*(desired_pwr - (dtctr + 2.0*g));
if(g > max_pwr){g = max_pwr;}
}
}