Transceiver52M: Refactor RACH and normal burst 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>
This commit is contained in:
parent
c88d8d53f8
commit
865bca42d6
|
@ -363,7 +363,7 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime,
|
|||
float chanOffset;
|
||||
success = analyzeTrafficBurst(*vectorBurst,
|
||||
mTSC,
|
||||
3.0,
|
||||
5.0,
|
||||
mSPS,
|
||||
&litude,
|
||||
&TOA,
|
||||
|
@ -398,7 +398,7 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime,
|
|||
else {
|
||||
// RACH burst
|
||||
success = detectRACHBurst(*vectorBurst,
|
||||
5.0, // detection threshold
|
||||
6.0,
|
||||
mSPS,
|
||||
&litude,
|
||||
&TOA);
|
||||
|
|
|
@ -259,7 +259,7 @@ void initGMSKRotationTables(int sps)
|
|||
|
||||
bool sigProcLibSetup(int sps)
|
||||
{
|
||||
if ((sps != 1) && (sps != 2) && (sps != 4))
|
||||
if ((sps != 1) && (sps != 4))
|
||||
return false;
|
||||
|
||||
initTrigTables();
|
||||
|
@ -955,77 +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;
|
||||
int num = 0;
|
||||
complex *peak;
|
||||
float rms, avg = 0.0;
|
||||
|
||||
if ((sps != 1) && (sps != 2) && (sps != 4))
|
||||
return -1;
|
||||
peak = corr->begin() + (int) rint(toa);
|
||||
|
||||
start = 40 * sps;
|
||||
len = 24 * sps;
|
||||
corr = signalVector(len);
|
||||
/* Check for bogus results */
|
||||
if ((toa < 0.0) || (toa > corr->size()))
|
||||
return 0.0;
|
||||
|
||||
if (!convolve(&rxBurst, sync, &corr,
|
||||
CUSTOM, start, len, sps, 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_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);
|
||||
|
||||
/* 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 interpolated values */
|
||||
_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,
|
||||
|
@ -1046,94 +1005,155 @@ 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
|
||||
*
|
||||
* For one sampler-per-symbol, perform fast peak detection (no interpolation)
|
||||
* for initial gating. We do this because energy detection should be disabled.
|
||||
* For higher oversampling values, we assume the energy detector is in place
|
||||
* and we run full interpolating peak detection.
|
||||
*/
|
||||
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;
|
||||
|
||||
if ((tsc < 0) || (tsc > 7) || ((sps != 1) && (sps != 2) && (sps != 4)))
|
||||
return -1;
|
||||
|
||||
target = 3 + 58 + 5 + 16;
|
||||
start = (target - 8) * sps;
|
||||
len = (8 + 8 + max_toa) * sps;
|
||||
|
||||
sync = gMidambles[tsc]->sequence;
|
||||
sync = gMidambles[tsc]->sequence;
|
||||
corr = signalVector(len);
|
||||
|
||||
if (!convolve(&rxBurst, sync, &corr,
|
||||
/* Correlate */
|
||||
if (!convolve(&burst, sync->sequence, &corr,
|
||||
CUSTOM, start, len, sps, 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_amp = peakDetect(corr, &_toa, NULL);
|
||||
peak = corr.begin() + (int) rint(_toa);
|
||||
/* Peak detection - place restrictions at correlation edges */
|
||||
*amp = fastPeakDetect(corr, toa);
|
||||
|
||||
/* Check for bogus results */
|
||||
if ((_toa < 0.0) || (_toa > corr.size()))
|
||||
goto notfound;
|
||||
if ((*toa < 3 * sps) || (*toa > len - 3 * sps))
|
||||
return 0;
|
||||
|
||||
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++;
|
||||
}
|
||||
/* Peak -to-average ratio */
|
||||
if (computePeakRatio(&corr, sps, *toa, *amp) < thresh)
|
||||
return 0;
|
||||
|
||||
/* Compute peak-to-average ratio. Reject if we don't have enough values */
|
||||
*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 8 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 != 4))
|
||||
return -1;
|
||||
|
||||
target = 8 + 40;
|
||||
head = 8;
|
||||
tail = head;
|
||||
|
||||
start = (target - head) * sps - 1;
|
||||
len = (head + tail) * sps;
|
||||
sync = gRACHSequence;
|
||||
corr = signalVector(len);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (num < 2)
|
||||
goto notfound;
|
||||
|
||||
rms = sqrtf(avg / (float) num) + 0.00001;
|
||||
par = (_amp.abs()) / rms;
|
||||
if (par < thresh)
|
||||
goto notfound;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/* Subtract forward search bits from delay */
|
||||
if (toa)
|
||||
*toa = _toa - head * sps;
|
||||
if (amp)
|
||||
*amp = _amp / gMidambles[tsc]->gain;
|
||||
*amp = _amp;
|
||||
|
||||
/* Delay one half of peak-centred correlation length */
|
||||
_toa -= sps * 8;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Normal burst detection
|
||||
*
|
||||
* Correlation window parameters:
|
||||
* target: Tail + data + mid-midamble + 1/2 remaining midamblebits
|
||||
* head: Search 8 symbols before target
|
||||
* tail: Search 8 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;
|
||||
CorrelationSequence *sync;
|
||||
|
||||
if ((tsc < 0) || (tsc > 7) || ((sps != 1) && (sps != 4)))
|
||||
return -1;
|
||||
|
||||
target = 3 + 58 + 16 + 5;
|
||||
head = 8;
|
||||
tail = head + max_toa;
|
||||
|
||||
start = (target - head) * sps - 1;
|
||||
len = (head + tail) * sps;
|
||||
sync = gMidambles[tsc];
|
||||
corr = signalVector(len);
|
||||
|
||||
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,
|
||||
|
|
Loading…
Reference in New Issue