-
Notifications
You must be signed in to change notification settings - Fork 0
/
libEDM_filter.h
123 lines (90 loc) · 3.46 KB
/
libEDM_filter.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#ifndef LIBEDM_FILTER_H
#define LIBEDM_FILTER_H
#include <complex>
#include <deque>
#include <libEDM_matrix.h>
using std::deque;
//
// class Filter
//
template <class State_T, class Coef_T>
class Filter {
public:
Filter (const Vector<Coef_T> &coefficients) : _coefficients(coefficients), _numCoefficients(coefficients.size()), _state(deque<State_T>(coefficients.size())) {}
virtual Vector<State_T> filter (const Vector<State_T> &input);
State_T operator() (const State_T input) {return filter(input);}
Vector<State_T> operator() (const Vector<State_T> &input) {return filter(input);}
Filter<State_T,Coef_T> operator= (const Filter<State_T,Coef_T> &filter);
void print(ostream &file = cout, const streamsize precision = 3, const bool final_newline = true) {_coefficients.print(file, precision, final_newline);}
private:
size_t _numCoefficients;
Vector<Coef_T> _coefficients;
deque<State_T> _state;
State_T filter (const State_T input);
};
//
// class PulseShapingFilter
//
template <class Type>
class PulseShapingFilter : public Filter<Type,Type> {
public:
PulseShapingFilter (const Vector<Type> &impulseResponse, const size_t overSamplingFactor) : Filter<Type,Type>(impulseResponse), _overSamplingFactor(overSamplingFactor) {}
Vector<Type> filter (const Vector<Type> &input) {return Filter<Type,Type>::filter(upsample(input));}
private:
const size_t _overSamplingFactor;
Vector<Type> upsample (const Type input);
Vector<Type> upsample (const Vector<Type> &input);
};
//
// class RRCFilter
//
class RRCFilter : public PulseShapingFilter<double> {
public:
RRCFilter (const size_t filterLength, const double rollOffFactor, const size_t overSamplingFactor) : PulseShapingFilter<double>(impulseResponse(filterLength, rollOffFactor, overSamplingFactor), overSamplingFactor) {}
private:
dVector impulseResponse (const size_t filterLength, const double rollOffFactor, const size_t overSamplingFactor);
};
template <class State_T, class Coef_T>
State_T Filter<State_T,Coef_T>::filter (const State_T input)
{
// update state with sample
_state.push_front(input);
_state.pop_back();
// compute output
State_T output = static_cast<State_T>(0.0);
for (size_t i=0; i<_numCoefficients; i++)
output += _coefficients[i] * _state[i];
return output;
}
template <class State_T, class Coef_T>
Vector<State_T> Filter<State_T,Coef_T>::filter (const Vector<State_T> &input)
{
Vector<State_T> output(input.size());
for (size_t i=0; i<input.size(); i++)
output[i] = filter(input[i]);
return output;
}
template <class State_T, class Coef_T>
Filter<State_T,Coef_T> Filter<State_T,Coef_T>::operator= (const Filter<State_T,Coef_T> &filter)
{
_numCoefficients = filter._numCoefficients;
_coefficients = filter._coefficients;
_state = filter._state;
return (*this);
}
template <class Type>
Vector<Type> PulseShapingFilter<Type>::upsample (const Type input)
{
Vector<Type> output(_overSamplingFactor);
output[0] = input;
return output;
}
template <class Type>
Vector<Type> PulseShapingFilter<Type>::upsample (const Vector<Type> &input)
{
Vector<Type> output(input.size() * _overSamplingFactor);
for (size_t i=0; i<input.size(); i++)
output[i*_overSamplingFactor] = input[i];
return output;
}
#endif