d315e722e0f26821ee8430ab38fc27dc90fb93a5
[debian/gnuradio] / gnuradio-core / src / lib / filter / gr_rational_resampler_base_scc.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2004 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 /*
24  * WARNING: This file is automatically generated by
25  * generate_gr_rational_resampler_base_XXX.py Any changes made to this
26  * file will be overwritten.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <gr_rational_resampler_base_scc.h>
34 #include <gr_fir_scc.h>
35 #include <gr_fir_util.h>
36 #include <gr_io_signature.h>
37 #include <stdexcept>
38 #include <iostream>
39
40 gr_rational_resampler_base_scc_sptr 
41 gr_make_rational_resampler_base_scc (unsigned interpolation,
42                      unsigned decimation, 
43                      const std::vector<gr_complex> &taps)
44 {
45   return gr_rational_resampler_base_scc_sptr (new gr_rational_resampler_base_scc (interpolation, decimation, taps));
46 }
47
48 gr_rational_resampler_base_scc::gr_rational_resampler_base_scc (unsigned interpolation, unsigned decimation,
49                 const std::vector<gr_complex> &taps)
50   : gr_block ("rational_resampler_base_scc",
51               gr_make_io_signature (1, 1, sizeof (short)),
52               gr_make_io_signature (1, 1, sizeof (gr_complex))),
53     d_history(1),
54     d_interpolation(interpolation), d_decimation(decimation),
55     d_ctr(0), d_updated(false),
56     d_firs(interpolation)
57 {
58   if (interpolation == 0)
59     throw std::out_of_range ("interpolation must be > 0");
60   if (decimation == 0)
61     throw std::out_of_range ("decimation must be > 0");
62
63   set_relative_rate (1.0 * interpolation / decimation);
64   set_output_multiple (1);
65
66   std::vector<gr_complex>       dummy_taps;
67   
68   for (unsigned i = 0; i < interpolation; i++)
69     d_firs[i] = gr_fir_util::create_gr_fir_scc (dummy_taps);
70
71   set_taps (taps);
72   install_taps (d_new_taps);
73 }
74
75 gr_rational_resampler_base_scc::~gr_rational_resampler_base_scc ()
76 {
77   int interp = interpolation();
78   for (int i = 0; i < interp; i++)
79     delete d_firs[i];
80 }
81
82 void
83 gr_rational_resampler_base_scc::set_taps (const std::vector<gr_complex> &taps)
84 {
85   d_new_taps = taps;
86   d_updated = true;
87
88   // round up length to a multiple of the interpolation factor
89   int n = taps.size () % interpolation ();
90   if (n > 0){
91     n = interpolation () - n;
92     while (n-- > 0)
93       d_new_taps.insert(d_new_taps.begin(), 0);
94   }
95
96   assert (d_new_taps.size () % interpolation () == 0);
97 }
98
99
100 void
101 gr_rational_resampler_base_scc::install_taps (const std::vector<gr_complex> &taps)
102 {
103   int nfilters = interpolation ();
104   int nt = taps.size () / nfilters;
105
106   assert (nt * nfilters == (int) taps.size ());
107
108   std::vector< std::vector <gr_complex> > xtaps (nfilters);
109
110   for (int n = 0; n < nfilters; n++)
111     xtaps[n].resize (nt);  
112
113   for (int i = 0; i < (int) taps.size(); i++)
114     xtaps[i % nfilters][i / nfilters] = taps[i];
115
116   for (int n = 0; n < nfilters; n++)
117     d_firs[n]->set_taps (xtaps[n]);
118   
119   set_history (nt);
120   d_updated = false;
121
122 #if 0
123   for (int i = 0; i < nfilters; i++){
124     std::cout << "filter[" << i << "] = ";
125     for (int j = 0; j < nt; j++)
126       std::cout << xtaps[i][j] << " ";
127
128     std::cout << "\n";
129   }
130 #endif
131
132 }
133
134 void
135 gr_rational_resampler_base_scc::forecast (int noutput_items, gr_vector_int &ninput_items_required)
136 {
137   int nreqd = std::max((unsigned)1, (int)((double) (noutput_items+1) * decimation() / interpolation()) + history() - 1);
138   unsigned ninputs = ninput_items_required.size ();
139   for (unsigned i = 0; i < ninputs; i++)
140     ninput_items_required[i] = nreqd;
141 }
142
143 int
144 gr_rational_resampler_base_scc::general_work (int noutput_items,
145                       gr_vector_int &ninput_items,
146                       gr_vector_const_void_star &input_items,
147                       gr_vector_void_star &output_items)
148 {
149   const short *in = (const short *) input_items[0];
150   gr_complex *out = (gr_complex *) output_items[0];
151
152   if (d_updated) {
153     install_taps (d_new_taps);
154     return 0;           // history requirement may have increased.
155   }
156
157   unsigned int ctr = d_ctr;
158
159   int i = 0;
160   while (i < noutput_items){
161     out[i++] = d_firs[ctr]->filter(in);
162     ctr += decimation();
163     while (ctr >= interpolation()){
164       ctr -= interpolation();
165       in++;
166     }
167   }
168
169   d_ctr = ctr;
170   consume_each(in - (short *) input_items[0]);
171   return i;
172 }