1 /*                                                     -*- linux-c -*-
2     Copyright (C) 2004 Tom Szilagyi
3 
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18     $Id: tap_doubler.c,v 1.4 2004/08/13 18:34:31 tszilagyi Exp $
19 */
20 
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <math.h>
26 #include <time.h>
27 
28 #include "ladspa.h"
29 #include "tap_utils.h"
30 
31 
32 /* The Unique ID of the plugin: */
33 
34 #define ID_STEREO       2156
35 
36 /* The port numbers for the plugin: */
37 
38 #define TIME            0
39 #define PITCH           1
40 #define DRYLEVEL        2
41 #define DRYPOSL         3
42 #define DRYPOSR         4
43 #define WETLEVEL        5
44 #define WETPOSL         6
45 #define WETPOSR         7
46 #define INPUT_L         8
47 #define INPUT_R         9
48 #define OUTPUT_L       10
49 #define OUTPUT_R       11
50 
51 /* Total number of ports */
52 
53 
54 #define PORTCOUNT_STEREO 12
55 
56 
57 /* Number of pink noise samples to be generated at once */
58 #define NOISE_LEN 1024
59 
60 /*
61  * Largest buffer length needed (at 192 kHz).
62  */
63 #define BUFLEN 11520
64 
65 
66 
67 /* The structure used to hold port connection information and state */
68 
69 typedef struct {
70 	LADSPA_Data * time;
71 	LADSPA_Data * pitch;
72 	LADSPA_Data * drylevel;
73 	LADSPA_Data * dryposl;
74 	LADSPA_Data * dryposr;
75 	LADSPA_Data * wetlevel;
76 	LADSPA_Data * wetposl;
77 	LADSPA_Data * wetposr;
78 	LADSPA_Data * input_L;
79 	LADSPA_Data * input_R;
80 	LADSPA_Data * output_L;
81 	LADSPA_Data * output_R;
82 
83 	LADSPA_Data old_time;
84 	LADSPA_Data old_pitch;
85 
86 	LADSPA_Data * ring_L;
87 	unsigned long buflen_L;
88 	unsigned long pos_L;
89 
90 	LADSPA_Data * ring_R;
91 	unsigned long buflen_R;
92 	unsigned long pos_R;
93 
94 	LADSPA_Data * ring_pnoise;
95 	unsigned long buflen_pnoise;
96 	unsigned long pos_pnoise;
97 
98 	LADSPA_Data * ring_dnoise;
99 	unsigned long buflen_dnoise;
100 	unsigned long pos_dnoise;
101 
102 	float delay;
103 	float d_delay;
104 	float p_delay;
105 	unsigned long n_delay;
106 
107 	float pitchmod;
108 	float d_pitch;
109 	float p_pitch;
110 	unsigned long n_pitch;
111 
112 	unsigned long p_stretch;
113 	unsigned long d_stretch;
114 
115 	unsigned long sample_rate;
116 	LADSPA_Data run_adding_gain;
117 } Doubler;
118 
119 
120 /* generate fractal pattern using Midpoint Displacement Method
121  * v: buffer of floats to output fractal pattern to
122  * N: length of v, MUST be integer power of 2 (ie 128, 256, ...)
123  * H: Hurst constant, between 0 and 0.9999 (fractal dimension)
124  */
125 void
fractal(LADSPA_Data * v,int N,float H)126 fractal(LADSPA_Data * v, int N, float H) {
127 
128         int l = N;
129         int k;
130         float r = 1.0f;
131         int c;
132 
133         v[0] = 0;
134         while (l > 1) {
135                 k = N / l;
136                 for (c = 0; c < k; c++) {
137                         v[c*l + l/2] = (v[c*l] + v[((c+1) * l) % N]) / 2.0f +
138                                 2.0f * r * (rand() - (float)RAND_MAX/2.0f) / (float)RAND_MAX;
139                         v[c*l + l/2] = LIMIT(v[c*l + l/2], -1.0f, 1.0f);
140                 }
141                 l /= 2;
142                 r /= powf(2, H);
143         }
144 }
145 
146 
147 
148 /* Construct a new plugin instance. */
149 LADSPA_Handle
instantiate_Doubler(const LADSPA_Descriptor * Descriptor,unsigned long sample_rate)150 instantiate_Doubler(const LADSPA_Descriptor * Descriptor,
151 		    unsigned long             sample_rate) {
152 
153         LADSPA_Handle * ptr;
154 
155 	if ((ptr = malloc(sizeof(Doubler))) != NULL) {
156 		((Doubler *)ptr)->sample_rate = sample_rate;
157 		((Doubler *)ptr)->run_adding_gain = 1.0f;
158 
159 		if ((((Doubler *)ptr)->ring_L =
160 		     calloc(BUFLEN * sample_rate / 192000, sizeof(LADSPA_Data))) == NULL)
161 			return NULL;
162 		((Doubler *)ptr)->buflen_L = BUFLEN * sample_rate / 192000;
163 		((Doubler *)ptr)->pos_L = 0;
164 
165 		if ((((Doubler *)ptr)->ring_R =
166 		     calloc(BUFLEN * sample_rate / 192000, sizeof(LADSPA_Data))) == NULL)
167 			return NULL;
168 		((Doubler *)ptr)->buflen_R = BUFLEN * sample_rate / 192000;
169 		((Doubler *)ptr)->pos_R = 0;
170 
171 		if ((((Doubler *)ptr)->ring_pnoise =
172 		     calloc(NOISE_LEN, sizeof(LADSPA_Data))) == NULL)
173 			return NULL;
174 		((Doubler *)ptr)->buflen_pnoise = NOISE_LEN;
175 		((Doubler *)ptr)->pos_pnoise = 0;
176 
177 		if ((((Doubler *)ptr)->ring_dnoise =
178 		     calloc(NOISE_LEN, sizeof(LADSPA_Data))) == NULL)
179 			return NULL;
180 		((Doubler *)ptr)->buflen_dnoise = NOISE_LEN;
181 		((Doubler *)ptr)->pos_dnoise = 0;
182 
183 		((Doubler *)ptr)->d_stretch = sample_rate / 10;
184 		((Doubler *)ptr)->p_stretch = sample_rate / 1000;
185 
186 		((Doubler *)ptr)->delay = 0.0f;
187 		((Doubler *)ptr)->d_delay = 0.0f;
188 		((Doubler *)ptr)->p_delay = 0.0f;
189 		((Doubler *)ptr)->n_delay = ((Doubler *)ptr)->d_stretch;
190 
191 		((Doubler *)ptr)->pitchmod = 0.0f;
192 		((Doubler *)ptr)->d_pitch = 0.0f;
193 		((Doubler *)ptr)->p_pitch = 0.0f;
194 		((Doubler *)ptr)->n_pitch = ((Doubler *)ptr)->p_stretch;
195 
196 		return ptr;
197 	}
198        	return NULL;
199 }
200 
201 
202 void
activate_Doubler(LADSPA_Handle Instance)203 activate_Doubler(LADSPA_Handle Instance) {
204 
205 	Doubler * ptr = (Doubler *)Instance;
206 	unsigned long i;
207 
208 	for (i = 0; i < BUFLEN * ptr->sample_rate / 192000; i++) {
209 		ptr->ring_L[i] = 0.0f;
210 		ptr->ring_R[i] = 0.0f;
211 	}
212 
213 	ptr->old_time = -1.0f;
214 	ptr->old_pitch = -1.0f;
215 }
216 
217 
218 
219 
220 /* Connect a port to a data location. */
221 void
connect_port_Doubler(LADSPA_Handle Instance,unsigned long Port,LADSPA_Data * data)222 connect_port_Doubler(LADSPA_Handle Instance,
223 		     unsigned long Port,
224 		     LADSPA_Data * data) {
225 
226 	Doubler * ptr = (Doubler *)Instance;
227 
228 	switch (Port) {
229 	case TIME:
230 		ptr->time = data;
231 		break;
232 	case PITCH:
233 		ptr->pitch = data;
234 		break;
235 	case DRYLEVEL:
236 		ptr->drylevel = data;
237 		break;
238 	case DRYPOSL:
239 		ptr->dryposl = data;
240 		break;
241 	case DRYPOSR:
242 		ptr->dryposr = data;
243 		break;
244 	case WETLEVEL:
245 		ptr->wetlevel = data;
246 		break;
247 	case WETPOSL:
248 		ptr->wetposl = data;
249 		break;
250 	case WETPOSR:
251 		ptr->wetposr = data;
252 		break;
253 	case INPUT_L:
254 		ptr->input_L = data;
255 		break;
256 	case INPUT_R:
257 		ptr->input_R = data;
258 		break;
259 	case OUTPUT_L:
260 		ptr->output_L = data;
261 		break;
262 	case OUTPUT_R:
263 		ptr->output_R = data;
264 		break;
265 	}
266 }
267 
268 
269 
270 void
run_Doubler(LADSPA_Handle Instance,unsigned long SampleCount)271 run_Doubler(LADSPA_Handle Instance,
272 	    unsigned long SampleCount) {
273 
274 	Doubler * ptr = (Doubler *)Instance;
275 
276 	LADSPA_Data pitch = LIMIT(*(ptr->pitch),0.0f,1.0f) + 0.75f;
277 	LADSPA_Data depth = LIMIT(((1.0f - LIMIT(*(ptr->pitch),0.0f,1.0f)) * 1.75f + 0.25f) *
278 				  ptr->sample_rate / 6000.0f / M_PI,
279 				  0, ptr->buflen_L / 2);
280 	LADSPA_Data time = LIMIT(*(ptr->time), 0.0f, 1.0f) + 0.5f;
281 	LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-90.0f,20.0f));
282 	LADSPA_Data wetlevel = db2lin(LIMIT(*(ptr->wetlevel),-90.0f,20.0f));
283 	LADSPA_Data dryposl = 1.0f - LIMIT(*(ptr->dryposl), 0.0f, 1.0f);
284 	LADSPA_Data dryposr = LIMIT(*(ptr->dryposr), 0.0f, 1.0f);
285 	LADSPA_Data wetposl = 1.0f - LIMIT(*(ptr->wetposl), 0.0f, 1.0f);
286 	LADSPA_Data wetposr = LIMIT(*(ptr->wetposr), 0.0f, 1.0f);
287 	LADSPA_Data * input_L = ptr->input_L;
288 	LADSPA_Data * input_R = ptr->input_R;
289 	LADSPA_Data * output_L = ptr->output_L;
290 	LADSPA_Data * output_R = ptr->output_R;
291 
292 	unsigned long sample_index;
293 	unsigned long sample_count = SampleCount;
294 
295 	LADSPA_Data in_L = 0.0f;
296 	LADSPA_Data in_R = 0.0f;
297 	LADSPA_Data out_L = 0.0f;
298 	LADSPA_Data out_R = 0.0f;
299 
300 	LADSPA_Data fpos = 0.0f;
301 	LADSPA_Data n = 0.0f;
302 	LADSPA_Data rem = 0.0f;
303 	LADSPA_Data s_a_L, s_a_R, s_b_L, s_b_R;
304 	LADSPA_Data prev_p_pitch = 0.0f;
305 	LADSPA_Data prev_p_delay = 0.0f;
306 	LADSPA_Data delay;
307 
308 	LADSPA_Data drystream_L = 0.0f;
309 	LADSPA_Data drystream_R = 0.0f;
310 	LADSPA_Data wetstream_L = 0.0f;
311 	LADSPA_Data wetstream_R = 0.0f;
312 
313 	if (ptr->old_pitch != pitch) {
314 		ptr->pitchmod = ptr->p_pitch;
315 		prev_p_pitch = ptr->p_pitch;
316 		fractal(ptr->ring_pnoise, NOISE_LEN, pitch);
317 		ptr->pos_pnoise = 0;
318 		ptr->p_pitch = push_buffer(0.0f, ptr->ring_pnoise,
319 					   ptr->buflen_pnoise, &(ptr->pos_pnoise));
320 		ptr->d_pitch = (ptr->p_pitch - prev_p_pitch) / (float)(ptr->p_stretch);
321 		ptr->n_pitch = 0;
322 
323 		ptr->old_pitch = pitch;
324 	}
325 
326 	if (ptr->old_time != time) {
327 		ptr->delay = ptr->p_delay;
328 		prev_p_delay = ptr->p_delay;
329 		fractal(ptr->ring_dnoise, NOISE_LEN, time);
330 		ptr->pos_dnoise = 0;
331 		ptr->p_delay = push_buffer(0.0f, ptr->ring_dnoise,
332 					   ptr->buflen_dnoise, &(ptr->pos_dnoise));
333 		ptr->d_delay = (ptr->p_delay - prev_p_delay) / (float)(ptr->d_stretch);
334 		ptr->n_delay = 0;
335 
336 		ptr->old_time = time;
337 	}
338 
339 
340 	for (sample_index = 0; sample_index < sample_count; sample_index++) {
341 
342 		in_L = *(input_L++);
343 		in_R = *(input_R++);
344 
345 		push_buffer(in_L, ptr->ring_L, ptr->buflen_L, &(ptr->pos_L));
346 		push_buffer(in_R, ptr->ring_R, ptr->buflen_R, &(ptr->pos_R));
347 
348 		if (ptr->n_pitch < ptr->p_stretch) {
349 			ptr->pitchmod += ptr->d_pitch;
350 			ptr->n_pitch++;
351 		} else {
352 			ptr->pitchmod = ptr->p_pitch;
353 			prev_p_pitch = ptr->p_pitch;
354 			if (!ptr->pos_pnoise) {
355 				fractal(ptr->ring_pnoise, NOISE_LEN, pitch);
356 			}
357 			ptr->p_pitch = push_buffer(0.0f, ptr->ring_pnoise,
358 						   ptr->buflen_pnoise, &(ptr->pos_pnoise));
359 			ptr->d_pitch = (ptr->p_pitch - prev_p_pitch) / (float)(ptr->p_stretch);
360 			ptr->n_pitch = 0;
361 		}
362 
363 		if (ptr->n_delay < ptr->d_stretch) {
364 			ptr->delay += ptr->d_delay;
365 			ptr->n_delay++;
366 		} else {
367 			ptr->delay = ptr->p_delay;
368 			prev_p_delay = ptr->p_delay;
369 			if (!ptr->pos_dnoise) {
370 				fractal(ptr->ring_dnoise, NOISE_LEN, time);
371 			}
372 			ptr->p_delay = push_buffer(0.0f, ptr->ring_dnoise,
373 						   ptr->buflen_dnoise, &(ptr->pos_dnoise));
374 			ptr->d_delay = (ptr->p_delay - prev_p_delay) / (float)(ptr->d_stretch);
375 			ptr->n_delay = 0;
376 		}
377 
378 		delay = (12.5f * ptr->delay + 37.5f) * ptr->sample_rate / 1000.0f;
379 		fpos = ptr->buflen_L - depth * (1.0f - ptr->pitchmod) - delay - 1.0f;
380 		n = floorf(fpos);
381 		rem = fpos - n;
382 
383 		s_a_L = read_buffer(ptr->ring_L, ptr->buflen_L,
384 				    ptr->pos_L, (unsigned long) n);
385 		s_b_L = read_buffer(ptr->ring_L, ptr->buflen_L,
386 				    ptr->pos_L, (unsigned long) n + 1);
387 
388 		s_a_R = read_buffer(ptr->ring_R, ptr->buflen_R,
389 				    ptr->pos_R, (unsigned long) n);
390 		s_b_R = read_buffer(ptr->ring_R, ptr->buflen_R,
391 				    ptr->pos_R, (unsigned long) n + 1);
392 
393 		drystream_L = drylevel * in_L;
394 		drystream_R = drylevel * in_R;
395 		wetstream_L = wetlevel * ((1 - rem) * s_a_L + rem * s_b_L);
396 		wetstream_R = wetlevel * ((1 - rem) * s_a_R + rem * s_b_R);
397 
398 		out_L = dryposl * drystream_L + (1.0f - dryposr) * drystream_R +
399 			wetposl * wetstream_L + (1.0f - wetposr) * wetstream_R;
400 		out_R = (1.0f - dryposl) * drystream_L + dryposr * drystream_R +
401 			(1.0f - wetposl) * wetstream_L + wetposr * wetstream_R;
402 
403 		*(output_L++) = out_L;
404 		*(output_R++) = out_R;
405 	}
406 }
407 
408 
409 void
set_run_adding_gain_Doubler(LADSPA_Handle Instance,LADSPA_Data gain)410 set_run_adding_gain_Doubler(LADSPA_Handle Instance, LADSPA_Data gain) {
411 
412 	Doubler * ptr = (Doubler *)Instance;
413 
414 	ptr->run_adding_gain = gain;
415 }
416 
417 
418 
419 void
run_adding_Doubler(LADSPA_Handle Instance,unsigned long SampleCount)420 run_adding_Doubler(LADSPA_Handle Instance,
421 		   unsigned long SampleCount) {
422 
423 	Doubler * ptr = (Doubler *)Instance;
424 
425 	LADSPA_Data pitch = LIMIT(*(ptr->pitch),0.0f,1.0f) + 0.75f;
426 	LADSPA_Data depth = LIMIT(((1.0f - LIMIT(*(ptr->pitch),0.0f,1.0f)) * 1.75f + 0.25f) *
427 				  ptr->sample_rate / 6000.0f / M_PI,
428 				  0, ptr->buflen_L / 2);
429 	LADSPA_Data time = LIMIT(*(ptr->time), 0.0f, 1.0f) + 0.5f;
430 	LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-90.0f,20.0f));
431 	LADSPA_Data wetlevel = db2lin(LIMIT(*(ptr->wetlevel),-90.0f,20.0f));
432 	LADSPA_Data dryposl = 1.0f - LIMIT(*(ptr->dryposl), 0.0f, 1.0f);
433 	LADSPA_Data dryposr = LIMIT(*(ptr->dryposr), 0.0f, 1.0f);
434 	LADSPA_Data wetposl = 1.0f - LIMIT(*(ptr->wetposl), 0.0f, 1.0f);
435 	LADSPA_Data wetposr = LIMIT(*(ptr->wetposr), 0.0f, 1.0f);
436 	LADSPA_Data * input_L = ptr->input_L;
437 	LADSPA_Data * input_R = ptr->input_R;
438 	LADSPA_Data * output_L = ptr->output_L;
439 	LADSPA_Data * output_R = ptr->output_R;
440 
441 	unsigned long sample_index;
442 	unsigned long sample_count = SampleCount;
443 
444 	LADSPA_Data in_L = 0.0f;
445 	LADSPA_Data in_R = 0.0f;
446 	LADSPA_Data out_L = 0.0f;
447 	LADSPA_Data out_R = 0.0f;
448 
449 	LADSPA_Data fpos = 0.0f;
450 	LADSPA_Data n = 0.0f;
451 	LADSPA_Data rem = 0.0f;
452 	LADSPA_Data s_a_L, s_a_R, s_b_L, s_b_R;
453 	LADSPA_Data prev_p_pitch = 0.0f;
454 	LADSPA_Data prev_p_delay = 0.0f;
455 	LADSPA_Data delay;
456 
457 	LADSPA_Data drystream_L = 0.0f;
458 	LADSPA_Data drystream_R = 0.0f;
459 	LADSPA_Data wetstream_L = 0.0f;
460 	LADSPA_Data wetstream_R = 0.0f;
461 
462 	if (ptr->old_pitch != pitch) {
463 		ptr->pitchmod = ptr->p_pitch;
464 		prev_p_pitch = ptr->p_pitch;
465 		fractal(ptr->ring_pnoise, NOISE_LEN, pitch);
466 		ptr->pos_pnoise = 0;
467 		ptr->p_pitch = push_buffer(0.0f, ptr->ring_pnoise,
468 					   ptr->buflen_pnoise, &(ptr->pos_pnoise));
469 		ptr->d_pitch = (ptr->p_pitch - prev_p_pitch) / (float)(ptr->p_stretch);
470 		ptr->n_pitch = 0;
471 
472 		ptr->old_pitch = pitch;
473 	}
474 
475 	if (ptr->old_time != time) {
476 		ptr->delay = ptr->p_delay;
477 		prev_p_delay = ptr->p_delay;
478 		fractal(ptr->ring_dnoise, NOISE_LEN, time);
479 		ptr->pos_dnoise = 0;
480 		ptr->p_delay = push_buffer(0.0f, ptr->ring_dnoise,
481 					   ptr->buflen_dnoise, &(ptr->pos_dnoise));
482 		ptr->d_delay = (ptr->p_delay - prev_p_delay) / (float)(ptr->d_stretch);
483 		ptr->n_delay = 0;
484 
485 		ptr->old_time = time;
486 	}
487 
488 
489 	for (sample_index = 0; sample_index < sample_count; sample_index++) {
490 
491 		in_L = *(input_L++);
492 		in_R = *(input_R++);
493 
494 		push_buffer(in_L, ptr->ring_L, ptr->buflen_L, &(ptr->pos_L));
495 		push_buffer(in_R, ptr->ring_R, ptr->buflen_R, &(ptr->pos_R));
496 
497 		if (ptr->n_pitch < ptr->p_stretch) {
498 			ptr->pitchmod += ptr->d_pitch;
499 			ptr->n_pitch++;
500 		} else {
501 			ptr->pitchmod = ptr->p_pitch;
502 			prev_p_pitch = ptr->p_pitch;
503 			if (!ptr->pos_pnoise) {
504 				fractal(ptr->ring_pnoise, NOISE_LEN, pitch);
505 			}
506 			ptr->p_pitch = push_buffer(0.0f, ptr->ring_pnoise,
507 						   ptr->buflen_pnoise, &(ptr->pos_pnoise));
508 			ptr->d_pitch = (ptr->p_pitch - prev_p_pitch) / (float)(ptr->p_stretch);
509 			ptr->n_pitch = 0;
510 		}
511 
512 		if (ptr->n_delay < ptr->d_stretch) {
513 			ptr->delay += ptr->d_delay;
514 			ptr->n_delay++;
515 		} else {
516 			ptr->delay = ptr->p_delay;
517 			prev_p_delay = ptr->p_delay;
518 			if (!ptr->pos_dnoise) {
519 				fractal(ptr->ring_dnoise, NOISE_LEN, time);
520 			}
521 			ptr->p_delay = push_buffer(0.0f, ptr->ring_dnoise,
522 						   ptr->buflen_dnoise, &(ptr->pos_dnoise));
523 			ptr->d_delay = (ptr->p_delay - prev_p_delay) / (float)(ptr->d_stretch);
524 			ptr->n_delay = 0;
525 		}
526 
527 		delay = (12.5f * ptr->delay + 37.5f) * ptr->sample_rate / 1000.0f;
528 		fpos = ptr->buflen_L - depth * (1.0f - ptr->pitchmod) - delay - 1.0f;
529 		n = floorf(fpos);
530 		rem = fpos - n;
531 
532 		s_a_L = read_buffer(ptr->ring_L, ptr->buflen_L,
533 				    ptr->pos_L, (unsigned long) n);
534 		s_b_L = read_buffer(ptr->ring_L, ptr->buflen_L,
535 				    ptr->pos_L, (unsigned long) n + 1);
536 
537 		s_a_R = read_buffer(ptr->ring_R, ptr->buflen_R,
538 				    ptr->pos_R, (unsigned long) n);
539 		s_b_R = read_buffer(ptr->ring_R, ptr->buflen_R,
540 				    ptr->pos_R, (unsigned long) n + 1);
541 
542 		drystream_L = drylevel * in_L;
543 		drystream_R = drylevel * in_R;
544 		wetstream_L = wetlevel * ((1 - rem) * s_a_L + rem * s_b_L);
545 		wetstream_R = wetlevel * ((1 - rem) * s_a_R + rem * s_b_R);
546 
547 		out_L = dryposl * drystream_L + (1.0f - dryposr) * drystream_R +
548 			wetposl * wetstream_L + (1.0f - wetposr) * wetstream_R;
549 		out_R = (1.0f - dryposl) * drystream_L + dryposr * drystream_R +
550 			(1.0f - wetposl) * wetstream_L + wetposr * wetstream_R;
551 
552 		*(output_L++) += ptr->run_adding_gain * out_L;
553 		*(output_R++) += ptr->run_adding_gain * out_R;
554 	}
555 }
556 
557 
558 
559 /* Throw away a Doubler effect instance. */
560 void
cleanup_Doubler(LADSPA_Handle Instance)561 cleanup_Doubler(LADSPA_Handle Instance) {
562 
563   	Doubler * ptr = (Doubler *)Instance;
564 	free(ptr->ring_L);
565 	free(ptr->ring_R);
566 	free(ptr->ring_pnoise);
567 	free(ptr->ring_dnoise);
568 	free(Instance);
569 }
570 
571 
572 
573 LADSPA_Descriptor * stereo_descriptor = NULL;
574 
575 
576 
577 /* _init() is called automatically when the plugin library is first
578    loaded. */
579 void
_init()580 _init() {
581 
582 	char ** port_names;
583 	LADSPA_PortDescriptor * port_descriptors;
584 	LADSPA_PortRangeHint * port_range_hints;
585 
586 	if ((stereo_descriptor =
587 	     (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
588 		exit(1);
589 
590 	stereo_descriptor->UniqueID = ID_STEREO;
591 	stereo_descriptor->Label = strdup("tap_doubler");
592 	stereo_descriptor->Properties = 0;
593 	stereo_descriptor->Name = strdup("TAP Fractal Doubler");
594 	stereo_descriptor->Maker = strdup("Tom Szilagyi");
595 	stereo_descriptor->Copyright = strdup("GPL");
596 	stereo_descriptor->PortCount = PORTCOUNT_STEREO;
597 
598 	if ((port_descriptors =
599 	     (LADSPA_PortDescriptor *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortDescriptor))) == NULL)
600 		exit(1);
601 
602 	stereo_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
603 	port_descriptors[TIME] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
604 	port_descriptors[PITCH] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
605 	port_descriptors[DRYLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
606 	port_descriptors[DRYPOSL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
607 	port_descriptors[DRYPOSR] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
608 	port_descriptors[WETLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
609 	port_descriptors[WETPOSL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
610 	port_descriptors[WETPOSR] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
611 	port_descriptors[INPUT_L] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
612 	port_descriptors[INPUT_R] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
613 	port_descriptors[OUTPUT_L] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
614 	port_descriptors[OUTPUT_R] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
615 
616 	if ((port_names =
617 	     (char **)calloc(PORTCOUNT_STEREO, sizeof(char *))) == NULL)
618 		exit(1);
619 
620 	stereo_descriptor->PortNames = (const char **)port_names;
621 	port_names[TIME] = strdup("Time Tracking");
622 	port_names[PITCH] = strdup("Pitch Tracking");
623 	port_names[DRYLEVEL] = strdup("Dry Level [dB]");
624 	port_names[DRYPOSL] = strdup("Dry Left Position");
625 	port_names[DRYPOSR] = strdup("Dry Right Position");
626 	port_names[WETLEVEL] = strdup("Wet Level [dB]");
627 	port_names[WETPOSL] = strdup("Wet Left Position");
628 	port_names[WETPOSR] = strdup("Wet Right Position");
629 	port_names[INPUT_L] = strdup("Input_L");
630 	port_names[INPUT_R] = strdup("Input_R");
631 	port_names[OUTPUT_L] = strdup("Output_L");
632 	port_names[OUTPUT_R] = strdup("Output_R");
633 
634 	if ((port_range_hints =
635 	     ((LADSPA_PortRangeHint *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortRangeHint)))) == NULL)
636 		exit(1);
637 
638 	stereo_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
639 	port_range_hints[TIME].HintDescriptor =
640 		(LADSPA_HINT_BOUNDED_BELOW |
641 		 LADSPA_HINT_BOUNDED_ABOVE |
642 		 LADSPA_HINT_DEFAULT_MIDDLE);
643 	port_range_hints[PITCH].HintDescriptor =
644 		(LADSPA_HINT_BOUNDED_BELOW |
645 		 LADSPA_HINT_BOUNDED_ABOVE |
646 		 LADSPA_HINT_DEFAULT_MIDDLE);
647 	port_range_hints[DRYLEVEL].HintDescriptor =
648 		(LADSPA_HINT_BOUNDED_BELOW |
649 		 LADSPA_HINT_BOUNDED_ABOVE |
650 		 LADSPA_HINT_DEFAULT_0);
651 	port_range_hints[DRYPOSL].HintDescriptor =
652 		(LADSPA_HINT_BOUNDED_BELOW |
653 		 LADSPA_HINT_BOUNDED_ABOVE |
654 		 LADSPA_HINT_DEFAULT_MINIMUM);
655 	port_range_hints[DRYPOSR].HintDescriptor =
656 		(LADSPA_HINT_BOUNDED_BELOW |
657 		 LADSPA_HINT_BOUNDED_ABOVE |
658 		 LADSPA_HINT_DEFAULT_MAXIMUM);
659 	port_range_hints[WETLEVEL].HintDescriptor =
660 		(LADSPA_HINT_BOUNDED_BELOW |
661 		 LADSPA_HINT_BOUNDED_ABOVE |
662 		 LADSPA_HINT_DEFAULT_0);
663 	port_range_hints[WETPOSL].HintDescriptor =
664 		(LADSPA_HINT_BOUNDED_BELOW |
665 		 LADSPA_HINT_BOUNDED_ABOVE |
666 		 LADSPA_HINT_DEFAULT_MINIMUM);
667 	port_range_hints[WETPOSR].HintDescriptor =
668 		(LADSPA_HINT_BOUNDED_BELOW |
669 		 LADSPA_HINT_BOUNDED_ABOVE |
670 		 LADSPA_HINT_DEFAULT_MAXIMUM);
671 	port_range_hints[TIME].LowerBound = 0.0f;
672 	port_range_hints[TIME].UpperBound = 1.0f;
673 	port_range_hints[PITCH].LowerBound = 0.0f;
674 	port_range_hints[PITCH].UpperBound = 1.0f;
675 	port_range_hints[DRYLEVEL].LowerBound = -90.0f;
676 	port_range_hints[DRYLEVEL].UpperBound = +20.0f;
677 	port_range_hints[DRYPOSL].LowerBound = 0.0f;
678 	port_range_hints[DRYPOSL].UpperBound = 1.0f;
679 	port_range_hints[DRYPOSR].LowerBound = 0.0f;
680 	port_range_hints[DRYPOSR].UpperBound = 1.0f;
681 	port_range_hints[WETLEVEL].LowerBound = -90.0f;
682 	port_range_hints[WETLEVEL].UpperBound = +20.0f;
683 	port_range_hints[WETPOSL].LowerBound = 0.0f;
684 	port_range_hints[WETPOSL].UpperBound = 1.0f;
685 	port_range_hints[WETPOSR].LowerBound = 0.0f;
686 	port_range_hints[WETPOSR].UpperBound = 1.0f;
687 	port_range_hints[INPUT_L].HintDescriptor = 0;
688 	port_range_hints[INPUT_R].HintDescriptor = 0;
689 	port_range_hints[OUTPUT_L].HintDescriptor = 0;
690 	port_range_hints[OUTPUT_R].HintDescriptor = 0;
691 	stereo_descriptor->instantiate = instantiate_Doubler;
692 	stereo_descriptor->connect_port = connect_port_Doubler;
693 	stereo_descriptor->activate = activate_Doubler;
694 	stereo_descriptor->run = run_Doubler;
695 	stereo_descriptor->run_adding = run_adding_Doubler;
696 	stereo_descriptor->set_run_adding_gain = set_run_adding_gain_Doubler;
697 	stereo_descriptor->deactivate = NULL;
698 	stereo_descriptor->cleanup = cleanup_Doubler;
699 }
700 
701 
702 void
delete_descriptor(LADSPA_Descriptor * descriptor)703 delete_descriptor(LADSPA_Descriptor * descriptor) {
704 	unsigned long index;
705 	if (descriptor) {
706 		free((char *)descriptor->Label);
707 		free((char *)descriptor->Name);
708 		free((char *)descriptor->Maker);
709 		free((char *)descriptor->Copyright);
710 		free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
711 		for (index = 0; index < descriptor->PortCount; index++)
712 			free((char *)(descriptor->PortNames[index]));
713 		free((char **)descriptor->PortNames);
714 		free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
715 		free(descriptor);
716 	}
717 }
718 
719 
720 /* _fini() is called automatically when the library is unloaded. */
721 void
_fini()722 _fini() {
723 	delete_descriptor(stereo_descriptor);
724 }
725 
726 
727 /* Return a descriptor of the requested plugin type. */
728 const LADSPA_Descriptor *
ladspa_descriptor(unsigned long Index)729 ladspa_descriptor(unsigned long Index) {
730 
731 	switch (Index) {
732 	case 0:
733 		return stereo_descriptor;
734 	default:
735 		return NULL;
736 	}
737 }
738