GNU Radio 3.6.4 C++ API
gr_single_pole_iir.h
Go to the documentation of this file.
1
/* -*- c++ -*- */
2
/*
3
* Copyright 2002,2006 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
#ifndef _GR_SINGLE_POLE_IIR_H_
23
#define _GR_SINGLE_POLE_IIR_H_
24
25
#include <
gr_core_api.h
>
26
#include <stdexcept>
27
#include <
gr_complex.h
>
28
/*!
29
* \brief class template for single pole IIR filter
30
*/
31
template
<
class
o_type,
class
i_type,
class
tap_type>
32
class
gr_single_pole_iir
{
33
public
:
34
/*!
35
* \brief construct new single pole IIR with given alpha
36
*
37
* computes y(i) = (1-alpha) * y(i-1) + alpha * x(i)
38
*/
39
gr_single_pole_iir
(tap_type alpha = 1.0)
40
{
41
d_prev_output
= 0;
42
set_taps
(alpha);
43
}
44
45
/*!
46
* \brief compute a single output value.
47
* \returns the filtered input value.
48
*/
49
o_type
filter
(
const
i_type input);
50
51
/*!
52
* \brief compute an array of N output values.
53
* \p input must have n valid entries.
54
*/
55
void
filterN
(o_type output[],
const
i_type input[],
unsigned
long
n);
56
57
/*!
58
* \brief install \p alpha as the current taps.
59
*/
60
void
set_taps
(tap_type alpha)
61
{
62
if
(alpha < 0 || alpha > 1)
63
throw
std::out_of_range (
"Alpha must be in [0, 1]\n"
);
64
65
d_alpha
= alpha;
66
d_one_minus_alpha
= 1.0 - alpha;
67
}
68
69
//! reset state to zero
70
void
reset
()
71
{
72
d_prev_output
= 0;
73
}
74
75
o_type
prev_output
()
const
{
return
d_prev_output
; }
76
77
protected
:
78
tap_type
d_alpha
;
79
tap_type
d_one_minus_alpha
;
80
o_type
d_prev_output
;
81
};
82
83
84
//
85
// general case. We may want to specialize this
86
//
87
template
<
class
o_type,
class
i_type,
class
tap_type>
88
o_type
89
gr_single_pole_iir<o_type, i_type, tap_type>::filter
(
const
i_type input)
90
{
91
o_type output;
92
93
output = d_alpha * input + d_one_minus_alpha * d_prev_output;
94
d_prev_output = output;
95
96
return
(o_type) output;
97
}
98
99
100
template
<
class
o_type,
class
i_type,
class
tap_type>
101
void
102
gr_single_pole_iir<o_type, i_type, tap_type>::filterN
(o_type output[],
103
const
i_type input[],
104
unsigned
long
n)
105
{
106
for
(
unsigned
i = 0; i < n; i++)
107
output[i] = filter (input[i]);
108
}
109
110
111
//
112
// Specialized case for gr_complex output and double taps
113
// We need to have a gr_complexd type for the calculations and prev_output variable (in stead of double)
114
115
template
<
class
i_type>
116
class
gr_single_pole_iir
<
gr_complex
, i_type, double> {
117
public
:
118
/*!
119
* \brief construct new single pole IIR with given alpha
120
*
121
* computes y(i) = (1-alpha) * y(i-1) + alpha * x(i)
122
*/
123
gr_single_pole_iir
(
double
alpha = 1.0)
124
{
125
d_prev_output
= 0;
126
set_taps
(alpha);
127
}
128
129
/*!
130
* \brief compute a single output value.
131
* \returns the filtered input value.
132
*/
133
gr_complex
filter
(
const
i_type input);
134
135
/*!
136
* \brief compute an array of N output values.
137
* \p input must have n valid entries.
138
*/
139
void
filterN
(
gr_complex
output[],
const
i_type input[],
unsigned
long
n);
140
141
/*!
142
* \brief install \p alpha as the current taps.
143
*/
144
void
set_taps
(
double
alpha)
145
{
146
if
(alpha < 0 || alpha > 1)
147
throw
std::out_of_range (
"Alpha must be in [0, 1]\n"
);
148
149
d_alpha
= alpha;
150
d_one_minus_alpha
= 1.0 - alpha;
151
}
152
153
//! reset state to zero
154
void
reset
()
155
{
156
d_prev_output
= 0;
157
}
158
159
gr_complexd
prev_output
()
const
{
return
d_prev_output
; }
160
161
protected
:
162
double
d_alpha
;
163
double
d_one_minus_alpha
;
164
gr_complexd
d_prev_output
;
165
};
166
167
template
<
class
i_type>
168
gr_complex
169
gr_single_pole_iir<gr_complex, i_type, double>::filter
(
const
i_type input)
170
{
171
gr_complexd
output;
172
173
output =
d_alpha
* (
gr_complexd
)input +
d_one_minus_alpha
*
d_prev_output
;
174
d_prev_output
= output;
175
176
return
(
gr_complex
) output;
177
}
178
179
//Do we need to specialize this, although it is the same as the general case?
180
181
template
<
class
i_type>
182
void
183
gr_single_pole_iir<gr_complex, i_type, double>::filterN
(
gr_complex
output[],
184
const
i_type input[],
185
unsigned
long
n)
186
{
187
for
(
unsigned
i = 0; i < n; i++)
188
output[i] =
filter
(input[i]);
189
}
190
191
#endif
/* _GR_SINGLE_POLE_IIR_H_ */
gnuradio
gnuradio-core
src
lib
filter
gr_single_pole_iir.h
Generated by
1.8.1.2