summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtem Pisarenko <artem.k.pisarenko@gmail.com>2021-01-17 00:25:21 +0600
committerMarcus Müller <marcus@hostalia.de>2021-01-17 00:07:12 +0100
commit3de68c1c88f72d32eccdd5ff0ceb7d52b53b5d4d (patch)
treed6572f257fb28bd5465e30f680be579c0037a718
parentc9b01b8409b5fcfa12154898bfedc45fed7f5354 (diff)
runtime: simplify math fxpt sine/cosine calculation
Algorithm improved in order to eliminate getting output values outside of range [-1.0, 1.0) Fixes #2993 Signed-off-by: Artem Pisarenko <artem.k.pisarenko@gmail.com>
-rw-r--r--gnuradio-runtime/include/gnuradio/fxpt.h9
-rw-r--r--gnuradio-runtime/lib/math/gen_sine_table.py20
-rw-r--r--gnuradio-runtime/python/gnuradio/gr/bindings/fxpt_python.cc2
3 files changed, 10 insertions, 21 deletions
diff --git a/gnuradio-runtime/include/gnuradio/fxpt.h b/gnuradio-runtime/include/gnuradio/fxpt.h
index 8dff3f740f..e64dc3297a 100644
--- a/gnuradio-runtime/include/gnuradio/fxpt.h
+++ b/gnuradio-runtime/include/gnuradio/fxpt.h
@@ -31,6 +31,7 @@ class GR_RUNTIME_API fxpt
{
static constexpr int WORDBITS = 32;
static constexpr int NBITS = 10;
+ static constexpr uint32_t ACCUM_MASK = ((1 << (WORDBITS - NBITS)) - 1);
static const float s_sine_table[1 << NBITS][2];
static const float PI;
static const float TAU;
@@ -55,7 +56,7 @@ public:
{
uint32_t ux = x;
int index = ux >> (WORDBITS - NBITS);
- return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1];
+ return s_sine_table[index][0] * (ux & ACCUM_MASK) + s_sine_table[index][1];
}
/*
@@ -65,7 +66,7 @@ public:
{
uint32_t ux = x + 0x40000000;
int index = ux >> (WORDBITS - NBITS);
- return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1];
+ return s_sine_table[index][0] * (ux & ACCUM_MASK) + s_sine_table[index][1];
}
/*
@@ -75,11 +76,11 @@ public:
{
uint32_t ux = x;
int sin_index = ux >> (WORDBITS - NBITS);
- *s = s_sine_table[sin_index][0] * (ux >> 1) + s_sine_table[sin_index][1];
+ *s = s_sine_table[sin_index][0] * (ux & ACCUM_MASK) + s_sine_table[sin_index][1];
ux = x + 0x40000000;
int cos_index = ux >> (WORDBITS - NBITS);
- *c = s_sine_table[cos_index][0] * (ux >> 1) + s_sine_table[cos_index][1];
+ *c = s_sine_table[cos_index][0] * (ux & ACCUM_MASK) + s_sine_table[cos_index][1];
return;
}
diff --git a/gnuradio-runtime/lib/math/gen_sine_table.py b/gnuradio-runtime/lib/math/gen_sine_table.py
index b84f9b2f3e..ae31b6b81a 100644
--- a/gnuradio-runtime/lib/math/gen_sine_table.py
+++ b/gnuradio-runtime/lib/math/gen_sine_table.py
@@ -11,14 +11,9 @@
import math
import sys
-def wrap (x):
- if x >= 2**31:
- return x - 2**32
- return x
-
def gen_approx_table (f, nentries, min_x, max_x):
"""return a list of nentries containing tuples of the form:
- (m, c, abs_error). min_x and max_x specify the domain
+ (m, c). min_x and max_x specify the domain
of the table.
"""
r = []
@@ -27,9 +22,8 @@ def gen_approx_table (f, nentries, min_x, max_x):
a = (i * incx) + min_x
b = ((i + 1) * incx) + min_x
m = (f(b)-f(a)) / (b-a)
- c = (3.0*a+b)*(f(a)-f(b))/(4.0*(b-a)) + (f((a+b)/2.0) + f(a))/2.0
- abs_error = c+m*a-f(a)
- r.append ((m, c, abs_error))
+ c = f(a)
+ r.append ((m, c))
return r
def scaled_sine (x):
@@ -45,19 +39,13 @@ def gen_sine_table ():
max_x = 2**32-1
t = gen_approx_table (scaled_sine, nentries, min_x, max_x)
- max_error = 0
- for e in t:
- max_error = max (max_error, abs (e[2]))
-
# sys.stdout.write ('static const int WORDBITS = 32;\n')
# sys.stdout.write ('static const int NBITS = %d;\n' % (nbits,))
- sys.stdout.write (' // max_error = %22.15e\n' % (max_error,))
-
# sys.stdout.write ('static const double sine_table[%d][2] = {\n'% (nentries,))
for e in t:
- sys.stdout.write (' { %22.15e, %22.15e },\n' % (2.0 * e[0], e[1]))
+ sys.stdout.write (' { %22.15e, %22.15e },\n' % (e[0], e[1]))
# sys.stdout.write ('};\n')
diff --git a/gnuradio-runtime/python/gnuradio/gr/bindings/fxpt_python.cc b/gnuradio-runtime/python/gnuradio/gr/bindings/fxpt_python.cc
index 52ef1f249c..ae29ee060b 100644
--- a/gnuradio-runtime/python/gnuradio/gr/bindings/fxpt_python.cc
+++ b/gnuradio-runtime/python/gnuradio/gr/bindings/fxpt_python.cc
@@ -14,7 +14,7 @@
/* BINDTOOL_GEN_AUTOMATIC(0) */
/* BINDTOOL_USE_PYGCCXML(0) */
/* BINDTOOL_HEADER_FILE(fxpt.h) */
-/* BINDTOOL_HEADER_FILE_HASH(d8f127eabbf6b31d6fb100ad04eb21b2) */
+/* BINDTOOL_HEADER_FILE_HASH(2299d7b3bd19eed3eb2e59c8075cfdb3) */
/***********************************************************************************/
#include <pybind11/complex.h>