aboutsummaryrefslogtreecommitdiffstats
path: root/Transceiver52M/sigProcLib.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Transceiver52M/sigProcLib.cpp')
-rw-r--r--Transceiver52M/sigProcLib.cpp73
1 files changed, 59 insertions, 14 deletions
diff --git a/Transceiver52M/sigProcLib.cpp b/Transceiver52M/sigProcLib.cpp
index 24e984d..efa8f5d 100644
--- a/Transceiver52M/sigProcLib.cpp
+++ b/Transceiver52M/sigProcLib.cpp
@@ -37,7 +37,8 @@ extern "C" {
using namespace GSM;
-#define TABLESIZE 1024
+#define TABLESIZE 1024
+#define DELAYFILTS 64
/** Lookup tables for trigonometric approximation */
float cosTable[TABLESIZE+1]; // add 1 element for wrap around
@@ -54,6 +55,9 @@ static signalVector *GMSKReverseRotationN = NULL;
static signalVector *GMSKRotation1 = NULL;
static signalVector *GMSKReverseRotation1 = NULL;
+/* Precomputed fractional delay filters */
+static signalVector *delayFilters[DELAYFILTS];
+
/*
* RACH and midamble correlation waveforms. Store the buffer separately
* because we need to allocate it explicitly outside of the signal vector
@@ -116,6 +120,11 @@ void sigProcLibDestroy()
gMidambles[i] = NULL;
}
+ for (int i = 0; i < DELAYFILTS; i++) {
+ delete delayFilters[i];
+ delayFilters[i] = NULL;
+ }
+
delete GMSKRotationN;
delete GMSKReverseRotationN;
delete GMSKRotation1;
@@ -818,33 +827,67 @@ float sinc(float x)
return 1.0F;
}
-bool delayVector(signalVector &wBurst, float delay)
+/*
+ * Create fractional delay filterbank with Blackman-harris windowed
+ * sinc function generator. The number of filters generated is specified
+ * by the DELAYFILTS value.
+ */
+void generateDelayFilters()
{
- int whole, h_len = 20;
- float frac;
+ int h_len = 20;
complex *data;
- signalVector *h, *shift;
+ signalVector *h;
signalVector::iterator itr;
- whole = floor(delay);
- frac = delay - whole;
+ float k, sum;
+ float a0 = 0.35875;
+ float a1 = 0.48829;
+ float a2 = 0.14128;
+ float a3 = 0.01168;
- /* Sinc interpolated fractional shift (if allowable) */
- if (fabs(frac) > 1e-2) {
+ for (int i = 0; i < DELAYFILTS; i++) {
data = (complex *) convolve_h_alloc(h_len);
h = new signalVector(data, 0, h_len);
h->setAligned(true);
h->isReal(true);
+ sum = 0.0;
itr = h->end();
- for (int i = 0; i < h_len; i++)
- *--itr = (complex) sinc(M_PI_F * (i - h_len / 2 - frac));
+ for (int n = 0; n < h_len; n++) {
+ k = (float) n;
+ *--itr = (complex) sinc(M_PI_F *
+ (k - (float) h_len / 2.0 - (float) i / DELAYFILTS));
+ *itr *= a0 -
+ a1 * cos(2 * M_PI * n / (h_len - 1)) +
+ a2 * cos(4 * M_PI * n / (h_len - 1)) -
+ a3 * cos(6 * M_PI * n / (h_len - 1));
+
+ sum += itr->real();
+ }
- shift = convolve(&wBurst, h, NULL, NO_DELAY);
+ itr = h->begin();
+ for (int n = 0; n < h_len; n++)
+ *itr++ /= sum;
- delete h;
- free(data);
+ delayFilters[i] = h;
+ }
+}
+
+bool delayVector(signalVector &wBurst, float delay)
+{
+ int whole, index;
+ float frac;
+ signalVector *h, *shift;
+ whole = floor(delay);
+ frac = delay - whole;
+
+ /* Sinc interpolated fractional shift (if allowable) */
+ if (fabs(frac) > 1e-2) {
+ index = floorf(frac * (float) DELAYFILTS);
+ h = delayFilters[index];
+
+ shift = convolve(&wBurst, h, NULL, NO_DELAY);
if (!shift)
return false;
@@ -1653,5 +1696,7 @@ bool sigProcLibSetup(int sps)
return false;
}
+ generateDelayFilters();
+
return true;
}