forked from sensorium/Mozzi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DCfilter.h
89 lines (78 loc) · 2.17 KB
/
DCfilter.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
/*
* DCfilter.h
*
* This file is part of Mozzi.
*
* Copyright 2012-2024 Tim Barrass and the Mozzi Team
*
* Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*
*/
#ifndef DCFILTER_H
#define DCFILTER_H
/*
tb2010 adapted from:
robert bristow-johnson, DSP Trick: Fixed-Point DC Blocking Filter with Noise-Shaping
http://www.dspguru.com/book/export/html/126
y[n] = x[n] - x[n-1] + a * y[n-1]
Where y[n] is the output at the current time n, and x[n] is the input at the current time n.
also, see DC Blocker Algorithms, http://www.ingelec.uns.edu.ar/pds2803/materiales/articulos/04472252.pdf
*/
/**
A DC-blocking filter useful for highlighting changes in control signals.
The output of the filter settles to 0 if the incoming signal stays constant. If the input changes, the
filter output swings to track the change and eventually settles back to 0.
*/
class DCfilter
{
public:
/**
Instantiate a DC-blocking filter.
@param pole sets the responsiveness of the filter,
how long it takes to settle to 0 if the input signal levels out at a constant value.
*/
DCfilter(float pole):acc(0),prev_x(0),prev_y(0)
{
A = (int)(32768.0*(1.0 - pole));
}
/* almost original
// timing: 20us
int next(int x)
{
setPin13High();
acc -= prev_x;
prev_x = (long)x<<15;
acc += prev_x;
acc -= A*prev_y;
prev_y = acc>>15; // quantization happens here
int filtered = (int)prev_y;
// acc has y[n] in upper 17 bits and -e[n] in lower 15 bits
setPin13Low();
return filtered;
}
*/
/**
Filter the incoming value and return the result.
@param x the value to filter
@return filtered signal
*/
// timing :8us
inline
int next(int x)
{
acc += ((long)(x-prev_x)<<16)>>1;
prev_x = x;
acc -= (long)A*prev_y; // acc has y[n] in upper 17 bits and -e[n] in lower 15 bits
prev_y = (acc>>16)<<1; // faster than >>15 but loses bit 0
if (acc & 32784) prev_y += 1; // adds 1 if it was in the 0 bit position lost in the shifts above
return prev_y;
}
private:
long acc;
int prev_x, prev_y,A;
};
/**
@example 05.Control_Filters/DCFilter/DCFilter.ino
This example demonstrates the DCFilter class.
*/
#endif // #ifndef DCFILTER_H