forked from sensorium/Mozzi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
LowPassFilter.h
127 lines (101 loc) · 2.55 KB
/
LowPassFilter.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
124
125
126
127
/*
* LowPassFilter.h
*
* Copyright 2012 Tim Barrass
*
* This file is part of Mozzi.
*
* Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
*
*/
#ifndef LOWPASS_H_
#define LOWPASS_H_
/*
simple resonant filter posted to musicdsp.org by Paul Kellett http://www.musicdsp.org/archive.php?classid=3#259
// set feedback amount given f and q between 0 and 1
fb = q + q/(1.0 - f);
// for each sample...
buf0 = buf0 + f * (in - buf0 + fb * (buf0 - buf1));
buf1 = buf1 + f * (buf0 - buf1);
out = buf1;
fixed point version of the filter
"dave's blog of art and programming" http://www.pawfal.org/dave/blog/2011/09/
*/
// we are using .n fixed point (n bits for the fractional part)
#define FX_SHIFT 8
#define SHIFTED_1 ((uint8_t) 255)
/** A resonant low pass filter for audio signals.
*/
class LowPassFilter
{
public:
/** Constructor.
*/
LowPassFilter(){;
}
/** Set the cut off frequency,
@param cutoff use the range 0-255 to represent 0-8192 Hz (AUDIO_RATE/2).
Be careful of distortion at the lower end, especially with high resonance.
*/
void setCutoffFreq(uint8_t cutoff)
{
f = cutoff;
fb = q+ucfxmul(q, SHIFTED_1 - cutoff);
}
/** Set the resonance. If you hear unwanted distortion, back off the resonance.
@param resonance in the range 0-255, with 255 being most resonant.
*/
void setResonance(uint8_t resonance)
{
q = resonance;
}
/** Calculate the next sample, given an input signal.
@param in the signal input.
@return the signal output.
@note Timing: about 11us.
*/
// 10.5 to 12.5 us, mostly 10.5 us (was 14us)
inline
int next(int in)
{
//setPin13High();
buf0+=fxmul(((in - buf0) + fxmul(fb, buf0-buf1)), f);
buf1+=ifxmul(buf0-buf1, f); // could overflow if input changes fast
//setPin13Low();
return buf1;
}
private:
uint8_t q;
uint8_t f;
unsigned int fb;
int buf0,buf1;
// // multiply two fixed point numbers (returns fixed point)
// inline
// long fxmul(long a, long b)
// {
// return (a*b)>>FX_SHIFT;
// }
// multiply two fixed point numbers (returns fixed point)
inline
unsigned int ucfxmul(uint8_t a, uint8_t b)
{
return (((unsigned int)a*b)>>FX_SHIFT);
}
// multiply two fixed point numbers (returns fixed point)
inline
int ifxmul(int a, uint8_t b)
{
return ((a*b)>>FX_SHIFT);
}
// multiply two fixed point numbers (returns fixed point)
inline
long fxmul(long a, int b)
{
return ((a*b)>>FX_SHIFT);
}
};
/**
@example 10.Audio_Filters/LowPassFilter/LowPassFilter.ino
This example demonstrates the LowPassFilter class.
*/
#endif /* LOWPASS_H_ */