aboutsummaryrefslogtreecommitdiffstats
path: root/Transceiver52M/sigProcLib.cpp
diff options
context:
space:
mode:
authorThomas Tsou <tom@tsou.cc>2013-08-20 20:54:54 -0400
committerThomas Tsou <tom@tsou.cc>2013-10-18 13:10:17 -0400
commit03e6ecf9771ea029e69fd4cdc2f2e289e93d3978 (patch)
tree9bd4abdc74ba979a051386b1d730378ae254bdab /Transceiver52M/sigProcLib.cpp
parent3eaae80c90752abe3173c43a5dae5cdf17493764 (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.cpp188
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,