GNU Radio's LFAST Package
fir_filter_lfast.h
Go to the documentation of this file.
1 /*
2  * fir_filter_lfast.h
3  *
4  * Copyright 2019, Michael Piscopo
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19 
20 #ifndef INCLUDE_LFAST_FIR_FILTER_LFAST_H_
21 #define INCLUDE_LFAST_FIR_FILTER_LFAST_H_
22 
23 #include <gnuradio/gr_complex.h>
24 
25 #include <boost/thread/thread.hpp>
26 #include <volk/volk.h>
27 using namespace std;
28 
29 namespace gr {
30  namespace lfast {
31  /*
32  * Base Filter
33  */
34  template<class io_type, class tap_type>
35  class Filter {
36  protected:
37  tap_type *alignedTaps;
39  std::vector<tap_type> d_taps;
40  long numTaps;
41 
42  public:
43  Filter();
44  Filter(const std::vector<tap_type>& newTaps);
45  virtual ~Filter();
46 
47  virtual void setTaps(const std::vector<tap_type>& newTaps);
48  // For compatibility
49  inline virtual void set_taps(const std::vector<tap_type>& newTaps) { setTaps(newTaps); };
50  virtual std::vector<tap_type> getTaps() const;
51  inline virtual std::vector<tap_type> taps() const { return getTaps();};
52  inline virtual long ntaps() { return numTaps;};
53 
54  // Returns number of samples consumed / produced
55  virtual long filter(io_type *outputBuffer, const io_type *inputBuffer, long numSamples) {return 0;};
56  }; // end base filter template
57 
58  /*
59  * FIR Filter - Complex inputs, float taps
60  */
61  class FIRFilterCCF:public Filter<gr_complex,float> {
62  public:
63  FIRFilterCCF();
64  FIRFilterCCF(const std::vector<float>& newTaps);
65  virtual ~FIRFilterCCF();
66 
67  // NOTE: This routine is expecting numSamples to be an integer multiple of the number of taps
68  virtual long filterN(gr_complex *outputBuffer, const gr_complex *inputBuffer, long numSamples);
69 
70  // OutputBuffer here should be at least numSamples/decimation in length
71  virtual long filterNdec(gr_complex *outputBuffer, const gr_complex *inputBuffer, long numSamples, int decimation);
72 
73  virtual gr_complex filter(const gr_complex *inputBuffer);
74 
75  // This is for testing comparison. This function does all calculations in 1 CPU-based thread.
76  virtual long filterCPU(gr_complex *outputBuffer, const gr_complex *inputBuffer, long numSamples);
77  };
78 
79  /*
80  * FIR Filter - float inputs, float taps
81  */
82  class FIRFilterFFF:public Filter<float,float> {
83  public:
84  FIRFilterFFF();
85  FIRFilterFFF(const std::vector<float>& newTaps);
86  virtual ~FIRFilterFFF();
87 
88  // NOTE: This routine is expecting numSamples to be an integer multiple of the number of taps
89  virtual long filterN(float *outputBuffer, const float *inputBuffer, long numSamples);
90 
91  // OutputBuffer here should be at least numSamples/decimation in length
92  virtual long filterNdec(float *outputBuffer, const float *inputBuffer, long numSamples, int decimation);
93 
94  virtual gr_complex filter(const float *inputBuffer);
95 
96  // This is for testing comparison. This function does all calculations in 1 CPU-based thread.
97  virtual long filterCPU(float *outputBuffer, const float *inputBuffer, long numSamples);
98  };
99 
100  /*
101  * FIR Filter - complex inputs, complex taps
102  */
103  class FIRFilterCCC:public Filter<gr_complex,gr_complex> {
104  public:
105  FIRFilterCCC();
106  FIRFilterCCC(const std::vector<gr_complex>& newTaps);
107  virtual ~FIRFilterCCC();
108 
109  // NOTE: This routine is expecting numSamples to be an integer multiple of the number of taps
110  virtual long filterN(gr_complex *outputBuffer, const gr_complex *inputBuffer, long numSamples);
111 
112  // OutputBuffer here should be at least numSamples/decimation in length
113  virtual long filterNdec(gr_complex *outputBuffer, const gr_complex *inputBuffer, long numSamples, int decimation);
114 
115  virtual gr_complex filter(const gr_complex *inputBuffer);
116 
117  // This is for testing comparison. This function does all calculations in 1 CPU-based thread.
118  virtual long filterCPU(gr_complex *outputBuffer, const gr_complex *inputBuffer, long numSamples);
119  };
120 
121 
122  // -----------------------------------------------------------------
123  // ------ Multi-threaded filters ----------------------------------
124  // -----------------------------------------------------------------
125 
126  /*
127  * Multi-threaded base template.
128  * Provides threading and buffers
129  *
130  */
131  template<class io_type>
132  class MTBase {
133  protected:
134  const io_type *pInputBuffer;
135  io_type *pOutputBuffer;
136 
137  // Supports up to 16 threads
138  boost::thread *threads[16];
139  bool threadRunning[16];
143 
144 
145  public:
146  MTBase(int nthreads=4);
147  virtual ~MTBase();
148 
149  int numThreads() { return d_nthreads; };
150 
151  inline virtual void setDecimation(int newDecimation) { decimation = newDecimation; };
152  inline virtual int getDecimation() { return decimation; };
153  inline virtual bool decimating() { if (decimation > 1) return true; else return false; };
154 
155  virtual long calcDecimationBlockSize(long numSamples);
156 
157  // NOTE: calcDecimationIndex assumes the index is an even multiple of a decimation block size
158  // In other words, calcDecimationBlockSize was called to get an appropriate block size,
159  // then blockStartIndex is an integer multiple of that result.
160  virtual long calcDecimationIndex(long blockStartIndex);
161 
162  // NOTE: This method IS NOT thread-safe. Make sure to use a scoped_lock or be sure no threads are running
163  // before changing the number of threads.
164  virtual void setThreads(int nthreads);
165 
166  virtual bool anyThreadRunning();
167  };
168 
169  // --------------------------------------------------
170  // Multi-threaded filter, complex data, float taps
171  // --------------------------------------------------
172  class FIRFilterCCF_MT:public MTBase<gr_complex>, public FIRFilterCCF {
173  protected:
174  virtual void runThread1(long startIndex,long numSamples);
175  virtual void runThread2(long startIndex,long numSamples);
176  virtual void runThread3(long startIndex,long numSamples);
177  virtual void runThread4(long startIndex,long numSamples);
178  virtual void runThread5(long startIndex,long numSamples);
179  virtual void runThread6(long startIndex,long numSamples);
180  virtual void runThread7(long startIndex,long numSamples);
181  virtual void runThread8(long startIndex,long numSamples);
182  virtual void runThread9(long startIndex,long numSamples);
183  virtual void runThread10(long startIndex,long numSamples);
184  virtual void runThread11(long startIndex,long numSamples);
185  virtual void runThread12(long startIndex,long numSamples);
186  virtual void runThread13(long startIndex,long numSamples);
187  virtual void runThread14(long startIndex,long numSamples);
188  virtual void runThread15(long startIndex,long numSamples);
189  virtual void runThread16(long startIndex,long numSamples);
190 
191  public:
192  FIRFilterCCF_MT(int nthreads);
193  FIRFilterCCF_MT(const std::vector<float>& newTaps, int nthreads);
194  virtual ~FIRFilterCCF_MT();
195 
196  // NOTE: This routine is expecting numSamples to be an integer multiple of the number of taps
197  virtual long filterN(gr_complex *outputBuffer, const gr_complex *inputBuffer, long numSamples);
198 
199  // OutputBuffer here should be at least numSamples/decimation in length
200  virtual long filterNdec(gr_complex *outputBuffer, const gr_complex *inputBuffer, long numSamples, int decimation);
201 
202  };
203 
204  // --------------------------------------------------
205  // Multi-threaded filter, complex data, float taps
206  // --------------------------------------------------
207  class FIRFilterFFF_MT:public MTBase<float>, public FIRFilterFFF {
208  protected:
209  virtual void runThread1(long startIndex,long numSamples);
210  virtual void runThread2(long startIndex,long numSamples);
211  virtual void runThread3(long startIndex,long numSamples);
212  virtual void runThread4(long startIndex,long numSamples);
213  virtual void runThread5(long startIndex,long numSamples);
214  virtual void runThread6(long startIndex,long numSamples);
215  virtual void runThread7(long startIndex,long numSamples);
216  virtual void runThread8(long startIndex,long numSamples);
217  virtual void runThread9(long startIndex,long numSamples);
218  virtual void runThread10(long startIndex,long numSamples);
219  virtual void runThread11(long startIndex,long numSamples);
220  virtual void runThread12(long startIndex,long numSamples);
221  virtual void runThread13(long startIndex,long numSamples);
222  virtual void runThread14(long startIndex,long numSamples);
223  virtual void runThread15(long startIndex,long numSamples);
224  virtual void runThread16(long startIndex,long numSamples);
225 
226  public:
227  FIRFilterFFF_MT(int nthreads);
228  FIRFilterFFF_MT(const std::vector<float>& newTaps, int nthreads);
229  virtual ~FIRFilterFFF_MT();
230 
231  // NOTE: This routine is expecting numSamples to be an integer multiple of the number of taps
232  virtual long filterN(float *outputBuffer, const float *inputBuffer, long numSamples);
233 
234  // OutputBuffer here should be at least numSamples/decimation in length
235  virtual long filterNdec(float *outputBuffer, const float *inputBuffer, long numSamples, int decimation);
236  };
237 
238  // --------------------------------------------------
239  // Multi-threaded filter, complex data, complex taps
240  // --------------------------------------------------
241  class FIRFilterCCC_MT:public MTBase<gr_complex>, public FIRFilterCCC {
242  protected:
243  virtual void runThread1(long startIndex,long numSamples);
244  virtual void runThread2(long startIndex,long numSamples);
245  virtual void runThread3(long startIndex,long numSamples);
246  virtual void runThread4(long startIndex,long numSamples);
247  virtual void runThread5(long startIndex,long numSamples);
248  virtual void runThread6(long startIndex,long numSamples);
249  virtual void runThread7(long startIndex,long numSamples);
250  virtual void runThread8(long startIndex,long numSamples);
251  virtual void runThread9(long startIndex,long numSamples);
252  virtual void runThread10(long startIndex,long numSamples);
253  virtual void runThread11(long startIndex,long numSamples);
254  virtual void runThread12(long startIndex,long numSamples);
255  virtual void runThread13(long startIndex,long numSamples);
256  virtual void runThread14(long startIndex,long numSamples);
257  virtual void runThread15(long startIndex,long numSamples);
258  virtual void runThread16(long startIndex,long numSamples);
259 
260  public:
261  FIRFilterCCC_MT(int nthreads);
262  FIRFilterCCC_MT(const std::vector<gr_complex>& newTaps, int nthreads);
263  virtual ~FIRFilterCCC_MT();
264 
265  // NOTE: This routine is expecting numSamples to be an integer multiple of the number of taps
266  virtual long filterN(gr_complex *outputBuffer, const gr_complex *inputBuffer, long numSamples);
267 
268  // OutputBuffer here should be at least numSamples/decimation in length
269  virtual long filterNdec(gr_complex *outputBuffer, const gr_complex *inputBuffer, long numSamples, int decimation);
270  };
271  } // end lfast
272 } // end gr
273 
274 
275 
276 #endif /* INCLUDE_LFAST_FIR_FILTER_LFAST_H_ */
Definition: fir_filter_lfast.h:241
const io_type * pInputBuffer
Definition: fir_filter_lfast.h:134
int decimation
Definition: fir_filter_lfast.h:142
virtual long filter(io_type *outputBuffer, const io_type *inputBuffer, long numSamples)
Definition: fir_filter_lfast.h:55
int d_nthreads
Definition: fir_filter_lfast.h:141
Definition: fir_filter_lfast.h:35
int numThreads()
Definition: fir_filter_lfast.h:149
Definition: fir_filter_lfast.h:132
Definition: fir_filter_lfast.h:172
virtual long ntaps()
Definition: fir_filter_lfast.h:52
std::vector< tap_type > d_taps
Definition: fir_filter_lfast.h:39
Definition: fir_filter_lfast.h:82
bool threadReady
Definition: fir_filter_lfast.h:140
long numTaps
Definition: fir_filter_lfast.h:40
Definition: fir_filter_lfast.h:103
io_type * pOutputBuffer
Definition: fir_filter_lfast.h:135
virtual void setDecimation(int newDecimation)
Definition: fir_filter_lfast.h:151
Definition: fir_filter_lfast.h:61
io_type * singlePointBuffer
Definition: fir_filter_lfast.h:38
Definition: fir_filter_lfast.h:207
virtual std::vector< tap_type > taps() const
Definition: fir_filter_lfast.h:51
tap_type * alignedTaps
Definition: fir_filter_lfast.h:37
virtual void set_taps(const std::vector< tap_type > &newTaps)
Definition: fir_filter_lfast.h:49
virtual bool decimating()
Definition: fir_filter_lfast.h:153
virtual int getDecimation()
Definition: fir_filter_lfast.h:152