merging receiver branch -r6837:7375 into trunk. Improves speed of MPSK receiver;...
authortrondeau <trondeau@221aa14e-8319-0410-a670-987f0aec2ac5>
Wed, 9 Jan 2008 23:27:36 +0000 (23:27 +0000)
committertrondeau <trondeau@221aa14e-8319-0410-a670-987f0aec2ac5>
Wed, 9 Jan 2008 23:27:36 +0000 (23:27 +0000)
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@7389 221aa14e-8319-0410-a670-987f0aec2ac5

13 files changed:
gnuradio-core/src/lib/general/Makefile.am
gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.cc
gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.h
gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.cc
gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.h
gnuradio-core/src/lib/general/gr_math.h
gnuradio-core/src/lib/general/gr_mpsk_receiver_cc.cc
gnuradio-core/src/lib/general/gr_mpsk_receiver_cc.h
gnuradio-core/src/lib/general/qa_general.cc
gnuradio-core/src/lib/general/qa_gr_math.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/qa_gr_math.h [new file with mode: 0644]
gnuradio-examples/python/digital/benchmark_loopback.py
gnuradio-examples/python/digital/transmit_path_lb.py

index cde6a754967a36e016dec087f3c7b7dbaaa891f8..238c56d848e0fdd42ecd1ff436d19e8063c25e6b 100644 (file)
@@ -169,7 +169,8 @@ libgeneral_qa_la_SOURCES =          \
        qa_gr_firdes.cc                 \
        qa_gr_fxpt.cc                   \
        qa_gr_fxpt_nco.cc               \
-       qa_gr_fxpt_vco.cc               
+       qa_gr_fxpt_vco.cc               \
+       qa_gr_math.cc
 
 
 
@@ -325,7 +326,8 @@ noinst_HEADERS =                    \
        qa_gr_fxpt.h                    \
        qa_gr_fxpt_nco.h                \
        qa_gr_fxpt_vco.h                \
-       sine_table.h                    
+       sine_table.h                    \
+       qa_gr_math.h
 
 swiginclude_HEADERS =                  \
        general.i                       \
