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.
This commit is contained in:
Alexander Chemeris
2015-11-13 09:38:56 -08:00
parent 511a662394
commit 5d1eaaffcc
4 changed files with 151 additions and 480 deletions

View File

@@ -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;
/* Detect normal or RACH bursts */
if (type == TSC)
success = detectTSC(*burst, amp, toa);
else
success = detectRACH(*burst, amp, toa);
/* Set time and determine correlation type */
GSM::Time time = radio_burst->getTime();
CorrType type = expectedCorrType(time, 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";
}
/* 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);
/* 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
CorrType burstType;
rxBurst = pullRadioVector(burstTime, RSSI, isRssiValid, TOA, noise, chan);
/* Blocking FIFO read */
radio_burst = mReceiveFIFO[chan]->read();
if (!radio_burst)
return;
if (rxBurst) {
dBm = RSSI+rssiOffset;
TOAint = (int) (TOA * 256.0 + 0.5); // round to closest integer
/* Set time and determine correlation type */
burstTime = radio_burst->getTime();
burstType = expectedCorrType(burstTime, chan);
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;
/* 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);
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;
mDataSockets[chan]->write(burstString,gSlotLen+10);
/* 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()

View File

@@ -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();

View File

@@ -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))

View File

@@ -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 */