diff options
author | Tom Rondeau <tom@trondeau.com> | 2016-02-02 22:41:14 -0500 |
---|---|---|
committer | Tom Rondeau <tom@trondeau.com> | 2016-02-02 22:41:14 -0500 |
commit | 0f4859c0a1c705199b74131e05605342c840bd31 (patch) | |
tree | 58fa2226bbbc20564f32eebcd353c1520d35c55b | |
parent | 11973c64437683cc99c48eae9eb4db8234f1ac42 (diff) |
digital: addresses issue #890.
The set_taps was redone a while ago to better handle the differential
taps as well as the normal ones, but this made externally resetting
them impossible. Adding a new update_taps function to properly handle
this case so as to not change the API. We should fix this in 3.8.
-rw-r--r-- | gr-digital/include/gnuradio/digital/pfb_clock_sync_ccf.h | 11 | ||||
-rw-r--r-- | gr-digital/include/gnuradio/digital/pfb_clock_sync_fff.h | 11 | ||||
-rw-r--r-- | gr-digital/lib/pfb_clock_sync_ccf_impl.cc | 24 | ||||
-rw-r--r-- | gr-digital/lib/pfb_clock_sync_ccf_impl.h | 5 | ||||
-rw-r--r-- | gr-digital/lib/pfb_clock_sync_fff_impl.cc | 23 | ||||
-rw-r--r-- | gr-digital/lib/pfb_clock_sync_fff_impl.h | 3 | ||||
-rwxr-xr-x | gr-digital/python/digital/qa_pfb_clock_sync.py | 104 |
7 files changed, 151 insertions, 30 deletions
diff --git a/gr-digital/include/gnuradio/digital/pfb_clock_sync_ccf.h b/gr-digital/include/gnuradio/digital/pfb_clock_sync_ccf.h index 4d489d1534..118435289c 100644 --- a/gr-digital/include/gnuradio/digital/pfb_clock_sync_ccf.h +++ b/gr-digital/include/gnuradio/digital/pfb_clock_sync_ccf.h @@ -187,7 +187,16 @@ namespace gr { virtual void update_gains() = 0; /*! - * Resets the filterbank's filter taps with the new prototype filter + * Resets the filterbank's filter taps with the new prototype filter. + */ + virtual void update_taps(const std::vector<float> &taps) = 0; + + /*! + * Used to set the taps of the filters in the filterbank and + * differential filterbank. + * + * WARNING: this should not be used externally and will be moved + * to a private funtion in the next API. */ virtual void set_taps(const std::vector<float> &taps, std::vector< std::vector<float> > &ourtaps, diff --git a/gr-digital/include/gnuradio/digital/pfb_clock_sync_fff.h b/gr-digital/include/gnuradio/digital/pfb_clock_sync_fff.h index c3034579a5..b774ee49aa 100644 --- a/gr-digital/include/gnuradio/digital/pfb_clock_sync_fff.h +++ b/gr-digital/include/gnuradio/digital/pfb_clock_sync_fff.h @@ -187,7 +187,16 @@ namespace gr { virtual void update_gains() = 0; /*! - * Resets the filterbank's filter taps with the new prototype filter + * Resets the filterbank's filter taps with the new prototype filter. + */ + virtual void update_taps(const std::vector<float> &taps) = 0; + + /*! + * Used to set the taps of the filters in the filterbank and + * differential filterbank. + * + * WARNING: this should not be used externally and will be moved + * to a private funtion in the next API. */ virtual void set_taps(const std::vector<float> &taps, std::vector< std::vector<float> > &ourtaps, diff --git a/gr-digital/lib/pfb_clock_sync_ccf_impl.cc b/gr-digital/lib/pfb_clock_sync_ccf_impl.cc index c8e1221c90..314ff94b0b 100644 --- a/gr-digital/lib/pfb_clock_sync_ccf_impl.cc +++ b/gr-digital/lib/pfb_clock_sync_ccf_impl.cc @@ -134,6 +134,14 @@ namespace gr { ninput_items_required[i] = (noutput_items + history()) * (d_sps/d_osps); } + void + pfb_clock_sync_ccf_impl::update_taps(const std::vector<float> &taps) + { + d_updated_taps = taps; + d_updated = true; + } + + /******************************************************************* SET FUNCTIONS *******************************************************************/ @@ -279,8 +287,6 @@ namespace gr { // Make sure there is enough output space for d_osps outputs/input. set_output_multiple(d_osps); - - d_updated = true; } void @@ -397,6 +403,15 @@ namespace gr { gr_complex *in = (gr_complex *) input_items[0]; gr_complex *out = (gr_complex *) output_items[0]; + if(d_updated) { + std::vector<float> dtaps; + create_diff_taps(d_updated_taps, dtaps); + set_taps(d_updated_taps, d_taps, d_filters); + set_taps(dtaps, d_dtaps, d_diff_filters); + d_updated = false; + return 0; // history requirements may have changed. + } + float *err = NULL, *outrate = NULL, *outk = NULL; if(output_items.size() == 4) { err = (float *) output_items[1]; @@ -404,11 +419,6 @@ namespace gr { outk = (float*)output_items[3]; } - if(d_updated) { - d_updated = false; - return 0; // history requirements may have changed. - } - std::vector<tag_t> tags; get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+d_sps*noutput_items, diff --git a/gr-digital/lib/pfb_clock_sync_ccf_impl.h b/gr-digital/lib/pfb_clock_sync_ccf_impl.h index 015e037275..535628189f 100644 --- a/gr-digital/lib/pfb_clock_sync_ccf_impl.h +++ b/gr-digital/lib/pfb_clock_sync_ccf_impl.h @@ -47,6 +47,7 @@ namespace gr { std::vector<kernel::fir_filter_ccf*> d_diff_filters; std::vector< std::vector<float> > d_taps; std::vector< std::vector<float> > d_dtaps; + std::vector<float> d_updated_taps; float d_k; float d_rate; @@ -73,9 +74,11 @@ namespace gr { void setup_rpc(); void update_gains(); - + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + void update_taps(const std::vector<float> &taps); + void set_taps(const std::vector<float> &taps, std::vector< std::vector<float> > &ourtaps, std::vector<kernel::fir_filter_ccf*> &ourfilter); diff --git a/gr-digital/lib/pfb_clock_sync_fff_impl.cc b/gr-digital/lib/pfb_clock_sync_fff_impl.cc index beb6bf5579..09c72495a0 100644 --- a/gr-digital/lib/pfb_clock_sync_fff_impl.cc +++ b/gr-digital/lib/pfb_clock_sync_fff_impl.cc @@ -131,6 +131,13 @@ namespace gr { ninput_items_required[i] = (noutput_items + history()) * (d_sps/d_osps); } + void + pfb_clock_sync_fff_impl::update_taps(const std::vector<float> &taps) + { + d_updated_taps = taps; + d_updated = true; + } + /******************************************************************* SET FUNCTIONS *******************************************************************/ @@ -258,8 +265,6 @@ namespace gr { // Make sure there is enough output space for d_osps outputs/input. set_output_multiple(d_osps); - - d_updated = true; } void @@ -376,6 +381,15 @@ namespace gr { float *in = (float *) input_items[0]; float *out = (float *) output_items[0]; + if(d_updated) { + std::vector<float> dtaps; + create_diff_taps(d_updated_taps, dtaps); + set_taps(d_updated_taps, d_taps, d_filters); + set_taps(dtaps, d_dtaps, d_diff_filters); + d_updated = false; + return 0; // history requirements may have changed. + } + float *err = NULL, *outrate = NULL, *outk = NULL; if(output_items.size() == 4) { err = (float *) output_items[1]; @@ -383,11 +397,6 @@ namespace gr { outk = (float*)output_items[3]; } - if(d_updated) { - d_updated = false; - return 0; // history requirements may have changed. - } - int i = 0, count = 0; // produce output as long as we can and there are enough input samples diff --git a/gr-digital/lib/pfb_clock_sync_fff_impl.h b/gr-digital/lib/pfb_clock_sync_fff_impl.h index 2c88341c55..7bbbd995d1 100644 --- a/gr-digital/lib/pfb_clock_sync_fff_impl.h +++ b/gr-digital/lib/pfb_clock_sync_fff_impl.h @@ -47,6 +47,7 @@ namespace gr { std::vector<kernel::fir_filter_fff*> d_diff_filters; std::vector< std::vector<float> > d_taps; std::vector< std::vector<float> > d_dtaps; + std::vector<float> d_updated_taps; float d_k; float d_rate; @@ -74,6 +75,8 @@ namespace gr { void forecast(int noutput_items, gr_vector_int &ninput_items_required); + void update_taps(const std::vector<float> &taps); + void set_taps(const std::vector<float> &taps, std::vector< std::vector<float> > &ourtaps, std::vector<kernel::fir_filter_fff*> &ourfilter); diff --git a/gr-digital/python/digital/qa_pfb_clock_sync.py b/gr-digital/python/digital/qa_pfb_clock_sync.py index 3c8074b154..e16a99338e 100755 --- a/gr-digital/python/digital/qa_pfb_clock_sync.py +++ b/gr-digital/python/digital/qa_pfb_clock_sync.py @@ -1,27 +1,28 @@ #!/usr/bin/env python # # Copyright 2011,2013 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. -# +# import random import cmath +import time from gnuradio import gr, gr_unittest, filter, digital, blocks @@ -43,7 +44,7 @@ class test_pfb_clock_sync(gr_unittest.TestCase): init_phase = nfilts/2 max_rate_deviation = 0.5 osps = 1 - + ntaps = 11 * int(sps*nfilts) taps = filter.firdes.root_raised_cosine(nfilts, nfilts*sps, 1.0, excess_bw, ntaps) @@ -52,7 +53,7 @@ class test_pfb_clock_sync(gr_unittest.TestCase): nfilts, init_phase, max_rate_deviation, osps) - + data = 10000*[complex(1,0), complex(-1,0)] self.src = blocks.vector_source_c(data, False) @@ -69,7 +70,7 @@ class test_pfb_clock_sync(gr_unittest.TestCase): self.tb.connect(self.src, self.rrc_filter, self.test, self.snk) self.tb.run() - + expected_result = 10000*[complex(1,0), complex(-1,0)] dst_data = self.snk.data() @@ -82,7 +83,7 @@ class test_pfb_clock_sync(gr_unittest.TestCase): #for e,d in zip(expected_result, dst_data): # print e, d - + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 1) @@ -96,7 +97,7 @@ class test_pfb_clock_sync(gr_unittest.TestCase): init_phase = nfilts/2 max_rate_deviation = 0.5 osps = 1 - + ntaps = 11 * int(sps*nfilts) taps = filter.firdes.root_raised_cosine(nfilts, nfilts*sps, 1.0, excess_bw, ntaps) @@ -105,7 +106,7 @@ class test_pfb_clock_sync(gr_unittest.TestCase): nfilts, init_phase, max_rate_deviation, osps) - + data = 10000*[1, -1] self.src = blocks.vector_source_f(data, False) @@ -122,7 +123,7 @@ class test_pfb_clock_sync(gr_unittest.TestCase): self.tb.connect(self.src, self.rrc_filter, self.test, self.snk) self.tb.run() - + expected_result = 10000*[1, -1] dst_data = self.snk.data() @@ -135,9 +136,86 @@ class test_pfb_clock_sync(gr_unittest.TestCase): #for e,d in zip(expected_result, dst_data): # print e, d - + self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 1) + def test03(self): + # Test resting of taps + excess_bw0 = 0.35 + excess_bw1 = 0.22 + + sps = 4 + loop_bw = cmath.pi/100.0 + nfilts = 32 + init_phase = nfilts/2 + max_rate_deviation = 0.5 + osps = 1 + + ntaps = 11 * int(sps*nfilts) + taps = filter.firdes.root_raised_cosine(nfilts, nfilts*sps, + 1.0, excess_bw0, ntaps) + + self.test = digital.pfb_clock_sync_ccf(sps, loop_bw, taps, + nfilts, init_phase, + max_rate_deviation, + osps) + + self.src = blocks.null_source(gr.sizeof_gr_complex) + self.snk = blocks.null_sink(gr.sizeof_gr_complex) + + self.tb.connect(self.src, self.test, self.snk) + self.tb.start() + time.sleep(0.1) + + taps = filter.firdes.root_raised_cosine(nfilts, nfilts*sps, + 1.0, excess_bw1, ntaps) + + self.test.update_taps(taps) + + self.tb.stop() + self.tb.wait() + + self.assertTrue(True) + + def test03_f(self): + # Test resting of taps + excess_bw0 = 0.35 + excess_bw1 = 0.22 + + sps = 4 + loop_bw = cmath.pi/100.0 + nfilts = 32 + init_phase = nfilts/2 + max_rate_deviation = 0.5 + osps = 1 + + ntaps = 11 * int(sps*nfilts) + taps = filter.firdes.root_raised_cosine(nfilts, nfilts*sps, + 1.0, excess_bw0, ntaps) + + self.test = digital.pfb_clock_sync_fff(sps, loop_bw, taps, + nfilts, init_phase, + max_rate_deviation, + osps) + + self.src = blocks.null_source(gr.sizeof_float) + self.snk = blocks.null_sink(gr.sizeof_float) + + self.tb.connect(self.src, self.test, self.snk) + self.tb.start() + time.sleep(0.1) + + taps = filter.firdes.root_raised_cosine(nfilts, nfilts*sps, + 1.0, excess_bw1, ntaps) + + self.test.update_taps(taps) + + self.tb.stop() + self.tb.wait() + + self.assertTrue(True) + + if __name__ == '__main__': gr_unittest.run(test_pfb_clock_sync, "test_pfb_clock_sync.xml") |