-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathDCRemoval.cpp
148 lines (130 loc) · 4.67 KB
/
DCRemoval.cpp
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright (c) 2015-2015 Josh Blum
// SPDX-License-Identifier: BSL-1.0
#include "MovingAverage.hpp"
#include <Pothos/Framework.hpp>
#include <cstdint>
#include <complex>
#include <iostream>
/***********************************************************************
* |PothosDoc DC Removal
*
* The DC removal block calculates the DC level of input port 0
* and outputs the stream minus the DC level to output port 0.
*
* The DC level is calculated using a moving average algorithm:<br />
* <a href="http://www.digitalsignallabs.com/dcblock.pdf">
* http://www.digitalsignallabs.com/dcblock.pdf</a>
*
* |category /Filter
* |keywords filter dc blocker bias
*
* |param dtype[Data Type] The data type of the input and output element stream.
* |widget DTypeChooser(float=1,cfloat=1,int=1,cint=1)
* |default "complex_float32"
* |preview disable
*
* |param averageSize[Average Size] The depth of the moving average in number of samples.
* This parameter configures the depth of the history used in the moving average delay-line.
* |default 512
* |units samples
*
* |param cascadeSize[Cascade Size] The number of moving average filters to cascade.
* Increasing this parameter will narrow the transition region at the expense of increased computation.
* |default 2
* |units filters
*
* |factory /comms/dc_removal(dtype)
* |setter setAverageSize(averageSize)
* |setter setCascadeSize(cascadeSize)
**********************************************************************/
template <typename Type, typename AccType>
class DCRemoval : public Pothos::Block
{
public:
DCRemoval(void):
_averageSize(0),
_cascadeSize(0)
{
this->setupInput(0, typeid(Type));
this->setupOutput(0, typeid(Type));
this->registerCall(this, POTHOS_FCN_TUPLE(DCRemoval, setAverageSize));
this->registerCall(this, POTHOS_FCN_TUPLE(DCRemoval, getAverageSize));
this->registerCall(this, POTHOS_FCN_TUPLE(DCRemoval, setCascadeSize));
this->registerCall(this, POTHOS_FCN_TUPLE(DCRemoval, getCascadeSize));
this->setAverageSize(512); //initial state
this->setCascadeSize(2); //initial state
}
void setAverageSize(const size_t num)
{
if (num == 0) throw Pothos::InvalidArgumentException("DCRemoval::setAverageSize()", "average size cannot be zero");
_averageSize = num;
this->resetFilters();
}
size_t getAverageSize(void) const
{
return _averageSize;
}
void setCascadeSize(const size_t num)
{
if (num == 0) throw Pothos::InvalidArgumentException("DCRemoval::setCascadeSize()", "cascade size cannot be zero");
_cascadeSize = num;
this->resetFilters();
}
size_t getCascadeSize(void) const
{
return _cascadeSize;
}
void activate(void)
{
this->resetFilters();
}
void work(void)
{
auto inPort = this->input(0);
auto outPort = this->output(0);
const size_t N = this->workInfo().minElements;
//cast the input and output buffers
const Type *in = inPort->buffer();
Type *out = outPort->buffer();
//remove DC from each point
for (size_t i = 0; i < N; i++)
{
auto y = in[i];
//advance the filters
for (auto &f : _filters) y = f(y);
//output delayed input minus the dc level
out[i] = _filters[0].front() - y;
}
inPort->consume(N);
outPort->produce(N);
}
private:
void resetFilters(void)
{
_filters.resize(_cascadeSize);
for (auto &f : _filters) f.resize(_averageSize);
}
size_t _averageSize;
size_t _cascadeSize;
std::vector<MovingAverage<Type, AccType>> _filters;
};
/***********************************************************************
* registration
**********************************************************************/
static Pothos::Block *DCRemovalFactory(const Pothos::DType &dtype)
{
#define ifTypeDeclareFactory__(Type, AccType) \
if (dtype == Pothos::DType(typeid(Type))) return new DCRemoval<Type, AccType>();
#define ifTypeDeclareFactory(Type, AccType) \
ifTypeDeclareFactory__(Type, AccType) \
ifTypeDeclareFactory__(std::complex<Type>, std::complex<AccType>)
ifTypeDeclareFactory(double, double);
ifTypeDeclareFactory(float, float);
ifTypeDeclareFactory(int64_t, int64_t);
ifTypeDeclareFactory(int32_t, int64_t);
ifTypeDeclareFactory(int16_t, int32_t);
ifTypeDeclareFactory(int8_t, int16_t);
throw Pothos::InvalidArgumentException("DCRemovalFactory("+dtype.toString()+")", "unsupported type");
}
static Pothos::BlockRegistry registerDCRemoval(
"/comms/dc_removal", &DCRemovalFactory);