History

First commit.

mulshine committed 7 years ago

Commit 127a1131 parent 824e8d1147 files · +49021 −-7Browse files

Showing the changes to LEAF/Src_cpp/leaf-delay.cpp (1 of 147 files). Show all

Unified · Split

LEAF/Src_cpp/leaf-delay.cpp+409−0
@@ -0,0 +1,409 @@
1/*
2 ==============================================================================
3
4 LEAFDelay.c
5 Created: 20 Jan 2017 12:01:24pm
6 Author: Michael R Mulshine
7
8 ==============================================================================
9*/
10
11#if _WIN32 || _WIN64
12
13#include "..\Inc\leaf-delay.h"
14#include "..\leaf.h"
15
16#else
17
18#include "../Inc/leaf-delay.h"
19#include "../leaf.h"
20
21#endif
22
23// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Delay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
24void tDelay_init (tDelay* const d, uint32_t delay, uint32_t maxDelay)
25{
26 d->maxDelay = maxDelay;
27
28 d->delay = delay;
29
30 d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
31
32 d->delay = 0.0f;
33
34 d->inPoint = 0;
35 d->outPoint = 0;
36
37 d->lastIn = 0.0f;
38 d->lastOut = 0.0f;
39
40 d->gain = 1.0f;
41
42 tDelay_setDelay(d, d->delay);
43}
44
45void tDelay_free(tDelay* const d)
46{
47 leaf_free(d->buff);
48 leaf_free(d);
49}
50
51float tDelay_tick (tDelay* const d, float input)
52{
53 // Input
54 d->lastIn = input;
55 d->buff[d->inPoint] = input * d->gain;
56 if (++(d->inPoint) == d->maxDelay) d->inPoint = 0;
57
58 // Output
59 d->lastOut = d->buff[d->outPoint];
60 if (++(d->outPoint) == d->maxDelay) d->outPoint = 0;
61
62 return d->lastOut;
63}
64
65
66int tDelay_setDelay (tDelay* const d, uint32_t delay)
67{
68 if (delay >= d->maxDelay) d->delay = d->maxDelay;
69 else d->delay = delay;
70
71 // read chases write
72 if ( d->inPoint >= delay ) d->outPoint = d->inPoint - d->delay;
73 else d->outPoint = d->maxDelay + d->inPoint - d->delay;
74
75 return 0;
76}
77
78float tDelay_tapOut (tDelay* const d, uint32_t tapDelay)
79{
80 int32_t tap = d->inPoint - tapDelay - 1;
81
82 // Check for wraparound.
83 while ( tap < 0 ) tap += d->maxDelay;
84
85 return d->buff[tap];
86
87}
88
89void tDelay_tapIn (tDelay* const d, float value, uint32_t tapDelay)
90{
91 int32_t tap = d->inPoint - tapDelay - 1;
92
93 // Check for wraparound.
94 while ( tap < 0 ) tap += d->maxDelay;
95
96 d->buff[tap] = value;
97}
98
99float tDelay_addTo (tDelay* const d, float value, uint32_t tapDelay)
100{
101 int32_t tap = d->inPoint - tapDelay - 1;
102
103 // Check for wraparound.
104 while ( tap < 0 ) tap += d->maxDelay;
105
106 return (d->buff[tap] += value);
107}
108
109uint32_t tDelay_getDelay (tDelay* const d)
110{
111 return d->delay;
112}
113
114float tDelay_getLastOut (tDelay* const d)
115{
116 return d->lastOut;
117}
118
119float tDelay_getLastIn (tDelay* const d)
120{
121 return d->lastIn;
122}
123
124void tDelay_setGain (tDelay* const d, float gain)
125{
126 if (gain < 0.0f) d->gain = 0.0f;
127 else d->gain = gain;
128}
129
130float tDelay_getGain (tDelay* const d)
131{
132 return d->gain;
133}
134
135// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ DelayL ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
136void tDelayL_init (tDelayL* const d, float delay, uint32_t maxDelay)
137{
138 d->maxDelay = maxDelay;
139
140 if (delay > maxDelay) d->delay = maxDelay;
141 else if (delay < 0.0f) d->delay = 0.0f;
142 else d->delay = delay;
143
144 d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
145
146 d->delay = 0.0f;
147
148 d->gain = 1.0f;
149
150 d->lastIn = 0.0f;
151 d->lastOut = 0.0f;
152
153 d->inPoint = 0;
154 d->outPoint = 0;
155
156 tDelayL_setDelay(d, d->delay);
157}
158
159void tDelayL_free(tDelayL* const d)
160{
161 leaf_free(d->buff);
162 leaf_free(d);
163}
164
165float tDelayL_tick (tDelayL* const d, float input)
166{
167 d->buff[d->inPoint] = input * d->gain;
168
169 // Increment input pointer modulo length.
170 if (++(d->inPoint) == d->maxDelay ) d->inPoint = 0;
171
172
173 // First 1/2 of interpolation
174 d->lastOut = d->buff[d->outPoint] * d->omAlpha;
175
176 // Second 1/2 of interpolation
177 if (d->outPoint + 1 < d->maxDelay)
178 d->lastOut += d->buff[d->outPoint+1] * d->alpha;
179 else
180 d->lastOut += d->buff[0] * d->alpha;
181
182 // Increment output pointer modulo length.
183 if ( ++(d->outPoint) == d->maxDelay ) d->outPoint = 0;
184
185 return d->lastOut;
186}
187
188int tDelayL_setDelay (tDelayL* const d, float delay)
189{
190 if (delay < 0.0f) d->delay = 0.0f;
191 else if (delay <= d->maxDelay) d->delay = delay;
192 else d->delay = d->maxDelay;
193
194 float outPointer = d->inPoint - d->delay;
195
196 while ( outPointer < 0 )
197 outPointer += d->maxDelay; // modulo maximum length
198
199 d->outPoint = (uint32_t) outPointer; // integer part
200
201 d->alpha = outPointer - d->outPoint; // fractional part
202 d->omAlpha = 1.0f - d->alpha;
203
204 if ( d->outPoint == d->maxDelay ) d->outPoint = 0;
205
206 return 0;
207}
208
209float tDelayL_tapOut (tDelayL* const d, uint32_t tapDelay)
210{
211 int32_t tap = d->inPoint - tapDelay - 1;
212
213 // Check for wraparound.
214 while ( tap < 0 ) tap += d->maxDelay;
215
216 return d->buff[tap];
217
218}
219
220void tDelayL_tapIn (tDelayL* const d, float value, uint32_t tapDelay)
221{
222 int32_t tap = d->inPoint - tapDelay - 1;
223
224 // Check for wraparound.
225 while ( tap < 0 ) tap += d->maxDelay;
226
227 d->buff[tap] = value;
228}
229
230float tDelayL_addTo (tDelayL* const d, float value, uint32_t tapDelay)
231{
232 int32_t tap = d->inPoint - tapDelay - 1;
233
234 // Check for wraparound.
235 while ( tap < 0 ) tap += d->maxDelay;
236
237 return (d->buff[tap] += value);
238}
239
240float tDelayL_getDelay (tDelayL *d)
241{
242 return d->delay;
243}
244
245float tDelayL_getLastOut (tDelayL* const d)
246{
247 return d->lastOut;
248}
249
250float tDelayL_getLastIn (tDelayL* const d)
251{
252 return d->lastIn;
253}
254
255void tDelayL_setGain (tDelayL* const d, float gain)
256{
257 if (gain < 0.0f) d->gain = 0.0f;
258 else d->gain = gain;
259}
260
261float tDelayL_getGain (tDelayL* const d)
262{
263 return d->gain;
264}
265
266// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ DelayA ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
267void tDelayA_init (tDelayA* const d, float delay, uint32_t maxDelay)
268{
269 d->maxDelay = maxDelay;
270
271 if (delay > maxDelay) d->delay = maxDelay;
272 else if (delay < 0.0f) d->delay = 0.0f;
273 else d->delay = delay;
274
275 d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
276
277 d->delay = 0.0f;
278
279 d->gain = 1.0f;
280
281 d->lastIn = 0.0f;
282 d->lastOut = 0.0f;
283
284 d->inPoint = 0;
285 d->outPoint = 0;
286
287 tDelayA_setDelay(d, d->delay);
288
289 d->apInput = 0.0f;
290}
291
292void tDelayA_free(tDelayA* const d)
293{
294 leaf_free(d->buff);
295 leaf_free(d);
296}
297
298float tDelayA_tick (tDelayA* const d, float input)
299{
300 d->buff[d->inPoint] = input * d->gain;
301
302 // Increment input pointer modulo length.
303 if ( ++(d->inPoint) >= d->maxDelay ) d->inPoint = 0;
304
305 // Do allpass interpolation delay.
306 float out = d->lastOut * -d->coeff;
307 out += d->apInput + ( d->coeff * d->buff[d->outPoint] );
308 d->lastOut = out;
309
310 // Save allpass input
311 d->apInput = d->buff[d->outPoint];
312
313 // Increment output pointer modulo length.
314 if (++(d->outPoint) >= d->maxDelay ) d->outPoint = 0;
315
316 return d->lastOut;
317}
318
319int tDelayA_setDelay (tDelayA* const d, float delay)
320{
321 if (delay < 0.5f) d->delay = 0.5f;
322 else if (delay <= d->maxDelay) d->delay = delay;
323 else d->delay = d->maxDelay;
324
325 // outPoint chases inPoint
326 float outPointer = (float)d->inPoint - d->delay + 1.0f;
327
328 while ( outPointer < 0 ) outPointer += d->maxDelay; // mod max length
329
330 d->outPoint = (uint32_t) outPointer; // integer part
331
332 if ( d->outPoint >= d->maxDelay ) d->outPoint = 0;
333
334 d->alpha = 1.0f + (float)d->outPoint - outPointer; // fractional part
335
336 if ( d->alpha < 0.5f )
337 {
338 // The optimal range for alpha is about 0.5 - 1.5 in order to
339 // achieve the flattest phase delay response.
340
341 d->outPoint += 1;
342
343 if ( d->outPoint >= d->maxDelay ) d->outPoint -= d->maxDelay;
344
345 d->alpha += 1.0f;
346 }
347
348 d->coeff = (1.0f - d->alpha) / (1.0f + d->alpha); // coefficient for allpass
349
350 return 0;
351}
352
353float tDelayA_tapOut (tDelayA* const d, uint32_t tapDelay)
354{
355 int32_t tap = d->inPoint - tapDelay - 1;
356
357 // Check for wraparound.
358 while ( tap < 0 ) tap += d->maxDelay;
359
360 return d->buff[tap];
361
362}
363
364void tDelayA_tapIn (tDelayA* const d, float value, uint32_t tapDelay)
365{
366 int32_t tap = d->inPoint - tapDelay - 1;
367
368 // Check for wraparound.
369 while ( tap < 0 ) tap += d->maxDelay;
370
371 d->buff[tap] = value;
372}
373
374float tDelayA_addTo (tDelayA* const d, float value, uint32_t tapDelay)
375{
376 int32_t tap = d->inPoint - tapDelay - 1;
377
378 // Check for wraparound.
379 while ( tap < 0 ) tap += d->maxDelay;
380
381 return (d->buff[tap] += value);
382}
383
384float tDelayA_getDelay (tDelayA* const d)
385{
386 return d->delay;
387}
388
389float tDelayA_getLastOut (tDelayA* const d)
390{
391 return d->lastOut;
392}
393
394float tDelayA_getLastIn (tDelayA* const d)
395{
396 return d->lastIn;
397}
398
399void tDelayA_setGain (tDelayA* const d, float gain)
400{
401 if (gain < 0.0f) d->gain = 0.0f;
402 else d->gain = gain;
403}
404
405float tDelayA_getGain (tDelayA* const d)
406{
407 return d->gain;
408}
409

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t