diff options
author | Tom Rondeau | 2009-10-12 17:55:17 -0400 |
---|---|---|
committer | Tom Rondeau | 2009-10-12 17:55:17 -0400 |
commit | c1ab962946bb05b8a20a0f19dd294eb3b3056142 (patch) | |
tree | 83e609752d3d522ef01b75f795a0b22548bad905 /gnuradio-core/src | |
parent | 2b60291c2883dbd3b85c6f694d830fa3ccf0a6e6 (diff) | |
download | gnuradio-c1ab962946bb05b8a20a0f19dd294eb3b3056142.tar.gz gnuradio-c1ab962946bb05b8a20a0f19dd294eb3b3056142.tar.bz2 gnuradio-c1ab962946bb05b8a20a0f19dd294eb3b3056142.zip |
This splits the rate into a fractional an integer value, which allows the loop to adjust the fractional rate while the integer rate keeps the increments moving properly. Allows the max rate deviation to be independent of the integer rate. Scaling of the differential taps also allows alpha and beta to operate independent of the rate when fractional samples per symbol are used. Slightly more tolerant to large signal values, but they still should be close to +/-1.
Diffstat (limited to 'gnuradio-core/src')
-rw-r--r-- | gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc | 20 | ||||
-rw-r--r-- | gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h | 2 |
2 files changed, 18 insertions, 4 deletions
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc index 43412f25b..433b7d613 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc +++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc @@ -68,6 +68,8 @@ gr_pfb_clock_sync_ccf::gr_pfb_clock_sync_ccf (double sps, float gain, set_beta(0.25*gain*gain); d_k = init_phase; d_rate = (sps-floor(sps))*(double)d_nfilters; + d_rate_i = (int)floor(d_rate); + d_rate_f = d_rate - (float)d_rate_i; d_filtnum = (int)floor(d_k); d_filters = std::vector<gr_fir_ccf*>(d_nfilters); @@ -137,13 +139,23 @@ void gr_pfb_clock_sync_ccf::create_diff_taps(const std::vector<float> &newtaps, std::vector<float> &difftaps) { + float maxtap = 1e-20; difftaps.clear(); difftaps.push_back(0); //newtaps[0]); for(unsigned int i = 1; i < newtaps.size()-1; i++) { float tap = newtaps[i+1] - newtaps[i-1]; difftaps.push_back(tap); + if(tap > maxtap) { + maxtap = tap; + } } difftaps.push_back(0);//-newtaps[newtaps.size()-1]); + + // Scale the differential taps; helps scale error term to better update state + // FIXME: should this be scaled this way or use the same gain as the taps? + for(unsigned int i = 0; i < difftaps.size(); i++) { + difftaps[i] /= maxtap; + } } void @@ -250,18 +262,18 @@ gr_pfb_clock_sync_ccf::general_work (int noutput_items, error = (error_i + error_r) / 2.0; // average error from I&Q channel // Run the control loop to update the current phase (k) and tracking rate - d_k = d_k + d_alpha*error + d_rate; - d_rate = d_rate + d_beta*error; + d_k = d_k + d_alpha*error + d_rate_i + d_rate_f; + d_rate_f = d_rate_f + d_beta*error; // Keep our rate within a good range - d_rate = gr_branchless_clip(d_rate, d_max_dev); + d_rate_f = gr_branchless_clip(d_rate_f, d_max_dev); i++; count += (int)floor(d_sps); if(output_items.size() > 2) { err[i] = error; - outrate[i] = d_rate; + outrate[i] = d_rate_f; outk[i] = d_k; } } diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h index 778db59e5..a07192a7f 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h +++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h @@ -69,6 +69,8 @@ class gr_pfb_clock_sync_ccf : public gr_block std::vector< std::vector<float> > d_dtaps; float d_k; float d_rate; + float d_rate_i; + float d_rate_f; float d_max_dev; int d_filtnum; int d_taps_per_filter; |