summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gr-digital/include/digital_mpsk_snr_est_cc.h31
-rw-r--r--gr-digital/lib/digital_mpsk_snr_est_cc.cc152
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);
}