1 /*
2 
3     This LV2 plugin provides munged delay plugins
4 
5     (c) Fraser Stuart 2009
6 
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <math.h>
27 #include <lv2.h>
28 #include "library/common.h"
29 #include "inv_delay.h"
30 
31 static LV2_Descriptor *IDelayMonoDescriptor = NULL;
32 static LV2_Descriptor *IDelaySumDescriptor = NULL;
33 
34 
35 
36 typedef struct {
37 
38 	/* Ports */
39 	float *ControlBypass;
40 	float *ControlMode;
41 	float *ControlMungeMode;
42 	float *ControlMunge;
43 	float *ControlCycle;
44 	float *ControlWidth;
45 	float *Control1Delay;
46 	float *Control1FB;
47 	float *Control1Pan;
48 	float *Control1Vol;
49 	float *Control2Delay;
50 	float *Control2FB;
51 	float *Control2Pan;
52 	float *Control2Vol;
53 
54 	float *AudioOutputBufferL;
55 	float *AudioOutputBufferR;
56 	float *AudioInputBufferL;
57 	float *AudioInputBufferR;
58 
59 	float *LampLFO;
60 	float *MeterInputL;
61 	float *MeterOutputL;
62 	float *MeterOutputR;
63 
64 	double SampleRate;
65 
66 	struct Envelope EnvAD[4];
67 
68 	/* Stuff to remember to avoid recalculating the delays every run */
69 	float LastBypass;
70 	float LastMode;
71 	float LastMungeMode;
72 	float LastMunge;
73 	float LastCycle;
74 	float LastWidth;
75 	float Last1Delay;
76 	float Last1FB;
77 	float Last1Pan;
78 	float Last1Vol;
79 	float Last2Delay;
80 	float Last2FB;
81 	float Last2Pan;
82 	float Last2Vol;
83 
84 
85 	float LFOAngle;
86 	float AudioLPF1;
87 	float AudioLPF2;
88 	float AudioHPF1;
89 	float AudioHPF2;
90 	float AudioDegrain1;
91 	float AudioDegrain2;
92 	float EnvInLLast;
93 	float EnvOutLLast;
94 	float EnvOutRLast;
95 
96 	float ConvertedBypass;
97 	float ConvertedMode;
98 	float ConvertedMungeMode;
99 	float ConvertedMunge;
100 	float ConvertedCycle;
101 	float ConvertedWidth;
102 	float ConvertedLPFsamples;
103 	float ConvertedHPFsamples;
104 	float Converted1Delay;
105 	float Converted1FB;
106 	float Converted1Pan;
107 	float Converted1Vol;
108 	float Converted2Delay;
109 	float Converted2FB;
110 	float Converted2Pan;
111 	float Converted2Vol;
112 
113 
114 	/* Delay Space Data */
115 	unsigned long SpaceSize;
116 	float * SpaceL;
117 	float * SpaceR;
118 	float * SpaceLCur;
119 	float * SpaceRCur;
120 	float * SpaceLEnd;
121 	float * SpaceREnd;
122 
123 } IDelay;
124 
125 
126 static LV2_Handle
instantiateIDelay(const LV2_Descriptor * descriptor,double s_rate,const char * path,const LV2_Feature * const * features)127 instantiateIDelay(const LV2_Descriptor *descriptor, double s_rate, const char *path, const LV2_Feature * const* features)
128 {
129 	IDelay *plugin = (IDelay *)malloc(sizeof(IDelay));
130 	if(plugin==NULL)
131 		return NULL;
132 
133 	/* set some initial params */
134 	plugin->SampleRate=s_rate;
135 	plugin->SpaceSize = IDELAY_SPACE_SIZE * s_rate / 1000;
136 
137 	/* the delay space */
138 	if((plugin->SpaceL  = (float *)malloc(sizeof(float) * plugin->SpaceSize))==NULL)
139     		return NULL;
140 
141 	if((plugin->SpaceR  = (float *)malloc(sizeof(float) * plugin->SpaceSize))==NULL)
142     		return NULL;
143 
144 	return (LV2_Handle)plugin;
145 }
146 
147 static void
connectPortIDelay(LV2_Handle instance,uint32_t port,void * data)148 connectPortIDelay(LV2_Handle instance, uint32_t port, void *data)
149 {
150 	IDelay *plugin = (IDelay *)instance;
151 	switch (port) {
152 		case IDELAY_BYPASS:
153 			plugin->ControlBypass = data;
154 			break;
155 		case IDELAY_MODE:
156 			plugin->ControlMode = data;
157 			break;
158 		case IDELAY_MUNGEMODE:
159 			plugin->ControlMungeMode = data;
160 			break;
161 		case IDELAY_MUNGE:
162 			plugin->ControlMunge = data;
163 			break;
164 		case IDELAY_LFO_CYCLE:
165 			plugin->ControlCycle = data;
166 			break;
167 		case IDELAY_LFO_WIDTH:
168 			plugin->ControlWidth = data;
169 			break;
170 		case IDELAY_1_DELAY:
171 			plugin->Control1Delay = data;
172 			break;
173 		case IDELAY_1_FB:
174 			plugin->Control1FB = data;
175 			break;
176 		case IDELAY_1_PAN:
177 			plugin->Control1Pan = data;
178 			break;
179 		case IDELAY_1_VOL:
180 			plugin->Control1Vol = data;
181 			break;
182 		case IDELAY_2_DELAY:
183 			plugin->Control2Delay = data;
184 			break;
185 		case IDELAY_2_FB:
186 			plugin->Control2FB = data;
187 			break;
188 		case IDELAY_2_PAN:
189 			plugin->Control2Pan = data;
190 			break;
191 		case IDELAY_2_VOL:
192 			plugin->Control2Vol = data;
193 			break;
194 		case IDELAY_AUDIO_INL:
195 			plugin->AudioInputBufferL = data;
196 			break;
197 		case IDELAY_AUDIO_INR:
198 			plugin->AudioInputBufferR = data;
199 			break;
200 		case IDELAY_AUDIO_OUTL:
201 			plugin->AudioOutputBufferL = data;
202 			break;
203 		case IDELAY_AUDIO_OUTR:
204 			plugin->AudioOutputBufferR = data;
205 			break;
206 		case IDELAY_METER_INL:
207 			plugin->MeterInputL = data;
208 			break;
209 		case IDELAY_METER_OUTL:
210 			plugin->MeterOutputL = data;
211 			break;
212 		case IDELAY_METER_OUTR:
213 			plugin->MeterOutputR = data;
214 			break;
215 		case IDELAY_LAMP_LFO:
216 			plugin->LampLFO = data;
217 			break;
218 	}
219 }
220 
221 
222 static void
activateIDelay(LV2_Handle instance)223 activateIDelay(LV2_Handle instance)
224 {
225 	IDelay *plugin = (IDelay *)instance;
226 
227 	unsigned long i;
228 	float * p;
229 	float * q;
230 
231 	//set ourselves at the beginning of space
232 	plugin->SpaceLCur=plugin->SpaceL;
233 	plugin->SpaceRCur=plugin->SpaceR;
234 
235 	// clear space
236 	p=plugin->SpaceL;
237 	q=plugin->SpaceR;
238 	for(i=0; i < plugin->SpaceSize; i++) {
239 		*(p++)=0;
240 		*(q++)=0;
241 	}
242 	plugin->SpaceLEnd=--p;
243 	plugin->SpaceREnd=--q;
244 
245 	//set defaults
246 	plugin->LastBypass    	= 0.0;
247 	plugin->LastMode	= 0.0;
248 	plugin->LastMungeMode	= 0.0;
249 	plugin->LastMunge	= 50.0;
250 	plugin->LastCycle	= 20.0;
251 	plugin->LastWidth	= 0.0;
252 	plugin->Last1Delay	= 0.3;
253 	plugin->Last1FB		= 50.0;
254 	plugin->Last1Pan	= -0.7;
255 	plugin->Last1Vol	= 100.0;
256 	plugin->Last2Delay	= 0.2;
257 	plugin->Last2FB		= 50.0;
258 	plugin->Last2Pan	= 0.7;
259 	plugin->Last2Vol	= 100.0;
260 
261 	plugin->LFOAngle 	= 0;
262 	plugin->AudioLPF1 	= 0;
263 	plugin->AudioLPF2 	= 0;
264 	plugin->AudioHPF1 	= 0;
265 	plugin->AudioHPF2 	= 0;
266 	plugin->AudioDegrain1 	= 0;
267 	plugin->AudioDegrain2 	= 0;
268 	plugin->EnvInLLast 	= 0;
269 	plugin->EnvOutLLast 	= 0;
270 	plugin->EnvOutRLast 	= 0;
271 
272 	plugin->ConvertedBypass     = convertParam(IDELAY_BYPASS,    plugin->LastBypass,    plugin->SampleRate);
273 	plugin->ConvertedMode       = convertParam(IDELAY_MODE,	     plugin->LastMode,      plugin->SampleRate);
274 	plugin->ConvertedMungeMode  = convertParam(IDELAY_MUNGEMODE, plugin->LastMungeMode, plugin->SampleRate);
275 	plugin->ConvertedMunge      = convertParam(IDELAY_MUNGE,     plugin->LastMunge,     plugin->SampleRate);
276 	plugin->ConvertedLPFsamples = convertMunge(0,                plugin->LastMunge,     plugin->SampleRate);
277 	plugin->ConvertedHPFsamples = convertMunge(1,                plugin->LastMunge,     plugin->SampleRate);
278 	plugin->ConvertedCycle      = convertParam(IDELAY_LFO_CYCLE, plugin->LastCycle,     plugin->SampleRate);
279 	plugin->ConvertedWidth      = convertParam(IDELAY_LFO_WIDTH, plugin->LastWidth,     plugin->SampleRate);
280 	plugin->Converted1Delay     = convertParam(IDELAY_1_DELAY,   plugin->Last1Delay,    plugin->SampleRate);
281 	plugin->Converted1FB        = convertParam(IDELAY_1_FB,      plugin->Last1FB,       plugin->SampleRate);
282 	plugin->Converted1Pan       = convertParam(IDELAY_1_PAN,     plugin->Last1Pan,      plugin->SampleRate);
283 	plugin->Converted1Vol       = convertParam(IDELAY_1_VOL,     plugin->Last1Vol,      plugin->SampleRate);
284 	plugin->Converted2Delay     = convertParam(IDELAY_2_DELAY,   plugin->Last2Delay,    plugin->SampleRate);
285 	plugin->Converted2FB        = convertParam(IDELAY_2_FB,      plugin->Last2FB,       plugin->SampleRate);
286 	plugin->Converted2Pan       = convertParam(IDELAY_2_PAN,     plugin->Last2Pan,      plugin->SampleRate);
287 	plugin->Converted2Vol       = convertParam(IDELAY_2_VOL,     plugin->Last2Vol,      plugin->SampleRate);
288 
289 	/* initialise envelopes */
290 	initIEnvelope(&plugin->EnvAD[INVADA_METER_VU],    INVADA_METER_VU,    plugin->SampleRate);
291 	initIEnvelope(&plugin->EnvAD[INVADA_METER_PEAK],  INVADA_METER_PEAK,  plugin->SampleRate);
292 	initIEnvelope(&plugin->EnvAD[INVADA_METER_PHASE], INVADA_METER_PHASE, plugin->SampleRate);
293 	initIEnvelope(&plugin->EnvAD[INVADA_METER_LAMP],  INVADA_METER_LAMP,  plugin->SampleRate);
294 }
295 
296 
297 static void
runMonoIDelay(LV2_Handle instance,uint32_t SampleCount)298 runMonoIDelay(LV2_Handle instance, uint32_t SampleCount)
299 {
300 	float (*pParamFunc)(unsigned long, float, double) = NULL;
301 	float * pfAudioInputL;
302 	float * pfAudioOutputL;
303 	float * pfAudioOutputR;
304 	float In,Out1,Out2,OutL,OutR;
305 	float LPF1,LPF2,HPF1,HPF2,Degrain1,Degrain2;
306 	float EnvIn,EnvOutL,EnvOutR;
307 	float fBypass,fMode,fMunge,fMungeMode,fHPFsamples,fLPFsamples,fAngle,fAngleDelta,fLFO;
308 	float f1Delay,f1DelayOffset,fLFOsamp1,fActualDelay1;
309 	float f2Delay,f2DelayOffset,fLFOsamp2,fActualDelay2;
310 	float f1DelayDelta,f1DelayOld,f1DelayOffsetOld,fLFOsamp1Old,fActualDelay1Old;
311 	float f2DelayDelta,f2DelayOld,f2DelayOffsetOld,fLFOsamp2Old,fActualDelay2Old;
312 	float oldVol,newVol;
313 	float f1Vol,f1Pan,f1PanLGain,f1PanRGain,f1FBraw,f1FB,In1FB,In1FBmix,In1Munged;
314 	float f2Vol,f2Pan,f2PanLGain,f2PanRGain,f2FBraw,f2FB,In2FB,In2FBmix,In2Munged;
315 	double fMungeDelta,fLPFDelta,fHPFDelta,fCycleDelta,fWidthDelta,fFB1Delta,fPan1Delta,fVol1Delta,fFB2Delta,fPan2Delta,fVol2Delta;
316 	int   HasDelta,HasDelay1Old,HasDelay2Old;
317 	unsigned long l1DelaySample, l2DelaySample;
318 	unsigned long l1DelaySampleOld, l2DelaySampleOld;
319 	unsigned long lSampleIndex;
320 	unsigned long SpaceSize;
321 	float * SpaceLStr;
322 	float * SpaceRStr;
323 	float * SpaceLCur;
324 	float * SpaceRCur;
325 	float * SpaceLEnd;
326 	float * SpaceREnd;
327 
328 	IDelay *plugin = (IDelay *)instance;
329 	pParamFunc = &convertParam;
330 
331 	/* check if any other params have changed */
332 	checkParamChange(IDELAY_BYPASS,    plugin->ControlBypass,    &(plugin->LastBypass),    &(plugin->ConvertedBypass),    plugin->SampleRate, pParamFunc);
333 	checkParamChange(IDELAY_MODE,      plugin->ControlMode,      &(plugin->LastMode),      &(plugin->ConvertedMode),      plugin->SampleRate, pParamFunc);
334 	checkParamChange(IDELAY_MUNGEMODE, plugin->ControlMungeMode, &(plugin->LastMungeMode), &(plugin->ConvertedMungeMode), plugin->SampleRate, pParamFunc);
335 
336 	fMungeDelta  = getParamChange(IDELAY_MUNGE,     plugin->ControlMunge,  &(plugin->LastMunge),  &(plugin->ConvertedMunge),  plugin->SampleRate, pParamFunc);
337 	fCycleDelta  = getParamChange(IDELAY_LFO_CYCLE, plugin->ControlCycle,  &(plugin->LastCycle),  &(plugin->ConvertedCycle),  plugin->SampleRate, pParamFunc);
338 	fWidthDelta  = getParamChange(IDELAY_LFO_WIDTH, plugin->ControlWidth,  &(plugin->LastWidth),  &(plugin->ConvertedWidth),  plugin->SampleRate, pParamFunc);
339 	f1DelayDelta = getParamChange(IDELAY_1_DELAY,   plugin->Control1Delay, &(plugin->Last1Delay), &(plugin->Converted1Delay), plugin->SampleRate, pParamFunc);
340 	fFB1Delta    = getParamChange(IDELAY_1_FB,      plugin->Control1FB,    &(plugin->Last1FB),    &(plugin->Converted1FB),    plugin->SampleRate, pParamFunc);
341 	fPan1Delta   = getParamChange(IDELAY_1_PAN,     plugin->Control1Pan,   &(plugin->Last1Pan),   &(plugin->Converted1Pan),   plugin->SampleRate, pParamFunc);
342 	fVol1Delta   = getParamChange(IDELAY_1_VOL,     plugin->Control1Vol,   &(plugin->Last1Vol),   &(plugin->Converted1Vol),   plugin->SampleRate, pParamFunc);
343 	f2DelayDelta = getParamChange(IDELAY_2_DELAY,   plugin->Control2Delay, &(plugin->Last2Delay), &(plugin->Converted2Delay), plugin->SampleRate, pParamFunc);
344 	fFB2Delta    = getParamChange(IDELAY_2_FB,      plugin->Control2FB,    &(plugin->Last2FB),    &(plugin->Converted2FB),    plugin->SampleRate, pParamFunc);
345 	fPan2Delta   = getParamChange(IDELAY_2_PAN,     plugin->Control2Pan,   &(plugin->Last2Pan),   &(plugin->Converted2Pan),   plugin->SampleRate, pParamFunc);
346 	fVol2Delta   = getParamChange(IDELAY_2_VOL,     plugin->Control2Vol,   &(plugin->Last2Vol),   &(plugin->Converted2Vol),   plugin->SampleRate, pParamFunc);
347 
348 	fBypass         = plugin->ConvertedBypass;
349 	fMode           = plugin->ConvertedMode;
350 	fMungeMode	= plugin->ConvertedMungeMode;
351 
352 	if(fMungeDelta==0 && fCycleDelta == 0 && fWidthDelta==0 && fFB1Delta==0 && fFB2Delta==0 && fPan1Delta==0 && fPan2Delta==0 && fVol1Delta==0 && fVol2Delta==0) {
353 		HasDelta=0;
354 		fMunge		= plugin->ConvertedMunge;
355 		fLPFDelta	= 0.0;
356 		fHPFDelta	= 0.0;
357 		fLPFsamples	= plugin->ConvertedLPFsamples;
358 		fHPFsamples	= plugin->ConvertedHPFsamples;
359 		fAngleDelta	= plugin->ConvertedCycle;
360 		fLFO		= plugin->ConvertedWidth;
361 		f1FBraw		= plugin->Converted1FB;
362 		f1Pan		= plugin->Converted1Pan;
363 		f1Vol		= plugin->Converted1Vol;
364 		f2FBraw		= plugin->Converted2FB;
365 		f2Pan		= plugin->Converted2Pan;
366 		f2Vol		= plugin->Converted2Vol;
367 	} else {
368 		HasDelta	= 1;
369 		fMunge		= plugin->ConvertedMunge - fMungeDelta;
370 		if(fMungeDelta == 0) {
371 			fLPFDelta			= 0.0;
372 			fHPFDelta			= 0.0;
373 		} else {
374 			// this is a bit wonky i know but creating varibles for the old values and then calculating the delta with new-old doesn't save any cpu
375 			fLPFDelta			= -plugin->ConvertedLPFsamples;
376 			fHPFDelta			= -plugin->ConvertedHPFsamples;
377 			plugin->ConvertedLPFsamples	= convertMunge(0, plugin->LastMunge, plugin->SampleRate);
378 			plugin->ConvertedHPFsamples	= convertMunge(1, plugin->LastMunge, plugin->SampleRate);
379 			fLPFDelta			+= plugin->ConvertedLPFsamples;
380 			fHPFDelta			+= plugin->ConvertedHPFsamples;
381 		}
382 		fLPFsamples	= plugin->ConvertedLPFsamples	- fLPFDelta;
383 		fHPFsamples	= plugin->ConvertedHPFsamples 	- fHPFDelta;
384 		fAngleDelta	= plugin->ConvertedCycle 	- fCycleDelta;
385 		fLFO		= plugin->ConvertedWidth 	- fWidthDelta;
386 		f1FBraw		= plugin->Converted1FB   	- fFB1Delta;
387 		f1Pan		= plugin->Converted1Pan  	- fPan1Delta;
388 		f1Vol		= plugin->Converted1Vol  	- fVol1Delta;
389 		f2FBraw		= plugin->Converted2FB   	- fFB2Delta;
390 		f2Pan		= plugin->Converted2Pan  	- fPan2Delta;
391 		f2Vol		= plugin->Converted2Vol  	- fVol2Delta;
392 		if(SampleCount > 0) {
393 			/* these are the incements to use in the run loop */
394 			fLPFDelta    = fLPFDelta/(float)SampleCount;
395 			fHPFDelta    = fHPFDelta/(float)SampleCount;
396 			fMungeDelta  = fMungeDelta/(float)SampleCount;
397 			fCycleDelta  = fCycleDelta/(float)SampleCount;
398 			fWidthDelta  = fWidthDelta/(float)SampleCount;
399 			fFB1Delta    = fFB1Delta/(float)SampleCount;
400 			fPan1Delta   = fPan1Delta/(float)SampleCount;
401 			fVol1Delta   = fVol1Delta/(float)SampleCount;
402 			fFB2Delta    = fFB2Delta/(float)SampleCount;
403 			fPan2Delta   = fPan2Delta/(float)SampleCount;
404 			fVol2Delta   = fVol2Delta/(float)SampleCount;
405 		}
406 	}
407 
408 	if(f1DelayDelta==0.0) {
409 		HasDelay1Old	= 0;
410 		f1Delay		= plugin->Converted1Delay;
411 		l1DelaySample	= (unsigned long)f1Delay;
412 		f1DelayOffset	= f1Delay-(float)l1DelaySample;
413 		fLFOsamp1	= fLFO * f1Delay;
414 		f1DelayOld	= 0.0;
415 		l1DelaySampleOld= 0;
416 		f1DelayOffsetOld= 0.0;
417 		fLFOsamp1Old	= 0.0;
418 	} else {
419 		HasDelay1Old	= 1;
420 		f1Delay		= plugin->Converted1Delay;
421 		l1DelaySample	= (unsigned long)f1Delay;
422 		f1DelayOffset	= f1Delay-(float)l1DelaySample;
423 		fLFOsamp1	= fLFO * f1Delay;
424 		f1DelayOld	= plugin->Converted1Delay-f1DelayDelta;
425 		l1DelaySampleOld= (unsigned long)f1DelayOld;
426 		f1DelayOffsetOld= f1DelayOld-(float)l1DelaySampleOld;
427 		fLFOsamp1Old	= fLFO * f1DelayOld;
428 	}
429 
430 	if(f2DelayDelta==0.0) {
431 		HasDelay2Old	= 0;
432 		f2Delay		= plugin->Converted2Delay;
433 		l2DelaySample	= (unsigned long)f2Delay;
434 		f2DelayOffset	= f2Delay-(float)l2DelaySample;
435 		fLFOsamp2	= fLFO * f2Delay;
436 		f2DelayOld	= 0.0;
437 		l2DelaySampleOld= 0;
438 		f2DelayOffsetOld= 0.0;
439 		fLFOsamp2Old	= 0.0;
440 	} else {
441 		HasDelay2Old	= 1;
442 		f2Delay		= plugin->Converted2Delay;
443 		l2DelaySample	= (unsigned long)f2Delay;
444 		f2DelayOffset	= f2Delay-(float)l2DelaySample;
445 		fLFOsamp2	= fLFO * f2Delay;
446 		f2DelayOld	= plugin->Converted2Delay-f2DelayDelta;
447 		l2DelaySampleOld= (unsigned long)f2DelayOld;
448 		f2DelayOffsetOld= f2DelayOld-(float)l2DelaySampleOld;
449 		fLFOsamp2Old	= fLFO * f2DelayOld;
450 	}
451 	oldVol=0.0;
452 	newVol=1.0;
453 
454 	f1PanLGain	= f1Vol * (1-f1Pan)/2;
455 	f1PanRGain	= f1Vol * (1+f1Pan)/2;
456 	f2PanLGain	= f2Vol * (1-f2Pan)/2;
457 	f2PanRGain	= f2Vol * (1+f2Pan)/2;
458 	if(fMungeMode < 0.5) {
459 		f1FB	= f1FBraw / (1+fMunge);
460 		f2FB	= f2FBraw / (1+fMunge);
461 	} else {
462 		f1FB	= f1FBraw * pow(2.0,-2.0*fMunge);
463 		f2FB	= f2FBraw * pow(2.0,-2.0*fMunge);
464 	}
465 
466 	SpaceSize 	= plugin->SpaceSize;
467 
468 	SpaceLStr	= plugin->SpaceL;
469 	SpaceRStr 	= plugin->SpaceR;
470 	SpaceLCur 	= plugin->SpaceLCur;
471 	SpaceRCur 	= plugin->SpaceRCur;
472 	SpaceLEnd 	= plugin->SpaceLEnd;
473 	SpaceREnd 	= plugin->SpaceREnd;
474 
475 	pfAudioInputL 	= plugin->AudioInputBufferL;
476 	pfAudioOutputL 	= plugin->AudioOutputBufferL;
477 	pfAudioOutputR 	= plugin->AudioOutputBufferR;
478 
479 	fAngle     	= plugin->LFOAngle;
480 	LPF1     	= plugin->AudioLPF1;
481 	LPF2     	= plugin->AudioLPF2;
482 	HPF1     	= plugin->AudioHPF1;
483 	HPF2     	= plugin->AudioHPF2;
484 	Degrain1     	= plugin->AudioDegrain1;
485 	Degrain2     	= plugin->AudioDegrain2;
486 	EnvIn     	= plugin->EnvInLLast;
487 	EnvOutL    	= plugin->EnvOutLLast;
488 	EnvOutR   	= plugin->EnvOutRLast;
489 
490 	if(fBypass==0) {
491 		for (lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++) {
492 
493 			if(HasDelay1Old==1 || HasDelay2Old==1) {
494 				newVol = (float)lSampleIndex/(float)SampleCount;               // 0 -> 1
495 				oldVol = (float)(SampleCount-lSampleIndex)/(float)SampleCount; // 1 -> 0
496 			}
497 
498 			// read the audio out of the delay space
499 			Out1 = *(SpaceLCur);
500 			Out2 = *(SpaceRCur);
501 
502 			// read the input
503 			In = *(pfAudioInputL++);
504 
505 			// and mix the feedback in
506 			if(fMode<0.5 ) {
507 				// normal
508 				In1FBmix= In+(f1FB*Out1);
509 				In2FBmix= In+(f2FB*Out2);
510 			} else {
511  				//ping pong
512 				In1FBmix= In+(f2FB*Out2);
513 				In2FBmix= In+(f1FB*Out1);
514 			}
515 
516 			// munge it
517 			In1FB	= (1-fMunge)*In1FBmix + fMunge*ITube_do(In1FBmix,1+fMunge);
518 			In2FB	= (1-fMunge)*In2FBmix + fMunge*ITube_do(In2FBmix,1+fMunge);
519 			HPF1 	= ((fHPFsamples-1) * HPF1 + In1FB) / fHPFsamples;
520 			HPF2 	= ((fHPFsamples-1) * HPF2 + In2FB) / fHPFsamples;
521 			LPF1 	= ((fLPFsamples-1) * LPF1 + (In1FB-HPF1)) / fLPFsamples;
522 			LPF2 	= ((fLPFsamples-1) * LPF2 + (In2FB-HPF2)) / fLPFsamples;
523 			if(fMungeMode<0.5) {
524 				In1Munged = LPF1;
525 				In2Munged = LPF2;
526 			} else {
527 				In1Munged = 2 * (In1FB-HPF1) - LPF1;
528 				In2Munged = 2 * (In2FB-HPF2) - LPF2;
529 			}
530 			Degrain1     	= (In1Munged+(2*Degrain1))/3;
531 			Degrain2     	= (In2Munged+(2*Degrain2))/3;
532 
533 			// LFO
534 			if(fLFO > 0) {
535 				fActualDelay1	= f1Delay + (fLFOsamp1 * cos(fAngle));
536 				l1DelaySample	= (unsigned long)fActualDelay1;
537 				f1DelayOffset	= fActualDelay1-(float)l1DelaySample;
538 
539 				fActualDelay2	= f2Delay + (fLFOsamp2 * cos(fAngle));
540 				l2DelaySample	= (unsigned long)fActualDelay2;
541 				f2DelayOffset	= fActualDelay2-(float)l2DelaySample;
542 
543 				if(HasDelay1Old==1) {
544 					fActualDelay1Old	= f1DelayOld + (fLFOsamp1Old * cos(fAngle));
545 					l1DelaySampleOld	= (unsigned long)fActualDelay1Old;
546 					f1DelayOffsetOld	= fActualDelay1Old-(float)l1DelaySampleOld;
547 				}
548 				if(HasDelay2Old==1) {
549 					fActualDelay2Old	= f2DelayOld + (fLFOsamp2Old * cos(fAngle));
550 					l2DelaySampleOld	= (unsigned long)fActualDelay2Old;
551 					f2DelayOffsetOld	= fActualDelay2Old-(float)l2DelaySampleOld;
552 				}
553 
554 				fAngle += fAngleDelta;
555 			}
556 
557 			// add to the delay space
558 			if(HasDelay1Old==0) {
559 				SpaceAdd(SpaceLCur, SpaceLEnd, SpaceSize, l1DelaySample,    f1DelayOffset,    Degrain1);
560 			} else {
561 				SpaceAdd(SpaceLCur, SpaceLEnd, SpaceSize, l1DelaySample,    f1DelayOffset,    newVol*Degrain1);
562 				SpaceAdd(SpaceLCur, SpaceLEnd, SpaceSize, l1DelaySampleOld, f1DelayOffsetOld, oldVol*Degrain1);
563 
564 			}
565 
566 			if(HasDelay2Old==0) {
567 				SpaceAdd(SpaceRCur, SpaceREnd, SpaceSize, l2DelaySample,    f2DelayOffset,    Degrain2);
568 			} else {
569 				SpaceAdd(SpaceRCur, SpaceREnd, SpaceSize, l2DelaySample,    f2DelayOffset,    newVol*Degrain2);
570 				SpaceAdd(SpaceLCur, SpaceLEnd, SpaceSize, l2DelaySampleOld, f2DelayOffsetOld, oldVol*Degrain2);
571 
572 			}
573 
574 			// mix the two delays in
575 			OutL = f1PanLGain*Out1 + f2PanLGain*Out2;
576 			OutR = f1PanRGain*Out1 + f2PanRGain*Out2;
577 			// write the output
578 			*(pfAudioOutputL++) = OutL;
579 			*(pfAudioOutputR++) = OutR;
580 			// zero the spot we just read
581 			*(SpaceLCur)=0;
582 			*(SpaceRCur)=0;
583 			// advance the pointer to the next spot
584 			SpaceLCur = SpaceLCur < SpaceLEnd ? SpaceLCur + 1 : SpaceLStr;
585 			SpaceRCur = SpaceRCur < SpaceREnd ? SpaceRCur + 1 : SpaceRStr;
586 
587 			//evelope on in and out for meters
588 			EnvIn  		+= applyIEnvelope(&plugin->EnvAD[INVADA_METER_PEAK], In,   EnvIn);
589 			EnvOutL  	+= applyIEnvelope(&plugin->EnvAD[INVADA_METER_PEAK], OutL, EnvOutL);
590 			EnvOutR  	+= applyIEnvelope(&plugin->EnvAD[INVADA_METER_PEAK], OutR, EnvOutR);
591 
592 			//update any changing parameters
593 			if(HasDelta==1) {
594 				fMunge	    += fMungeDelta;
595 				fLPFsamples += fLPFDelta;
596 				fHPFsamples += fHPFDelta;
597 				fAngleDelta += fCycleDelta;
598 				fLFO	    += fWidthDelta;
599 				f1FBraw	    += fFB1Delta;
600 				f1Pan	    += fPan1Delta;
601 				f1Vol	    += fVol1Delta;
602 				f2FBraw	    += fFB2Delta;
603 				f2Pan	    += fPan2Delta;
604 				f2Vol	    += fVol2Delta;
605 
606 				fLFOsamp1	= fLFO * f1Delay;
607 				fLFOsamp2	= fLFO * f2Delay;
608 				f1PanLGain	= f1Vol * (1-f1Pan)/2;
609 				f1PanRGain	= f1Vol * (1+f1Pan)/2;
610 				f2PanLGain	= f2Vol * (1-f2Pan)/2;
611 				f2PanRGain	= f2Vol * (1+f2Pan)/2;
612 
613 				if(fMungeMode < 0.5) {
614 					f1FB	= f1FBraw / (1+fMunge);
615 					f2FB	= f2FBraw / (1+fMunge);
616 				} else {
617 					f1FB	= f1FBraw * pow(2.0,-2.0*fMunge);
618 					f2FB	= f2FBraw * pow(2.0,-2.0*fMunge);
619 				}
620 
621 				if(HasDelay1Old==1) {
622 					fLFOsamp1Old	= fLFO * f1DelayOld;
623 				}
624 
625 				if(HasDelay2Old==1) {
626 					fLFOsamp2Old	= fLFO * f2DelayOld;
627 				}
628 			}
629 		}
630 	} else {
631 		for (lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++) {
632 
633 			*(pfAudioOutputL++) = *pfAudioInputL;
634 			*(pfAudioOutputR++) = *(pfAudioInputL++);
635 			// zero the spot we just read
636 			*(SpaceLCur)=0;
637 			*(SpaceRCur)=0;
638 			// advance the pointer to the next spot
639 			SpaceLCur = SpaceLCur < SpaceLEnd ? SpaceLCur + 1 : SpaceLStr;
640 			SpaceRCur = SpaceRCur < SpaceREnd ? SpaceRCur + 1 : SpaceRStr;
641 		}
642 		//zero filters
643 		LPF1    =0;
644 		LPF2    =0;
645 		HPF1    =0;
646 		HPF2    =0;
647 		Degrain1    =0;
648 		Degrain2    =0;
649 		//zero envelope on in and out for meters
650 		EnvIn   =0;
651 		EnvOutL =0;
652 		EnvOutR =0;
653 	}
654 	if(fLFO > 0) {
655 		while(fAngle > PI_2) {
656 			fAngle -= PI_2;
657 		}
658 	} else {
659 		fAngle=0;
660 	}
661 
662 	// remember for next run
663 	plugin->SpaceLCur=SpaceLCur;
664 	plugin->SpaceRCur=SpaceRCur;
665 
666 	plugin->LFOAngle    = fAngle;
667 	plugin->AudioLPF1   = (fabs(LPF1)<1.0e-10)     ? 0.f : LPF1;
668 	plugin->AudioLPF2   = (fabs(LPF2)<1.0e-10)     ? 0.f : LPF2;
669 	plugin->AudioHPF1   = (fabs(HPF1)<1.0e-10)     ? 0.f : HPF1;
670 	plugin->AudioHPF2   = (fabs(HPF2)<1.0e-10)     ? 0.f : HPF2;
671 	plugin->AudioDegrain1   = (fabs(Degrain1)<1.0e-10)     ? 0.f : Degrain1;
672 	plugin->AudioDegrain2   = (fabs(Degrain2)<1.0e-10)     ? 0.f : Degrain2;
673 	plugin->EnvInLLast  = (fabs(EnvIn)<1.0e-10)    ? 0.f : EnvIn;
674 	plugin->EnvOutLLast = (fabs(EnvOutL)<1.0e-10)  ? 0.f : EnvOutL;
675 	plugin->EnvOutRLast = (fabs(EnvOutR)<1.0e-10)  ? 0.f : EnvOutR;
676 
677 	// update the meters
678 	*(plugin->LampLFO)      = 1.75*(1-(cos(fAngle)));
679 	*(plugin->MeterInputL)  = (EnvIn   > 0.001) ? 20*log10(EnvIn)   : -90.0;
680 	*(plugin->MeterOutputL) = (EnvOutL > 0.001) ? 20*log10(EnvOutL) : -90.0;
681 	*(plugin->MeterOutputR) = (EnvOutR > 0.001) ? 20*log10(EnvOutR) : -90.0;
682 }
683 
684 
685 
686 
687 static void
runSumIDelay(LV2_Handle instance,uint32_t SampleCount)688 runSumIDelay(LV2_Handle instance, uint32_t SampleCount)
689 {
690 	float (*pParamFunc)(unsigned long, float, double) = NULL;
691 	float * pfAudioInputL;
692 	float * pfAudioInputR;
693 	float * pfAudioOutputL;
694 	float * pfAudioOutputR;
695 	float In,Out1,Out2,OutL,OutR;
696 	float LPF1,LPF2,HPF1,HPF2,Degrain1,Degrain2;
697 	float EnvIn,EnvOutL,EnvOutR;
698 	float fBypass,fMode,fMunge,fMungeMode,fHPFsamples,fLPFsamples,fAngle,fAngleDelta,fLFO;
699 	float f1Delay,f1DelayOffset,fLFOsamp1,fActualDelay1;
700 	float f2Delay,f2DelayOffset,fLFOsamp2,fActualDelay2;
701 	float f1DelayDelta,f1DelayOld,f1DelayOffsetOld,fLFOsamp1Old,fActualDelay1Old;
702 	float f2DelayDelta,f2DelayOld,f2DelayOffsetOld,fLFOsamp2Old,fActualDelay2Old;
703 	float oldVol,newVol;
704 	float f1Vol,f1Pan,f1PanLGain,f1PanRGain,f1FBraw,f1FB,In1FB,In1FBmix,In1Munged;
705 	float f2Vol,f2Pan,f2PanLGain,f2PanRGain,f2FBraw,f2FB,In2FB,In2FBmix,In2Munged;
706 	double fMungeDelta,fLPFDelta,fHPFDelta,fCycleDelta,fWidthDelta,fFB1Delta,fPan1Delta,fVol1Delta,fFB2Delta,fPan2Delta,fVol2Delta;
707 	int   HasDelta,HasDelay1Old,HasDelay2Old;
708 	unsigned long l1DelaySample, l2DelaySample;
709 	unsigned long l1DelaySampleOld, l2DelaySampleOld;
710 	unsigned long lSampleIndex;
711 	unsigned long SpaceSize;
712 
713 	float * SpaceLStr;
714 	float * SpaceRStr;
715 	float * SpaceLCur;
716 	float * SpaceRCur;
717 	float * SpaceLEnd;
718 	float * SpaceREnd;
719 
720 	IDelay *plugin = (IDelay *)instance;
721 	pParamFunc = &convertParam;
722 
723 	/* check if any other params have changed */
724 	checkParamChange(IDELAY_BYPASS,    plugin->ControlBypass,    &(plugin->LastBypass),    &(plugin->ConvertedBypass),    plugin->SampleRate, pParamFunc);
725 	checkParamChange(IDELAY_MODE,      plugin->ControlMode,      &(plugin->LastMode),      &(plugin->ConvertedMode),      plugin->SampleRate, pParamFunc);
726 	checkParamChange(IDELAY_MUNGEMODE, plugin->ControlMungeMode, &(plugin->LastMungeMode), &(plugin->ConvertedMungeMode), plugin->SampleRate, pParamFunc);
727 
728 	fMungeDelta  = getParamChange(IDELAY_MUNGE,     plugin->ControlMunge,  &(plugin->LastMunge),  &(plugin->ConvertedMunge),  plugin->SampleRate, pParamFunc);
729 	fCycleDelta  = getParamChange(IDELAY_LFO_CYCLE, plugin->ControlCycle,  &(plugin->LastCycle),  &(plugin->ConvertedCycle),  plugin->SampleRate, pParamFunc);
730 	fWidthDelta  = getParamChange(IDELAY_LFO_WIDTH, plugin->ControlWidth,  &(plugin->LastWidth),  &(plugin->ConvertedWidth),  plugin->SampleRate, pParamFunc);
731 	f1DelayDelta = getParamChange(IDELAY_1_DELAY,   plugin->Control1Delay, &(plugin->Last1Delay), &(plugin->Converted1Delay), plugin->SampleRate, pParamFunc);
732 	fFB1Delta    = getParamChange(IDELAY_1_FB,      plugin->Control1FB,    &(plugin->Last1FB),    &(plugin->Converted1FB),    plugin->SampleRate, pParamFunc);
733 	fPan1Delta   = getParamChange(IDELAY_1_PAN,     plugin->Control1Pan,   &(plugin->Last1Pan),   &(plugin->Converted1Pan),   plugin->SampleRate, pParamFunc);
734 	fVol1Delta   = getParamChange(IDELAY_1_VOL,     plugin->Control1Vol,   &(plugin->Last1Vol),   &(plugin->Converted1Vol),   plugin->SampleRate, pParamFunc);
735 	f2DelayDelta = getParamChange(IDELAY_2_DELAY,   plugin->Control2Delay, &(plugin->Last2Delay), &(plugin->Converted2Delay), plugin->SampleRate, pParamFunc);
736 	fFB2Delta    = getParamChange(IDELAY_2_FB,      plugin->Control2FB,    &(plugin->Last2FB),    &(plugin->Converted2FB),    plugin->SampleRate, pParamFunc);
737 	fPan2Delta   = getParamChange(IDELAY_2_PAN,     plugin->Control2Pan,   &(plugin->Last2Pan),   &(plugin->Converted2Pan),   plugin->SampleRate, pParamFunc);
738 	fVol2Delta   = getParamChange(IDELAY_2_VOL,     plugin->Control2Vol,   &(plugin->Last2Vol),   &(plugin->Converted2Vol),   plugin->SampleRate, pParamFunc);
739 
740 	fBypass         = plugin->ConvertedBypass;
741 	fMode           = plugin->ConvertedMode;
742 	fMungeMode	= plugin->ConvertedMungeMode;
743 
744 	if(fMungeDelta==0 && fCycleDelta == 0 && fWidthDelta==0 && fFB1Delta==0 && fFB2Delta==0 && fPan1Delta==0 && fPan2Delta==0 && fVol1Delta==0 && fVol2Delta==0) {
745 		HasDelta=0;
746 		fMunge		= plugin->ConvertedMunge;
747 		fLPFDelta	= 0.0;
748 		fHPFDelta	= 0.0;
749 		fLPFsamples	= plugin->ConvertedLPFsamples;
750 		fHPFsamples	= plugin->ConvertedHPFsamples;
751 		fAngleDelta	= plugin->ConvertedCycle;
752 		fLFO		= plugin->ConvertedWidth;
753 		f1FBraw		= plugin->Converted1FB;
754 		f1Pan		= plugin->Converted1Pan;
755 		f1Vol		= plugin->Converted1Vol;
756 		f2FBraw		= plugin->Converted2FB;
757 		f2Pan		= plugin->Converted2Pan;
758 		f2Vol		= plugin->Converted2Vol;
759 	} else {
760 		HasDelta	= 1;
761 		fMunge		= plugin->ConvertedMunge - fMungeDelta;
762 		if(fMungeDelta == 0) {
763 			fLPFDelta			= 0.0;
764 			fHPFDelta			= 0.0;
765 		} else {
766 			// this is a bit wonky i know but creating varibles for the old values and then calculating the delta with new-old doesn't save any cpu
767 			fLPFDelta			= -plugin->ConvertedLPFsamples;
768 			fHPFDelta			= -plugin->ConvertedHPFsamples;
769 			plugin->ConvertedLPFsamples	= convertMunge(0, plugin->LastMunge, plugin->SampleRate);
770 			plugin->ConvertedHPFsamples	= convertMunge(1, plugin->LastMunge, plugin->SampleRate);
771 			fLPFDelta			+= plugin->ConvertedLPFsamples;
772 			fHPFDelta			+= plugin->ConvertedHPFsamples;
773 		}
774 		fLPFsamples	= plugin->ConvertedLPFsamples	- fLPFDelta;
775 		fHPFsamples	= plugin->ConvertedHPFsamples 	- fHPFDelta;
776 		fAngleDelta	= plugin->ConvertedCycle 	- fCycleDelta;
777 		fLFO		= plugin->ConvertedWidth 	- fWidthDelta;
778 		f1FBraw		= plugin->Converted1FB   	- fFB1Delta;
779 		f1Pan		= plugin->Converted1Pan  	- fPan1Delta;
780 		f1Vol		= plugin->Converted1Vol  	- fVol1Delta;
781 		f2FBraw		= plugin->Converted2FB   	- fFB2Delta;
782 		f2Pan		= plugin->Converted2Pan  	- fPan2Delta;
783 		f2Vol		= plugin->Converted2Vol  	- fVol2Delta;
784 		if(SampleCount > 0) {
785 			/* these are the incements to use in the run loop */
786 			fLPFDelta    = fLPFDelta/(float)SampleCount;
787 			fHPFDelta    = fHPFDelta/(float)SampleCount;
788 			fMungeDelta  = fMungeDelta/(float)SampleCount;
789 			fCycleDelta  = fCycleDelta/(float)SampleCount;
790 			fWidthDelta  = fWidthDelta/(float)SampleCount;
791 			fFB1Delta    = fFB1Delta/(float)SampleCount;
792 			fPan1Delta   = fPan1Delta/(float)SampleCount;
793 			fVol1Delta   = fVol1Delta/(float)SampleCount;
794 			fFB2Delta    = fFB2Delta/(float)SampleCount;
795 			fPan2Delta   = fPan2Delta/(float)SampleCount;
796 			fVol2Delta   = fVol2Delta/(float)SampleCount;
797 		}
798 	}
799 
800 	if(f1DelayDelta==0.0) {
801 		HasDelay1Old	= 0;
802 		f1Delay		= plugin->Converted1Delay;
803 		l1DelaySample	= (unsigned long)f1Delay;
804 		f1DelayOffset	= f1Delay-(float)l1DelaySample;
805 		fLFOsamp1	= fLFO * f1Delay;
806 		f1DelayOld	= 0.0;
807 		l1DelaySampleOld= 0;
808 		f1DelayOffsetOld= 0.0;
809 		fLFOsamp1Old	= 0.0;
810 	} else {
811 		HasDelay1Old	= 1;
812 		f1Delay		= plugin->Converted1Delay;
813 		l1DelaySample	= (unsigned long)f1Delay;
814 		f1DelayOffset	= f1Delay-(float)l1DelaySample;
815 		fLFOsamp1	= fLFO * f1Delay;
816 		f1DelayOld	= plugin->Converted1Delay-f1DelayDelta;
817 		l1DelaySampleOld= (unsigned long)f1DelayOld;
818 		f1DelayOffsetOld= f1DelayOld-(float)l1DelaySampleOld;
819 		fLFOsamp1Old	= fLFO * f1DelayOld;
820 	}
821 
822 	if(f2DelayDelta==0.0) {
823 		HasDelay2Old	= 0;
824 		f2Delay		= plugin->Converted2Delay;
825 		l2DelaySample	= (unsigned long)f2Delay;
826 		f2DelayOffset	= f2Delay-(float)l2DelaySample;
827 		fLFOsamp2	= fLFO * f2Delay;
828 		f2DelayOld	= 0.0;
829 		l2DelaySampleOld= 0;
830 		f2DelayOffsetOld= 0.0;
831 		fLFOsamp2Old	= 0.0;
832 	} else {
833 		HasDelay2Old	= 1;
834 		f2Delay		= plugin->Converted2Delay;
835 		l2DelaySample	= (unsigned long)f2Delay;
836 		f2DelayOffset	= f2Delay-(float)l2DelaySample;
837 		fLFOsamp2	= fLFO * f2Delay;
838 		f2DelayOld	= plugin->Converted2Delay-f2DelayDelta;
839 		l2DelaySampleOld= (unsigned long)f2DelayOld;
840 		f2DelayOffsetOld= f2DelayOld-(float)l2DelaySampleOld;
841 		fLFOsamp2Old	= fLFO * f2DelayOld;
842 	}
843 	oldVol=0.0;
844 	newVol=1.0;
845 
846 	f1PanLGain	= f1Vol * (1-f1Pan)/2;
847 	f1PanRGain	= f1Vol * (1+f1Pan)/2;
848 	f2PanLGain	= f2Vol * (1-f2Pan)/2;
849 	f2PanRGain	= f2Vol * (1+f2Pan)/2;
850 	if(fMungeMode < 0.5) {
851 		f1FB	= f1FBraw / (1+fMunge);
852 		f2FB	= f2FBraw / (1+fMunge);
853 	} else {
854 		f1FB	= f1FBraw * pow(2.0,-2.0*fMunge);
855 		f2FB	= f2FBraw * pow(2.0,-2.0*fMunge);
856 	}
857 
858 	SpaceSize 	= plugin->SpaceSize;
859 
860 	SpaceLStr	= plugin->SpaceL;
861 	SpaceRStr 	= plugin->SpaceR;
862 	SpaceLCur 	= plugin->SpaceLCur;
863 	SpaceRCur 	= plugin->SpaceRCur;
864 	SpaceLEnd 	= plugin->SpaceLEnd;
865 	SpaceREnd 	= plugin->SpaceREnd;
866 
867 	pfAudioInputL 	= plugin->AudioInputBufferL;
868 	pfAudioInputR 	= plugin->AudioInputBufferR;
869 	pfAudioOutputL 	= plugin->AudioOutputBufferL;
870 	pfAudioOutputR 	= plugin->AudioOutputBufferR;
871 
872 	fAngle     	= plugin->LFOAngle;
873 	LPF1     	= plugin->AudioLPF1;
874 	LPF2     	= plugin->AudioLPF2;
875 	HPF1     	= plugin->AudioHPF1;
876 	HPF2     	= plugin->AudioHPF2;
877 	Degrain1     	= plugin->AudioDegrain1;
878 	Degrain2     	= plugin->AudioDegrain2;
879 	EnvIn     	= plugin->EnvInLLast;
880 	EnvOutL    	= plugin->EnvOutLLast;
881 	EnvOutR   	= plugin->EnvOutRLast;
882 
883 	if(fBypass==0) {
884 		for (lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++) {
885 
886 			if(HasDelay1Old==1 || HasDelay2Old==1) {
887 				newVol = (float)lSampleIndex/(float)SampleCount;               // 0 -> 1
888 				oldVol = (float)(SampleCount-lSampleIndex)/(float)SampleCount; // 1 -> 0
889 			}
890 			// read the audio out of the delay space
891 			Out1 = *(SpaceLCur);
892 			Out2 = *(SpaceRCur);
893 
894 			// now read the input
895 			In=( *(pfAudioInputL++) + *(pfAudioInputR++) )/2;
896 
897 			// and mix the feedback in
898 			if(fMode<0.5 ) {
899 				// normal
900 				In1FBmix= In+(f1FB*Out1);
901 				In2FBmix= In+(f2FB*Out2);
902 			} else {
903  				//ping pong
904 				In1FBmix= In+(f2FB*Out2);
905 				In2FBmix= In+(f1FB*Out1);
906 			}
907 
908 			// munge it
909 			In1FB	= (1-fMunge)*In1FBmix + fMunge*ITube_do(In1FBmix,1+fMunge);
910 			In2FB	= (1-fMunge)*In2FBmix + fMunge*ITube_do(In2FBmix,1+fMunge);
911 			HPF1 = ((fHPFsamples-1) * HPF1 + In1FB) / fHPFsamples;
912 			HPF2 = ((fHPFsamples-1) * HPF2 + In2FB) / fHPFsamples;
913 			LPF1 = ((fLPFsamples-1) * LPF1 + (In1FB-HPF1)) / fLPFsamples;
914 			LPF2 = ((fLPFsamples-1) * LPF2 + (In2FB-HPF2)) / fLPFsamples;
915 			if(fMungeMode<0.5) {
916 				In1Munged = LPF1;
917 				In2Munged = LPF2;
918 			} else {
919 				In1Munged = 2 * (In1FB-HPF1) - LPF1;
920 				In2Munged = 2 * (In2FB-HPF2) - LPF2;
921 			}
922 			Degrain1     	= (In1Munged+(1.1*Degrain1))/2.1;
923 			Degrain2     	= (In2Munged+(1.1*Degrain2))/2.1;
924 
925 			//LFO
926 			if(fLFO > 0) {
927 				fActualDelay1	= f1Delay + (fLFOsamp1 * cos(fAngle));
928 				l1DelaySample	= (unsigned long)fActualDelay1;
929 				f1DelayOffset	= fActualDelay1-(float)l1DelaySample;
930 
931 				fActualDelay2	= f2Delay + (fLFOsamp2 * cos(fAngle));
932 				l2DelaySample	= (unsigned long)fActualDelay2;
933 				f2DelayOffset	= fActualDelay2-(float)l2DelaySample;
934 
935 				if(HasDelay1Old==1) {
936 					fActualDelay1Old	= f1DelayOld + (fLFOsamp1Old * cos(fAngle));
937 					l1DelaySampleOld	= (unsigned long)fActualDelay1Old;
938 					f1DelayOffsetOld	= fActualDelay1Old-(float)l1DelaySampleOld;
939 				}
940 				if(HasDelay2Old==1) {
941 					fActualDelay2Old	= f2DelayOld + (fLFOsamp2Old * cos(fAngle));
942 					l2DelaySampleOld	= (unsigned long)fActualDelay2Old;
943 					f2DelayOffsetOld	= fActualDelay2Old-(float)l2DelaySampleOld;
944 				}
945 
946 				fAngle += fAngleDelta;
947 			}
948 
949 			// add to the delay space
950 			if(HasDelay1Old==0) {
951 				SpaceAdd(SpaceLCur, SpaceLEnd, SpaceSize, l1DelaySample,    f1DelayOffset,    Degrain1);
952 			} else {
953 				SpaceAdd(SpaceLCur, SpaceLEnd, SpaceSize, l1DelaySample,    f1DelayOffset,    newVol*Degrain1);
954 				SpaceAdd(SpaceLCur, SpaceLEnd, SpaceSize, l1DelaySampleOld, f1DelayOffsetOld, oldVol*Degrain1);
955 
956 			}
957 
958 			if(HasDelay2Old==0) {
959 				SpaceAdd(SpaceRCur, SpaceREnd, SpaceSize, l2DelaySample,    f2DelayOffset,    Degrain2);
960 			} else {
961 				SpaceAdd(SpaceRCur, SpaceREnd, SpaceSize, l2DelaySample,    f2DelayOffset,    newVol*Degrain2);
962 				SpaceAdd(SpaceLCur, SpaceLEnd, SpaceSize, l2DelaySampleOld, f2DelayOffsetOld, oldVol*Degrain2);
963 
964 			}
965 
966 			// mix the two delays in
967 			OutL = f1PanLGain*Out1 + f2PanLGain*Out2;
968 			OutR = f1PanRGain*Out1 + f2PanRGain*Out2;
969 			// write the output
970 			*(pfAudioOutputL++) = OutL;
971 			*(pfAudioOutputR++) = OutR;
972 			// zero the spot we just read
973 			*(SpaceLCur)=0;
974 			*(SpaceRCur)=0;
975 			// advance the pointer to the next spot
976 			SpaceLCur = SpaceLCur < SpaceLEnd ? SpaceLCur + 1 : SpaceLStr;
977 			SpaceRCur = SpaceRCur < SpaceREnd ? SpaceRCur + 1 : SpaceRStr;
978 
979 			//evelope on in and out for meters
980 			EnvIn  		+= applyIEnvelope(&plugin->EnvAD[INVADA_METER_PEAK], In,   EnvIn);
981 			EnvOutL  	+= applyIEnvelope(&plugin->EnvAD[INVADA_METER_PEAK], OutL, EnvOutL);
982 			EnvOutR  	+= applyIEnvelope(&plugin->EnvAD[INVADA_METER_PEAK], OutR, EnvOutR);
983 
984 			//update any changing parameters
985 			if(HasDelta==1) {
986 				fMunge	    += fMungeDelta;
987 				fLPFsamples += fLPFDelta;
988 				fHPFsamples += fHPFDelta;
989 				fAngleDelta += fCycleDelta;
990 				fLFO	    += fWidthDelta;
991 				f1FBraw	    += fFB1Delta;
992 				f1Pan	    += fPan1Delta;
993 				f1Vol	    += fVol1Delta;
994 				f2FBraw	    += fFB2Delta;
995 				f2Pan	    += fPan2Delta;
996 				f2Vol	    += fVol2Delta;
997 
998 				fLFOsamp1	= fLFO * f1Delay;
999 				fLFOsamp2	= fLFO * f2Delay;
1000 				f1PanLGain	= f1Vol * (1-f1Pan)/2;
1001 				f1PanRGain	= f1Vol * (1+f1Pan)/2;
1002 				f2PanLGain	= f2Vol * (1-f2Pan)/2;
1003 				f2PanRGain	= f2Vol * (1+f2Pan)/2;
1004 
1005 				if(fMungeMode < 0.5) {
1006 					f1FB	= f1FBraw / (1+fMunge);
1007 					f2FB	= f2FBraw / (1+fMunge);
1008 				} else {
1009 					f1FB	= f1FBraw * pow(2.0,-2.0*fMunge);
1010 					f2FB	= f2FBraw * pow(2.0,-2.0*fMunge);
1011 				}
1012 
1013 				if(HasDelay1Old==1) {
1014 					fLFOsamp1Old	= fLFO * f1DelayOld;
1015 				}
1016 
1017 				if(HasDelay2Old==1) {
1018 					fLFOsamp2Old	= fLFO * f2DelayOld;
1019 				}
1020 			}
1021 		}
1022 	} else {
1023 		for (lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++) {
1024 
1025 			*(pfAudioOutputL++) = *pfAudioInputL;
1026 			*(pfAudioOutputR++) = *(pfAudioInputL++);
1027 			// zero the spot we just read
1028 			*(SpaceLCur)=0;
1029 			*(SpaceRCur)=0;
1030 			// advance the pointer to the next spot
1031 			SpaceLCur = SpaceLCur < SpaceLEnd ? SpaceLCur + 1 : SpaceLStr;
1032 			SpaceRCur = SpaceRCur < SpaceREnd ? SpaceRCur + 1 : SpaceRStr;
1033 		}
1034 		//zero filters
1035 		LPF1    =0;
1036 		LPF2    =0;
1037 		HPF1    =0;
1038 		HPF2    =0;
1039 		Degrain1    =0;
1040 		Degrain2    =0;
1041 		//zero envelope on in and out for meters
1042 		EnvIn   =0;
1043 		EnvOutL =0;
1044 		EnvOutR =0;
1045 	}
1046 	if(fLFO > 0) {
1047 		while(fAngle > PI_2) {
1048 			fAngle -= PI_2;
1049 		}
1050 	} else {
1051 		fAngle=0;
1052 	}
1053 
1054 	// remember for next run
1055 	plugin->SpaceLCur=SpaceLCur;
1056 	plugin->SpaceRCur=SpaceRCur;
1057 
1058 	plugin->LFOAngle    = fAngle;
1059 	plugin->AudioLPF1   = (fabs(LPF1)<1.0e-10)     ? 0.f : LPF1;
1060 	plugin->AudioLPF2   = (fabs(LPF2)<1.0e-10)     ? 0.f : LPF2;
1061 	plugin->AudioHPF1   = (fabs(HPF1)<1.0e-10)     ? 0.f : HPF1;
1062 	plugin->AudioHPF2   = (fabs(HPF2)<1.0e-10)     ? 0.f : HPF2;
1063 	plugin->AudioDegrain1   = (fabs(Degrain1)<1.0e-10)     ? 0.f : Degrain1;
1064 	plugin->AudioDegrain2   = (fabs(Degrain2)<1.0e-10)     ? 0.f : Degrain2;
1065 	plugin->EnvInLLast  = (fabs(EnvIn)<1.0e-10)    ? 0.f : EnvIn;
1066 	plugin->EnvOutLLast = (fabs(EnvOutL)<1.0e-10)  ? 0.f : EnvOutL;
1067 	plugin->EnvOutRLast = (fabs(EnvOutR)<1.0e-10)  ? 0.f : EnvOutR;
1068 
1069 	// update the meters
1070 	*(plugin->LampLFO)     = 1.75*(1-(cos(fAngle)));
1071 	*(plugin->MeterInputL) =(EnvIn   > 0.001) ? 20*log10(EnvIn)   : -90.0;
1072 	*(plugin->MeterOutputL)=(EnvOutL > 0.001) ? 20*log10(EnvOutL) : -90.0;
1073 	*(plugin->MeterOutputR)=(EnvOutR > 0.001) ? 20*log10(EnvOutR) : -90.0;
1074 }
1075 
1076 
1077 static void
cleanupIDelay(LV2_Handle instance)1078 cleanupIDelay(LV2_Handle instance)
1079 {
1080 	IDelay *plugin = (IDelay *)instance;
1081 
1082 	free(plugin->SpaceL);
1083 	free(plugin->SpaceR);
1084 	free(instance);
1085 }
1086 
1087 
1088 static void
init()1089 init()
1090 {
1091 	IDelayMonoDescriptor =
1092 	 (LV2_Descriptor *)malloc(sizeof(LV2_Descriptor));
1093 
1094 	IDelayMonoDescriptor->URI 		= IDELAY_MONO_URI;
1095 	IDelayMonoDescriptor->activate 	= activateIDelay;
1096 	IDelayMonoDescriptor->cleanup 		= cleanupIDelay;
1097 	IDelayMonoDescriptor->connect_port 	= connectPortIDelay;
1098 	IDelayMonoDescriptor->deactivate 	= NULL;
1099 	IDelayMonoDescriptor->instantiate 	= instantiateIDelay;
1100 	IDelayMonoDescriptor->run 		= runMonoIDelay;
1101 	IDelayMonoDescriptor->extension_data	= NULL;
1102 
1103 	IDelaySumDescriptor =
1104 	 (LV2_Descriptor *)malloc(sizeof(LV2_Descriptor));
1105 
1106 	IDelaySumDescriptor->URI 		= IDELAY_SUM_URI;
1107 	IDelaySumDescriptor->activate 		= activateIDelay;
1108 	IDelaySumDescriptor->cleanup 		= cleanupIDelay;
1109 	IDelaySumDescriptor->connect_port 	= connectPortIDelay;
1110 	IDelaySumDescriptor->deactivate 	= NULL;
1111 	IDelaySumDescriptor->instantiate 	= instantiateIDelay;
1112 	IDelaySumDescriptor->run 		= runSumIDelay;
1113 	IDelaySumDescriptor->extension_data	= NULL;
1114 
1115 }
1116 
1117 
1118 LV2_SYMBOL_EXPORT
lv2_descriptor(uint32_t index)1119 const LV2_Descriptor *lv2_descriptor(uint32_t index)
1120 {
1121 	if (!IDelayMonoDescriptor) init();
1122 
1123 	switch (index) {
1124 		case 0:
1125 			return IDelayMonoDescriptor;
1126 		case 1:
1127 			return IDelaySumDescriptor;
1128 
1129 		default:
1130 			return NULL;
1131 	}
1132 }
1133 
1134 
1135 /*****************************************************************************/
1136 
1137 float
convertParam(unsigned long param,float value,double sr)1138 convertParam(unsigned long param, float value, double sr) {
1139 	float result;
1140 
1141 	switch(param)
1142 	{
1143 		case IDELAY_BYPASS:
1144 		case IDELAY_MODE:
1145 		case IDELAY_MUNGEMODE:
1146 			if(value<=0.0)
1147 				result= 0;
1148 			else
1149 				result= 1;
1150 			break;
1151 		case IDELAY_MUNGE:
1152 			if(value<0)
1153 				result = 0.0;
1154 			else if (value < 100)
1155 				result = value/100.0;
1156 			else
1157 				result = 1.0;
1158 			break;
1159 		case IDELAY_LFO_CYCLE:
1160 			if (value < 2.0)
1161 				result = PI_2/(2.0*sr);
1162 			else if (value <= 200.0)
1163 				result = PI_2/(value * sr);
1164 			else
1165 				result = PI_2/(200.0 * sr);
1166 			break;
1167 		case IDELAY_1_DELAY:
1168 		case IDELAY_2_DELAY:
1169 			if (value < 0.02)
1170 				result = 0.02 * sr;
1171 			else if (value <= 2.0)
1172 				result = value * sr;
1173 			else
1174 				result = 2.0 * sr;
1175 			break;
1176 		case IDELAY_1_FB:
1177 		case IDELAY_2_FB:
1178 			if(value<0)
1179 				result = 0.0;
1180 			else if (value < 133.333333)
1181 				result = value/100.0;
1182 			else
1183 				result = 1.3333333;
1184 			break;
1185 		case IDELAY_1_PAN:
1186 		case IDELAY_2_PAN:
1187 			if(value<-1.0)
1188 				result = -1.0;
1189 			else if (value < 1.0)
1190 				result = value;
1191 			else
1192 				result = 1.0;
1193 			break;
1194 		case IDELAY_LFO_WIDTH:
1195 			if(value<0.0)
1196 				result = 0.0;
1197 			else if (value < 100.0)
1198 				result = value/400.0;
1199 			else
1200 				result = 0.25;
1201 			break;
1202 		case IDELAY_1_VOL:
1203 		case IDELAY_2_VOL:
1204 			if(value<0.0)
1205 				result = 0.0;
1206 			else if (value < 100.0)
1207 				result = value/100.0;
1208 			else
1209 				result = 1.0;
1210 			break;
1211 		default:
1212 			result=0;
1213 			break;
1214 	}
1215 	return result;
1216 }
1217 
1218 float
convertMunge(unsigned int mode,float munge,double sr)1219 convertMunge (unsigned int mode, float munge, double sr)
1220 {
1221 	float result;
1222 	switch(mode) {
1223 		case 0: //LPF
1224 			if (munge < 0)
1225 				result = sr/(2*pow(10,(4.34)));  //22kHz
1226 			else if (munge <= 100.0)
1227 				result = sr/(2*pow(10,(4.34-(munge*0.0074))));
1228 			else
1229 				result = sr/(2*pow(10,(3.60)));  //4kHz
1230 			break;
1231 		case 1: //HPF
1232 			if (munge < 0)
1233 				result = sr/(2*pow(10,(1.30)));  //20Hz
1234 			else if (munge <= 100.0)
1235 				result = sr/(2*pow(10,(1.30+(munge*0.0160))));
1236 			else
1237 				result = sr/(2*pow(10,(2.90)));  //800Hz
1238 			break;
1239 		default:
1240 			result=1;
1241 			break;
1242 	}
1243 	return result;
1244 }
1245 
1246 
1247