diff options
author | Thomas Tsou <tom@tsou.cc> | 2013-08-20 20:54:54 -0400 |
---|---|---|
committer | Thomas Tsou <tom@tsou.cc> | 2013-10-18 13:10:17 -0400 |
commit | 03e6ecf9771ea029e69fd4cdc2f2e289e93d3978 (patch) | |
tree | 9bd4abdc74ba979a051386b1d730378ae254bdab /Transceiver52M/sigProcLib.cpp | |
parent | 3eaae80c90752abe3173c43a5dae5cdf17493764 (diff) |
Transceiver52M: Replace resampler with SSE enabled implementation
Replace the polyphase filter and resampler with a separate
implementation using SSE enabled convolution. The USRP2 (including
derived devices N200, N210) are the only supported devices that
require sample rate conversion, so set the default resampling
parameters for the 100 MHz FPGA clock. This changes the previous
resampling ratios.
270.833 kHz -> 400 kHz (65 / 96)
270.833 kHz -> 390.625 kHz (52 / 75)
The new resampling factor uses a USRP resampling factor of 256
instead of 250. On the device, this allows two halfband filters to
be used rather than one. The end result is reduced distortial and
aliasing effecits from CIC filter rolloff.
B100 and USRP1 will no be supported at 400 ksps with these changes.
Signed-off-by: Thomas Tsou <tom@tsou.cc>
Diffstat (limited to 'Transceiver52M/sigProcLib.cpp')
-rw-r--r-- | Transceiver52M/sigProcLib.cpp | 188 |
1 files changed, 0 insertions, 188 deletions
diff --git a/Transceiver52M/sigProcLib.cpp b/Transceiver52M/sigProcLib.cpp index 8237aa5..a647f84 100644 --- a/Transceiver52M/sigProcLib.cpp +++ b/Transceiver52M/sigProcLib.cpp @@ -1128,195 +1128,7 @@ SoftVector *demodulateBurst(signalVector &rxBurst, int sps, return burstBits; } - - -// 1.0 is sampling frequency -// must satisfy cutoffFreq > 1/filterLen -signalVector *createLPF(float cutoffFreq, - int filterLen, - float gainDC) -{ -#if 0 - signalVector *LPF = new signalVector(filterLen-1); - LPF->isRealOnly(true); - LPF->setSymmetry(ABSSYM); - signalVector::iterator itr = LPF->begin(); - double sum = 0.0; - for (int i = 1; i < filterLen; i++) { - float ys = sinc(M_2PI_F*cutoffFreq*((float)i-(float)(filterLen)/2.0F)); - float yg = 4.0F * cutoffFreq; - // Blackman -- less brickwall (sloping transition) but larger stopband attenuation - float yw = 0.42 - 0.5*cos(((float)i)*M_2PI_F/(float)(filterLen)) + 0.08*cos(((float)i)*2*M_2PI_F/(float)(filterLen)); - // Hamming -- more brickwall with smaller stopband attenuation - //float yw = 0.53836F - 0.46164F * cos(((float)i)*M_2PI_F/(float)(filterLen+1)); - *itr++ = (complex) ys*yg*yw; - sum += ys*yg*yw; - } -#else - double sum = 0.0; - signalVector *LPF; - signalVector::iterator itr; - if (filterLen == 651) { // receive LPF - LPF = new signalVector(651); - LPF->isRealOnly(true); - itr = LPF->begin(); - for (int i = 0; i < filterLen; i++) { - *itr++ = complex(rcvLPF_651[i],0.0); - sum += rcvLPF_651[i]; - } - } - else { - LPF = new signalVector(961); - LPF->isRealOnly(true); - itr = LPF->begin(); - for (int i = 0; i < filterLen; i++) { - *itr++ = complex(sendLPF_961[i],0.0); - sum += sendLPF_961[i]; - } - } -#endif - - float normFactor = gainDC/sum; //sqrtf(gainDC/vectorNorm2(*LPF)); - // normalize power - itr = LPF->begin(); - for (int i = 0; i < filterLen; i++) { - *itr = *itr*normFactor; - itr++; - } - return LPF; - -} - - -#define POLYPHASESPAN 10 - -// assumes filter group delay is 0.5*(length of filter) -signalVector *polyphaseResampleVector(signalVector &wVector, - int P, int Q, - signalVector *LPF) - -{ - - bool deleteLPF = false; - - if (LPF==NULL) { - float cutoffFreq = (P < Q) ? (1.0/(float) Q) : (1.0/(float) P); - LPF = createLPF(cutoffFreq/3.0,100*POLYPHASESPAN+1,Q); - deleteLPF = true; - } - - signalVector *resampledVector = new signalVector((int) ceil(wVector.size()*(float) P / (float) Q)); - resampledVector->fill(0); - resampledVector->isRealOnly(wVector.isRealOnly()); - signalVector::iterator newItr = resampledVector->begin(); - - //FIXME: need to update for real-only vectors - int outputIx = (LPF->size()+1)/2/Q; //((P > Q) ? P : Q); - while (newItr < resampledVector->end()) { - int outputBranch = (outputIx*Q) % P; - int inputOffset = (outputIx*Q - outputBranch)/P; - signalVector::const_iterator inputItr = wVector.begin() + inputOffset; - signalVector::const_iterator filtItr = LPF->begin() + outputBranch; - while (inputItr >= wVector.end()) { - inputItr--; - filtItr+=P; - } - complex sum = 0.0; - if ((LPF->getSymmetry()!=ABSSYM) || (P>1)) { - if (!LPF->isRealOnly()) { - while ( (inputItr >= wVector.begin()) && (filtItr < LPF->end()) ) { - sum += (*inputItr)*(*filtItr); - inputItr--; - filtItr += P; - } - } - else { - while ( (inputItr >= wVector.begin()) && (filtItr < LPF->end()) ) { - sum += (*inputItr)*(filtItr->real()); - inputItr--; - filtItr += P; - } - } - } - else { - signalVector::const_iterator revInputItr = inputItr- LPF->size() + 1; - signalVector::const_iterator filtMidpoint = LPF->begin()+(LPF->size()-1)/2; - if (!LPF->isRealOnly()) { - while (filtItr <= filtMidpoint) { - if (inputItr < revInputItr) break; - if (inputItr == revInputItr) - sum += (*inputItr)*(*filtItr); - else if ( (inputItr < wVector.end()) && (revInputItr >= wVector.begin()) ) - sum += (*inputItr + *revInputItr)*(*filtItr); - else if ( inputItr < wVector.end() ) - sum += (*inputItr)*(*filtItr); - else if ( revInputItr >= wVector.begin() ) - sum += (*revInputItr)*(*filtItr); - inputItr--; - revInputItr++; - filtItr++; - } - } - else { - while (filtItr <= filtMidpoint) { - if (inputItr < revInputItr) break; - if (inputItr == revInputItr) - sum += (*inputItr)*(filtItr->real()); - else if ( (inputItr < wVector.end()) && (revInputItr >= wVector.begin()) ) - sum += (*inputItr + *revInputItr)*(filtItr->real()); - else if ( inputItr < wVector.end() ) - sum += (*inputItr)*(filtItr->real()); - else if ( revInputItr >= wVector.begin() ) - sum += (*revInputItr)*(filtItr->real()); - inputItr--; - revInputItr++; - filtItr++; - } - } - } - *newItr = sum; - newItr++; - outputIx++; - } - - if (deleteLPF) delete LPF; - - return resampledVector; -} - - -signalVector *resampleVector(signalVector &wVector, - float expFactor, - complex endPoint) - -{ - - if (expFactor < 1.0) return NULL; - - signalVector *retVec = new signalVector((int) ceil(wVector.size()*expFactor)); - - float t = 0.0; - - signalVector::iterator retItr = retVec->begin(); - while (retItr < retVec->end()) { - unsigned tLow = (unsigned int) floor(t); - unsigned tHigh = tLow + 1; - if (tLow > wVector.size()-1) break; - if (tHigh > wVector.size()) break; - complex lowPoint = wVector[tLow]; - complex highPoint = (tHigh == wVector.size()) ? endPoint : wVector[tHigh]; - complex a = (tHigh-t); - complex b = (t-tLow); - *retItr = (a*lowPoint + b*highPoint); - t += 1.0/expFactor; - } - - return retVec; - -} - - // Assumes symbol-spaced sampling!!! // Based upon paper by Al-Dhahir and Cioffi bool designDFE(signalVector &channelResponse, |