diff options
author | Tom Tsou <tom.tsou@ettus.com> | 2017-06-19 15:23:59 -0700 |
---|---|---|
committer | Tom Tsou <tom@tsou.cc> | 2017-06-22 17:39:44 +0000 |
commit | d2e5c5694e6dae078a104e7f5d05c87ed8286ea4 (patch) | |
tree | 10cf93e8d72f64f1752aa8ec7e0188a72307c7ff | |
parent | a3dce85ffca6b3eceb0bcd84719797a6443a217c (diff) |
sigProcLib: Replace dynamically allocated resampling buffers
Instead use object allocated STL vectors. This simplifies code,
removes the need to explicitly release buffers, and fixes a
memory leak in destructor deallocation. Also, remove simplified
init and release sub-calls.
Maintain partition filter allocation using memalign() for SIMD
alignment requirements.
Change-Id: Ie836982794c10fb1b6334e40592d44b200454846
-rw-r--r-- | Transceiver52M/Resampler.cpp | 101 | ||||
-rw-r--r-- | Transceiver52M/Resampler.h | 14 |
2 files changed, 39 insertions, 76 deletions
diff --git a/Transceiver52M/Resampler.cpp b/Transceiver52M/Resampler.cpp index 1927e45..6b9621c 100644 --- a/Transceiver52M/Resampler.cpp +++ b/Transceiver52M/Resampler.cpp @@ -22,6 +22,7 @@ #include <string.h> #include <malloc.h> #include <iostream> +#include <algorithm> #include "Resampler.h" @@ -35,6 +36,8 @@ extern "C" { #define MAX_OUTPUT_LEN 4096 +using namespace std; + static float sinc(float x) { if (x == 0.0) @@ -43,32 +46,19 @@ static float sinc(float x) return sin(M_PI * x) / (M_PI * x); } -bool Resampler::initFilters(float bw) +void Resampler::initFilters(float bw) { - size_t proto_len = p * filt_len; - float *proto, val, cutoff; + float cutoff; float sum = 0.0f, scale = 0.0f; - float midpt = (float) (proto_len - 1.0) / 2.0; /* * Allocate partition filters and the temporary prototype filter * according to numerator of the rational rate. Coefficients are * real only and must be 16-byte memory aligned for SSE usage. */ - proto = new float[proto_len]; - if (!proto) - return false; - - partitions = (float **) malloc(sizeof(float *) * p); - if (!partitions) { - delete[] proto; - return false; - } - - for (size_t i = 0; i < p; i++) { - partitions[i] = (float *) - memalign(16, filt_len * 2 * sizeof(float)); - } + auto proto = vector<float>(p * filt_len); + for (auto &part : partitions) + part = (complex<float> *) memalign(16, filt_len * sizeof(complex<float>)); /* * Generate the prototype filter with a Blackman-harris window. @@ -85,47 +75,26 @@ bool Resampler::initFilters(float bw) else cutoff = (float) q; - for (size_t i = 0; i < proto_len; i++) { + float midpt = (proto.size() - 1) / 2.0; + for (size_t i = 0; i < proto.size(); i++) { proto[i] = sinc(((float) i - midpt) / cutoff * bw); proto[i] *= a0 - - a1 * cos(2 * M_PI * i / (proto_len - 1)) + - a2 * cos(4 * M_PI * i / (proto_len - 1)) - - a3 * cos(6 * M_PI * i / (proto_len - 1)); + a1 * cos(2 * M_PI * i / (proto.size() - 1)) + + a2 * cos(4 * M_PI * i / (proto.size() - 1)) - + a3 * cos(6 * M_PI * i / (proto.size() - 1)); sum += proto[i]; } scale = p / sum; /* Populate filter partitions from the prototype filter */ for (size_t i = 0; i < filt_len; i++) { - for (size_t n = 0; n < p; n++) { - partitions[n][2 * i + 0] = proto[i * p + n] * scale; - partitions[n][2 * i + 1] = 0.0f; - } - } - - /* For convolution, we store the filter taps in reverse */ - for (size_t n = 0; n < p; n++) { - for (size_t i = 0; i < filt_len / 2; i++) { - val = partitions[n][2 * i]; - partitions[n][2 * i] = partitions[n][2 * (filt_len - 1 - i)]; - partitions[n][2 * (filt_len - 1 - i)] = val; - } + for (size_t n = 0; n < p; n++) + partitions[n][i] = complex<float>(proto[i * p + n] * scale); } - delete[] proto; - - return true; -} - -void Resampler::releaseFilters() -{ - if (partitions) { - for (size_t i = 0; i < p; i++) - free(partitions[i]); - } - - free(partitions); - partitions = NULL; + /* Store filter taps in reverse */ + for (auto &part : partitions) + reverse(&part[0], &part[filt_len]); } static bool check_vec_len(int in_len, int out_len, int p, int q) @@ -159,14 +128,6 @@ static bool check_vec_len(int in_len, int out_len, int p, int q) return true; } -void Resampler::computePath() -{ - for (int i = 0; i < MAX_OUTPUT_LEN; i++) { - in_index[i] = (q * i) / p; - out_path[i] = (q * i) % p; - } -} - int Resampler::rotate(const float *in, size_t in_len, float *out, size_t out_len) { int n, path; @@ -180,8 +141,8 @@ int Resampler::rotate(const float *in, size_t in_len, float *out, size_t out_len path = out_path[i]; convolve_real(in, in_len, - partitions[path], filt_len, - &out[2 * i], out_len - i, + reinterpret_cast<float *>(partitions[path]), + filt_len, &out[2 * i], out_len - i, n, 1, 1, 0); } @@ -190,14 +151,18 @@ int Resampler::rotate(const float *in, size_t in_len, float *out, size_t out_len bool Resampler::init(float bw) { + if (p == 0 || q == 0 || filt_len == 0) return false; + /* Filterbank filter internals */ - if (!initFilters(bw)) - return false; + initFilters(bw); /* Precompute filterbank paths */ - in_index = new size_t[MAX_OUTPUT_LEN]; - out_path = new size_t[MAX_OUTPUT_LEN]; - computePath(); + int i = 0; + for (auto &index : in_index) + index = (q * i++) / p; + i = 0; + for (auto &path : out_path) + path = (q * i++) % p; return true; } @@ -208,7 +173,7 @@ size_t Resampler::len() } Resampler::Resampler(size_t p, size_t q, size_t filt_len) - : in_index(NULL), out_path(NULL), partitions(NULL) + : in_index(MAX_OUTPUT_LEN), out_path(MAX_OUTPUT_LEN), partitions(p) { this->p = p; this->q = q; @@ -217,8 +182,6 @@ Resampler::Resampler(size_t p, size_t q, size_t filt_len) Resampler::~Resampler() { - releaseFilters(); - - delete in_index; - delete out_path; + for (auto &part : partitions) + free(part); } diff --git a/Transceiver52M/Resampler.h b/Transceiver52M/Resampler.h index c9f9787..caffc08 100644 --- a/Transceiver52M/Resampler.h +++ b/Transceiver52M/Resampler.h @@ -20,6 +20,9 @@ #ifndef _RESAMPLER_H_ #define _RESAMPLER_H_ +#include <vector> +#include <complex> + class Resampler { public: /* Constructor for rational sample rate conversion @@ -63,14 +66,11 @@ private: size_t p; size_t q; size_t filt_len; - size_t *in_index; - size_t *out_path; - - float **partitions; + std::vector<size_t> in_index; + std::vector<size_t> out_path; + std::vector<std::complex<float> *> partitions; - bool initFilters(float bw); - void releaseFilters(); - void computePath(); + void initFilters(float bw); }; #endif /* _RESAMPLER_H_ */ |