index 6761392e67929c1de98b760f04c765ebcff32929..675b8611f0634335b850241acb4ae0e3d0b8e1dc 100644 (file)
@@ -151,25 +151,14 @@ gr_clock_recovery_mm_cc::general_work (int noutput_items,
       out[oo++] = d_p_0T;
       
       // limit mm_val
-      if (mm_val > 1.0)
-       mm_val = 1.0;
-      else if (mm_val < -1.0)
-       mm_val = -1.0;
-      
+      gr_branchless_clip(mm_val,1.0);
       d_omega = d_omega + d_gain_omega * mm_val;
-      if (d_omega > d_max_omega)
-       d_omega = d_max_omega;
-      else if (d_omega < d_min_omega)
-       d_omega = d_min_omega;
-      
+      d_omega = d_omega_mid + gr_branchless_clip(d_omega-d_omega_mid, d_omega_relative_limit);   // make sure we don't walk away
+
       d_mu = d_mu + d_omega + d_gain_mu * mm_val;
       ii += (int)floor(d_mu);
       d_mu -= floor(d_mu);
-      
-      #if 0
-      printf("%f\t%f\n", d_omega, d_mu);
-      #endif
-      
+            
       // write the error signal to the second output
       foptr[oo-1] = gr_complex(d_mu,0);
       
@@ -195,16 +184,10 @@ gr_clock_recovery_mm_cc::general_work (int noutput_items,
       out[oo++] = d_p_0T;
       
       // limit mm_val
-      if (mm_val > 1.0)
-       mm_val = 1.0;
-      else if (mm_val < -1.0)
-       mm_val = -1.0;
+      gr_branchless_clip(mm_val,1.0);
       
       d_omega = d_omega + d_gain_omega * mm_val;
-      if (d_omega > d_max_omega)
-       d_omega = d_max_omega;
-      else if (d_omega < d_min_omega)
-       d_omega = d_min_omega;
+      d_omega = d_omega_mid + gr_branchless_clip(d_omega-d_omega_mid, d_omega_relative_limit);   // make sure we don't walk away
       
       d_mu = d_mu + d_omega + d_gain_mu * mm_val;
       ii += (int)floor(d_mu);
index 453bafbe1c02c6302bd81242526712631a0552b2..86673228612e9dbadfe48c251b0d7dd4380e0135 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <gr_block.h>
 #include <gr_complex.h>
+#include <gr_math.h>
 
 class gri_mmse_fir_interpolator_cc;
 
@@ -69,6 +70,7 @@ class gr_clock_recovery_mm_cc : public gr_block
     d_omega = omega;
     d_min_omega = omega*(1.0 - d_omega_relative_limit);
     d_max_omega = omega*(1.0 + d_omega_relative_limit);
+    d_omega_mid = 0.5*(d_min_omega+d_max_omega);
   }
 
 protected:
@@ -82,6 +84,7 @@ protected:
   float                                d_min_omega;            // minimum allowed omega
   float                                d_max_omega;            // maximum allowed omeg
   float                                d_omega_relative_limit; // used to compute min and max omega
+  float                         d_omega_mid;
   float                         d_gain_mu;
   gr_complex                    d_last_sample;
   gri_mmse_fir_interpolator_cc         *d_interp;
index d27ab9d65e52f8bdc0cf4c9dda40456b27d98ca3..fdf82667ae572b59772829c7374db8292621723a 100644 (file)
@@ -118,11 +118,7 @@ gr_clock_recovery_mm_ff::general_work (int noutput_items,
     d_last_sample = out[oo];
 
     d_omega = d_omega + d_gain_omega * mm_val;
-    if (d_omega > d_max_omega)
-      d_omega = d_max_omega;
-    else if (d_omega < d_min_omega)
-      d_omega = d_min_omega;
-
+    d_omega = d_omega_mid + gr_branchless_clip(d_omega-d_omega_mid, d_omega_relative_limit);   // make sure we don't walk away
     d_mu = d_mu + d_omega + d_gain_mu * mm_val;
 
     ii += (int) floor(d_mu);
index 87823c44e3cf9985b6c74de1c8c5d7bb8bfa0c7d..a121fe8213cb3d06db910d8780a7a0693d96d92d 100644 (file)
@@ -24,6 +24,7 @@
 #define        INCLUDED_GR_CLOCK_RECOVERY_MM_FF_H
 
 #include <gr_block.h>
+#include <gr_math.h>
 #include <stdio.h>
 
 class gri_mmse_fir_interpolator;
@@ -67,6 +68,7 @@ class gr_clock_recovery_mm_ff : public gr_block
     d_omega = omega;
     d_min_omega = omega*(1.0 - d_omega_relative_limit);
     d_max_omega = omega*(1.0 + d_omega_relative_limit);
+    d_omega_mid = 0.5*(d_min_omega+d_max_omega);
   }
 
 protected:
@@ -76,7 +78,8 @@ protected:
  private:
   float                        d_mu;           // fractional sample position [0.0, 1.0]
   float                        d_omega;        // nominal frequency
-  float                                d_min_omega;    // minimum allowed omega
+  float                                d_min_omega;    // minimum allowed omega 
+  float                         d_omega_mid;   // average omega
   float                                d_max_omega;    // maximum allowed omega
   float                         d_gain_omega;  // gain for adjusting omega
   float                         d_gain_mu;     // gain for adjusting mu
index 2cd5b8eb7beeea245ceb634bf052082e7618f34b..e5173eceb88e7a08cfdf93da3503ba847f45be8a 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2003,2005 Free Software Foundation, Inc.
+ * Copyright 2003,2005,2008 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -64,9 +64,7 @@ static inline float gr_fast_atan2f(gr_complex z)
   return gr_fast_atan2f(z.imag(), z.real()); 
 }
 
-
 /* This bounds x by +/- clip without a branch */
-
 static inline float gr_branchless_clip(float x, float clip)
 {
   float x1 = fabsf(x+clip);
@@ -75,6 +73,98 @@ static inline float gr_branchless_clip(float x, float clip)
   return 0.5*x1;
 }
 
