summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorghostop14 <ghostop14@gmail.com>2020-02-14 11:47:37 -0500
committerMarcus Müller <marcus@hostalia.de>2020-02-15 14:25:57 +0100
commit504ab76d9e4fc3e9f497b9fd34f01c1bad346a5d (patch)
treec64edca089a87217e56d8840a38382d7e2b4ec56
parenta56c3a7f4908133dc6ceb93ffd3b2f9e1dda8e0e (diff)
gr-digital: Improve PLL Loops and Clock Recovery
These updates incorporate the same inlining of loop functions and the newly pushed fast_cc_multiply function to ensure consistent performance improvements across systems that do not support the cx-limited-range compiler parameter (Macs and Windows).
-rw-r--r--gr-analog/lib/pll_carriertracking_cc_impl.cc27
-rw-r--r--gr-analog/lib/pll_carriertracking_cc_impl.h23
-rw-r--r--gr-analog/lib/pll_freqdet_cf_impl.cc17
-rw-r--r--gr-analog/lib/pll_freqdet_cf_impl.h21
-rw-r--r--gr-analog/lib/pll_refout_cc_impl.cc18
-rw-r--r--gr-analog/lib/pll_refout_cc_impl.h20
-rw-r--r--gr-digital/lib/clock_recovery_mm_cc_impl.cc29
-rw-r--r--gr-digital/lib/clock_recovery_mm_cc_impl.h22
-rw-r--r--gr-digital/lib/clock_recovery_mm_ff_impl.cc2
-rw-r--r--gr-digital/lib/clock_recovery_mm_ff_impl.h2
-rw-r--r--gr-digital/lib/clock_tracking_loop.cc54
-rw-r--r--gr-digital/lib/clock_tracking_loop.h54
-rw-r--r--gr-dtv/lib/atsc/atsc_fpll_impl.cc7
13 files changed, 135 insertions, 161 deletions
diff --git a/gr-analog/lib/pll_carriertracking_cc_impl.cc b/gr-analog/lib/pll_carriertracking_cc_impl.cc
index 81c04aa01b..f403cf3528 100644
--- a/gr-analog/lib/pll_carriertracking_cc_impl.cc
+++ b/gr-analog/lib/pll_carriertracking_cc_impl.cc
@@ -14,7 +14,6 @@
#include "pll_carriertracking_cc_impl.h"
#include <gnuradio/io_signature.h>
-#include <gnuradio/math.h>
#include <gnuradio/sincos.h>
#include <cmath>
@@ -44,29 +43,6 @@ pll_carriertracking_cc_impl::pll_carriertracking_cc_impl(float loop_bw,
pll_carriertracking_cc_impl::~pll_carriertracking_cc_impl() {}
-float pll_carriertracking_cc_impl::mod_2pi(float in)
-{
- if (in > GR_M_PI)
- return in - (2.0 * GR_M_PI);
- else if (in < -GR_M_PI)
- return in + (2.0 * GR_M_PI);
- else
- return in;
-}
-
-float pll_carriertracking_cc_impl::phase_detector(gr_complex sample, float ref_phase)
-{
- float sample_phase;
- // sample_phase = atan2(sample.imag(),sample.real());
- sample_phase = gr::fast_atan2f(sample.imag(), sample.real());
- return mod_2pi(sample_phase - ref_phase);
-}
-
-bool pll_carriertracking_cc_impl::lock_detector(void)
-{
- return (fabsf(d_locksig) > d_lock_threshold);
-}
-
bool pll_carriertracking_cc_impl::squelch_enable(bool set_squelch)
{
return d_squelch_enable = set_squelch;
@@ -89,7 +65,8 @@ int pll_carriertracking_cc_impl::work(int noutput_items,
for (int i = 0; i < noutput_items; i++) {
gr::sincosf(d_phase, &t_imag, &t_real);
- optr[i] = iptr[i] * gr_complex(t_real, -t_imag);
+
+ fast_cc_multiply(optr[i], iptr[i], gr_complex(t_real, -t_imag));
error = phase_detector(iptr[i], d_phase);
diff --git a/gr-analog/lib/pll_carriertracking_cc_impl.h b/gr-analog/lib/pll_carriertracking_cc_impl.h
index 3cb7146da9..82a2f1c21c 100644
--- a/gr-analog/lib/pll_carriertracking_cc_impl.h
+++ b/gr-analog/lib/pll_carriertracking_cc_impl.h
@@ -12,6 +12,7 @@
#define INCLUDED_ANALOG_PLL_CARRIERTRACKING_CC_IMPL_H
#include <gnuradio/analog/pll_carriertracking_cc.h>
+#include <gnuradio/math.h>
namespace gr {
namespace analog {
@@ -22,14 +23,30 @@ private:
float d_locksig, d_lock_threshold;
bool d_squelch_enable;
- float mod_2pi(float in);
- float phase_detector(gr_complex sample, float ref_phase);
+ float mod_2pi(float in)
+ {
+ if (in > GR_M_PI)
+ return in - (2.0 * GR_M_PI);
+ else if (in < -GR_M_PI)
+ return in + (2.0 * GR_M_PI);
+ else
+ return in;
+ }
+
+ float phase_detector(gr_complex sample, float ref_phase)
+ {
+ float sample_phase;
+ // sample_phase = atan2(sample.imag(),sample.real());
+ sample_phase = gr::fast_atan2f(sample.imag(), sample.real());
+ return mod_2pi(sample_phase - ref_phase);
+ }
public:
pll_carriertracking_cc_impl(float loop_bw, float max_freq, float min_freq);
~pll_carriertracking_cc_impl();
- bool lock_detector(void);
+ bool lock_detector(void) { return (fabsf(d_locksig) > d_lock_threshold); }
+
bool squelch_enable(bool);
float set_lock_threshold(float);
diff --git a/gr-analog/lib/pll_freqdet_cf_impl.cc b/gr-analog/lib/pll_freqdet_cf_impl.cc
index f460441e92..baeecc7739 100644
--- a/gr-analog/lib/pll_freqdet_cf_impl.cc
+++ b/gr-analog/lib/pll_freqdet_cf_impl.cc
@@ -37,23 +37,6 @@ pll_freqdet_cf_impl::pll_freqdet_cf_impl(float loop_bw, float max_freq, float mi
pll_freqdet_cf_impl::~pll_freqdet_cf_impl() {}
-float pll_freqdet_cf_impl::mod_2pi(float in)
-{
- if (in > GR_M_PI)
- return in - (2.0 * GR_M_PI);
- else if (in < -GR_M_PI)
- return in + (2.0 * GR_M_PI);
- else
- return in;
-}
-
-float pll_freqdet_cf_impl::phase_detector(gr_complex sample, float ref_phase)
-{
- float sample_phase;
- sample_phase = gr::fast_atan2f(sample.imag(), sample.real());
- return mod_2pi(sample_phase - ref_phase);
-}
-
int pll_freqdet_cf_impl::work(int noutput_items,
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items)
diff --git a/gr-analog/lib/pll_freqdet_cf_impl.h b/gr-analog/lib/pll_freqdet_cf_impl.h
index de5c03192b..2110bcc720 100644
--- a/gr-analog/lib/pll_freqdet_cf_impl.h
+++ b/gr-analog/lib/pll_freqdet_cf_impl.h
@@ -12,6 +12,7 @@
#define INCLUDED_ANALOG_PLL_FREQDET_CF_IMPL_H
#include <gnuradio/analog/pll_freqdet_cf.h>
+#include <gnuradio/math.h>
namespace gr {
namespace analog {
@@ -19,14 +20,28 @@ namespace analog {
class pll_freqdet_cf_impl : public pll_freqdet_cf
{
private:
- float phase_detector(gr_complex sample, float ref_phase);
+ float mod_2pi(float in)
+ {
+ if (in > GR_M_PI)
+ return in - (2.0 * GR_M_PI);
+ else if (in < -GR_M_PI)
+ return in + (2.0 * GR_M_PI);
+ else
+ return in;
+ }
+
+ float phase_detector(gr_complex sample, float ref_phase)
+ {
+ float sample_phase;
+ sample_phase = gr::fast_atan2f(sample.imag(), sample.real());
+ return mod_2pi(sample_phase - ref_phase);
+ }
+
public:
pll_freqdet_cf_impl(float loop_bw, float max_freq, float min_freq);
~pll_freqdet_cf_impl();
- float mod_2pi(float in);
-
void set_loop_bandwidth(float bw);
void set_damping_factor(float df);
void set_alpha(float alpha);
diff --git a/gr-analog/lib/pll_refout_cc_impl.cc b/gr-analog/lib/pll_refout_cc_impl.cc
index 067e650de5..9824d12178 100644
--- a/gr-analog/lib/pll_refout_cc_impl.cc
+++ b/gr-analog/lib/pll_refout_cc_impl.cc
@@ -14,7 +14,6 @@
#include "pll_refout_cc_impl.h"
#include <gnuradio/io_signature.h>
-#include <gnuradio/math.h>
#include <gnuradio/sincos.h>
#include <math.h>
@@ -37,23 +36,6 @@ pll_refout_cc_impl::pll_refout_cc_impl(float loop_bw, float max_freq, float min_
pll_refout_cc_impl::~pll_refout_cc_impl() {}
-float pll_refout_cc_impl::mod_2pi(float in)
-{
- if (in > GR_M_PI)
- return in - (2.0 * GR_M_PI);
- else if (in < -GR_M_PI)
- return in + (2.0 * GR_M_PI);
- else
- return in;
-}
-
-float pll_refout_cc_impl::phase_detector(gr_complex sample, float ref_phase)
-{
- float sample_phase;
- sample_phase = gr::fast_atan2f(sample.imag(), sample.real());
- return mod_2pi(sample_phase - ref_phase);
-}
-
int pll_refout_cc_impl::work(int noutput_items,
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items)
diff --git a/gr-analog/lib/pll_refout_cc_impl.h b/gr-analog/lib/pll_refout_cc_impl.h
index da9be48b16..dc8bf2dc9d 100644
--- a/gr-analog/lib/pll_refout_cc_impl.h
+++ b/gr-analog/lib/pll_refout_cc_impl.h
@@ -12,6 +12,7 @@
#define INCLUDED_ANALOG_PLL_REFOUT_CC_IMPL_H
#include <gnuradio/analog/pll_refout_cc.h>
+#include <gnuradio/math.h>
namespace gr {
namespace analog {
@@ -19,8 +20,23 @@ namespace analog {
class pll_refout_cc_impl : public pll_refout_cc
{
private:
- float mod_2pi(float in);
- float phase_detector(gr_complex sample, float ref_phase);
+ float mod_2pi(float in)
+ {
+ if (in > GR_M_PI)
+ return in - (2.0 * GR_M_PI);
+ else if (in < -GR_M_PI)
+ return in + (2.0 * GR_M_PI);
+ else
+ return in;
+ }
+
+ float phase_detector(gr_complex sample, float ref_phase)
+ {
+ float sample_phase;
+ sample_phase = gr::fast_atan2f(sample.imag(), sample.real());
+ return mod_2pi(sample_phase - ref_phase);
+ }
+
public:
pll_refout_cc_impl(float loop_bw, float max_freq, float min_freq);
diff --git a/gr-digital/lib/clock_recovery_mm_cc_impl.cc b/gr-digital/lib/clock_recovery_mm_cc_impl.cc
index 0c1b7e0892..4f2f4c0c58 100644
--- a/gr-digital/lib/clock_recovery_mm_cc_impl.cc
+++ b/gr-digital/lib/clock_recovery_mm_cc_impl.cc
@@ -74,27 +74,6 @@ void clock_recovery_mm_cc_impl::forecast(int noutput_items,
(int)ceil((noutput_items * d_omega) + d_interp->ntaps()) + FUDGE;
}
-gr_complex clock_recovery_mm_cc_impl::slicer_0deg(gr_complex sample)
-{
- float real = 0, imag = 0;
-
- if (sample.real() > 0)
- real = 1;
- if (sample.imag() > 0)
- imag = 1;
- return gr_complex(real, imag);
-}
-
-gr_complex clock_recovery_mm_cc_impl::slicer_45deg(gr_complex sample)
-{
- float real = -1, imag = -1;
- if (sample.real() > 0)
- real = 1;
- if (sample.imag() > 0)
- imag = 1;
- return gr_complex(real, imag);
-}
-
void clock_recovery_mm_cc_impl::set_omega(float omega)
{
d_omega = omega;
@@ -135,8 +114,8 @@ int clock_recovery_mm_cc_impl::general_work(int noutput_items,
d_c_1T = d_c_0T;
d_c_0T = slicer_0deg(d_p_0T);
- x = (d_c_0T - d_c_2T) * conj(d_p_1T);
- y = (d_p_0T - d_p_2T) * conj(d_c_1T);
+ fast_cc_multiply(x, d_c_0T - d_c_2T, conj(d_p_1T));
+ fast_cc_multiply(y, d_p_0T - d_p_2T, conj(d_c_1T));
u = y - x;
mm_val = u.real();
out[oo++] = d_p_0T;
@@ -169,8 +148,8 @@ int clock_recovery_mm_cc_impl::general_work(int noutput_items,
d_c_1T = d_c_0T;
d_c_0T = slicer_0deg(d_p_0T);
- x = (d_c_0T - d_c_2T) * conj(d_p_1T);
- y = (d_p_0T - d_p_2T) * conj(d_c_1T);
+ fast_cc_multiply(x, d_c_0T - d_c_2T, conj(d_p_1T));
+ fast_cc_multiply(y, d_p_0T - d_p_2T, conj(d_c_1T));
u = y - x;
mm_val = u.real();
out[oo++] = d_p_0T;
diff --git a/gr-digital/lib/clock_recovery_mm_cc_impl.h b/gr-digital/lib/clock_recovery_mm_cc_impl.h
index cb444020c3..79402f5896 100644
--- a/gr-digital/lib/clock_recovery_mm_cc_impl.h
+++ b/gr-digital/lib/clock_recovery_mm_cc_impl.h
@@ -61,8 +61,26 @@ private:
gr_complex d_p_2T, d_p_1T, d_p_0T;
gr_complex d_c_2T, d_c_1T, d_c_0T;
- gr_complex slicer_0deg(gr_complex sample);
- gr_complex slicer_45deg(gr_complex sample);
+ gr_complex slicer_0deg(gr_complex sample)
+ {
+ float real = 0.0f, imag = 0.0f;
+
+ if (sample.real() > 0.0f)
+ real = 1.0f;
+ if (sample.imag() > 0.0f)
+ imag = 1.0f;
+ return gr_complex(real, imag);
+ }
+
+ gr_complex slicer_45deg(gr_complex sample)
+ {
+ float real = -1.0f, imag = -1.0f;
+ if (sample.real() > 0.0f)
+ real = 1.0f;
+ if (sample.imag() > 0.0f)
+ imag = 1.0f;
+ return gr_complex(real, imag);
+ }
};
} /* namespace digital */
diff --git a/gr-digital/lib/clock_recovery_mm_ff_impl.cc b/gr-digital/lib/clock_recovery_mm_ff_impl.cc
index 1c35c3c44e..ceff90a8e5 100644
--- a/gr-digital/lib/clock_recovery_mm_ff_impl.cc
+++ b/gr-digital/lib/clock_recovery_mm_ff_impl.cc
@@ -60,8 +60,6 @@ void clock_recovery_mm_ff_impl::forecast(int noutput_items,
(int)ceil((noutput_items * d_omega) + d_interp->ntaps());
}
-static inline float slice(float x) { return x < 0 ? -1.0F : 1.0F; }
-
void clock_recovery_mm_ff_impl::set_omega(float omega)
{
d_omega = omega;
diff --git a/gr-digital/lib/clock_recovery_mm_ff_impl.h b/gr-digital/lib/clock_recovery_mm_ff_impl.h
index 4a2b127134..f0361a8074 100644
--- a/gr-digital/lib/clock_recovery_mm_ff_impl.h
+++ b/gr-digital/lib/clock_recovery_mm_ff_impl.h
@@ -57,6 +57,8 @@ private:
filter::mmse_fir_interpolator_ff* d_interp;
bool d_verbose;
+
+ float slice(float x) { return x < 0 ? -1.0F : 1.0F; }
};
} /* namespace digital */
diff --git a/gr-digital/lib/clock_tracking_loop.cc b/gr-digital/lib/clock_tracking_loop.cc
index 6c04d2d87e..2cb7c996c9 100644
--- a/gr-digital/lib/clock_tracking_loop.cc
+++ b/gr-digital/lib/clock_tracking_loop.cc
@@ -101,60 +101,6 @@ void clock_tracking_loop::update_gains()
set_beta(beta);
}
-void clock_tracking_loop::advance_loop(float error)
-{
- // So the loop can be reverted one step, if needed.
- d_prev_avg_period = d_avg_period;
- d_prev_inst_period = d_inst_period;
- d_prev_phase = d_phase;
-
- // Integral arm of PI filter
- d_avg_period = d_avg_period + d_beta * error;
- // Limit the integral arm output here, as a large negative
- // error input can lead to a negative d_avg_period, which
- // will cause an infitine loop in the phase wrap method.
- period_limit();
-
- // Proportional arm of PI filter and final sum of PI filter arms
- d_inst_period = d_avg_period + d_alpha * error;
- // Limit the filter output here, for the errant case of a large
- // negative error input, that can lead to a negative d_inst_period,
- // which results in an incorrect phase increment, as it is assumed
- // to be moving forward to the next symbol.
- if (d_inst_period <= 0.f)
- d_inst_period = d_avg_period;
-
- // Compute the new, unwrapped clock phase
- d_phase = d_phase + d_inst_period;
-}
-
-void clock_tracking_loop::revert_loop()
-{
- d_avg_period = d_prev_avg_period;
- d_inst_period = d_prev_inst_period;
- d_phase = d_prev_phase;
-}
-
-void clock_tracking_loop::phase_wrap()
-{
- float period = d_avg_period; // One could argue d_inst_period instead
- float limit = period / 2.0f;
-
- while (d_phase > limit)
- d_phase -= period;
-
- while (d_phase <= -limit)
- d_phase += period;
-}
-
-void clock_tracking_loop::period_limit()
-{
- if (d_avg_period > d_max_avg_period)
- d_avg_period = d_max_avg_period;
- else if (d_avg_period < d_min_avg_period)
- d_avg_period = d_min_avg_period;
-}
-
/*******************************************************************
* SET FUNCTIONS
*******************************************************************/
diff --git a/gr-digital/lib/clock_tracking_loop.h b/gr-digital/lib/clock_tracking_loop.h
index f215316a3e..981114117f 100644
--- a/gr-digital/lib/clock_tracking_loop.h
+++ b/gr-digital/lib/clock_tracking_loop.h
@@ -360,7 +360,32 @@ public:
/*! \brief Advance the loop based on the current gain
* settings and the input error signal.
*/
- void advance_loop(float error);
+ void advance_loop(float error)
+ {
+ // So the loop can be reverted one step, if needed.
+ d_prev_avg_period = d_avg_period;
+ d_prev_inst_period = d_inst_period;
+ d_prev_phase = d_phase;
+
+ // Integral arm of PI filter
+ d_avg_period = d_avg_period + d_beta * error;
+ // Limit the integral arm output here, as a large negative
+ // error input can lead to a negative d_avg_period, which
+ // will cause an infitine loop in the phase wrap method.
+ period_limit();
+
+ // Proportional arm of PI filter and final sum of PI filter arms
+ d_inst_period = d_avg_period + d_alpha * error;
+ // Limit the filter output here, for the errant case of a large
+ // negative error input, that can lead to a negative d_inst_period,
+ // which results in an incorrect phase increment, as it is assumed
+ // to be moving forward to the next symbol.
+ if (d_inst_period <= 0.f)
+ d_inst_period = d_avg_period;
+
+ // Compute the new, unwrapped clock phase
+ d_phase = d_phase + d_inst_period;
+ }
/*! \brief Undo a single, prior advance_loop() call.
*
@@ -373,7 +398,12 @@ public:
* perform correctly given the constraints of GNURadio's streaming
* engine, interpolation filtering, and tag propagation.
*/
- void revert_loop();
+ void revert_loop()
+ {
+ d_avg_period = d_prev_avg_period;
+ d_inst_period = d_prev_inst_period;
+ d_phase = d_prev_phase;
+ }
/*! \brief
* Keep the clock phase estimate, tau, between -T_avg/2 and T_avg/2.
@@ -391,7 +421,17 @@ public:
* clock, and this class doesn't actually use the phase at all,
* so calling this is optional.
*/
- void phase_wrap();
+ void phase_wrap()
+ {
+ float period = d_avg_period; // One could argue d_inst_period instead
+ float limit = period / 2.0f;
+
+ while (d_phase > limit)
+ d_phase -= period;
+
+ while (d_phase <= -limit)
+ d_phase += period;
+ }
/*! \brief
* Keep the estimated average clock period, T_avg, between T_avg_min
@@ -409,7 +449,13 @@ public:
* It is set as a separate virtual method in case another way is desired
* as this is fairly heavy-handed.
*/
- virtual void period_limit();
+ virtual void period_limit()
+ {
+ if (d_avg_period > d_max_avg_period)
+ d_avg_period = d_max_avg_period;
+ else if (d_avg_period < d_min_avg_period)
+ d_avg_period = d_min_avg_period;
+ }
/*******************************************************************
* SET FUNCTIONS
diff --git a/gr-dtv/lib/atsc/atsc_fpll_impl.cc b/gr-dtv/lib/atsc/atsc_fpll_impl.cc
index b85a38207d..88d9940615 100644
--- a/gr-dtv/lib/atsc/atsc_fpll_impl.cc
+++ b/gr-dtv/lib/atsc/atsc_fpll_impl.cc
@@ -55,12 +55,7 @@ int atsc_fpll_impl::work(int noutput_items,
d_nco.sincos(&a_sin, &a_cos); // compute cos and sin
// Mix out carrier and output I-only signal
-
- // PR Merge Note: Once the Costas Optimization PR #3076 merges, this
- // line below helps with performance when cx_limited_range is not available
- // such as on Macs and Windows. Once the merge happens I'll push an update.
- // gr::fast_cc_multiply(result, in[k], gr_complex(a_sin, a_cos));
- result = in[k] * gr_complex(a_sin, a_cos);
+ gr::fast_cc_multiply(result, in[k], gr_complex(a_sin, a_cos));
out[k] = result.real();