diff options
Diffstat (limited to 'gr-digital/lib')
-rw-r--r-- | gr-digital/lib/digital_mpsk_snr_est_cc.cc | 152 |
1 files changed, 24 insertions, 128 deletions
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); } |