diff options
author | Alexander Chemeris <Alexander.Chemeris@gmail.com> | 2015-11-13 09:38:56 -0800 |
---|---|---|
committer | Alexander Chemeris <Alexander.Chemeris@gmail.com> | 2015-11-13 09:38:56 -0800 |
commit | 5d1eaaffccfcb6f9fdd5a28dfdaf8cdd3d310b44 (patch) | |
tree | 6669994449d4e1a8755462ef1a1ad14b01d64392 | |
parent | 511a662394ff939ae6a8a8623515543199c3c69a (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.cpp | 319 | ||||
-rw-r--r-- | Transceiver52M/Transceiver.h | 45 | ||||
-rw-r--r-- | Transceiver52M/sigProcLib.cpp | 231 | ||||
-rw-r--r-- | Transceiver52M/sigProcLib.h | 42 |
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 &, 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 &, float &toa, GSM::Time &time) +int Transceiver::detectTSC(signalVector &burst, + complex &, 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 &, float &toa); /** Detect normal bursts */ - int detectTSC(TransceiverState *state, - signalVector &burst, - complex &, 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 &, 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 &, float &toa, unsigned max_toa, - bool chan_req, signalVector **chan, float *chan_offset) + int sps, complex &, 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 &litude, 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 */ |