+static inline float gr_clip(float x, float clip)
+{
+  float y;
+  if(x > clip)
+    y = clip;
+  else if(x < clip)
+    y = -clip;
+  return y;
+}
+
+// Slicer Functions
+static inline unsigned int gr_binary_slicer(float x)
+{
+  if(x >= 0)
+    return 1;
+  else
+    return 0;
+}
+
+static inline unsigned int gr_quad_45deg_slicer(float r, float i)
+{
+  unsigned int ret = 0;
+  if((r >= 0) && (i >= 0))
+    ret = 0;
+  else if((r < 0) && (i >= 0))
+    ret = 1;
+  else if((r < 0) && (i < 0))
+    ret = 2;
+  else 
+    ret = 3;
+  return ret;
+}
+
+static inline unsigned int gr_quad_0deg_slicer(float r, float i)
+{
+  unsigned int ret = 0;
+  if(fabsf(r) > fabsf(i)) {
+    if(r > 0)
+      ret = 0;
+    else
+      ret = 2;
+  }
+  else {
+    if(i > 0)
+      ret = 1;
+    else
+      ret = 3;
+  }
+
+  return ret;
+}
 
+static inline unsigned int gr_quad_45deg_slicer(gr_complex x)
+{
+  return gr_quad_45deg_slicer(x.real(), x.imag());
+}
+
+static inline unsigned int gr_quad_0deg_slicer(gr_complex x)
+{
+  return gr_quad_0deg_slicer(x.real(), x.imag());
+}
+
+// Branchless Slicer Functions
+static inline unsigned int gr_branchless_binary_slicer(float x)
+{
+  return (x >= 0);
+}
+
+static inline unsigned int gr_branchless_quad_0deg_slicer(float r, float i)
+{
+  unsigned int ret = 0;
+  ret =  (fabsf(r) > fabsf(i)) * (((r < 0) << 0x1));       // either 0 (00) or 2 (10)
+  ret |= (fabsf(i) > fabsf(r)) * (((i < 0) << 0x1) | 0x1); // either 1 (01) or 3 (11)
+
+  return ret;
+}
+
+static inline unsigned int gr_branchless_quad_0deg_slicer(gr_complex x)
+{
+  return gr_branchless_quad_0deg_slicer(x.real(), x.imag());
+}
+
+static inline unsigned int gr_branchless_quad_45deg_slicer(float r, float i)
+{
+  char ret = (r <= 0);
+  ret |= ((i <= 0) << 1);
+  return (ret ^ ((ret & 0x2) >> 0x1));
+}
+
+static inline unsigned int gr_branchless_quad_45deg_slicer(gr_complex x)
+{
+  return gr_branchless_quad_45deg_slicer(x.real(), x.imag());
+}
 
 #endif /* _GR_MATH_H_ */
