/* -*- c++ -*- */
/*
- * Copyright 2009 Free Software Foundation, Inc.
+ * Copyright 2009,2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
#include <cstring>
gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans,
- const std::vector<float> &taps)
+ const std::vector<float> &taps,
+ float oversample_rate)
{
- return gr_pfb_channelizer_ccf_sptr (new gr_pfb_channelizer_ccf (numchans, taps));
+ return gr_pfb_channelizer_ccf_sptr (new gr_pfb_channelizer_ccf (numchans, taps,
+ oversample_rate));
}
gr_pfb_channelizer_ccf::gr_pfb_channelizer_ccf (unsigned int numchans,
- const std::vector<float> &taps)
- : gr_sync_block ("pfb_channelizer_ccf",
- gr_make_io_signature (numchans, numchans, sizeof(gr_complex)),
- gr_make_io_signature (1, 1, numchans*sizeof(gr_complex))),
- d_updated (false)
+ const std::vector<float> &taps,
+ float oversample_rate)
+ : gr_sync_interpolator ("pfb_channelizer_ccf",
+ gr_make_io_signature (numchans, numchans, sizeof(gr_complex)),
+ gr_make_io_signature (1, 1, numchans*sizeof(gr_complex)),
+ oversample_rate),
+ d_updated (false), d_oversample_rate(oversample_rate)
{
d_numchans = numchans;
d_filters = std::vector<gr_fir_ccf*>(d_numchans);
return 0; // history requirements may have changed.
}
- for(int i = 0; i < noutput_items; i++) {
- // Move through filters from bottom to top
- for(int j = d_numchans-1; j >= 0; j--) {
- // Take in the items from the first input stream to d_numchans
- in = (gr_complex*)input_items[d_numchans - 1 - j];
+ int M = d_oversample_rate;
+ int N = d_numchans;
+ int r = N / M;
- // Filter current input stream from bottom filter to top
- d_fft->get_inbuf()[j] = d_filters[j]->filter(&in[i]);
+ int n=1, i=-1, j=0, last;
+ //int state = 0;
+
+ // Although the filters change, we use this look up table
+ // to set the index of the FFT input buffer, which equivalently
+ // performs the FFT shift operation on every other turn.
+ int *idxlut = new int[N];
+ for(int ii = 0; ii < N; ii++) {
+ idxlut[ii] = N - ((ii + r) % N) - 1;
+ }
+
+ while(n <= noutput_items/M) {
+ j = 0;
+ i = (i + r) % N;
+ last = i;
+ while(i >= 0) {
+ in = (gr_complex*)input_items[j];
+ //d_fft->get_inbuf()[(i + state*r) % N] = d_filters[i]->filter(&in[n]);
+ d_fft->get_inbuf()[idxlut[j]] = d_filters[i]->filter(&in[n]);
+ j++;
+ i--;
}
+ i = N-1;
+ while(i > last) {
+ in = (gr_complex*)input_items[j];
+ //d_fft->get_inbuf()[(i + state*r) % N] = d_filters[i]->filter(&in[n-1]);
+ d_fft->get_inbuf()[idxlut[j]] = d_filters[i]->filter(&in[n-1]);
+ j++;
+ i--;
+ }
+
+ n += (i+r) >= N;
+ //state ^= 1;
+
// despin through FFT
d_fft->execute();
- memcpy(&out[d_numchans*i], d_fft->get_outbuf(), d_numchans*sizeof(gr_complex));
+ memcpy(out, d_fft->get_outbuf(), d_numchans*sizeof(gr_complex));
+ out += d_numchans;
}
+ delete [] idxlut;
+
return noutput_items;
}