Modify all block factories to use gnuradio::get_initial_sptr.
[debian/gnuradio] / gnuradio-core / src / lib / general / gr_costas_loop_cc.cc
index 4ad627f0290a1df73ca9134546e7cc95b9fd1252..f3bfd095188792e6f92a97b93c3d88ed6e911904 100644 (file)
@@ -1,12 +1,12 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2010 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 2, or (at your option)
+ * 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,
@@ -16,8 +16,8 @@
  * 
  * 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -38,7 +38,7 @@ gr_make_costas_loop_cc (float alpha, float beta,
                        int order
                        ) throw (std::invalid_argument)
 {
-  return gr_costas_loop_cc_sptr (new gr_costas_loop_cc (alpha, beta,
+  return gnuradio::get_initial_sptr(new gr_costas_loop_cc (alpha, beta,
                                                        max_freq, min_freq,
                                                        order));
 }
@@ -49,7 +49,7 @@ gr_costas_loop_cc::gr_costas_loop_cc (float alpha, float beta,
                                      ) throw (std::invalid_argument)
   : gr_sync_block ("costas_loop_cc",
                   gr_make_io_signature (1, 1, sizeof (gr_complex)),
-                  gr_make_io_signature (1, 1, sizeof (gr_complex))),
+                  gr_make_io_signature (1, 2, sizeof (gr_complex))),
     d_alpha(alpha), d_beta(beta), 
     d_max_freq(max_freq), d_min_freq(min_freq),
     d_phase(0), d_freq((max_freq+min_freq)/2),
@@ -85,6 +85,18 @@ gr_costas_loop_cc::phase_detector_2(gr_complex sample) const
   return (sample.real()*sample.imag());
 }
 
+void
+gr_costas_loop_cc::set_alpha(float alpha)
+{
+  d_alpha = alpha;
+}
+
+void
+gr_costas_loop_cc::set_beta(float beta)
+{
+  d_beta = beta;
+}
+
 int
 gr_costas_loop_cc::work (int noutput_items,
                         gr_vector_const_void_star &input_items,
@@ -92,27 +104,65 @@ gr_costas_loop_cc::work (int noutput_items,
 {
   const gr_complex *iptr = (gr_complex *) input_items[0];
   gr_complex *optr = (gr_complex *) output_items[0];
+  gr_complex *foptr = (gr_complex *) output_items[1];
+
+  bool write_foptr = output_items.size() >= 2;
 
   float error;
   gr_complex nco_out;
+  
+  if (write_foptr) {
 
-  for (int i = 0; i < noutput_items; i++){
-    nco_out = gr_expj(-d_phase);
-    optr[i] = iptr[i] * nco_out;
-    
-    error = (*this.*d_phase_detector)(optr[i]);
-    
-    d_freq = d_freq + d_beta * error;
-    d_phase = d_phase + d_freq + d_alpha * error;
-    while(d_phase>M_TWOPI)
-      d_phase -= M_TWOPI;
-    while(d_phase<-M_TWOPI)
-      d_phase += M_TWOPI;
-    
-     if (d_freq > d_max_freq)
-      d_freq = d_max_freq;
-    else if (d_freq < d_min_freq)
-      d_freq = d_min_freq;
+    for (int i = 0; i < noutput_items; i++){
+      nco_out = gr_expj(-d_phase);
+      optr[i] = iptr[i] * nco_out;
+      
+      error = (*this.*d_phase_detector)(optr[i]);
+      if (error > 1)
+       error = 1;
+      else if (error < -1)
+       error = -1;
+      
+      d_freq = d_freq + d_beta * error;
+      d_phase = d_phase + d_freq + d_alpha * error;
+      
+      while(d_phase>M_TWOPI)
+       d_phase -= M_TWOPI;
+      while(d_phase<-M_TWOPI)
+       d_phase += M_TWOPI;
+      
+      if (d_freq > d_max_freq)
+       d_freq = d_max_freq;
+      else if (d_freq < d_min_freq)
+       d_freq = d_min_freq;
+      
+      foptr[i] = gr_complex(d_freq,0);
+    } 
+  } else {
+    for (int i = 0; i < noutput_items; i++){
+      nco_out = gr_expj(-d_phase);
+      optr[i] = iptr[i] * nco_out;
+      
+      error = (*this.*d_phase_detector)(optr[i]);
+      if (error > 1)
+       error = 1;
+      else if (error < -1)
+       error = -1;
+      
+      d_freq = d_freq + d_beta * error;
+      d_phase = d_phase + d_freq + d_alpha * error;
+      
+      while(d_phase>M_TWOPI)
+       d_phase -= M_TWOPI;
+      while(d_phase<-M_TWOPI)
+       d_phase += M_TWOPI;
+      
+      if (d_freq > d_max_freq)
+       d_freq = d_max_freq;
+      else if (d_freq < d_min_freq)
+       d_freq = d_min_freq;
+      
+    }
   }
   return noutput_items;
 }