index c943e3637b656c2eb0a55a0ee9fa1b6f1bae4000..d1a743f14a06faadeaa62b0898ee713d7f89161b 100644 (file)
@@ -91,12 +91,12 @@ gr_mpsk_receiver_cc::gr_mpsk_receiver_cc (unsigned int M, float theta,
   switch(d_M) {
   case 2:  // optimized algorithms for BPSK
     d_phase_error_detector = &gr_mpsk_receiver_cc::phase_error_detector_generic; //bpsk;
-    d_decision = &gr_mpsk_receiver_cc::decision_generic; //bpsk;
+    d_decision = &gr_mpsk_receiver_cc::decision_bpsk;
     break;
 
   case 4: // optimized algorithms for QPSK
     d_phase_error_detector = &gr_mpsk_receiver_cc::phase_error_detector_generic; //qpsk;
-    d_decision = &gr_mpsk_receiver_cc::decision_generic; //qpsk;
+    d_decision = &gr_mpsk_receiver_cc::decision_qpsk;
     break;
 
   default: // generic algorithms for any M (power of 2?) but not pretty
@@ -145,31 +145,20 @@ float gr_mpsk_receiver_cc::phase_error_detector_generic(gr_complex sample) const
   return -arg(sample*conj(d_constellation[d_current_const_point]));
 }
 
-// FIXME add these back in an test difference in performance
 unsigned int
 gr_mpsk_receiver_cc::decision_bpsk(gr_complex sample) const
 {
-  unsigned int index = 0;
-
-  // Implements a 1-demensional slicer
-  if(sample.real() > 0)
-    index = 1;
-  return index;
+  return (gr_branchless_binary_slicer(sample.real()) ^ 1);
+  //return gr_binary_slicer(sample.real()) ^ 1;
 }
 
-// FIXME add these back in an test difference in performance
 unsigned int
 gr_mpsk_receiver_cc::decision_qpsk(gr_complex sample) const
 {
-  unsigned int index = 0;
-
-  // Implements a simple slicer function
-  if((sample.real() < 0) && (sample.imag() > 0))
-    index = 1;
-  else if((sample.real() < 0) && (sample.imag() < 0))
-    index = 2;
-  else
-    index = 3;
+  unsigned int index;
+
+  //index = gr_branchless_quad_0deg_slicer(sample);
+  index = gr_quad_0deg_slicer(sample);
   return index;
 }
 
@@ -211,11 +200,8 @@ gr_mpsk_receiver_cc::mm_sampler(const gr_complex symbol)
   d_phase += d_freq;  // increment the phase based on the frequency of the rotation
 
   // Keep phase clamped and not walk to infinity
-  while(d_phase>M_TWOPI)
-    d_phase -= M_TWOPI;
-  while(d_phase<-M_TWOPI)
-    d_phase += M_TWOPI;
-
+  d_phase = gr_branchless_clip(d_phase, M_TWOPI);
+  
   nco = gr_expj(d_phase+d_theta);   // get the NCO value for derotating the current sample
   sample = nco*symbol;      // get the downconverted symbol
   
@@ -247,20 +233,10 @@ gr_mpsk_receiver_cc::mm_error_tracking(gr_complex sample)
   y = (d_p_0T - d_p_2T) * conj(d_c_1T);
   u = y - x;
   mm_error = u.real();   // the error signal is in the real part
-  
-  // limit mm_val
-  if (mm_error > 1.0)
-    mm_error = 1.0;
-  else if (mm_error < -1.0)
-    mm_error = -1.0;
-  
+  mm_error = gr_branchless_clip(mm_error, 1.0); // limit mm_val
+    
   d_omega = d_omega + d_gain_omega * mm_error;  // update omega based on loop error
-
-  // make sure we don't walk away
-  if (d_omega > d_max_omega)
-    d_omega = d_max_omega;
-  else if (d_omega < d_min_omega)
-    d_omega = d_min_omega;
+  d_omega = d_omega_mid + gr_branchless_clip(d_omega-d_omega_mid, d_omega_rel);   // make sure we don't walk away
   
   d_mu += d_omega + d_gain_mu * mm_error;   // update mu based on loop error
   
@@ -280,26 +256,17 @@ gr_mpsk_receiver_cc::phase_error_tracking(gr_complex sample)
   // Make phase and frequency corrections based on sampled value
   phase_error = (*this.*d_phase_error_detector)(sample);
 
-  if (phase_error > 1)
-    phase_error = 1;
-  else if (phase_error < -1)
-    phase_error = -1;  
-
+  phase_error = gr_branchless_clip(phase_error, 1.0);
+    
   d_freq += d_beta*phase_error;             // adjust frequency based on error
   d_phase += d_freq + d_alpha*phase_error;  // adjust phase based on error
-  
+
   // Make sure we stay within +-2pi
-  while(d_phase>M_TWOPI)
-    d_phase -= M_TWOPI;
-  while(d_phase<-M_TWOPI)
-    d_phase += M_TWOPI;
+  d_phase = gr_branchless_clip(d_phase, M_TWOPI);
   
   // Limit the frequency range
-  if (d_freq > d_max_freq)
-    d_freq = d_max_freq;
-  else if (d_freq < d_min_freq)
-    d_freq = d_min_freq;
-
+  d_freq = gr_branchless_clip(d_freq, d_max_freq);
+  
 #if VERBOSE_COSTAS
   printf("cl: phase_error: %f  phase: %f  freq: %f  sample: %f+j%f  constellation: %f+j%f\n",
         phase_error, d_phase, d_freq, sample.real(), sample.imag(), 
@@ -318,7 +285,6 @@ gr_mpsk_receiver_cc::general_work (int noutput_items,
 
   int i=0, o=0;
 
-  //while(i < ninput_items[0]) {    
   while((o < noutput_items) && (i < ninput_items[0])) {
     while((d_mu > 1) && (i < ninput_items[0]))  {
       mm_sampler(in[i]);   // puts symbols into a buffer and adjusts d_mu
index b0ecb7c93ed551f10aacdddeb85df1474f389149..cddb697acb8669a6b60661f8cedf55b87e20112f 100644 (file)
@@ -100,6 +100,7 @@ class gr_mpsk_receiver_cc : public gr_block
     d_omega = omega;
     d_min_omega = omega*(1.0 - d_omega_rel);
     d_max_omega = omega*(1.0 + d_omega_rel);
+    d_omega_mid = 0.5*(d_min_omega+d_max_omega);
   }
 
   //! (M&M) Sets value for mu gain factor
@@ -275,7 +276,7 @@ protected:
 
   // Members related to symbol timing
   float d_mu, d_gain_mu;
-  float d_omega, d_gain_omega, d_omega_rel, d_max_omega, d_min_omega;
+  float d_omega, d_gain_omega, d_omega_rel, d_max_omega, d_min_omega, d_omega_mid;
   gr_complex d_p_2T, d_p_1T, d_p_0T;
   gr_complex d_c_2T, d_c_1T, d_c_0T;
 
index cf00dc7633ec8b397c667e4e48ddadefa398340d..75d5632360f01de61b980802b937c90480911bcd 100644 (file)
@@ -31,6 +31,7 @@
 #include <qa_gr_fxpt.h>
 #include <qa_gr_fxpt_nco.h>
 #include <qa_gr_fxpt_vco.h>
+#include <qa_gr_math.h>
 
 CppUnit::TestSuite *
 qa_general::suite ()
@@ -42,6 +43,7 @@ qa_general::suite ()
   s->addTest (qa_gr_fxpt::suite ());
   s->addTest (qa_gr_fxpt_nco::suite ());
   s->addTest (qa_gr_fxpt_vco::suite ());
+  s->addTest (qa_gr_math::suite ());
   
   return s;
 }
diff --git a/gnuradio-core/src/lib/general/qa_gr_math.cc b/gnuradio-core/src/lib/general/qa_gr_math.cc
new file mode 100644 (file)
index 0000000..b3a1b95
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_math.h>
+#include <qa_gr_math.h>
+#include <cppunit/TestAssert.h>
+#include <stdio.h>
+
+void
+qa_gr_math::test_binary_slicer1 ()
+{
+  float x[5] = {-1, -0.5, 0, 0.5, 1.0};
+  unsigned int z[5] = {0, 0, 1, 1, 1};
+  unsigned int y;
+
+  //printf("\nBinary\n");
+  for (unsigned int i = 0; i < 5; i++) {
+    y = gr_binary_slicer(x[i]);
+    //printf("in: %f   out: %d   desired: %d\n", x[i], y, z[i]);
+
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
+  }
+
+  //printf("\nBranchless Binary\n");
+  for (unsigned int i = 0; i < 5; i++) {
+    y = gr_branchless_binary_slicer(x[i]);
+    //printf("in: %f   out: %d   desired: %d\n", x[i], y, z[i]);
+
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);    
+  }
+}
+
+void
+qa_gr_math::test_quad_0deg_slicer1 ()
+{
+  gr_complex x[4] = {gr_complex(1, 0),
+                    gr_complex(0, 1), 
+                    gr_complex(-1, 0),
+                    gr_complex(0, -1)};
+
+  unsigned int z[4] = {0, 1, 2, 3};
+  unsigned int y;
+
+  //printf("\nQuad0\n");
+  for (unsigned int i = 0; i < 4; i++) {
+    y = gr_quad_0deg_slicer(x[i]);
+    //printf("in: %.4f+j%.4f   out: %d   desired: %d\n", x[i].real(), x[i].imag(), y, z[i]);
+
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
+  }
+
+  //printf("\nBranchless Quad0\n");
+  for (unsigned int i = 0; i < 4; i++) {
+    y = gr_branchless_quad_0deg_slicer(x[i]);
+    //printf("in: %.4f+j%.4f   out: %d   desired: %d\n", x[i].real(), x[i].imag(), y, z[i]);
+    
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
+  }
+}
+
+void
+qa_gr_math::test_quad_45deg_slicer1 ()
+{
+  gr_complex x[4] = {gr_complex(0.707, 0.707),
+                    gr_complex(-0.707, 0.707), 
+                    gr_complex(-0.707, -0.707),
+                    gr_complex(0.707, -0.707)};
+  
+  unsigned int z[4] = {0, 1, 2, 3};
+  unsigned int y;
+
+  //printf("\nQuad45\n");
+  for (unsigned int i = 0; i < 4; i++) {
+    y = gr_quad_45deg_slicer(x[i]);
+    //printf("in: %.4f+j%.4f   out: %d   desired: %d\n", x[i].real(), x[i].imag(), y, z[i]);
+
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
+  }
+
+  //printf("\nBranchless Quad45\n");
+  for (unsigned int i = 0; i < 4; i++) {
+    y = gr_branchless_quad_45deg_slicer(x[i]);
+    //printf("in: %.4f+j%.4f   out: %d   desired: %d\n", x[i].real(), x[i].imag(), y, z[i]);
+
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
+  }
+}
diff --git a/gnuradio-core/src/lib/general/qa_gr_math.h b/gnuradio-core/src/lib/general/qa_gr_math.h
new file mode 100644 (file)
index 0000000..bcc3a62
--- /dev/null
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_GR_MATH_H_
+#define _QA_GR_MATH_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_math : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE(qa_gr_math);
+  CPPUNIT_TEST(test_binary_slicer1);
+  CPPUNIT_TEST(test_quad_0deg_slicer1);
+  CPPUNIT_TEST(test_quad_45deg_slicer1);
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  void test_binary_slicer1();
+  void test_quad_0deg_slicer1();
+  void test_quad_45deg_slicer1();
+};
+
+#endif /* _QA_GR_MATH_H_ */
index e9a0f5d5ab6dbcf501361e7d1b8b2dd5246dff7e..e46bbdeeb8a8b9760d4b90a0fd99c87aba9fc678 100755 (executable)
@@ -20,7 +20,7 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-from gnuradio import gr, gru, modulation_utils
+from gnuradio import gr, gru, modulation_utils, blks2
 from gnuradio import eng_notation
 from gnuradio.eng_option import eng_option
 from optparse import OptionParser
@@ -32,34 +32,6 @@ from transmit_path_lb import transmit_path
 from receive_path_lb import receive_path
 import fusb_options
 
-class awgn_channel(gr.hier_block2):
-    def __init__(self, sample_rate, noise_voltage, frequency_offset, seed=False):
-
-       gr.hier_block2.__init__(self, "awgn_channel",
-                               gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
-                               gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
-                                       
-        # Create the Gaussian noise source
-        if not seed:
-            self.noise = gr.noise_source_c(gr.GR_GAUSSIAN, noise_voltage)
-        else:
-            rseed = int(time.time())
-            self.noise = gr.noise_source_c(gr.GR_GAUSSIAN, noise_voltage, rseed)
-
-        self.adder =  gr.add_cc()
-
-        # Create the frequency offset
-        self.offset = gr.sig_source_c(1, gr.GR_SIN_WAVE,
-                                      frequency_offset, 1.0, 0.0)
-        self.mixer = gr.multiply_cc()
-
-        # Connect the components
-        self.connect(self, (self.mixer, 0))
-        self.connect(self.offset, (self.mixer, 1))
-        self.connect(self.mixer, (self.adder, 0))
-        self.connect(self.noise, (self.adder, 1))
-       self.connect(self.adder, self)
-
 class my_top_block(gr.top_block):
     def __init__(self, mod_class, demod_class, rx_callback, options):
         gr.top_block.__init__(self)
@@ -78,8 +50,7 @@ class my_top_block(gr.top_block):
         self.rxpath = receive_path(demod_class, rx_callback, options)
 
         if channelon:
-            self.channel = awgn_channel(options.sample_rate, noise_voltage,
-                                        frequency_offset, options.seed)
+            self.channel = blks2.channel_model(noise_voltage, frequency_offset, 1.01)
 
             if options.discontinuous:
                 z = 20000*[0,]
index 49f53076e6e0693195671e3d3877a7473fd486a3..11d37026940f23c50bd43b28ff210a02695903a2 100644 (file)
@@ -51,8 +51,6 @@ class transmit_path(gr.hier_block2):
         mod_kwargs = self._modulator_class.extract_kwargs_from_options(options)
     
         # transmitter
-       print self._modulator_class
-       print mod_kwargs
        modulator = self._modulator_class(**mod_kwargs)
         self.packet_transmitter = \
             blks2.mod_pkts(modulator,