aboutsummaryrefslogtreecommitdiffstats
path: root/Transceiver52M/sigProcLib.cpp
diff options
context:
space:
mode:
authorThomas Tsou <tom@tsou.cc>2013-08-21 20:58:00 -0400
committerThomas Tsou <tom@tsou.cc>2013-09-05 06:07:50 -0400
commitef7c258cbf2b56a9dca6df68c4b03f60cdd52bd4 (patch)
tree063129f77a5f9c599b22379a6485950b0322d488 /Transceiver52M/sigProcLib.cpp
parentfb6e75789b9a87065814b4caf8c5cad77f253df6 (diff)
Transceiver52M: Refactor RACH and TSC detection
Both RACH and normal bursts are detected with the same approach of midamble correlation combined with peak-to-average ratio. The difference is the midamble placements and lengths. Thus, there is no reason to have independent implementations. This patch creates a common call burstDetect(), while leaving the correlation window indexing in the original calls. Signed-off-by: Thomas Tsou <tom@tsou.cc>
Diffstat (limited to 'Transceiver52M/sigProcLib.cpp')
-rw-r--r--Transceiver52M/sigProcLib.cpp250
1 files changed, 133 insertions, 117 deletions
diff --git a/Transceiver52M/sigProcLib.cpp b/Transceiver52M/sigProcLib.cpp
index b34c580..74dd915 100644
--- a/Transceiver52M/sigProcLib.cpp
+++ b/Transceiver52M/sigProcLib.cpp
@@ -955,78 +955,36 @@ release:
return status;
}
-int detectRACHBurst(signalVector &rxBurst,
- float thresh,
- int sps,
- complex *amp,
- float *toa)
+static float computePeakRatio(signalVector *corr,
+ int sps, float toa, complex amp)
{
- int start, len, num = 0;
- float _toa, rms, par, avg = 0.0f;
- complex _amp, *peak;
- signalVector corr, *sync = gRACHSequence->sequence;
-
- if ((sps != 1) && (sps != 2) && (sps != 4))
- return -1;
+ int num = 0;
+ complex *peak;
+ float rms, avg = 0.0;
- start = 40 * sps;
- len = 24 * sps;
- corr = signalVector(len);
+ peak = corr->begin() + (int) rint(toa);
- if (!convolve(&rxBurst, sync, &corr,
- CUSTOM, start, len, sps, 0)) {
- return -1;
- }
-
- /* Perform fast peak detection (no interpolation) for initial gating */
- _amp = fastPeakDetect(corr, &_toa);
-
- /* Restrict peak-to-average calculations at the edges */
- if ((_toa < 3) || (_toa > len - 3))
- goto notfound;
-
- peak = corr.begin() + (int) rint(_toa);
+ /* Check for bogus results */
+ if ((toa < 0.0) || (toa > corr->size()))
+ return 0.0;
- /* Compute peak-to-average ratio. Reject if we don't have enough values */
for (int i = 2 * sps; i <= 5 * sps; i++) {
- if (peak - i >= corr.begin()) {
+ if (peak - i >= corr->begin()) {
avg += (peak - i)->norm2();
num++;
}
- if (peak + i < corr.end()) {
+ if (peak + i < corr->end()) {
avg += (peak + i)->norm2();
num++;
}
}
if (num < 2)
- goto notfound;
+ return 0.0;
rms = sqrtf(avg / (float) num) + 0.00001;
- par = _amp.abs() / rms;
- if (par < thresh)
- goto notfound;
-
- /* Run the full peak detection to obtain when we have a burst */
- _amp = peakDetect(corr, &_toa, NULL);
-
- /* Subtract forward tail bits from delay */
- if (toa)
- *toa = _toa - 8 * sps;
-
- /* Normalize our channel gain */
- if (amp)
- *amp = _amp / gRACHSequence->gain;
-
- return 1;
-
-notfound:
- if (amp)
- *amp = 0.0f;
- if (toa)
- *toa = 0.0f;
- return 0;
+ return (amp.abs()) / rms;
}
bool energyDetect(signalVector &rxBurst,
@@ -1047,94 +1005,152 @@ bool energyDetect(signalVector &rxBurst,
return (energy/windowLength > detectThreshold*detectThreshold);
}
-int analyzeTrafficBurst(signalVector &rxBurst, unsigned tsc, float thresh,
- int sps, complex *amp, float *toa, unsigned max_toa,
- bool chan_req, signalVector **chan, float *chan_offset)
+/*
+ * Detect a burst based on correlation and peak-to-average ratio. Perform
+ * fast peak detection (no interpolation) for initial gating. Interpolate
+ * the sub-sample peak after we have detected the burst.
+ */
+static int detectBurst(signalVector &burst,
+ signalVector &corr, CorrelationSequence *sync,
+ float thresh, int sps, complex *amp, float *toa,
+ int start, int len)
{
- int start, target, len, num = 0;
- complex _amp, *peak;
- float _toa, rms, par, avg = 0.0f;
- signalVector corr, *sync, *_chan;
+ /* Correlate */
+ if (!convolve(&burst, sync->sequence, &corr,
+ CUSTOM, start, len, sps, 0)) {
+ return -1;
+ }
- if ((tsc < 0) || (tsc > 7) || ((sps != 1) && (sps != 2) && (sps != 4)))
+ /* Peak detection - place restrictions at correlation edges */
+ *amp = fastPeakDetect(corr, toa);
+
+ if ((*toa < 3 * sps) || (*toa > len - 3 * sps))
+ return 0;
+
+ /* Peak -to-average ratio */
+ if (computePeakRatio(&corr, sps, *toa, *amp) < thresh)
+ return 0;
+
+ /* Run the full peak detection when we have a burst */
+ *amp = peakDetect(corr, toa, NULL);
+
+ /* Normalize our channel gain */
+ *amp = *amp / sync->gain;
+
+ return 1;
+}
+
+/*
+ * RACH burst detection
+ *
+ * Correlation window parameters:
+ * target: Tail bits + RACH length (reduced from 41 to a multiple of 4)
+ * head: Search 4 symbols before target
+ * tail: Search 8 symbols after target
+ */
+int detectRACHBurst(signalVector &rxBurst,
+ float thresh,
+ int sps,
+ complex *amp,
+ float *toa)
+{
+ int rc, start, target, head, tail, len;
+ float _toa;
+ complex _amp;
+ signalVector corr;
+ CorrelationSequence *sync;
+
+ if ((sps != 1) && (sps != 2) && (sps != 4))
return -1;
- target = 3 + 58 + 5 + 16;
- start = (target - 8) * sps;
- len = (8 + 8 + max_toa) * sps;
+ target = 8 + 40;
+ head = 4;
+ tail = 8;
- sync = gMidambles[tsc]->sequence;
- sync = gMidambles[tsc]->sequence;
+ start = (target - head) * sps - 1;
+ len = (head + tail) * sps;
+ sync = gRACHSequence;
corr = signalVector(len);
- if (!convolve(&rxBurst, sync, &corr,
- CUSTOM, start, len, sps, 0)) {
+ rc = detectBurst(rxBurst, corr, sync,
+ thresh, sps, &_amp, &_toa, start, len);
+ if (rc < 0) {
return -1;
+ } else if (!rc) {
+ if (amp)
+ *amp = 0.0f;
+ if (toa)
+ *toa = 0.0f;
+ return 0;
}
- _amp = peakDetect(corr, &_toa, NULL);
- peak = corr.begin() + (int) rint(_toa);
+ /* Subtract forward search bits from delay */
+ if (toa)
+ *toa = _toa - head * sps;
+ if (amp)
+ *amp = _amp;
- /* Check for bogus results */
- if ((_toa < 0.0) || (_toa > corr.size()))
- goto notfound;
+ return 1;
+}
- for (int i = 2 * sps; i <= 5 * sps; i++) {
- if (peak - i >= corr.begin()) {
- avg += (peak - i)->norm2();
- num++;
- }
- if (peak + i < corr.end()) {
- avg += (peak + i)->norm2();
- num++;
- }
- }
+/*
+ * Normal burst detection
+ *
+ * Correlation window parameters:
+ * target: Tail + data + mid-midamble + 1/2 remaining midamblebits
+ * head: Search 4 symbols before target
+ * tail: Search 6 symbols + maximum expected delay
+ */
+int analyzeTrafficBurst(signalVector &rxBurst, unsigned tsc, float thresh,
+ int sps, complex *amp, float *toa, unsigned max_toa,
+ bool chan_req, signalVector **chan, float *chan_offset)
+{
+ int rc, start, target, head, tail, len;
+ complex _amp;
+ float _toa;
+ signalVector corr, *_chan;
+ CorrelationSequence *sync;
- if (num < 2)
- goto notfound;
+ if ((tsc < 0) || (tsc > 7) || ((sps != 1) && (sps != 2) && (sps != 4)))
+ return -1;
- rms = sqrtf(avg / (float) num) + 0.00001;
- par = (_amp.abs()) / rms;
- if (par < thresh)
- goto notfound;
+ target = 3 + 58 + 16 + 5;
+ head = 4;
+ tail = 6 + max_toa;
- /*
- * NOTE: Because ideal TSC is 66 symbols into burst,
- * the ideal TSC has an +/- 180 degree phase shift,
- * due to the pi/4 frequency shift, that
- * needs to be accounted for.
- */
- if (amp)
- *amp = _amp / gMidambles[tsc]->gain;
+ start = (target - head) * sps - 1;
+ len = (head + tail) * sps;
+ sync = gMidambles[tsc];
+ corr = signalVector(len);
- /* Delay one half of peak-centred correlation length */
- _toa -= sps * 8;
+ rc = detectBurst(rxBurst, corr, sync,
+ thresh, sps, &_amp, &_toa, start, len);
+ if (rc < 0) {
+ return -1;
+ } else if (!rc) {
+ if (amp)
+ *amp = 0.0f;
+ if (toa)
+ *toa = 0.0f;
+ return 0;
+ }
+ /* Subtract forward search bits from delay */
+ _toa -= head * sps;
if (toa)
*toa = _toa;
+ if (amp)
+ *amp = _amp;
+ /* Equalization not currently supported */
if (chan_req) {
- _chan = new signalVector(6 * sps);
-
- delayVector(corr, -_toa);
- corr.segmentCopyTo(*_chan, target - 3, _chan->size());
- scaleVector(*_chan, complex(1.0, 0.0) / gMidambles[tsc]->gain);
-
- *chan = _chan;
+ *chan = new signalVector(6 * sps);
if (chan_offset)
- *chan_offset = 3.0 * sps;;
+ *chan_offset = 0.0;
}
return 1;
-
-notfound:
- if (amp)
- *amp = 0.0f;
- if (toa)
- *toa = 0.0f;
-
- return 0;
}
signalVector *decimateVector(signalVector &wVector,