X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=gnuradio-core%2Fsrc%2Flib%2Ffilter%2Fgr_pfb_arb_resampler_ccf.cc;h=84b0c578f59bc12310a261e6391f2a20d7034c7f;hb=1a3e498933844e995e91e71b932b9e0bf8e2cc3f;hp=d4b14c5945d1470561176be5cc700f4a6b105600;hpb=419ffcfea1c886d71cbb0eaac590aa1f5a088495;p=debian%2Fgnuradio diff --git a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc index d4b14c59..84b0c578 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc +++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2009 Free Software Foundation, Inc. + * Copyright 2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -34,8 +34,8 @@ gr_pfb_arb_resampler_ccf_sptr gr_make_pfb_arb_resampler_ccf (float rate, const std::vector &taps, unsigned int filter_size) { - return gr_pfb_arb_resampler_ccf_sptr (new gr_pfb_arb_resampler_ccf (rate, taps, - filter_size)); + return gnuradio::get_initial_sptr(new gr_pfb_arb_resampler_ccf (rate, taps, + filter_size)); } @@ -47,6 +47,8 @@ gr_pfb_arb_resampler_ccf::gr_pfb_arb_resampler_ccf (float rate, gr_make_io_signature (1, 1, sizeof(gr_complex))), d_updated (false) { + d_acc = 0; // start accumulator at 0 + /* The number of filters is specified by the user as the filter size; this is also the interpolation rate of the filter. We use it and the rate provided to determine the decimation rate. This acts as a @@ -69,7 +71,7 @@ gr_pfb_arb_resampler_ccf::gr_pfb_arb_resampler_ccf (float rate, // Create an FIR filter for each channel and zero out the taps std::vector vtaps(0, d_int_rate); - for(int i = 0; i < d_int_rate; i++) { + for(unsigned int i = 0; i < d_int_rate; i++) { d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps); d_diff_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps); } @@ -77,8 +79,10 @@ gr_pfb_arb_resampler_ccf::gr_pfb_arb_resampler_ccf (float rate, // Now, actually set the filters' taps std::vector dtaps; create_diff_taps(taps, dtaps); - set_taps(taps, d_taps, d_filters); - set_taps(dtaps, d_dtaps, d_diff_filters); + create_taps(taps, d_taps, d_filters); + create_taps(dtaps, d_dtaps, d_diff_filters); + + set_relative_rate(rate); } gr_pfb_arb_resampler_ccf::~gr_pfb_arb_resampler_ccf () @@ -89,12 +93,10 @@ gr_pfb_arb_resampler_ccf::~gr_pfb_arb_resampler_ccf () } void -gr_pfb_arb_resampler_ccf::set_taps (const std::vector &newtaps, - std::vector< std::vector > &ourtaps, - std::vector &ourfilter) +gr_pfb_arb_resampler_ccf::create_taps (const std::vector &newtaps, + std::vector< std::vector > &ourtaps, + std::vector &ourfilter) { - int i,j; - unsigned int ntaps = newtaps.size(); d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_int_rate); @@ -110,10 +112,10 @@ gr_pfb_arb_resampler_ccf::set_taps (const std::vector &newtaps, } // Partition the filter - for(i = 0; i < d_int_rate; i++) { + for(unsigned int i = 0; i < d_int_rate; i++) { // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out ourtaps[d_int_rate-1-i] = std::vector(d_taps_per_filter, 0); - for(j = 0; j < d_taps_per_filter; j++) { + for(unsigned int j = 0; j < d_taps_per_filter; j++) { ourtaps[d_int_rate - 1 - i][j] = tmp_taps[i + j*d_int_rate]; } @@ -131,23 +133,15 @@ void gr_pfb_arb_resampler_ccf::create_diff_taps(const std::vector &newtaps, std::vector &difftaps) { - float maxtap = 1e-20; + // Calculate the differential taps (derivative filter) by taking the difference + // between two taps. Duplicate the last one to make both filters the same length. + float tap; 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]; + for(unsigned int i = 0; i < newtaps.size()-1; i++) { + tap = newtaps[i+1] - newtaps[i]; 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; } + difftaps.push_back(tap); } void @@ -177,25 +171,30 @@ gr_pfb_arb_resampler_ccf::general_work (int noutput_items, return 0; // history requirements may have changed. } - int i = 0, j, count = d_start_index; + int i = 0, count = d_start_index; + unsigned int j; gr_complex o0, o1; // Restore the last filter position j = d_last_filter; // produce output as long as we can and there are enough input samples - while((i < noutput_items) && (count < ninput_items[0]-1)) { + int max_input = ninput_items[0]-(int)d_taps_per_filter; + while((i < noutput_items) && (count < max_input)) { // start j by wrapping around mod the number of channels while((j < d_int_rate) && (i < noutput_items)) { - // Take the current filter output + // Take the current filter and derivative filter output o0 = d_filters[j]->filter(&in[count]); o1 = d_diff_filters[j]->filter(&in[count]); - out[i] = o0 + o1*d_flt_rate; // linearly interpolate between samples + out[i] = o0 + o1*d_acc; // linearly interpolate between samples i++; - - j += d_dec_rate; + + // Adjust accumulator and index into filterbank + d_acc += d_flt_rate; + j += d_dec_rate + (int)floor(d_acc); + d_acc = fmodf(d_acc, 1.0); } if(i < noutput_items) { // keep state for next entry float ss = (int)(j / d_int_rate); // number of items to skip ahead by