diff options
author | Hendrik van Wyk | 2012-07-08 17:31:19 -0400 |
---|---|---|
committer | Tom Rondeau | 2012-07-08 17:31:19 -0400 |
commit | 504a14dc0f24e165d0704ca2c0321598ae86f02e (patch) | |
tree | f78348bfbc917953b78fb40dde4b7b730fa2bcf7 /gr-digital | |
parent | c4805e3a02b7547823c81664dae497c145c8c66a (diff) | |
download | gnuradio-504a14dc0f24e165d0704ca2c0321598ae86f02e.tar.gz gnuradio-504a14dc0f24e165d0704ca2c0321598ae86f02e.tar.bz2 gnuradio-504a14dc0f24e165d0704ca2c0321598ae86f02e.zip |
digital: fix for FLL block; uses actual FIR filter.
This should work much more efficiently and also appears to fix issue 463.
Diffstat (limited to 'gr-digital')
-rw-r--r-- | gr-digital/include/digital_fll_band_edge_cc.h | 40 | ||||
-rw-r--r-- | gr-digital/lib/digital_fll_band_edge_cc.cc | 70 |
2 files changed, 67 insertions, 43 deletions
diff --git a/gr-digital/include/digital_fll_band_edge_cc.h b/gr-digital/include/digital_fll_band_edge_cc.h index c70bfc86d..68083bbae 100644 --- a/gr-digital/include/digital_fll_band_edge_cc.h +++ b/gr-digital/include/digital_fll_band_edge_cc.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2009,2011 Free Software Foundation, Inc. + * Copyright 2009,2011,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -27,13 +27,19 @@ #include <digital_api.h> #include <gr_sync_block.h> #include <gri_control_loop.h> +#include <gr_fir_util.h> +#include <gr_fir_ccc.h> + +typedef gr_fir_ccc* (*fir_maker_t)(const std::vector<gr_complex> &taps); +typedef gr_fir_ccc filter_t; class digital_fll_band_edge_cc; typedef boost::shared_ptr<digital_fll_band_edge_cc> digital_fll_band_edge_cc_sptr; -DIGITAL_API digital_fll_band_edge_cc_sptr digital_make_fll_band_edge_cc (float samps_per_sym, - float rolloff, - int filter_size, - float bandwidth); +DIGITAL_API digital_fll_band_edge_cc_sptr +digital_make_fll_band_edge_cc(float samps_per_sym, + float rolloff, + int filter_size, + float bandwidth); /*! * \class digital_fll_band_edge_cc @@ -86,7 +92,8 @@ DIGITAL_API digital_fll_band_edge_cc_sptr digital_make_fll_band_edge_cc (float s * */ -class DIGITAL_API digital_fll_band_edge_cc : public gr_sync_block, public gri_control_loop +class DIGITAL_API digital_fll_band_edge_cc : + public gr_sync_block, public gri_control_loop { private: /*! @@ -96,10 +103,11 @@ class DIGITAL_API digital_fll_band_edge_cc : public gr_sync_block, public gri_co * \param filter_size (int) Size (in taps) of the filter * \param bandwidth (float) Loop bandwidth */ - friend DIGITAL_API digital_fll_band_edge_cc_sptr digital_make_fll_band_edge_cc (float samps_per_sym, - float rolloff, - int filter_size, - float bandwidth); + friend DIGITAL_API digital_fll_band_edge_cc_sptr + digital_make_fll_band_edge_cc(float samps_per_sym, + float rolloff, + int filter_size, + float bandwidth); float d_sps; float d_rolloff; @@ -108,6 +116,10 @@ class DIGITAL_API digital_fll_band_edge_cc : public gr_sync_block, public gri_co std::vector<gr_complex> d_taps_lower; std::vector<gr_complex> d_taps_upper; bool d_updated; + filter_t* d_filter_lower; + filter_t* d_filter_upper; + std::vector<gr_complex> d_output_hist; + std::vector<gr_complex> d_fllbuffer; /*! * Build the FLL @@ -130,7 +142,7 @@ class DIGITAL_API digital_fll_band_edge_cc : public gr_sync_block, public gri_co void design_filter(float samps_per_sym, float rolloff, int filter_size); public: - ~digital_fll_band_edge_cc (); + ~digital_fll_band_edge_cc(); /******************************************************************* SET FUNCTIONS @@ -206,9 +218,9 @@ public: */ void print_taps(); - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); }; #endif diff --git a/gr-digital/lib/digital_fll_band_edge_cc.cc b/gr-digital/lib/digital_fll_band_edge_cc.cc index 05c092622..f2cfb1020 100644 --- a/gr-digital/lib/digital_fll_band_edge_cc.cc +++ b/gr-digital/lib/digital_fll_band_edge_cc.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2009-2011 Free Software Foundation, Inc. + * Copyright 2009-2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -50,37 +50,38 @@ digital_make_fll_band_edge_cc (float samps_per_sym, float rolloff, static int ios[] = {sizeof(gr_complex), sizeof(float), sizeof(float), sizeof(float)}; static std::vector<int> iosig(ios, ios+sizeof(ios)/sizeof(int)); -digital_fll_band_edge_cc::digital_fll_band_edge_cc (float samps_per_sym, float rolloff, - int filter_size, float bandwidth) - : gr_sync_block ("fll_band_edge_cc", - gr_make_io_signature (1, 1, sizeof(gr_complex)), - gr_make_io_signaturev (1, 4, iosig)), +digital_fll_band_edge_cc::digital_fll_band_edge_cc(float samps_per_sym, float rolloff, + int filter_size, float bandwidth) + : gr_sync_block("fll_band_edge_cc", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signaturev(1, 4, iosig)), gri_control_loop(bandwidth, M_TWOPI*(2.0/samps_per_sym), -M_TWOPI*(2.0/samps_per_sym)), - d_updated (false) + d_updated(false) { // Initialize samples per symbol if(samps_per_sym <= 0) { - throw std::out_of_range ("digital_fll_band_edge_cc: invalid number of sps. Must be > 0."); + throw std::out_of_range("digital_fll_band_edge_cc: invalid number of sps. Must be > 0."); } d_sps = samps_per_sym; // Initialize rolloff factor if(rolloff < 0 || rolloff > 1.0) { - throw std::out_of_range ("digital_fll_band_edge_cc: invalid rolloff factor. Must be in [0,1]."); + throw std::out_of_range("digital_fll_band_edge_cc: invalid rolloff factor. Must be in [0,1]."); } d_rolloff = rolloff; // Initialize filter length if(filter_size <= 0) { - throw std::out_of_range ("digital_fll_band_edge_cc: invalid filter size. Must be > 0."); + throw std::out_of_range("digital_fll_band_edge_cc: invalid filter size. Must be > 0."); } d_filter_size = filter_size; // Build the band edge filters design_filter(d_sps, d_rolloff, d_filter_size); + d_output_hist.resize(filter_size,0); } -digital_fll_band_edge_cc::~digital_fll_band_edge_cc () +digital_fll_band_edge_cc::~digital_fll_band_edge_cc() { } @@ -93,7 +94,7 @@ void digital_fll_band_edge_cc::set_samples_per_symbol(float sps) { if(sps <= 0) { - throw std::out_of_range ("digital_fll_band_edge_cc: invalid number of sps. Must be > 0."); + throw std::out_of_range("digital_fll_band_edge_cc: invalid number of sps. Must be > 0."); } d_sps = sps; design_filter(d_sps, d_rolloff, d_filter_size); @@ -103,7 +104,7 @@ void digital_fll_band_edge_cc::set_rolloff(float rolloff) { if(rolloff < 0 || rolloff > 1.0) { - throw std::out_of_range ("digital_fll_band_edge_cc: invalid rolloff factor. Must be in [0,1]."); + throw std::out_of_range("digital_fll_band_edge_cc: invalid rolloff factor. Must be in [0,1]."); } d_rolloff = rolloff; design_filter(d_sps, d_rolloff, d_filter_size); @@ -113,7 +114,7 @@ void digital_fll_band_edge_cc::set_filter_size(int filter_size) { if(filter_size <= 0) { - throw std::out_of_range ("digital_fll_band_edge_cc: invalid filter size. Must be > 0."); + throw std::out_of_range("digital_fll_band_edge_cc: invalid filter size. Must be > 0."); } d_filter_size = filter_size; design_filter(d_sps, d_rolloff, d_filter_size); @@ -185,6 +186,8 @@ digital_fll_band_edge_cc::design_filter(float samps_per_sym, // Set the history to ensure enough input items for each filter set_history(filter_size+1); + d_filter_upper = gr_fir_util::create_gr_fir_ccc(d_taps_upper); + d_filter_lower = gr_fir_util::create_gr_fir_ccc(d_taps_lower); } void @@ -206,23 +209,25 @@ digital_fll_band_edge_cc::print_taps() } int -digital_fll_band_edge_cc::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) +digital_fll_band_edge_cc::work(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]; - gr_complex *out = (gr_complex *) output_items[0]; + const gr_complex *in = (const gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + d_fllbuffer.reserve(d_filter_size+noutput_items); + float *frq = NULL; float *phs = NULL; float *err = NULL; if(output_items.size() == 4) { - frq = (float *) output_items[1]; - phs = (float *) output_items[2]; - err = (float *) output_items[3]; + frq = (float*)output_items[1]; + phs = (float*)output_items[2]; + err = (float*)output_items[3]; } - if (d_updated) { + if(d_updated) { d_updated = false; return 0; // history requirements may have changed. } @@ -231,17 +236,19 @@ digital_fll_band_edge_cc::work (int noutput_items, float error; gr_complex nco_out; gr_complex out_upper, out_lower; + gr_complex out_uppersse, out_lowersse; + copy( d_output_hist.begin(), d_output_hist.end(), d_fllbuffer.begin()); + for(i = 0; i < noutput_items; i++) { nco_out = gr_expj(d_phase); - out[i+d_filter_size-1] = in[i] * nco_out; - + d_fllbuffer[i+d_filter_size] = in[i] * nco_out; // Perform the dot product of the output with the filters out_upper = 0; out_lower = 0; - for(int k = 0; k < d_filter_size; k++) { - out_upper += d_taps_upper[k] * out[i+k]; - out_lower += d_taps_lower[k] * out[i+k]; - } + + out_upper = d_filter_lower->filter(&d_fllbuffer[i]); + out_lower = d_filter_upper->filter(&d_fllbuffer[i]); + error = norm(out_lower) - norm(out_upper); advance_loop(error); @@ -255,5 +262,10 @@ digital_fll_band_edge_cc::work (int noutput_items, } } + copy(d_fllbuffer.begin(), d_fllbuffer.begin()+noutput_items, out); + copy(d_fllbuffer.begin()+noutput_items, + d_fllbuffer.begin()+noutput_items+d_filter_size, + d_output_hist.begin()); + return noutput_items; } |