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 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
24+void 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+
45+void tDelay_free(tDelay* const d)
46+{
47+ leaf_free(d->buff);
48+ leaf_free(d);
49+}
50+
51+float 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+
66+int 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+
78+float 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+
89+void 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+
99+float 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+
109+uint32_t tDelay_getDelay (tDelay* const d)
110+{
111+ return d->delay;
112+}
113+
114+float tDelay_getLastOut (tDelay* const d)
115+{
116+ return d->lastOut;
117+}
118+
119+float tDelay_getLastIn (tDelay* const d)
120+{
121+ return d->lastIn;
122+}
123+
124+void tDelay_setGain (tDelay* const d, float gain)
125+{
126+ if (gain < 0.0f) d->gain = 0.0f;
127+ else d->gain = gain;
128+}
129+
130+float tDelay_getGain (tDelay* const d)
131+{
132+ return d->gain;
133+}
134+
135+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ DelayL ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
136+void 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+
159+void tDelayL_free(tDelayL* const d)
160+{
161+ leaf_free(d->buff);
162+ leaf_free(d);
163+}
164+
165+float 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+
188+int 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+
209+float 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+
220+void 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+
230+float 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+
240+float tDelayL_getDelay (tDelayL *d)
241+{
242+ return d->delay;
243+}
244+
245+float tDelayL_getLastOut (tDelayL* const d)
246+{
247+ return d->lastOut;
248+}
249+
250+float tDelayL_getLastIn (tDelayL* const d)
251+{
252+ return d->lastIn;
253+}
254+
255+void tDelayL_setGain (tDelayL* const d, float gain)
256+{
257+ if (gain < 0.0f) d->gain = 0.0f;
258+ else d->gain = gain;
259+}
260+
261+float tDelayL_getGain (tDelayL* const d)
262+{
263+ return d->gain;
264+}
265+
266+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ DelayA ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
267+void 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+
292+void tDelayA_free(tDelayA* const d)
293+{
294+ leaf_free(d->buff);
295+ leaf_free(d);
296+}
297+
298+float 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+
319+int 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+
353+float 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+
364+void 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+
374+float 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+
384+float tDelayA_getDelay (tDelayA* const d)
385+{
386+ return d->delay;
387+}
388+
389+float tDelayA_getLastOut (tDelayA* const d)
390+{
391+ return d->lastOut;
392+}
393+
394+float tDelayA_getLastIn (tDelayA* const d)
395+{
396+ return d->lastIn;
397+}
398+
399+void tDelayA_setGain (tDelayA* const d, float gain)
400+{
401+ if (gain < 0.0f) d->gain = 0.0f;
402+ else d->gain = gain;
403+}
404+
405+float 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