~ubuntu-branches/ubuntu/breezy/tap-plugins/breezy

« back to all changes in this revision

Viewing changes to tap_doubler.c

  • Committer: Bazaar Package Importer
  • Author(s): Anand Kumria
  • Date: 2005-02-24 09:40:13 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 hoary)
  • Revision ID: james.westby@ubuntu.com-20050224094013-g2dv7untdana9pwp
Tags: 0.7.0-1
New upstream release (closes: #294086)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
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 
 
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
 
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 
 
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 
 
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
 
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 
 
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 
 
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 
 
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
 
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
 
722
_fini() {
 
723
        delete_descriptor(stereo_descriptor);
 
724
}
 
725
 
 
726
 
 
727
/* Return a descriptor of the requested plugin type. */
 
728
const LADSPA_Descriptor * 
 
729
ladspa_descriptor(unsigned long Index) {
 
730
 
 
731
        switch (Index) {
 
732
        case 0:
 
733
                return stereo_descriptor;
 
734
        default:
 
735
                return NULL;
 
736
        }
 
737
}