aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Chemeris <Alexander.Chemeris@gmail.com>2015-11-13 09:38:56 -0800
committerAlexander Chemeris <Alexander.Chemeris@gmail.com>2015-11-13 09:38:56 -0800
commit5d1eaaffccfcb6f9fdd5a28dfdaf8cdd3d310b44 (patch)
tree6669994449d4e1a8755462ef1a1ad14b01d64392
parent511a662394ff939ae6a8a8623515543199c3c69a (diff)
transceiver: Remove remainings of the equalizer, restructure driveReceiveFIFO() for better modularity.
Equalizer has never worked properly and was always disabled. Now is a good time to remove it completely to make the code cleaner.
-rw-r--r--Transceiver52M/Transceiver.cpp319
-rw-r--r--Transceiver52M/Transceiver.h45
-rw-r--r--Transceiver52M/sigProcLib.cpp231
-rw-r--r--Transceiver52M/sigProcLib.h42
4 files changed, 154 insertions, 483 deletions
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index 526153e..2fc9930 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -50,9 +50,6 @@ TransceiverState::TransceiverState()
for (int i = 0; i < 8; i++) {
chanType[i] = Transceiver::NONE;
fillerModulus[i] = 26;
- chanResponse[i] = NULL;
- DFEForward[i] = NULL;
- DFEFeedback[i] = NULL;
for (int n = 0; n < 102; n++)
fillerTable[n][i] = NULL;
@@ -62,10 +59,6 @@ TransceiverState::TransceiverState()
TransceiverState::~TransceiverState()
{
for (int i = 0; i < 8; i++) {
- delete chanResponse[i];
- delete DFEForward[i];
- delete DFEFeedback[i];
-
for (int n = 0; n < 102; n++)
delete fillerTable[n][i];
}
@@ -141,6 +134,12 @@ bool TransceiverState::init(int filler, size_t sps, float scale, size_t rtsc)
return false;
}
+void Transceiver::reset()
+{
+ for (size_t i = 0; i < mTxPriorityQueues.size(); i++)
+ mTxPriorityQueues[i].clear();
+}
+
Transceiver::Transceiver(int wBasePort,
const char *wTRXAddress,
size_t wSPS, size_t wChans,
@@ -556,11 +555,9 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
}
/*
- * Detect RACH synchronization sequence within a burst. No equalization
- * is used or available on the RACH channel.
+ * Detect RACH synchronization sequence within a burst.
*/
-int Transceiver::detectRACH(TransceiverState *state,
- signalVector &burst,
+int Transceiver::detectRACH(signalVector &burst,
complex &amp, float &toa)
{
float threshold = 6.0;
@@ -569,76 +566,16 @@ int Transceiver::detectRACH(TransceiverState *state,
}
/*
- * Detect normal burst training sequence midamble. Update equalization
- * state information and channel estimate if necessary. Equalization
- * is currently disabled.
+ * Detect normal burst training sequence midamble.
*/
-int Transceiver::detectTSC(TransceiverState *state, signalVector &burst,
- complex &amp, float &toa, GSM::Time &time)
+int Transceiver::detectTSC(signalVector &burst,
+ complex &amp, float &toa)
{
- int success;
- int tn = time.TN();
- float chanOffset, threshold = 5.0;
- bool needDFE = false, estimateChan = false;
- double elapsed = time - state->chanEstimateTime[tn];
- signalVector *chanResp;
-
- /* Check equalization update state */
- if (needDFE && ((elapsed > 50) || (!state->chanResponse[tn]))) {
- delete state->DFEForward[tn];
- delete state->DFEFeedback[tn];
- state->DFEForward[tn] = NULL;
- state->DFEFeedback[tn] = NULL;
-
- estimateChan = true;
- }
+ float threshold = 5.0;
/* Detect normal burst midambles */
- success = analyzeTrafficBurst(burst, mTSC, threshold, mSPSRx, amp,
- toa, mMaxExpectedDelay, estimateChan,
- &chanResp, &chanOffset);
- if (success <= 0) {
- return success;
- }
-
- /* Set equalizer if unabled */
- if (needDFE && estimateChan) {
- float noise = state->mNoiseLev;
- state->SNRestimate[tn] = amp.norm2() / (noise * noise + 1.0);
-
- state->chanResponse[tn] = chanResp;
- state->chanRespOffset[tn] = chanOffset;
- state->chanRespAmplitude[tn] = amp;
-
- scaleVector(*chanResp, complex(1.0, 0.0) / amp);
-
- designDFE(*chanResp, state->SNRestimate[tn],
- 7, &state->DFEForward[tn], &state->DFEFeedback[tn]);
-
- state->chanEstimateTime[tn] = time;
- }
-
- return 1;
-}
-
-/*
- * Demodulate GMSK burst using equalization if requested. Otherwise
- * demodulate by direct rotation and soft slicing.
- */
-SoftVector *Transceiver::demodulate(TransceiverState *state,
- signalVector &burst, complex amp,
- float toa, size_t tn, bool equalize)
-{
- if (equalize) {
- scaleVector(burst, complex(1.0, 0.0) / amp);
- return equalizeBurst(burst,
- toa - state->chanRespOffset[tn],
- mSPSRx,
- *state->DFEForward[tn],
- *state->DFEFeedback[tn]);
- }
-
- return demodulateBurst(burst, mSPSRx, amp, toa);
+ return analyzeTrafficBurst(burst, mTSC, threshold, mSPSRx, amp,
+ toa, mMaxExpectedDelay);
}
void writeToFile(radioVector *radio_burst, size_t chan)
@@ -655,42 +592,47 @@ void writeToFile(radioVector *radio_burst, size_t chan)
* Pull bursts from the FIFO and handle according to the slot
* and burst correlation type. Equalzation is currently disabled.
*/
-SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, double &RSSI, bool &isRssiValid,
- double &timingOffset, double &noise,
- size_t chan)
+SoftVector *Transceiver::demodSignalVector(signalVector *burst,
+ CorrType type,
+ double &timingOffset)
{
int success;
- bool equalize = false;
complex amp;
- float toa, pow, max = -1.0, avg = 0.0;
- int max_i = -1;
- signalVector *burst;
+ float toa;
SoftVector *bits = NULL;
- TransceiverState *state = &mStates[chan];
- isRssiValid = false;
-
- /* Blocking FIFO read */
- radioVector *radio_burst = mReceiveFIFO[chan]->read();
- if (!radio_burst)
- return NULL;
- /* Set time and determine correlation type */
- GSM::Time time = radio_burst->getTime();
- CorrType type = expectedCorrType(time, chan);
+ /* Detect normal or RACH bursts */
+ if (type == TSC)
+ success = detectTSC(*burst, amp, toa);
+ else
+ success = detectRACH(*burst, amp, toa);
- /* Debug: dump bursts to disk */
- /* bits 0-7 - chan 0 timeslots
- * bits 8-15 - chan 1 timeslots */
- if (mWriteBurstToDiskMask & ((1<<time.TN()) << (8*chan)))
- writeToFile(radio_burst, chan);
+ /* Alert an error and exit */
+ if (success <= 0) {
+ if (success == -SIGERR_CLIP) {
+ LOG(WARNING) << "Clipping detected on received RACH or Normal Burst";
+ } else if (success != SIGERR_NONE) {
+ LOG(WARNING) << "Unhandled RACH or Normal Burst detection error";
+ }
- /* No processing if the timeslot is off.
- * Not even power level or noise calculation. */
- if (type == OFF) {
- delete radio_burst;
return NULL;
}
+ timingOffset = toa / mSPSRx;
+
+ bits = demodulateBurst(*burst, mSPSRx, amp, toa);
+
+ return bits;
+}
+
+signalVector *Transceiver::chooseDiversityPath(radioVector *radio_burst, double &avg)
+{
+ signalVector *burst;
+ int max_i = -1;
+ float pow, max = -1.0;
+
+ avg = 0.0;
+
/* Select the diversity channel with highest energy */
for (size_t i = 0; i < radio_burst->chans(); i++) {
energyDetect(*radio_burst->getVector(i), 20 * mSPSRx, 0.0, &pow);
@@ -703,7 +645,6 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, double &RSSI, bool &i
if (max_i < 0) {
LOG(ALERT) << "Received empty burst";
- delete radio_burst;
return NULL;
}
@@ -711,62 +652,16 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, double &RSSI, bool &i
burst = radio_burst->getVector(max_i);
avg = sqrt(avg / radio_burst->chans());
- wTime = time;
- RSSI = 20.0 * log10(rxFullScale / avg);
-
- /* RSSI estimation are valid */
- isRssiValid = true;
-
- if (type == IDLE) {
- /* Update noise levels */
- state->mNoises.insert(avg);
- state->mNoiseLev = state->mNoises.avg();
- noise = 20.0 * log10(rxFullScale / state->mNoiseLev);
-
- delete radio_burst;
- return NULL;
- } else {
- /* Do not update noise levels */
- noise = 20.0 * log10(rxFullScale / state->mNoiseLev);
- }
-
- /* Detect normal or RACH bursts */
- if (type == TSC)
- success = detectTSC(state, *burst, amp, toa, time);
- else
- success = detectRACH(state, *burst, amp, toa);
-
- /* Alert an error and exit */
- if (success <= 0) {
- if (success == -SIGERR_CLIP) {
- LOG(WARNING) << "Clipping detected on received RACH or Normal Burst";
- } else if (success != SIGERR_NONE) {
- LOG(WARNING) << "Unhandled RACH or Normal Burst detection error";
- }
-
- delete radio_burst;
- return NULL;
- }
-
- timingOffset = toa / mSPSRx;
-
- /* Demodulate and set output info */
- if (equalize && (type != TSC))
- equalize = false;
-
- bits = demodulate(state, *burst, amp, toa, time.TN(), equalize);
-
- delete radio_burst;
- return bits;
+ return burst;
}
-void Transceiver::reset()
+void TransceiverState::updateNoiseEstimates(double avg)
{
- for (size_t i = 0; i < mTxPriorityQueues.size(); i++)
- mTxPriorityQueues[i].clear();
+ /* Update noise levels */
+ mNoises.insert(avg);
+ mNoiseLev = mNoises.avg();
}
-
void Transceiver::driveControl(size_t chan)
{
int MAX_PACKET_LENGTH = 100;
@@ -841,9 +736,8 @@ void Transceiver::driveControl(size_t chan)
}
else if (strcmp(command,"NOISELEV")==0) {
if (mOn) {
- float lev = mStates[chan].mNoiseLev;
sprintf(response,"RSP NOISELEV 0 %d",
- (int) round(20.0 * log10(rxFullScale / lev)));
+ (int) round(dB2(rxFullScale / mStates[chan].mNoiseLev)));
}
else {
sprintf(response,"RSP NOISELEV 1 0");
@@ -980,45 +874,94 @@ void Transceiver::driveReceiveRadio()
void Transceiver::driveReceiveFIFO(size_t chan)
{
+ radioVector *radio_burst = NULL;
+ signalVector *burst = NULL;
SoftVector *rxBurst = NULL;
+ double burst_power; // sqr(amp)
double RSSI; // in dBFS
double dBm; // in dBm
double TOA; // in symbols
- int TOAint; // in 1/256 symbols
double noise; // noise level in dBFS
GSM::Time burstTime;
- bool isRssiValid; // are RSSI, noise and burstTime valid
-
- rxBurst = pullRadioVector(burstTime, RSSI, isRssiValid, TOA, noise, chan);
-
- if (rxBurst) {
- dBm = RSSI+rssiOffset;
- TOAint = (int) (TOA * 256.0 + 0.5); // round to closest integer
-
- LOG(DEBUG) << std::fixed << std::right
- << " time: " << burstTime
- << " RSSI: " << std::setw(5) << std::setprecision(1) << RSSI << "dBFS/" << std::setw(6) << -dBm << "dBm"
- << " noise: " << std::setw(5) << std::setprecision(1) << noise << "dBFS/" << std::setw(6) << -(noise+rssiOffset) << "dBm"
- << " TOA: " << std::setw(5) << std::setprecision(2) << TOA
- << " bits: " << *rxBurst;
-
- char burstString[gSlotLen+10];
- burstString[0] = burstTime.TN();
- for (int i = 0; i < 4; i++)
- burstString[1+i] = (burstTime.FN() >> ((3-i)*8)) & 0x0ff;
- burstString[5] = (int)dBm;
- burstString[6] = (TOAint >> 8) & 0x0ff;
- burstString[7] = TOAint & 0x0ff;
- SoftVector::iterator burstItr = rxBurst->begin();
-
- for (unsigned int i = 0; i < gSlotLen; i++) {
- burstString[8+i] =(char) round((*burstItr++)*255.0);
- }
- burstString[gSlotLen+9] = '\0';
- delete rxBurst;
+ CorrType burstType;
- mDataSockets[chan]->write(burstString,gSlotLen+10);
+ /* Blocking FIFO read */
+ radio_burst = mReceiveFIFO[chan]->read();
+ if (!radio_burst)
+ return;
+
+ /* Set time and determine correlation type */
+ burstTime = radio_burst->getTime();
+ burstType = expectedCorrType(burstTime, chan);
+
+ /* Debug: dump bursts to disk */
+ /* bits 0-7 - chan 0 timeslots
+ * bits 8-15 - chan 1 timeslots */
+ if (mWriteBurstToDiskMask & ((1<<burstTime.TN()) << (8*chan)))
+ writeToFile(radio_burst, chan);
+
+ /* No processing if the timeslot is off. */
+ if (burstType == OFF) {
+ delete radio_burst;
+ return;
+ }
+
+ /* Choose a diversity channel to use */
+ burst = chooseDiversityPath(radio_burst, burst_power);
+ delete radio_burst;
+ if (!burst) {
+ return;
+ }
+
+ /* We use idle timeslots to calculate noise levels for informational purposes.
+ * Otherwise we ignore them. */
+ if (burstType == IDLE) {
+ mStates[chan].updateNoiseEstimates(burst_power);
+ return;
+ }
+
+ /* Update/calculate burst info */
+ noise = dB2(rxFullScale / mStates[chan].mNoiseLev);
+ RSSI = dB2(rxFullScale / burst_power);
+ dBm = RSSI+rssiOffset;
+
+ /* Pre-process and demodulate radio vector */
+ rxBurst = demodSignalVector(burst, burstType, TOA);
+ if (!rxBurst)
+ return;
+
+ LOG(DEBUG) << std::fixed << std::right
+ << " time: " << burstTime
+ << " RSSI: " << std::setw(5) << std::setprecision(1) << RSSI << "dBFS/" << std::setw(6) << -dBm << "dBm"
+ << " noise: " << std::setw(5) << std::setprecision(1) << noise << "dBFS/" << std::setw(6) << -(noise+rssiOffset) << "dBm"
+ << " TOA: " << std::setw(5) << std::setprecision(2) << TOA
+ << " bits: " << *rxBurst;
+
+ char burstString[gSlotLen+10];
+ formatDemodPacket(burstTime, dBm, TOA, rxBurst, burstString);
+ delete rxBurst;
+
+ mDataSockets[chan]->write(burstString,gSlotLen+10);
+}
+
+void Transceiver::formatDemodPacket(GSM::Time burstTime, double dBm, double TOA,
+ SoftVector *rxBurst, char *burstString)
+{
+ int TOAint; // in 1/256 symbols
+ TOAint = (int) (TOA * 256.0 + 0.5); // round to closest integer
+
+ burstString[0] = burstTime.TN();
+ for (int i = 0; i < 4; i++)
+ burstString[1+i] = (burstTime.FN() >> ((3-i)*8)) & 0x0ff;
+ burstString[5] = (int)dBm;
+ burstString[6] = (TOAint >> 8) & 0x0ff;
+ burstString[7] = TOAint & 0x0ff;
+ SoftVector::iterator burstItr = rxBurst->begin();
+
+ for (unsigned int i = 0; i < gSlotLen; i++) {
+ burstString[8+i] =(char) round((*burstItr++)*255.0);
}
+ burstString[gSlotLen+9] = '\0';
}
void Transceiver::driveTxFIFO()
diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h
index bd8ec4f..d8cdaee 100644
--- a/Transceiver52M/Transceiver.h
+++ b/Transceiver52M/Transceiver.h
@@ -55,29 +55,15 @@ struct TransceiverState {
/* Initialize a multiframe slot in the filler table */
bool init(int filler, size_t sps, float scale, size_t rtsc);
+ void updateNoiseEstimates(double avg);
int chanType[8];
- /* Last timestamp of each timeslot's channel estimate */
- GSM::Time chanEstimateTime[8];
-
/* The filler table */
signalVector *fillerTable[102][8];
int fillerModulus[8];
bool mRetrans;
- /* Most recent channel estimate of all timeslots */
- signalVector *chanResponse[8];
-
- /* Most recent DFE feedback filter of all timeslots */
- signalVector *DFEForward[8];
- signalVector *DFEFeedback[8];
-
- /* Most recent SNR, timing, and channel amplitude estimates */
- float SNRestimate[8];
- float chanRespOffset[8];
- complex chanRespAmplitude[8];
-
/* Received noise energy levels */
float mNoiseLev;
noiseVector mNoises;
@@ -195,9 +181,15 @@ private:
void pushRadioVector(GSM::Time &nowTime);
/** Pull and demodulate a burst from the receive FIFO */
- SoftVector *pullRadioVector(GSM::Time &wTime, double &RSSI, bool &isRssiValid,
- double &timingOffset, double &noise,
- size_t chan = 0);
+ SoftVector *demodSignalVector(signalVector *burst,
+ CorrType type,
+ double &timingOffset);
+
+ /** choose the channel to use */
+ signalVector *chooseDiversityPath(radioVector *radio_burst, double &avg);
+
+ /** update noise estimate */
+ double updateNoiseEstimates(TransceiverState *state, double avg);
/** Set modulus for specific timeslot */
void setModulus(size_t timeslot, size_t chan);
@@ -209,19 +201,12 @@ private:
void writeClockInterface(void);
/** Detect RACH bursts */
- int detectRACH(TransceiverState *state,
- signalVector &burst,
+ int detectRACH(signalVector &burst,
complex &amp, float &toa);
/** Detect normal bursts */
- int detectTSC(TransceiverState *state,
- signalVector &burst,
- complex &amp, float &toa, GSM::Time &time);
-
- /** Demodulat burst and output soft bits */
- SoftVector *demodulate(TransceiverState *state,
- signalVector &burst, complex amp,
- float toa, size_t tn, bool equalize);
+ int detectTSC(signalVector &burst,
+ complex &amp, float &toa);
int mSPSTx; ///< number of samples per Tx symbol
int mSPSRx; ///< number of samples per Rx symbol
@@ -251,6 +236,10 @@ protected:
/** drive demodulation of GSM bursts */
void driveReceiveFIFO(size_t chan);
+ /** format a packet of soft-bits to be sent over the network */
+ void formatDemodPacket(GSM::Time burstTime, double dBm, double TOA,
+ SoftVector *rxBurst, char *burstString);
+
/** drive transmission of GSM bursts */
void driveTxFIFO();
diff --git a/Transceiver52M/sigProcLib.cpp b/Transceiver52M/sigProcLib.cpp
index b5160ca..9eac061 100644
--- a/Transceiver52M/sigProcLib.cpp
+++ b/Transceiver52M/sigProcLib.cpp
@@ -147,64 +147,8 @@ void sigProcLibDestroy()
GSMPulse1 = NULL;
}
-// dB relative to 1.0.
-// if > 1.0, then return 0 dB
-float dB(float x) {
-
- float arg = 1.0F;
- float dB = 0.0F;
-
- if (x >= 1.0F) return 0.0F;
- if (x <= 0.0F) return -200.0F;
-
- float prevArg = arg;
- float prevdB = dB;
- float stepSize = 16.0F;
- float dBstepSize = 12.0F;
- while (stepSize > 1.0F) {
- do {
- prevArg = arg;
- prevdB = dB;
- arg /= stepSize;
- dB -= dBstepSize;
- } while (arg > x);
- arg = prevArg;
- dB = prevdB;
- stepSize *= 0.5F;
- dBstepSize -= 3.0F;
- }
- return ((arg-x)*(dB-3.0F) + (x-arg*0.5F)*dB)/(arg - arg*0.5F);
-
-}
-
-// 10^(-dB/10), inverse of dB func.
-float dBinv(float x) {
-
- float arg = 1.0F;
- float dB = 0.0F;
-
- if (x >= 0.0F) return 1.0F;
- if (x <= -200.0F) return 0.0F;
-
- float prevArg = arg;
- float prevdB = dB;
- float stepSize = 16.0F;
- float dBstepSize = 12.0F;
- while (stepSize > 1.0F) {
- do {
- prevArg = arg;
- prevdB = dB;
- arg /= stepSize;
- dB -= dBstepSize;
- } while (dB > x);
- arg = prevArg;
- dB = prevdB;
- stepSize *= 0.5F;
- dBstepSize -= 3.0F;
- }
-
- return ((dB-x)*(arg*0.5F)+(x-(dB-3.0F))*(arg))/3.0F;
-
+double dB2(double x) {
+ return 20.0 * log10(x);
}
float vectorNorm2(const signalVector &x)
@@ -1478,8 +1422,7 @@ int detectRACHBurst(signalVector &rxBurst,
* tail: Search 4 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 sps, complex &amp, float &toa, unsigned max_toa)
{
int rc, target, head, tail;
CorrelationSequence *sync;
@@ -1495,14 +1438,6 @@ int analyzeTrafficBurst(signalVector &rxBurst, unsigned tsc, float thresh,
rc = detectGeneralBurst(rxBurst, thresh, sps, amp, toa,
target, head, tail, sync);
- /* Equalization not currently supported */
- if (rc > 0 && chan_req) {
- *chan = new signalVector(6 * sps);
-
- if (chan_offset)
- *chan_offset = 0.0;
- }
-
return rc;
}
@@ -1559,166 +1494,6 @@ SoftVector *demodulateBurst(signalVector &rxBurst, int sps,
return bits;
}
-// Assumes symbol-spaced sampling!!!
-// Based upon paper by Al-Dhahir and Cioffi
-bool designDFE(signalVector &channelResponse,
- float SNRestimate,
- int Nf,
- signalVector **feedForwardFilter,
- signalVector **feedbackFilter)
-{
-
- signalVector G0(Nf);
- signalVector G1(Nf);
- signalVector::iterator G0ptr = G0.begin();
- signalVector::iterator G1ptr = G1.begin();
- signalVector::iterator chanPtr = channelResponse.begin();
-
- int nu = channelResponse.size()-1;
-
- *G0ptr = 1.0/sqrtf(SNRestimate);
- for(int j = 0; j <= nu; j++) {
- *G1ptr = chanPtr->conj();
- G1ptr++; chanPtr++;
- }
-
- signalVector *L[Nf];
- signalVector::iterator Lptr;
- float d = 1.0;
- for(int i = 0; i < Nf; i++) {
- d = G0.begin()->norm2() + G1.begin()->norm2();
- L[i] = new signalVector(Nf+nu);
- Lptr = L[i]->begin()+i;
- G0ptr = G0.begin(); G1ptr = G1.begin();
- while ((G0ptr < G0.end()) && (Lptr < L[i]->end())) {
- *Lptr = (*G0ptr*(G0.begin()->conj()) + *G1ptr*(G1.begin()->conj()) )/d;
- Lptr++;
- G0ptr++;
- G1ptr++;
- }
- complex k = (*G1.begin())/(*G0.begin());
-
- if (i != Nf-1) {
- signalVector G0new = G1;
- scaleVector(G0new,k.conj());
- addVector(G0new,G0);
-
- signalVector G1new = G0;
- scaleVector(G1new,k*(-1.0));
- addVector(G1new,G1);
- delayVector(&G1new, &G1new, -1.0);
-
- scaleVector(G0new,1.0/sqrtf(1.0+k.norm2()));
- scaleVector(G1new,1.0/sqrtf(1.0+k.norm2()));
- G0 = G0new;
- G1 = G1new;
- }
- }
-
- *feedbackFilter = new signalVector(nu);
- L[Nf-1]->segmentCopyTo(**feedbackFilter,Nf,nu);
- scaleVector(**feedbackFilter,(complex) -1.0);
- conjugateVector(**feedbackFilter);
-
- signalVector v(Nf);
- signalVector::iterator vStart = v.begin();
- signalVector::iterator vPtr;
- *(vStart+Nf-1) = (complex) 1.0;
- for(int k = Nf-2; k >= 0; k--) {
- Lptr = L[k]->begin()+k+1;
- vPtr = vStart + k+1;
- complex v_k = 0.0;
- for (int j = k+1; j < Nf; j++) {
- v_k -= (*vPtr)*(*Lptr);
- vPtr++; Lptr++;
- }
- *(vStart + k) = v_k;
- }
-
- *feedForwardFilter = new signalVector(Nf);
- signalVector::iterator w = (*feedForwardFilter)->end();
- for (int i = 0; i < Nf; i++) {
- delete L[i];
- complex w_i = 0.0;
- int endPt = ( nu < (Nf-1-i) ) ? nu : (Nf-1-i);
- vPtr = vStart+i;
- chanPtr = channelResponse.begin();
- for (int k = 0; k < endPt+1; k++) {
- w_i += (*vPtr)*(chanPtr->conj());
- vPtr++; chanPtr++;
- }
- *--w = w_i/d;
- }
-
-
- return true;
-
-}
-
-// Assumes symbol-rate sampling!!!!
-SoftVector *equalizeBurst(signalVector &rxBurst,
- float TOA,
- int sps,
- signalVector &w, // feedforward filter
- signalVector &b) // feedback filter
-{
- signalVector *postForwardFull;
-
- if (!delayVector(&rxBurst, &rxBurst, -TOA))
- return NULL;
-
- postForwardFull = convolve(&rxBurst, &w, NULL,
- CUSTOM, 0, rxBurst.size() + w.size() - 1);
- if (!postForwardFull)
- return NULL;
-
- signalVector* postForward = new signalVector(rxBurst.size());
- postForwardFull->segmentCopyTo(*postForward,w.size()-1,rxBurst.size());
- delete postForwardFull;
-
- signalVector::iterator dPtr = postForward->begin();
- signalVector::iterator dBackPtr;
- signalVector::iterator rotPtr = GMSKRotationN->begin();
- signalVector::iterator revRotPtr = GMSKReverseRotationN->begin();
-
- signalVector *DFEoutput = new signalVector(postForward->size());
- signalVector::iterator DFEItr = DFEoutput->begin();
-
- // NOTE: can insert the midamble and/or use midamble to estimate BER
- for (; dPtr < postForward->end(); dPtr++) {
- dBackPtr = dPtr-1;
- signalVector::iterator bPtr = b.begin();
- while ( (bPtr < b.end()) && (dBackPtr >= postForward->begin()) ) {
- *dPtr = *dPtr + (*bPtr)*(*dBackPtr);
- bPtr++;
- dBackPtr--;
- }
- *dPtr = *dPtr * (*revRotPtr);
- *DFEItr = *dPtr;
- // make decision on symbol
- *dPtr = (dPtr->real() > 0.0) ? 1.0 : -1.0;
- //*DFEItr = *dPtr;
- *dPtr = *dPtr * (*rotPtr);
- DFEItr++;
- rotPtr++;
- revRotPtr++;
- }
-
- vectorSlicer(DFEoutput);
-
- SoftVector *burstBits = new SoftVector(postForward->size());
- SoftVector::iterator burstItr = burstBits->begin();
- DFEItr = DFEoutput->begin();
- for (; DFEItr < DFEoutput->end(); DFEItr++)
- *burstItr++ = DFEItr->real();
-
- delete postForward;
-
- delete DFEoutput;
-
- return burstBits;
-}
-
bool sigProcLibSetup(int sps)
{
if ((sps != 1) && (sps != 4))
diff --git a/Transceiver52M/sigProcLib.h b/Transceiver52M/sigProcLib.h
index 8685f2d..0badb9d 100644
--- a/Transceiver52M/sigProcLib.h
+++ b/Transceiver52M/sigProcLib.h
@@ -36,8 +36,8 @@ enum signalError {
SIGERR_INTERNAL,
};
-/** Convert a linear number to a dB value */
-float dB(float x);
+/** Convert a power value to a dB value */
+double dB2(double x);
/** Convert a dB value into a linear value */
float dBinv(float x);
@@ -204,9 +204,6 @@ int detectRACHBurst(signalVector &rxBurst,
@param amplitude The estimated amplitude of received TSC burst.
@param TOA The estimate time-of-arrival of received TSC burst.
@param maxTOA The maximum expected time-of-arrival
- @param requestChannel Set to true if channel estimation is desired.
- @param channelResponse The estimated channel.
- @param channelResponseOffset The time offset b/w the first sample of the channel response and the reported TOA.
@return positive if threshold value is reached, negative on error, zero otherwise
*/
int analyzeTrafficBurst(signalVector &rxBurst,
@@ -215,10 +212,7 @@ int analyzeTrafficBurst(signalVector &rxBurst,
int sps,
complex &amplitude,
float &TOA,
- unsigned maxTOA,
- bool requestChannel = false,
- signalVector** channelResponse = NULL,
- float *channelResponseOffset = NULL);
+ unsigned maxTOA);
/**
Decimate a vector.
@@ -240,34 +234,4 @@ signalVector *decimateVector(signalVector &wVector, size_t factor);
SoftVector *demodulateBurst(signalVector &rxBurst, int sps,
complex channel, float TOA);
-/**
- Design the necessary filters for a decision-feedback equalizer.
- @param channelResponse The multipath channel that we're mitigating.
- @param SNRestimate The signal-to-noise estimate of the channel, a linear value
- @param Nf The number of taps in the feedforward filter.
- @param feedForwardFilter The designed feed forward filter.
- @param feedbackFilter The designed feedback filter.
- @return True if DFE can be designed.
-*/
-bool designDFE(signalVector &channelResponse,
- float SNRestimate,
- int Nf,
- signalVector **feedForwardFilter,
- signalVector **feedbackFilter);
-
-/**
- Equalize/demodulate a received burst via a decision-feedback equalizer.
- @param rxBurst The received burst to be demodulated.
- @param TOA The time-of-arrival of the received burst.
- @param sps The number of samples per GSM symbol.
- @param w The feed forward filter of the DFE.
- @param b The feedback filter of the DFE.
- @return The demodulated bit sequence.
-*/
-SoftVector *equalizeBurst(signalVector &rxBurst,
- float TOA,
- int sps,
- signalVector &w,
- signalVector &b);
-
#endif /* SIGPROCLIB_H */