-
Notifications
You must be signed in to change notification settings - Fork 0
/
Filter.h
185 lines (167 loc) · 6.71 KB
/
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
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#ifndef FILTER_MOD_H
#define FILTER_MOD_H
#include <JuceHeader.h> // for defining juce classes variables
#include "Parameters.h" // for accessing parameters set by the user interface
/// Filter class.
/// Filter type can be set by using setType() class method.
class Filter
{
public:
/// constructor that resets filter instance and initialises frequency range for cutoff and resonance
/// @param juce::NormalisableRange<float>, range for cutoff frequency
/// @param juce::NormalisableRange<float>, range for resonance
Filter(juce::NormalisableRange<float> frequencyRange, juce::NormalisableRange<float> resonanceRange)
: minFrequency(frequencyRange.start), maxFrequency(frequencyRange.end), minResonance(resonanceRange.start), maxResonance(resonanceRange.end)
{
filter.reset();
frequencyMaxOffset = 0.5 * (maxFrequency - minFrequency); // max frequency offset for envelope and LFO
resonanceMaxOffset = 0.5 * (maxResonance - minResonance); // max resonance offset for LFO
}
/// process input sample
/// @param float, input sample
/// @return float, filter output
float process (float _inSample)
{
jassert (sampleRate > 0.0f); // check if sample rate is set (the default value on initialization is 0)
float envVal = env.getNextSample();
// calculate frequency with modulations
float freq = frequency + envAmount * envVal * frequencyMaxOffset + frequencyOffset;
// check bounds
if (freq > maxFrequency)
freq = maxFrequency;
if (freq < minFrequency)
freq = minFrequency;
// calculate resonance with modulations
float res = resonance + resonanceOffset;
// check resonance bounds
if (res < minResonance)
res = minResonance;
if (res > maxResonance)
res = maxResonance;
filter.setCoefficients (makeFilterCoefficients (sampleRate, freq, res));
// reset modulations
resetModulations();
return filter.processSingleSampleRaw (_inSample);
}
/// set sample rate
/// @param float, sample rate
void setSampleRate (float _sampleRate)
{
jassert (_sampleRate > 0.0f); // check sample rate value
sampleRate = _sampleRate;
}
/// set filter frequency
/// @param float, frequency
void setFrequency (float _frequency)
{
frequency = _frequency;
}
/// set filter resonance
/// @param float, frequency
void setResonance (float _resonance)
{
resonance = _resonance;
}
/// set filter type
/// @param int, filter type (0 - low pass, 1 - high pass, 2 - band pass, 3 - notch
void setType (int _filterType)
{
switch (_filterType)
{
case 0:
setFilterCoefficientsFunction (&(juce::IIRCoefficients::makeLowPass));
break;
case 1:
setFilterCoefficientsFunction (&(juce::IIRCoefficients::makeHighPass));
break;
case 2:
setFilterCoefficientsFunction (&(juce::IIRCoefficients::makeBandPass));
break;
case 3:
setFilterCoefficientsFunction (&(juce::IIRCoefficients::makeNotchFilter));
break;
}
}
/// set ADSR parameters for a filter cutoff envelope
/// @param float, attack
/// @param float, decay
/// @param float, sustain
/// @param float, release
void setEnvParameters (float _attack, float _decay, float _sustain, float _release)
{
juce::ADSR::Parameters envParam(_attack, _decay, _sustain, _release);
env.setParameters (envParam);
}
/// set envelope amount
/// @param float, envelope amount (-100% to 100%)
void setEnvAmount (float _envAmount)
{
envAmount = _envAmount;
}
/// start the attack phase of the filter cutoff envelope and update filter's parameters
/// @param Parameters*, pointer to parameters set by the user interface
/// @param float, sample rate [Hz]
void startNote (Parameters* param, float _sampleRate)
{
filter.reset();
env.reset();
(*this).setSampleRate (_sampleRate);
(*this).setType (*param->filterTypeParam);
(*this).setFrequency (*param->filterFrequencyParam);
(*this).setResonance (*param->filterResonanceParam);
(*this).setEnvParameters (*param->filterAttackParam, *param->filterDecayParam, *param->filterSustainParam, *param->filterReleaseParam);
(*this).setEnvAmount (*param->filterEnvAmountParam);
env.noteOn();
}
/// start the release phase of the filter cutoff envelope
void stopNote()
{
env.noteOff();
}
/// set frequency offset (used for external modulations)
/// @param float, frequency offset amount (from -1 to 1)
void setFrequencyOffset (float _frequencyOffsetAmount)
{
frequencyOffset += _frequencyOffsetAmount * frequencyMaxOffset;
}
/// set resonance offset (used for external modulations)
/// @param float, resonance offset amount (from -1 to 1)
void setResonanceOffset (float _resonanceOffsetAmount)
{
resonanceOffset += _resonanceOffsetAmount * resonanceMaxOffset;
}
private:
float sampleRate = 0.0f; // sample rate [Hz]
// base members
juce::IIRFilter filter; // filter instance
juce::IIRCoefficients (*makeFilterCoefficients) (double sampleRate, double frequency, double Q); // pointer to a function with calculates filter coefficiens using specified sample rate, cutoff frequency and resonance
juce::ADSR env; // filter cutoff envelope
// filter parameters
float frequency;
float resonance;
float envAmount = 0.0f;
// modulation parameters
float frequencyOffset = 0.0f;
float resonanceOffset = 0.0f;
// parameters bounds
const float minFrequency;
const float maxFrequency;
const float minResonance;
const float maxResonance;
float frequencyMaxOffset;
float resonanceMaxOffset;
/// set filter coefficients function
/// @param juce::IIRCoefficients (*_func) (double, double, double), pointer to a function,
/// which calculates filter coefficients by using sample rate, cutoff and resonance values
void setFilterCoefficientsFunction (juce::IIRCoefficients (*_func) (double, double, double))
{
makeFilterCoefficients = _func;
}
/// reset external filter modulations (frequency and resonance modulations)
void resetModulations()
{
frequencyOffset = 0.0f;
resonanceOffset = 0.0f;
}
};
#endif // FILTER_MOD_H