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