X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=gnuradio-core%2Fsrc%2Flib%2Ffilter%2Fgr_pfb_clock_sync_ccf.cc;h=7dc5715d908825079737485e9ccc040f88e87927;hb=521f3e514a7e8a887ba7a35b81d255e85fbcabc1;hp=91cbf74c6bf59b9fff636db12b7f02f2f4579c12;hpb=302686ace014d7be82812c218121f00f5b28cdd1;p=debian%2Fgnuradio 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 91cbf74c..7dc5715d 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 @@ -43,15 +43,16 @@ gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (float sps, float gain, init_phase)); } - +int ios[] = {sizeof(gr_complex), sizeof(float), sizeof(float), sizeof(float)}; +std::vector iosig(ios, ios+sizeof(ios)/sizeof(int)); gr_pfb_clock_sync_ccf::gr_pfb_clock_sync_ccf (float sps, float gain, const std::vector &taps, unsigned int filter_size, float init_phase) : gr_block ("pfb_clock_sync_ccf", gr_make_io_signature (1, 1, sizeof(gr_complex)), - gr_make_io_signature2 (2, 2, sizeof(gr_complex), sizeof(float))), - d_updated (false), d_sps(sps), d_alpha(gain) + gr_make_io_signaturev (1, 4, iosig)), + d_updated (false), d_sps(sps) { d_nfilters = filter_size; @@ -59,10 +60,11 @@ gr_pfb_clock_sync_ccf::gr_pfb_clock_sync_ccf (float sps, float gain, // The accumulator keeps track of overflow to increment the stride correctly. // set it here to the fractional difference based on the initial phaes // assert(init_phase <= 2*M_PI); - float x = init_phase / (2*M_PI); //normalize initial phase - d_acc = x*(d_nfilters-1); - d_last_filter = (int)floor(d_acc); - d_acc = fmodf(d_acc, 1); + set_alpha(gain); + set_beta(0.25*gain*gain); + d_k = d_nfilters / 2; + d_filtnum = (int)floor(d_k); + d_rate = 0; d_start_count = 0; @@ -114,13 +116,15 @@ gr_pfb_clock_sync_ccf::set_taps (const std::vector &newtaps, // Partition the filter for(i = 0; i < d_nfilters; i++) { // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out - ourtaps[i] = std::vector(d_taps_per_filter, 0); + //ourtaps[i] = std::vector(d_taps_per_filter, 0); + ourtaps[d_nfilters-1-i] = std::vector(d_taps_per_filter, 0); for(j = 0; j < d_taps_per_filter; j++) { - ourtaps[i][j] = tmp_taps[i + j*d_nfilters]; // add taps to channels in reverse order + ourtaps[d_nfilters - 1 - i][j] = tmp_taps[i + j*d_nfilters]; } // Build a filter for each channel and add it's taps to it - ourfilter[i]->set_taps(ourtaps[i]); + //ourfilter[i]->set_taps(ourtaps[i]); + ourfilter[i]->set_taps(ourtaps[d_nfilters-1-i]); } // Set the history to ensure enough input items for each filter @@ -133,38 +137,52 @@ void gr_pfb_clock_sync_ccf::create_diff_taps(const std::vector &newtaps, std::vector &difftaps) { + float maxtap = -1e12; difftaps.clear(); difftaps.push_back(0); //newtaps[0]); for(unsigned int i = 1; i < newtaps.size()-1; i++) { - difftaps.push_back(newtaps[i+1] - newtaps[i-1]); + float tap = newtaps[i+1] - newtaps[i-1]; + if(tap > maxtap) { + maxtap = tap; + } + //maxtap += tap; + difftaps.push_back(tap); } difftaps.push_back(0);//-newtaps[newtaps.size()-1]); + + for(unsigned int i = 0; i < difftaps.size(); i++) { + difftaps[i] /= 1;//maxtap; + } } void gr_pfb_clock_sync_ccf::print_taps() { unsigned int i, j; + printf("[ "); for(i = 0; i < d_nfilters; i++) { - printf("filter[%d]: [%.4e, ", i, d_taps[i][0]); + printf("[%.4e, ", d_taps[i][0]); for(j = 1; j < d_taps_per_filter-1; j++) { printf("%.4e,", d_taps[i][j]); } - printf("%.4e]\n", d_taps[i][j]); + printf("%.4e],", d_taps[i][j]); } + printf(" ]\n"); } void gr_pfb_clock_sync_ccf::print_diff_taps() { unsigned int i, j; + printf("[ "); for(i = 0; i < d_nfilters; i++) { - printf("filter[%d]: [%.4e, ", i, d_dtaps[i][0]); + printf("[%.4e, ", d_dtaps[i][0]); for(j = 1; j < d_taps_per_filter-1; j++) { printf("%.4e,", d_dtaps[i][j]); } - printf("%.4e]\n", d_dtaps[i][j]); + printf("%.4e],", d_dtaps[i][j]); } + printf(" ]\n"); } @@ -199,7 +217,13 @@ gr_pfb_clock_sync_ccf::general_work (int noutput_items, { gr_complex *in = (gr_complex *) input_items[0]; gr_complex *out = (gr_complex *) output_items[0]; - float *err = (float *) output_items[1]; + + float *err, *outrate, *outk; + if(output_items.size() > 2) { + err = (float *) output_items[1]; + outrate = (float*)output_items[2]; + outk = (float*)output_items[3]; + } if (d_updated) { d_updated = false; @@ -210,36 +234,48 @@ gr_pfb_clock_sync_ccf::general_work (int noutput_items, int nrequired = ninput_items[0] - d_taps_per_filter; int i = 0, count = d_start_count; - float error = 0; + float error; + float error_r, error_i; // produce output as long as we can and there are enough input samples while((i < noutput_items) && (count < nrequired)) { - out[i] = d_filters[d_last_filter]->filter(&in[count]); - error = (out[i] * d_diff_filters[d_last_filter]->filter(&in[count])).real(); - err[i] = error; - d_acc += d_alpha*error; - gr_branchless_clip(d_acc, 1); + // FIXME: prevent this from asserting + assert(d_filtnum < d_nfilters); + out[i] = d_filters[d_filtnum]->filter(&in[count]); + error_r = out[i].real() * d_diff_filters[d_filtnum]->filter(&in[count]).real(); + error_i = out[i].imag() * d_diff_filters[d_filtnum]->filter(&in[count]).imag(); + error = error_i + error_r; - int newfilter; - newfilter = (int)((float)d_last_filter + d_acc); - if(newfilter != (int)d_last_filter) - d_acc = 0.5; + d_k = d_k + d_alpha*error + d_rate; + d_rate = d_rate + d_beta*error; + d_filtnum = (int)floor(d_k); - if(newfilter >= (int)d_nfilters) { - d_last_filter = newfilter - d_nfilters; + while(d_filtnum >= d_nfilters) { + d_k -= d_nfilters; + d_filtnum -= d_nfilters; count++; } - else if(newfilter < 0) { - d_last_filter = d_nfilters + newfilter; + while(d_filtnum < 0) { + d_k += d_nfilters; + d_filtnum += d_nfilters; count--; } - else { - d_last_filter = newfilter; - } + + // Keep our rate within a good range + d_rate = gr_branchless_clip(d_rate, 1.5); i++; count += d_sps; + + if(output_items.size() > 2) { + err[i] = error; + outrate[i] = d_rate; + outk[i] = d_k; + } + + //printf("error: %f k: %f rate: %f\n", + // error, d_k, d_rate); } // Set the start index at the next entrance to the work function