diff options
author | Artem Pisarenko <artem.k.pisarenko@gmail.com> | 2021-01-17 00:25:21 +0600 |
---|---|---|
committer | Marcus Müller <marcus@hostalia.de> | 2021-01-17 00:07:12 +0100 |
commit | 3de68c1c88f72d32eccdd5ff0ceb7d52b53b5d4d (patch) | |
tree | d6572f257fb28bd5465e30f680be579c0037a718 | |
parent | c9b01b8409b5fcfa12154898bfedc45fed7f5354 (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.h | 9 | ||||
-rw-r--r-- | gnuradio-runtime/lib/math/gen_sine_table.py | 20 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/bindings/fxpt_python.cc | 2 |
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> |