[PATCH] osmo-trx[master]: sigProcLib: Replace dynamically allocated resampling buffers

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Tom Tsou gerrit-no-reply at lists.osmocom.org
Tue Jun 20 00:52:29 UTC 2017


Hello Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/2978

to look at the new patch set (#2).

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
---
M Transceiver52M/Resampler.cpp
M Transceiver52M/Resampler.h
2 files changed, 39 insertions(+), 76 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-trx refs/changes/78/2978/2

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 @@
 
 #define MAX_OUTPUT_LEN		4096
 
+using namespace std;
+
 static float sinc(float x)
 {
 	if (x == 0.0)
@@ -43,32 +46,19 @@
 	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 @@
 	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 (size_t n = 0; n < p; n++)
+			partitions[n][i] = complex<float>(proto[i * p + n] * scale);
 	}
 
-	/* 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;
-		}
-	}
-
-	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 @@
 	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 @@
 		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 @@
 
 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 @@
 }
 
 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()
 {
-	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 @@
 	size_t p;
 	size_t q;
 	size_t filt_len;
-	size_t *in_index;
-	size_t *out_path;
+	std::vector<size_t> in_index;
+	std::vector<size_t> out_path;
+	std::vector<std::complex<float> *> partitions;
 
-	float **partitions;
-
-	bool initFilters(float bw);
-	void releaseFilters();
-	void computePath();
+	void initFilters(float bw);
 };
 
 #endif /* _RESAMPLER_H_ */

-- 
To view, visit https://gerrit.osmocom.org/2978
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: Ie836982794c10fb1b6334e40592d44b200454846
Gerrit-PatchSet: 2
Gerrit-Project: osmo-trx
Gerrit-Branch: master
Gerrit-Owner: Tom Tsou <tom at tsou.cc>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list