aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/GainControl.cpp166
-rw-r--r--src/GainControl.h12
2 files changed, 92 insertions, 86 deletions
diff --git a/src/GainControl.cpp b/src/GainControl.cpp
index 0bb0967..6304de3 100644
--- a/src/GainControl.cpp
+++ b/src/GainControl.cpp
@@ -2,6 +2,11 @@
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Her Majesty the Queen in Right of Canada (Communications Research
Center Canada)
+
+ Copyright (C) 2014
+ Matthias P. Braendli, matthias.braendli@mpb.li
+
+ http://opendigitalradio.org
*/
/*
This file is part of ODR-DabMod.
@@ -74,7 +79,6 @@ GainControl::GainControl(size_t framesize,
GainControl::~GainControl()
{
PDEBUG("GainControl::~GainControl() @ %p\n", this);
-
}
@@ -87,11 +91,11 @@ int GainControl::process(Buffer* const dataIn, Buffer* dataOut)
dataOut->setLength(dataIn->getLength());
#ifdef __SSE__
- const __m128* in = reinterpret_cast<const __m128*>(dataIn->getData());
- __m128* out = reinterpret_cast<__m128*>(dataOut->getData());
- size_t sizeIn = dataIn->getLength() / sizeof(__m128);
- size_t sizeOut = dataOut->getLength() / sizeof(__m128);
- __u128 gain128;
+ const __m128* in = reinterpret_cast<const __m128*>(dataIn->getData());
+ __m128* out = reinterpret_cast<__m128*>(dataOut->getData());
+ size_t sizeIn = dataIn->getLength() / sizeof(__m128);
+ size_t sizeOut = dataOut->getLength() / sizeof(__m128);
+ __u128 gain128;
if ((sizeIn % d_frameSize) != 0) {
PDEBUG("%zu != %zu\n", sizeIn, d_frameSize);
@@ -112,15 +116,15 @@ int GainControl::process(Buffer* const dataIn, Buffer* dataOut)
out[sample] = _mm_mul_ps(in[sample], gain128.m);
}
- in += d_frameSize;
+ in += d_frameSize;
out += d_frameSize;
}
#else // !__SSE__
const complexf* in = reinterpret_cast<const complexf*>(dataIn->getData());
- complexf* out = reinterpret_cast<complexf*>(dataOut->getData());
- size_t sizeIn = dataIn->getLength() / sizeof(complexf);
+ complexf* out = reinterpret_cast<complexf*>(dataOut->getData());
+ size_t sizeIn = dataIn->getLength() / sizeof(complexf);
size_t sizeOut = dataOut->getLength() / sizeof(complexf);
- float gain;
+ float gain;
if ((sizeIn % d_frameSize) != 0) {
PDEBUG("%zu != %zu\n", sizeIn, d_frameSize);
@@ -140,11 +144,11 @@ int GainControl::process(Buffer* const dataIn, Buffer* dataOut)
out[sample] = in[sample] * gain;
}
- in += d_frameSize;
+ in += d_frameSize;
out += d_frameSize;
}
#endif // __SSE__
-
+
return sizeOut;
}
@@ -154,15 +158,7 @@ __m128 GainControl::computeGainFix(const __m128* in, size_t sizeIn)
{
return _mm_set1_ps(512.0f);
}
-#else // !__SSE__
-float GainControl::computeGainFix(const complexf* in, size_t sizeIn)
-{
- return 512.0f;
-}
-#endif // __SSE__
-
-#ifdef __SSE__
__m128 GainControl::computeGainMax(const __m128* in, size_t sizeIn)
{
__u128 gain128;
@@ -201,69 +197,18 @@ __m128 GainControl::computeGainMax(const __m128* in, size_t sizeIn)
////////////////////////////////////////////////////////////////////////////
// max = max(-min, max)
max128.m = _mm_max_ps(_mm_mul_ps(min128.m, _mm_set1_ps(-1.0f)), max128.m);
+
// Detect NULL
if ((int)max128.f[0] != 0) {
gain128.m = _mm_div_ps(factor128, max128.m);
- } else {
+ }
+ else {
gain128.m = _mm_set1_ps(1.0f);
}
return gain128.m;
}
-#else // !__SSE__
-float GainControl::computeGainMax(const complexf* in, size_t sizeIn)
-{
- float gain;
- float min;
- float max;
- static const float factor = 0x7fff;
-
- ////////////////////////////////////////////////////////////////////////
- // Computing max, min and average
- ////////////////////////////////////////////////////////////////////////
- min = __FLT_MAX__;
- max = __FLT_MIN__;
-
- for (size_t sample = 0; sample < sizeIn; ++sample) {
- if (in[sample].real() < min) {
- min = in[sample].real();
- }
- if (in[sample].real() > max) {
- max = in[sample].real();
- }
- if (in[sample].imag() < min) {
- min = in[sample].imag();
- }
- if (in[sample].imag() > max) {
- max = in[sample].imag();
- }
- }
-
- PDEBUG("********** Min: %10f **********\n", min);
- PDEBUG("********** Max: %10f **********\n", max);
-
- ////////////////////////////////////////////////////////////////////////////
- // Computing gain
- ////////////////////////////////////////////////////////////////////////////
- // gain = factor128 / max(-min, max)
- min = -min;
- if (min > max) {
- max = min;
- }
-
- // Detect NULL
- if ((int)max != 0) {
- gain = factor / max;
- } else {
- gain = 1.0f;
- }
-
- return gain;
-}
-#endif // __SSE__
-
-#ifdef __SSE__
__m128 GainControl::computeGainVar(const __m128* in, size_t sizeIn)
{
__u128 gain128;
@@ -273,15 +218,12 @@ __m128 GainControl::computeGainVar(const __m128* in, size_t sizeIn)
static const __m128 factor128 = _mm_set1_ps(0x7fff);
mean128.m = _mm_setzero_ps();
-// var128.m = _mm_setzero_ps();
for (size_t sample = 0; sample < sizeIn; ++sample) {
__m128 delta128 = _mm_sub_ps(in[sample], mean128.m);
__m128 i128 = _mm_set1_ps(sample + 1);
__m128 q128 = _mm_div_ps(delta128, i128);
mean128.m = _mm_add_ps(mean128.m, q128);
-// var128.m = _mm_add_ps(var128.m,
-// _mm_mul_ps(delta128, _mm_sub_ps(in[sample], mean128.m)));
}
// Merging average
@@ -328,7 +270,65 @@ __m128 GainControl::computeGainVar(const __m128* in, size_t sizeIn)
return gain128.m;
}
+
#else // !__SSE__
+
+float GainControl::computeGainFix(const complexf* in, size_t sizeIn)
+{
+ return 512.0f;
+}
+
+float GainControl::computeGainMax(const complexf* in, size_t sizeIn)
+{
+ float gain;
+ float min;
+ float max;
+ static const float factor = 0x7fff;
+
+ ////////////////////////////////////////////////////////////////////////
+ // Computing max, min and average
+ ////////////////////////////////////////////////////////////////////////
+ min = __FLT_MAX__;
+ max = __FLT_MIN__;
+
+ for (size_t sample = 0; sample < sizeIn; ++sample) {
+ if (in[sample].real() < min) {
+ min = in[sample].real();
+ }
+ if (in[sample].real() > max) {
+ max = in[sample].real();
+ }
+ if (in[sample].imag() < min) {
+ min = in[sample].imag();
+ }
+ if (in[sample].imag() > max) {
+ max = in[sample].imag();
+ }
+ }
+
+ PDEBUG("********** Min: %10f **********\n", min);
+ PDEBUG("********** Max: %10f **********\n", max);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Computing gain
+ ////////////////////////////////////////////////////////////////////////////
+ // gain = factor128 / max(-min, max)
+ min = -min;
+ if (min > max) {
+ max = min;
+ }
+
+ // Detect NULL
+ if ((int)max != 0) {
+ gain = factor / max;
+ }
+ else {
+ gain = 1.0f;
+ }
+
+ return gain;
+}
+
float GainControl::computeGainVar(const complexf* in, size_t sizeIn)
{
float gain;
@@ -352,9 +352,10 @@ float GainControl::computeGainVar(const complexf* in, size_t sizeIn)
////////////////////////////////////////////////////////////////////////
var = complexf(0.0f, 0.0f);
for (size_t sample = 0; sample < sizeIn; ++sample) {
- complexf diff = in[sample] - mean;
- complexf delta = complexf(diff.real() * diff.real(), diff.imag() * diff.imag()) - var;
- float i = sample + 1;
+ complexf diff = in[sample] - mean;
+ complexf delta = complexf(diff.real() * diff.real(),
+ diff.imag() * diff.imag()) - var;
+ float i = sample + 1;
complexf q = delta / i;
var = var + q;
}
@@ -372,13 +373,14 @@ float GainControl::computeGainVar(const complexf* in, size_t sizeIn)
// Detect NULL
if ((int)var.real() == 0) {
gain = factor / var.real();
- } else {
+ }
+ else {
gain = 1.0f;
}
return gain;
}
-#endif // __SSE__
+#endif // !__SSE__
void GainControl::set_parameter(const string& parameter, const string& value)
{
diff --git a/src/GainControl.h b/src/GainControl.h
index 65b94da..00379b8 100644
--- a/src/GainControl.h
+++ b/src/GainControl.h
@@ -2,6 +2,11 @@
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Her Majesty the Queen in Right of Canada (Communications Research
Center Canada)
+
+ Copyright (C) 2014
+ Matthias P. Braendli, matthias.braendli@mpb.li
+
+ http://opendigitalradio.org
*/
/*
This file is part of ODR-DabMod.
@@ -54,7 +59,6 @@ class GainControl : public ModCodec, public RemoteControllable
GainControl(const GainControl&);
GainControl& operator=(const GainControl&);
-
int process(Buffer* const dataIn, Buffer* dataOut);
const char* name() { return "GainControl"; }
@@ -75,13 +79,13 @@ class GainControl : public ModCodec, public RemoteControllable
__m128 static computeGainFix(const __m128* in, size_t sizeIn);
__m128 static computeGainMax(const __m128* in, size_t sizeIn);
__m128 static computeGainVar(const __m128* in, size_t sizeIn);
-#else // !__SSE__
+#else
float (*computeGain)(const complexf* in, size_t sizeIn);
float static computeGainFix(const complexf* in, size_t sizeIn);
float static computeGainMax(const complexf* in, size_t sizeIn);
float static computeGainVar(const complexf* in, size_t sizeIn);
-#endif // __SSE__
+#endif
};
-
#endif // GAIN_CONTROL_H
+