-
Notifications
You must be signed in to change notification settings - Fork 39
/
Copy pathfilter_2p.c
137 lines (117 loc) · 2.81 KB
/
filter_2p.c
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
/* filter_2p.c
* null
* aleph
two-pole filters
*/
// std
#include <math.h>
// aleph
#include "filter_2p.h"
#include "module.h"
#include "fract_math.h"
#include <fract2float_conv.h>
// class-wide temp variable, compute at init
// inverse of samplerate * 2pi
static float rho;
//=========================
//==== external functions
//----------------------
//-------- lowpass
/* TODO
// intialize at pre-allocated memory
void filter_2p_lo_init(filter_2p_lo* f, fract32 in) {
f->y = in;
f->x = in;
f->sync = 1;
fSrInv = 1.f / (float)SAMPLERATE;
f->c = FR32_MAX;
}
// set cutoff frequency in hz
void filter_2p_lo_set_hz(filter_2p_lo* f, fix16 hz) {
f32 fc = (float) exp(-2.0 * M_PI * (double)(fix16_to_float(hz)) * fSrInv ); // / (float)(f->sr) );
// printf("\r1p slewicient: %f\n", fc);
f->c = float_to_fr32(fc);
}
// set integrator slewicient directly
void filter_2p_lo_set_slew(filter_2p_lo* f, fract32 slew) {
f->c = slew;
}
// set target value
void filter_2p_lo_in(filter_2p_lo* f, fract32 val) {
f->x = val;
f->sync = (val == f->y);
}
// get next filtered value
fract32 filter_2p_lo_next(filter_2p_lo* f) {
if(f->sync) {
;;
} else {
f->y = add_fr1x32( f->x,
mult_fr1x32x32(f->c,
sub_fr1x32(f->y, f->x)
));
if(fr32_compare(f->x, f->y)) {
f->y = f->x;
f->sync = 1;
}
}
return f->y;
}
*/
//---------------------
//---- hipass
// intialize at pre-allocated memory
void filter_2p_hi_init(filter_2p_hi* f) {
f->y = 0;
f->x = 0;
rho = (1.0 / (double)SAMPLERATE) * M_2_PI;
filter_2p_hi_calc_coeffs(10.f, 1.4142135623730951f, &(f->a), &(f->b), &(f->g));
}
// get next filtered value
fract32 filter_2p_hi_next(filter_2p_hi* f, fract32 x) {
/*
y = 2 * (a * (x + x2 - 2 * x1) + g * y1 - b * y2);
x2 = x1;
x1 = x;
y2 = y1;
y1 = y;
*/
f->y = shl_fr1x32(
sub_fr1x32(
add_fr1x32(
mult_fr1x32x32( f->a,
add_fr1x32( x,
sub_fr1x32( f->x2,
shl_fr1x32( f->x1, 1)
)
)
),
mult_fr1x32x32( f->g, f->y1)
),
mult_fr1x32x32( f->b, f->y2)
),
1 /*shift*/);
f->x2 = f->x1;
f->x1 = x;
f->y2 = f->y1;
f->y1 = f->y;
return f->y;
}
// set coefficients directly
void filter_2p_hi_set_alpha(filter_2p_hi* f, fract32 a) {
f->a = a;
}
void filter_2p_hi_set_beta(filter_2p_hi* f, fract32 b) {
f->b = b;
}
void filter_2p_hi_set_gamma(filter_2p_hi* f, fract32 g) {
f->g = g;
}
// calculate coefficients given cutoff in hz and damping factor
void filter_2p_hi_calc_coeffs(float hz, float d, fract32* a, fract32* b, fract32* g ) {
const float theta = hz * rho;
const float tmp = 0.5f * d * sinf(theta);
*b = float_to_fr32(0.5 * ((1.f - tmp) / (1.f + tmp)) );
*g = (*b + 0.5f) * cosf(theta);
*a = (0.5f + *b + *g )* 0.25f;
}