]> git.rkrishnan.org Git - dttsp.git/blobdiff - jDttSP/digitalagc.c
Major update
[dttsp.git] / jDttSP / digitalagc.c
index 352ebb2a6914b3d05e70a592a534aae99b9bf27c..c9fc7e50d6ddec02ceeda7629939fd2ece06dc4c 100644 (file)
@@ -36,6 +36,59 @@ Bridgewater, NJ 08807
 
 #include <common.h>
 
+void
+DigitalAgc(DIGITALAGC a, int tick) {
+
+  if (a->mode == agcOFF) {
+    int i;
+    for (i = 0; i < CXBsize(a->buff); i++)
+      CXBdata(a->buff, i) = Cscl(CXBdata(a->buff, i), a->gain.fix);
+
+  } else {
+    int i, k, hang;
+    REAL peak = 0.0;
+
+    hang = tick < a->over ? a->rcov : a->hang;
+    k = a->indx;
+
+    for (i = 0; i < CXBsize(a->buff); i++)
+      peak = max(peak, Cmag(CXBdata(a->buff, i)));
+
+    if (peak != 0) {
+      a->hist[a->indx] = a->gain.lim / peak;
+      for (i = 1, a->gain.now = a->hist[0]; i < hang; i++)
+       a->gain.now = min(a->hist[i], a->gain.now);
+    }
+    a->gain.raw = a->gain.now;
+    a->gain.now = min(a->gain.now, a->gain.top);
+
+    for (i = 0, k = (a->sndx + a->ramp) % a->mask;
+        i < CXBsize(a->buff);
+        i++, k = (k + 1) % a->mask)
+      a->circ[k] = CXBdata(a->buff, i);
+
+    if (a->gain.now != a->gain.old) {
+      REAL step = (a->gain.now - a->gain.old) / a->ramp;
+      for (i = 0, k = a->sndx;
+          i < a->ramp;
+          i++, k = (k + 1) % a->mask)
+       CXBdata(a->buff, i) = Cscl(a->circ[k], a->gain.old + i * step);
+      for (; i < CXBsize(a->buff); i++, k = (k + 1) % a->mask)
+       CXBdata(a->buff, i) = Cscl(a->circ[k], a->gain.now);
+      a->gain.old = a->gain.now;
+
+    } else {
+      for (i = 0, k = a->sndx;
+          i < CXBsize(a->buff);
+          i++, k = (k + 1) % a->mask)
+       CXBdata(a->buff, i) = Cscl(a->circ[k], a->gain.now);
+    }
+
+    a->sndx = (a->sndx + CXBsize(a->buff)) % a->mask;
+    a->indx = ((a->indx + 1) % hang);
+  }
+}
+
 /*
  * Mode is gross agc mode: off, slow, med, fast; just info
  * Hang is basic hang time
@@ -48,22 +101,17 @@ Bridgewater, NJ 08807
 DIGITALAGC
 newDigitalAgc(int Mode,
              int Hang,
-             int Size,
+             int Ramp,
              int Over,
              int Rcov,
-             int Ramp,
              int BufSize,
-             REAL MaxGain,
-             REAL Limit,
-             REAL CurGain,
-             COMPLEX *Vec) {
+             REAL MaxGain, REAL Limit, REAL CurGain, COMPLEX * Vec) {
   DIGITALAGC a = (DIGITALAGC) safealloc(1,
                                        sizeof(digital_agc_state),
                                        "new digital agc state");
   assert((Ramp >= 2) && (Ramp < BufSize));
   a->mode = Mode;
   a->hang = Hang;
-  a->size = Size;
   a->over = Over;
   a->rcov = Rcov;
   a->ramp = Ramp;
@@ -71,9 +119,12 @@ newDigitalAgc(int Mode,
   a->gain.lim = Limit;
   a->gain.old = a->gain.now = CurGain;
   a->buff = newCXB(BufSize, Vec, "agc buffer");
+  a->mask = 2 * CXBsize(a->buff);
+  a->circ = newvec_COMPLEX(2 * BufSize, "circular agc buffer");
   memset((void *) a->hist, 0, sizeof(a->hist));
   a->indx = 0;
-  a->gain.fix = 1000.0;
+  a->sndx = a->mask - Ramp;
+  a->gain.fix = 10.0;
   return a;
 }
 
@@ -81,47 +132,7 @@ void
 delDigitalAgc(DIGITALAGC a) {
   if (a) {
     delCXB(a->buff);
+    delvec_COMPLEX(a->circ);
     safefree((void *) a);
   }
 }
-
-void
-DigitalAgc(DIGITALAGC a, int tick) {
-  
-  if (a->mode == agcOFF) {
-    int i;
-    for (i = 0; i < CXBsize(a->buff); i++)
-      CXBdata(a->buff, i) = Cscl(CXBdata(a->buff, i), a->gain.fix);
-    
-  } else {
-    int i,
-        k = a->indx,
-        hang = tick < a->over ? a->rcov : a->hang;
-    REAL peak = 0.0;
-    
-    for (i = 0; i < CXBsize(a->buff); i++)
-      peak = max(peak, Cmag(CXBdata(a->buff, i)));
-    
-    if (peak != 0) {
-      a->size = hang;
-      a->hist[k] = a->gain.lim / peak;
-      for (i = 1, a->gain.now = a->hist[0]; i < hang; i++)
-       a->gain.now = max(a->hist[i], a->gain.now);
-    }
-    a->gain.now = min(a->gain.now, a->gain.top);
-    
-    if (a->gain.now != a->gain.old) {
-      REAL step = (a->gain.now - a->gain.old) / (a->ramp - 1);
-      for (i = 0; i < a->ramp; i++)
-       CXBdata(a->buff, i) = Cscl(CXBdata(a->buff, i), a->gain.old + i * step);
-      for (; i < CXBsize(a->buff); i++)
-       CXBdata(a->buff, i) = Cscl(CXBdata(a->buff, i), a->gain.now);
-      a->gain.old = a->gain.now;
-      
-    } else
-      for (i = 0; i < CXBsize(a->buff); i++)
-       CXBdata(a->buff, i) = Cscl(CXBdata(a->buff, i), a->gain.now);
-    
-    a->indx = ++k % a->size;
-  }
-}