-
Notifications
You must be signed in to change notification settings - Fork 0
/
am_DoubleCombFilter.h
214 lines (159 loc) · 5.37 KB
/
am_DoubleCombFilter.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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
//Can be altered to create a chorus class
/*
==============================================================================
am_DoubleCombFilter.h
Created: 10 Dec 2022 12:01:20am
Author: Andrew McGillivray
==============================================================================
*/
#pragma once
class DoubleCombFilter
{
public:
//destructor
~DoubleCombFilter()
{
if (delayLine != nullptr)
{
delete[] delayLine;
}
}
/// set the sample rate (Hz)
void setSampleRate(float sampleRateIn)
{
sampleRate = sampleRateIn;
}
///set the maximum size of the delay line
void setMaxDelay(int maxDelayIn)
{
maxLength = maxDelayIn * sampleRate;
//free up data
if (delayLine != nullptr)
delete[] delayLine;
delayLine = new float[maxLength]; //create array
//initialise array
for (int i=0; i<maxLength; i++)
{
delayLine[i] = 0.0;
}
}
///set the delay time in seconds
void setDelayTimes(float delayTimeOneIn, float delayTimeTwoIn)
{
delayTimeOne = delayTimeOneIn * sampleRate;
delayTimeTwo = delayTimeTwoIn * sampleRate;
// set read indexes
readIndexOne = writeIndex - delayTimeOne;
readIndexTwo = writeIndex - delayTimeTwo;
if (readIndexOne < 0)
{
readIndexOne = readIndexOne + maxLength;
}
if (readIndexTwo < 0)
{
readIndexTwo = readIndexTwo + maxLength;
}
}
///use delay line
float process(float input)
{
// read in current value
float outputSampleOne = linearInterpolationOne();
float outputSampleTwo = linearInterpolationTwo();
float outputSampleTotal = input + (outputSampleOne * feedbackOne) + (outputSampleTwo * feedbackTwo);
// store value in delay line
delayLine[writeIndex] = input;
// find next read and write values;
readIndexOne += 1;
if (readIndexOne >= maxLength)
{
readIndexOne -= maxLength;
}
readIndexTwo += 1;
if (readIndexTwo >= maxLength)
{
readIndexTwo -= maxLength;
}
writeIndex += 1;
if (writeIndex >= maxLength)
{
writeIndex -= maxLength;
}
return outputSampleTotal;
}
///uses linear interpolation to find the correct sample
float linearInterpolationOne()
{
//find relevant indexes
int indexOne = int(readIndexOne); // e.g. 2
int indexTwo = indexOne + 1; // e.g. 3
//failsafe on index two
if (indexTwo > maxLength)
{
indexTwo -= maxLength;
}
//read values
float valOne = delayLine[indexOne]; // e.g. data[2]
float valTwo = delayLine[indexTwo]; // e.g. data[3]
// calculate difference
float difference = readIndexOne - indexOne; // e.g. 2.3 - 2 = 0.3
// work out interpolated sample between two indexes
float interpolatedSample = (1 - difference) * valOne + difference * valTwo;
return interpolatedSample;
}
///uses linear interpolation to find the correct sample
float linearInterpolationTwo()
{
//find relevant indexes
int indexOne = int(readIndexTwo); // e.g. 2
int indexTwo = indexOne + 1; // e.g. 3
//failsafe on index two
if (indexTwo > maxLength)
{
indexTwo -= maxLength;
}
//read values
float valOne = delayLine[indexOne]; // e.g. data[2]
float valTwo = delayLine[indexTwo]; // e.g. data[3]
// calculate difference
float difference = readIndexTwo - indexOne; // e.g. 2.3 - 2 = 0.3
// work out interpolated sample between two indexes
float interpolatedSample = (1 - difference) * valOne + difference * valTwo;
return interpolatedSample;
}
///sets the feedback in the interval [0, 1]
void setFeedback(float feedbackInOne, float feedbackInTwo)
{
feedbackOne = feedbackInOne;
feedbackTwo = feedbackInTwo;
//failsafes
if (feedbackOne < 0)
{
feedbackOne = 0;
}
if (feedbackOne > 1.0)
{
feedbackOne = 1.0;
}
if (feedbackTwo < 0)
{
feedbackTwo = 0;
}
if (feedbackTwo > 1.0)
{
feedbackTwo = 1.0;
}
}
private:
float readIndexOne = 0; //read position 1
float readIndexTwo = 0; //read position 2
int writeIndex = 0; //write position
int maxLength; //maximum possible delay time
float* delayLine = nullptr; //stores delay data
//delay times
int delayTimeOne;
int delayTimeTwo;
float feedbackOne = 0.5; //must be in [0, 1]
float feedbackTwo = 0.5; //must be in [0, 1]
float sampleRate;
};