GNU Radio Manual and C++ API Reference  3.10.9.1
The Free & Open Software Radio Ecosystem
single_pole_iir.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2002,2006,2012 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * SPDX-License-Identifier: GPL-3.0-or-later
8  *
9  */
10 
11 #ifndef INCLUDED_SINGLE_POLE_IIR_H
12 #define INCLUDED_SINGLE_POLE_IIR_H
13 
14 #include <gnuradio/filter/api.h>
15 #include <gnuradio/gr_complex.h>
16 #include <stdexcept>
17 
18 namespace gr {
19 namespace filter {
20 
21 /*!
22  * \brief class template for single pole IIR filter
23  */
24 template <class o_type, class i_type, class tap_type>
26 {
27 public:
28  /*!
29  * \brief construct new single pole IIR with given alpha
30  *
31  * computes y(i) = (1-alpha) * y(i-1) + alpha * x(i)
32  */
33  single_pole_iir(tap_type alpha = 1.0)
34  {
35  d_prev_output = 0;
36  set_taps(alpha);
37  }
38 
39  /*!
40  * \brief compute a single output value.
41  * \returns the filtered input value.
42  */
43  o_type filter(const i_type input);
44 
45  /*!
46  * \brief compute an array of N output values.
47  * \p input must have n valid entries.
48  */
49  void filterN(o_type output[], const i_type input[], unsigned long n);
50 
51  /*!
52  * \brief install \p alpha as the current taps.
53  */
54  void set_taps(tap_type alpha)
55  {
56  if (alpha < 0 || alpha > 1)
57  throw std::out_of_range("Alpha must be in [0, 1]");
58 
59  d_alpha = alpha;
60  d_one_minus_alpha = 1.0 - alpha;
61  }
62 
63  //! reset state to zero
64  void reset() { d_prev_output = 0; }
65 
66  o_type prev_output() const { return d_prev_output; }
67 
68 protected:
69  tap_type d_alpha;
71  o_type d_prev_output;
72 };
73 
74 //
75 // general case. We may want to specialize this
76 //
77 template <class o_type, class i_type, class tap_type>
79 {
80  o_type output;
81 
82  output = d_alpha * input + d_one_minus_alpha * d_prev_output;
83  d_prev_output = output;
84 
85  return (o_type)output;
86 }
87 
88 
89 template <class o_type, class i_type, class tap_type>
91  const i_type input[],
92  unsigned long n)
93 {
94  for (unsigned i = 0; i < n; i++)
95  output[i] = filter(input[i]);
96 }
97 
98 
99 //
100 // Specialized case for gr_complex output and double taps
101 // We need to have a gr_complexd type for the calculations and prev_output variable (in
102 // stead of double)
103 
104 template <class i_type>
105 class single_pole_iir<gr_complex, i_type, double>
106 {
107 public:
108  /*!
109  * \brief construct new single pole IIR with given alpha
110  *
111  * computes y(i) = (1-alpha) * y(i-1) + alpha * x(i)
112  */
113  single_pole_iir(double alpha = 1.0)
114  {
115  d_prev_output = 0;
116  set_taps(alpha);
117  }
118 
119  /*!
120  * \brief compute a single output value.
121  * \returns the filtered input value.
122  */
123  gr_complex filter(const i_type input);
124 
125  /*!
126  * \brief compute an array of N output values.
127  * \p input must have n valid entries.
128  */
129  void filterN(gr_complex output[], const i_type input[], unsigned long n);
130 
131  /*!
132  * \brief install \p alpha as the current taps.
133  */
134  void set_taps(double alpha)
135  {
136  if (alpha < 0 || alpha > 1)
137  throw std::out_of_range("Alpha must be in [0, 1]");
138 
139  d_alpha = alpha;
140  d_one_minus_alpha = 1.0 - alpha;
141  }
142 
143  //! reset state to zero
144  void reset() { d_prev_output = 0; }
145 
147 
148 protected:
149  double d_alpha;
152 };
153 
154 template <class i_type>
156 {
157  gr_complexd output;
158 
159  output = d_alpha * (gr_complexd)input + d_one_minus_alpha * d_prev_output;
160  d_prev_output = output;
161 
162  return (gr_complex)output;
163 }
164 
165 // Do we need to specialize this, although it is the same as the general case?
166 
167 template <class i_type>
169  const i_type input[],
170  unsigned long n)
171 {
172  for (unsigned i = 0; i < n; i++)
173  output[i] = filter(input[i]);
174 }
175 
176 } /* namespace filter */
177 } /* namespace gr */
178 
179 #endif /* INCLUDED_SINGLE_POLE_IIR_H */
gr_complexd prev_output() const
Definition: single_pole_iir.h:146
double d_alpha
Definition: single_pole_iir.h:149
void reset()
reset state to zero
Definition: single_pole_iir.h:144
single_pole_iir(double alpha=1.0)
construct new single pole IIR with given alpha
Definition: single_pole_iir.h:113
void set_taps(double alpha)
install alpha as the current taps.
Definition: single_pole_iir.h:134
double d_one_minus_alpha
Definition: single_pole_iir.h:150
gr_complexd d_prev_output
Definition: single_pole_iir.h:151
class template for single pole IIR filter
Definition: single_pole_iir.h:26
o_type prev_output() const
Definition: single_pole_iir.h:66
single_pole_iir(tap_type alpha=1.0)
construct new single pole IIR with given alpha
Definition: single_pole_iir.h:33
o_type filter(const i_type input)
compute a single output value.
Definition: single_pole_iir.h:78
void reset()
reset state to zero
Definition: single_pole_iir.h:64
tap_type d_one_minus_alpha
Definition: single_pole_iir.h:70
tap_type d_alpha
Definition: single_pole_iir.h:69
o_type d_prev_output
Definition: single_pole_iir.h:71
void filterN(o_type output[], const i_type input[], unsigned long n)
compute an array of N output values. input must have n valid entries.
Definition: single_pole_iir.h:90
void set_taps(tap_type alpha)
install alpha as the current taps.
Definition: single_pole_iir.h:54
std::complex< double > gr_complexd
Definition: gr_complex.h:16
std::complex< float > gr_complex
Definition: gr_complex.h:15
GNU Radio logging wrapper.
Definition: basic_block.h:29