From 612be3956603941f6cf530c090eba02d26d33bcd Mon Sep 17 00:00:00 2001
From: Tom Rondeau <trondeau@vt.edu>
Date: Wed, 10 Aug 2011 22:35:17 -0400
Subject: digital: updated constellation receiver to use loop bandwidth and
 damping factor instead of setting alpha and beta independently. Also cleaning
 up Costas loop a bit more.

---
 .../lib/digital_constellation_receiver_cb.cc       | 135 ++++++++++++++++++++-
 1 file changed, 129 insertions(+), 6 deletions(-)

(limited to 'gr-digital/lib/digital_constellation_receiver_cb.cc')

diff --git a/gr-digital/lib/digital_constellation_receiver_cb.cc b/gr-digital/lib/digital_constellation_receiver_cb.cc
index 56385f11e6..e2b6bf1d80 100644
--- a/gr-digital/lib/digital_constellation_receiver_cb.cc
+++ b/gr-digital/lib/digital_constellation_receiver_cb.cc
@@ -40,28 +40,151 @@
 
 digital_constellation_receiver_cb_sptr 
 digital_make_constellation_receiver_cb(digital_constellation_sptr constell,
-				       float alpha, float beta,
-				       float fmin, float fmax)
+				       float loop_bw, float fmin, float fmax)
 {
   return gnuradio::get_initial_sptr(new digital_constellation_receiver_cb (constell,
-									   alpha, beta,
+									   loop_bw,
 									   fmin, fmax));
 }
  
 static int ios[] = {sizeof(char), sizeof(float), sizeof(float), sizeof(float)};
 static std::vector<int> iosig(ios, ios+sizeof(ios)/sizeof(int));
 digital_constellation_receiver_cb::digital_constellation_receiver_cb (digital_constellation_sptr constellation, 
-								      float alpha, float beta,
-								      float fmin, float fmax)
+								      float loop_bw, float fmin, float fmax)
   : gr_block ("constellation_receiver_cb",
 	      gr_make_io_signature (1, 1, sizeof (gr_complex)),
 	      gr_make_io_signaturev (1, 4, iosig)),
+    d_freq(0), d_max_freq(fmax), d_min_freq(fmin), d_phase(0),
     d_constellation(constellation), 
-    d_alpha(alpha), d_beta(beta), d_freq(0), d_max_freq(fmax), d_min_freq(fmin), d_phase(0),
     d_current_const_point(0)
 {
   if (d_constellation->dimensionality() != 1)
     throw std::runtime_error ("This receiver only works with constellations of dimension 1.");
+
+  // Set the damping factor for a critically damped system
+  d_damping = sqrtf(2.0f)/2.0f;
+
+  // Set the bandwidth, which will then call update_gains()
+  set_loop_bandwidth(loop_bw);
+}
+
+
+/*******************************************************************
+    SET FUNCTIONS
+*******************************************************************/
+
+void
+digital_constellation_receiver_cb::set_loop_bandwidth(float bw) 
+{
+  if(bw < 0) {
+    throw std::out_of_range ("digital_constellation_receiver_cb: invalid bandwidth. Must be >= 0.");
+  }
+  
+  d_loop_bw = bw;
+  update_gains();
+}
+
+void
+digital_constellation_receiver_cb::set_damping_factor(float df) 
+{
+  if(df < 0 || df > 1.0) {
+    throw std::out_of_range ("digital_constellation_receiver_cb: invalid damping factor. Must be in [0,1].");
+  }
+  
+  d_damping = df;
+  update_gains();
+}
+
+void
+digital_constellation_receiver_cb::set_alpha(float alpha)
+{
+  if(alpha < 0 || alpha > 1.0) {
+    throw std::out_of_range ("digital_constellation_receiver_cb: invalid alpha. Must be in [0,1].");
+  }
+  d_alpha = alpha;
+}
+
+void
+digital_constellation_receiver_cb::set_beta(float beta)
+{
+  if(beta < 0 || beta > 1.0) {
+    throw std::out_of_range ("digital_constellation_receiver_cb: invalid beta. Must be in [0,1].");
+  }
+  d_beta = beta;
+}
+
+void
+digital_constellation_receiver_cb::set_frequency(float freq)
+{
+  if(freq > d_max_freq)
+    d_freq = d_min_freq;
+  else if(freq < d_min_freq)
+    d_freq = d_max_freq;
+  else
+    d_freq = freq;
+}
+
+void
+digital_constellation_receiver_cb::set_phase(float phase)
+{
+  d_phase = phase;
+  while(d_phase>M_TWOPI)
+    d_phase -= M_TWOPI;
+  while(d_phase<-M_TWOPI)
+    d_phase += M_TWOPI;
+}
+
+   
+/*******************************************************************
+    GET FUNCTIONS
+*******************************************************************/
+
+
+float
+digital_constellation_receiver_cb::get_loop_bandwidth() const
+{
+  return d_loop_bw;
+}
+
+float
+digital_constellation_receiver_cb::get_damping_factor() const
+{
+  return d_damping;
+}
+
+float
+digital_constellation_receiver_cb::get_alpha() const
+{
+  return d_alpha;
+}
+
+float
+digital_constellation_receiver_cb::get_beta() const
+{
+  return d_beta;
+}
+
+float
+digital_constellation_receiver_cb::get_frequency() const
+{
+  return d_freq;
+}
+
+float
+digital_constellation_receiver_cb::get_phase() const
+{
+  return d_phase;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+void
+digital_constellation_receiver_cb::update_gains()
+{
+  float denom = (1.0 + 2.0*d_damping*d_loop_bw + d_loop_bw*d_loop_bw);
+  d_alpha = (4*d_damping*d_loop_bw) / denom;
+  d_beta = (4*d_loop_bw*d_loop_bw) / denom;
 }
 
 void
-- 
cgit v1.2.3