sigproc: Add clipping detection on RACH and TSC input

Alert user of overdriven burst input indicated by a positive
threshold detector result. This indication serves as notification
that the receive RF gain level is too high for the configured
transceiver setup.

Signed-off-by: Tom Tsou <tom.tsou@ettus.com>
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index 4885654..31eea60 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -615,8 +615,16 @@
   else
     success = detectRACH(state, *burst, amp, toa);
 
-  if (!success) {
-    state->mNoises.insert(avg);
+  /* Update noise average if no bust detected or alert on error */
+  if (success <= 0) {
+    if (!success) {
+      state->mNoises.insert(avg);
+    } else if (success == -SIGERR_CLIP) {
+      LOG(ALERT) << "Clipping detected on RACH input";
+    } else if (success < 0) {
+      LOG(ALERT) << "Unhandled RACH error";
+    }
+
     delete radio_burst;
     return NULL;
   }
diff --git a/Transceiver52M/sigProcLib.cpp b/Transceiver52M/sigProcLib.cpp
index 54dd8fc..4501a13 100644
--- a/Transceiver52M/sigProcLib.cpp
+++ b/Transceiver52M/sigProcLib.cpp
@@ -40,6 +40,9 @@
 #define TABLESIZE		1024
 #define DELAYFILTS		64
 
+/* Clipping detection threshold */
+#define CLIP_THRESH		30000.0f
+
 /** Lookup tables for trigonometric approximation */
 float cosTable[TABLESIZE+1]; // add 1 element for wrap around
 float sinTable[TABLESIZE+1];
@@ -1369,6 +1372,18 @@
   return 1;
 }
 
+static int detectClipping(signalVector &burst, float thresh)
+{
+	for (size_t i = 0; i < burst.size(); i++) {
+		if (fabs(burst[i].real()) > thresh)
+			return 1;
+		if (fabs(burst[i].imag()) > thresh)
+			return 1;
+	}
+
+	return 0;
+}
+
 /* 
  * RACH burst detection
  *
@@ -1390,7 +1405,10 @@
   CorrelationSequence *sync;
 
   if ((sps != 1) && (sps != 4))
-    return -1;
+    return -SIGERR_UNSUPPORTED;
+
+  if (detectClipping(rxBurst, CLIP_THRESH))
+    return -SIGERR_CLIP;
 
   target = 8 + 40;
   head = 4;
@@ -1406,7 +1424,7 @@
   delete corr;
 
   if (rc < 0) {
-    return -1;
+    return -SIGERR_INTERNAL;
   } else if (!rc) {
     if (amp)
       *amp = 0.0f;
@@ -1443,7 +1461,10 @@
   CorrelationSequence *sync;
 
   if ((tsc < 0) || (tsc > 7) || ((sps != 1) && (sps != 4)))
-    return -1;
+    return -SIGERR_UNSUPPORTED;
+
+  if (detectClipping(rxBurst, CLIP_THRESH))
+    return -SIGERR_CLIP;
 
   target = 3 + 58 + 16 + 5;
   head = 4;
@@ -1459,7 +1480,7 @@
   delete corr;
 
   if (rc < 0) {
-    return -1;
+    return -SIGERR_INTERNAL;
   } else if (!rc) {
     if (amp)
       *amp = 0.0f;
diff --git a/Transceiver52M/sigProcLib.h b/Transceiver52M/sigProcLib.h
index 147c14c..f7f6259 100644
--- a/Transceiver52M/sigProcLib.h
+++ b/Transceiver52M/sigProcLib.h
@@ -28,6 +28,14 @@
   UNDEFINED,
 };
 
+enum signalError {
+  SIGERR_NONE,
+  SIGERR_BOUNDS,
+  SIGERR_CLIP,
+  SIGERR_UNSUPPORTED,
+  SIGERR_INTERNAL,
+};
+
 /** Convert a linear number to a dB value */
 float dB(float x);