diff options
Diffstat (limited to 'gnuradio-core')
6 files changed, 38 insertions, 34 deletions
diff --git a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.cc b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.cc index bff22be25..34f2f88bc 100644 --- a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.cc +++ b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.cc @@ -26,7 +26,7 @@ #include <gr_frequency_modulator_fc.h> #include <gr_io_signature.h> -#include <gr_sincos.h> +#include <gr_fxpt.h> #include <math.h> #include <boost/math/special_functions/trunc.hpp> @@ -54,17 +54,17 @@ gr_frequency_modulator_fc::work (int noutput_items, for (int i = 0; i < noutput_items; i++){ d_phase = d_phase + d_sensitivity * in[i]; - float oi, oq; - gr_sincosf (d_phase, &oq, &oi); - out[i] = gr_complex (oi, oq); - } - // Limit the phase accumulator to [-16*pi,16*pi] - // to avoid loss of precision in the addition above. + while (d_phase > (float)(M_PI)) + d_phase -= (float)(2.0 * M_PI); + while (d_phase < (float)(-M_PI)) + d_phase += (float)(2.0 * M_PI); - if (fabs (d_phase) > 16 * M_PI){ - double ii = boost::math::trunc (d_phase / (2 * M_PI)); - d_phase = d_phase - (ii * 2 * M_PI); + float oi, oq; + + gr_int32 angle = gr_fxpt::float_to_fixed (d_phase); + gr_fxpt::sincos (angle, &oq, &oi); + out[i] = gr_complex (oi, oq); } return noutput_items; diff --git a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h index 932e7da36..e3aaafb1a 100644 --- a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h +++ b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h @@ -39,8 +39,8 @@ GR_CORE_API gr_frequency_modulator_fc_sptr gr_make_frequency_modulator_fc (doubl */ class GR_CORE_API gr_frequency_modulator_fc : public gr_sync_block { - double d_sensitivity; - double d_phase; + float d_sensitivity; + float d_phase; friend GR_CORE_API gr_frequency_modulator_fc_sptr gr_make_frequency_modulator_fc (double sensitivity); diff --git a/gnuradio-core/src/lib/general/gr_fxpt.cc b/gnuradio-core/src/lib/general/gr_fxpt.cc index fae02c71e..67f44a471 100644 --- a/gnuradio-core/src/lib/general/gr_fxpt.cc +++ b/gnuradio-core/src/lib/general/gr_fxpt.cc @@ -33,24 +33,3 @@ const float gr_fxpt::s_sine_table[1 << NBITS][2] = { const float gr_fxpt::PI = 3.14159265358979323846; const float gr_fxpt::TWO_TO_THE_31 = 2147483648.0; -#if 0 -/* - * Compute sine using table lookup with linear interpolation. - * Each table entry contains slope and intercept. - */ -float -gr_fxpt::sin (gr_int32 x) -{ - gr_uint32 ux = x; - int index = ux >> (WORDBITS - NBITS); - return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1]; -} - -float -gr_fxpt::cos (gr_int32 x) -{ - gr_uint32 ux = x + 0x40000000; - int index = ux >> (WORDBITS - NBITS); - return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1]; -} -#endif diff --git a/gnuradio-core/src/lib/general/gr_fxpt.h b/gnuradio-core/src/lib/general/gr_fxpt.h index 9f5937d1a..431102569 100644 --- a/gnuradio-core/src/lib/general/gr_fxpt.h +++ b/gnuradio-core/src/lib/general/gr_fxpt.h @@ -83,6 +83,22 @@ public: return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1]; } + /* + * \brief Given a fixedpoint angle x, return float cos(x) and sin (x) + */ + static void sincos(gr_int32 x, float *s, float *c) + { + gr_uint32 ux = x; + int sin_index = ux >> (WORDBITS - NBITS); + *s = s_sine_table[sin_index][0] * (ux >> 1) + 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]; + + return; + } + }; #endif /* INCLUDED_GR_FXPT_H */ diff --git a/gnuradio-core/src/lib/general/qa_gr_fxpt.cc b/gnuradio-core/src/lib/general/qa_gr_fxpt.cc index 83bb05b2d..00487714e 100644 --- a/gnuradio-core/src/lib/general/qa_gr_fxpt.cc +++ b/gnuradio-core/src/lib/general/qa_gr_fxpt.cc @@ -91,4 +91,13 @@ qa_gr_fxpt::t2 () void qa_gr_fxpt::t3 () { + for (float p = -M_PI; p < M_PI; p += 2 * M_PI / 3600){ + float expected_sin = sin (p); + float expected_cos = cos (p); + float actual_sin; + float actual_cos; + gr_fxpt::sincos (gr_fxpt::float_to_fixed (p), &actual_sin, &actual_cos); + CPPUNIT_ASSERT_DOUBLES_EQUAL (expected_sin, actual_sin, SIN_COS_TOLERANCE); + CPPUNIT_ASSERT_DOUBLES_EQUAL (expected_cos, actual_cos, SIN_COS_TOLERANCE); + } } diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_frequency_modulator.py b/gnuradio-core/src/python/gnuradio/gr/qa_frequency_modulator.py index 829185c34..7328f041d 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_frequency_modulator.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_frequency_modulator.py @@ -48,7 +48,7 @@ class test_frequency_modulator (gr_unittest.TestCase): self.tb.connect (op, dst) self.tb.run () result_data = dst.data () - self.assertComplexTuplesAlmostEqual (expected_result, result_data) + self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5) if __name__ == '__main__': |