diff options
author | Thomas Tsou <tom@tsou.cc> | 2013-10-08 21:34:35 -0400 |
---|---|---|
committer | Thomas Tsou <tom@tsou.cc> | 2013-10-18 13:10:17 -0400 |
commit | 2c282f5e1268146761413a145fd8ae2fb523fa4f (patch) | |
tree | 75d476e5b0cc513899c9efd76702dd0bed7492eb | |
parent | 92c16df87586283894decd761561cdc4890752fa (diff) |
Transceiver52M: Generate delay filter with SSE memory alignment
This requires an additional memcpy() on the signal vector
constructor, but allows the interpolation filter to use
SSE optimzationed convolution.
Signed-off-by: Thomas Tsou <tom@tsou.cc>
-rw-r--r-- | Transceiver52M/sigProcLib.cpp | 65 |
1 files changed, 41 insertions, 24 deletions
diff --git a/Transceiver52M/sigProcLib.cpp b/Transceiver52M/sigProcLib.cpp index 7598156..ab771ac 100644 --- a/Transceiver52M/sigProcLib.cpp +++ b/Transceiver52M/sigProcLib.cpp @@ -766,44 +766,61 @@ float sinc(float x) bool delayVector(signalVector &wBurst, float delay) { - - int intOffset = (int) floor(delay); - float fracOffset = delay - intOffset; - - // do fractional shift first, only do it for reasonable offsets - if (fabs(fracOffset) > 1e-2) { - // create sinc function - signalVector sincVector(21); - sincVector.isRealOnly(true); - signalVector::iterator sincBurstItr = sincVector.end(); - for (int i = 0; i < 21; i++) - *--sincBurstItr = (complex) sinc(M_PI_F*(i-10-fracOffset)); - - signalVector shiftedBurst(wBurst.size()); - if (!convolve(&wBurst, &sincVector, &shiftedBurst, NO_DELAY)) + int whole, h_len = 20; + float frac; + complex *data; + signalVector *h, *shift; + signalVector::iterator itr; + + whole = floor(delay); + frac = delay - whole; + + /* Sinc interpolated fractional shift (if allowable) */ + if (fabs(frac) > 1e-2) { + data = (complex *) convolve_h_alloc(h_len); + h = new signalVector(data, 0, h_len); + h->setAligned(true); + h->isRealOnly(true); + + itr = h->end(); + for (int i = 0; i < h_len; i++) + *--itr = (complex) sinc(M_PI_F * (i - h_len / 2 - frac)); + + shift = convolve(&wBurst, h, NULL, NO_DELAY); + + delete h; + free(data); + + if (!shift) return false; - wBurst.clone(shiftedBurst); + + wBurst.clone(*shift); + delete shift; } - if (intOffset < 0) { - intOffset = -intOffset; + /* Integer sample shift */ + if (whole < 0) { + whole = -whole; signalVector::iterator wBurstItr = wBurst.begin(); - signalVector::iterator shiftedItr = wBurst.begin()+intOffset; + signalVector::iterator shiftedItr = wBurst.begin() + whole; + while (shiftedItr < wBurst.end()) *wBurstItr++ = *shiftedItr++; while (wBurstItr < wBurst.end()) *wBurstItr++ = 0.0; - } - else { - signalVector::iterator wBurstItr = wBurst.end()-1; - signalVector::iterator shiftedItr = wBurst.end()-1-intOffset; + } else { + signalVector::iterator wBurstItr = wBurst.end() - 1; + signalVector::iterator shiftedItr = wBurst.end() - 1 - whole; + while (shiftedItr >= wBurst.begin()) *wBurstItr-- = *shiftedItr--; while (wBurstItr >= wBurst.begin()) *wBurstItr-- = 0.0; } + + return true; } - + signalVector *gaussianNoise(int length, float variance, complex mean) |