diff options
-rw-r--r-- | gr-digital/include/digital_mpsk_snr_est_cc.h | 31 | ||||
-rw-r--r-- | gr-digital/lib/digital_mpsk_snr_est_cc.cc | 152 |
2 files changed, 27 insertions, 156 deletions
diff --git a/gr-digital/include/digital_mpsk_snr_est_cc.h b/gr-digital/include/digital_mpsk_snr_est_cc.h index 9c2d636c4..84d6380a9 100644 --- a/gr-digital/include/digital_mpsk_snr_est_cc.h +++ b/gr-digital/include/digital_mpsk_snr_est_cc.h @@ -24,6 +24,7 @@ #include <digital_api.h> #include <gr_sync_block.h> +#include <digital_impl_mpsk_snr_est.h> class digital_mpsk_snr_est_cc; typedef boost::shared_ptr<digital_mpsk_snr_est_cc> digital_mpsk_snr_est_cc_sptr; @@ -45,14 +46,8 @@ class DIGITAL_API digital_mpsk_snr_est_cc : public gr_sync_block { private: snr_est_type_t d_type; - double d_y1, d_y2, d_y3, d_y4; - double d_alpha, d_beta; - - // Function pointers to the type of estimator used. - int (digital_mpsk_snr_est_cc::*d_estimator)(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - double (digital_mpsk_snr_est_cc::*d_calculator)(); + double d_alpha; + digital_impl_mpsk_snr_est *d_snr_est; // Factory function returning shared pointer of this class friend DIGITAL_API digital_mpsk_snr_est_cc_sptr @@ -61,26 +56,6 @@ class DIGITAL_API digital_mpsk_snr_est_cc : public gr_sync_block // Private constructor digital_mpsk_snr_est_cc(snr_est_type_t type, double alpha); - int est_simple(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - double est_simple_snr(); - - int est_skew(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - double est_skew_snr(); - - int est_m2m4(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - double est_m2m4_snr(); - - int est_svn(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - double est_svn_snr(); - public: ~digital_mpsk_snr_est_cc(); diff --git a/gr-digital/lib/digital_mpsk_snr_est_cc.cc b/gr-digital/lib/digital_mpsk_snr_est_cc.cc index 7793eed1d..0830b4a4d 100644 --- a/gr-digital/lib/digital_mpsk_snr_est_cc.cc +++ b/gr-digital/lib/digital_mpsk_snr_est_cc.cc @@ -39,126 +39,23 @@ digital_mpsk_snr_est_cc::digital_mpsk_snr_est_cc(snr_est_type_t type, double alpha) : gr_sync_block ("mpsk_snr_est_cc", gr_make_io_signature(1, 1, sizeof(gr_complex)), - gr_make_io_signature(1, 1, sizeof(gr_complex))), - d_type(type), d_y1(0), d_y2(0), d_y3(0), d_y4(0) + gr_make_io_signature(1, 1, sizeof(gr_complex))) { - set_type(type); - set_alpha(alpha); - set_history(2); -} - -digital_mpsk_snr_est_cc::~digital_mpsk_snr_est_cc() -{ -} - -int -digital_mpsk_snr_est_cc::est_simple(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const gr_complex *in = (const gr_complex *) input_items[0]; - - for (int i = 0; i < noutput_items; i++){ - double y1 = abs(in[i]); - d_y1 = d_alpha*y1 + d_beta*d_y1; - - double y2 = real(in[i]*in[i]); - d_y2 = d_alpha*y2 + d_beta*d_y2; - } - return noutput_items; -} - -double -digital_mpsk_snr_est_cc::est_simple_snr() -{ - double y1_2 = d_y1*d_y1; - double y3 = y1_2 - d_y2 + 1e-20; - return 10.0*log10(y1_2/y3); -} - -int -digital_mpsk_snr_est_cc::est_skew(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const gr_complex *in = (const gr_complex *) input_items[0]; - - for (int i = 0; i < noutput_items; i++){ - double y1 = abs(in[i]); - d_y1 = d_alpha*y1 + d_beta*d_y1; - - double y2 = real(in[i]*in[i]); - d_y2 = d_alpha*y2 + d_beta*d_y2; - - // online algorithm for calculating skewness - // See: - // http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Higher-order_statistics - double d = abs(in[i]) - d_y1; - double d_i = d / (i+1); - double y3 = (d*d_i*i)*d_i*(i-1) - 3.0*d_i*d_y2; - d_y3 = d_alpha*y3 + d_beta*d_y3; - } - return noutput_items; -} + d_snr_est = NULL; -double -digital_mpsk_snr_est_cc::est_skew_snr() -{ - double y3 = d_y3*d_y3 / (d_y2*d_y2*d_y2); - double y1_2 = d_y1*d_y1; - double x = y1_2 - d_y2; - return 10.0*log10(y1_2 / (x + y3*y1_2)); -} - -int -digital_mpsk_snr_est_cc::est_m2m4(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const gr_complex *in = (const gr_complex *) input_items[0]; - - for (int i = 0; i < noutput_items; i++){ - double y1 = abs(in[i])*abs(in[i]); - d_y1 = d_alpha*y1 + d_beta*d_y1; - - double y2 = abs(in[i])*abs(in[i])*abs(in[i])*abs(in[i]); - d_y2 = d_alpha*y2 + d_beta*d_y2; - } - return noutput_items; -} - -double -digital_mpsk_snr_est_cc::est_m2m4_snr() -{ - double y1_2 = d_y1*d_y1; - return 10.0*log10(2.0*sqrt(2*y1_2 - d_y2) / (d_y1 - sqrt(2*y1_2 - d_y2))); -} + d_type = type; + set_alpha(alpha); + set_type(type); -int -digital_mpsk_snr_est_cc::est_svn(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const gr_complex *in = (const gr_complex *) input_items[0]; - - for (int i = 0; i < noutput_items; i++){ - double x = abs(in[i]); - double x1 = abs(in[i-1]); - double y1 = (x*x)*(x1*x1); - d_y1 = d_alpha*y1 + d_beta*d_y1; - - double y2 = x*x*x*x; - d_y2 = d_alpha*y2 + d_beta*d_y2; - } - return noutput_items; + // at least 1 estimator has to look back + set_history(2); } -double -digital_mpsk_snr_est_cc::est_svn_snr() +digital_mpsk_snr_est_cc::~digital_mpsk_snr_est_cc() { - double x = d_y1 / (d_y2 - d_y1); - return 10.0*log10(2.*((x-1) + sqrt(x*(x-1)))); + if(d_snr_est) + delete d_snr_est; } int @@ -166,13 +63,16 @@ digital_mpsk_snr_est_cc::work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - return (*this.*d_estimator)(noutput_items, input_items, output_items); + return d_snr_est->update(noutput_items, input_items, output_items); } double digital_mpsk_snr_est_cc::snr() { - return (*this.*d_calculator)(); + if(d_snr_est) + return d_snr_est->snr(); + else + throw std::runtime_error("digital_mpsk_snr_est_cc:: No SNR estimator defined.\n"); } snr_est_type_t @@ -191,27 +91,22 @@ void digital_mpsk_snr_est_cc::set_type(snr_est_type_t t) { d_type = t; - d_y1 = 0; - d_y2 = 0; - d_y3 = 0; - d_y4 = 0; + + if(d_snr_est) + delete d_snr_est; switch (d_type) { case(SNR_EST_SIMPLE): - d_estimator = &digital_mpsk_snr_est_cc::est_simple; - d_calculator = &digital_mpsk_snr_est_cc::est_simple_snr; + d_snr_est = new digital_impl_mpsk_snr_est_simple(d_alpha); break; case(SNR_EST_SKEW): - d_estimator = &digital_mpsk_snr_est_cc::est_skew; - d_calculator = &digital_mpsk_snr_est_cc::est_skew_snr; + d_snr_est = new digital_impl_mpsk_snr_est_skew(d_alpha); break; case(SNR_EST_M2M4): - d_estimator = &digital_mpsk_snr_est_cc::est_m2m4; - d_calculator = &digital_mpsk_snr_est_cc::est_m2m4_snr; + d_snr_est = new digital_impl_mpsk_snr_est_m2m4(d_alpha); break; case(SNR_EST_SVN): - d_estimator = &digital_mpsk_snr_est_cc::est_svn; - d_calculator = &digital_mpsk_snr_est_cc::est_svn_snr; + d_snr_est = new digital_impl_mpsk_snr_est_svn(d_alpha); break; default: throw std::invalid_argument("digital_mpsk_snr_est_cc: unknown type specified.\n"); @@ -222,5 +117,6 @@ void digital_mpsk_snr_est_cc::set_alpha(double alpha) { d_alpha = alpha; - d_beta = 1.0-alpha; + if(d_snr_est) + d_snr_est->set_alpha(d_alpha); } |