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 <lv2.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 float * time;
71 float * pitch;
72 float * drylevel;
73 float smoothdrylevel;
74 float * dryposl;
75 float * dryposr;
76 float * wetlevel;
77 float smoothwetlevel;
78 float * wetposl;
79 float * wetposr;
80 float * input_L;
81 float * input_R;
82 float * output_L;
83 float * output_R;
84
85 float old_time;
86 float old_pitch;
87
88 float * ring_L;
89 unsigned long buflen_L;
90 unsigned long pos_L;
91
92 float * ring_R;
93 unsigned long buflen_R;
94 unsigned long pos_R;
95
96 float * ring_pnoise;
97 unsigned long buflen_pnoise;
98 unsigned long pos_pnoise;
99
100 float * ring_dnoise;
101 unsigned long buflen_dnoise;
102 unsigned long pos_dnoise;
103
104 float delay;
105 float d_delay;
106 float p_delay;
107 unsigned long n_delay;
108
109 float pitchmod;
110 float d_pitch;
111 float p_pitch;
112 unsigned long n_pitch;
113
114 unsigned long p_stretch;
115 unsigned long d_stretch;
116
117 double sample_rate;
118 } Doubler;
119
120
121 /* generate fractal pattern using Midpoint Displacement Method
122 * v: buffer of floats to output fractal pattern to
123 * N: length of v, MUST be integer power of 2 (ie 128, 256, ...)
124 * H: Hurst constant, between 0 and 0.9999 (fractal dimension)
125 */
126 void
fractal(float * v,int N,float H)127 fractal(float * v, int N, float H) {
128
129 int l = N;
130 int k;
131 float r = 1.0f;
132 int c;
133
134 v[0] = 0;
135 while (l > 1) {
136 k = N / l;
137 for (c = 0; c < k; c++) {
138 v[c*l + l/2] = (v[c*l] + v[((c+1) * l) % N]) / 2.0f +
139 2.0f * r * (rand() - (float)RAND_MAX/2.0f) / (float)RAND_MAX;
140 v[c*l + l/2] = LIMIT(v[c*l + l/2], -1.0f, 1.0f);
141 }
142 l /= 2;
143 r /= powf(2, H);
144 }
145 }
146
147
148
149 /* Construct a new plugin instance. */
150 LV2_Handle
instantiate_Doubler(const LV2_Descriptor * Descriptor,double sample_rate,const char * bundle_path,const LV2_Feature * const * features)151 instantiate_Doubler(const LV2_Descriptor * Descriptor, double sample_rate, const char* bundle_path, const LV2_Feature* const* features) {
152
153 LV2_Handle * ptr;
154
155 if ((ptr = malloc(sizeof(Doubler))) != NULL) {
156 ((Doubler *)ptr)->sample_rate = sample_rate;
157 ((Doubler *)ptr)->smoothdrylevel = 0.0;
158 ((Doubler *)ptr)->smoothwetlevel = 0.0;
159
160 if ((((Doubler *)ptr)->ring_L =
161 calloc(BUFLEN * sample_rate / 192000, sizeof(float))) == NULL)
162 return NULL;
163 ((Doubler *)ptr)->buflen_L = BUFLEN * sample_rate / 192000;
164 ((Doubler *)ptr)->pos_L = 0;
165
166 if ((((Doubler *)ptr)->ring_R =
167 calloc(BUFLEN * sample_rate / 192000, sizeof(float))) == NULL)
168 return NULL;
169 ((Doubler *)ptr)->buflen_R = BUFLEN * sample_rate / 192000;
170 ((Doubler *)ptr)->pos_R = 0;
171
172 if ((((Doubler *)ptr)->ring_pnoise =
173 calloc(NOISE_LEN, sizeof(float))) == NULL)
174 return NULL;
175 ((Doubler *)ptr)->buflen_pnoise = NOISE_LEN;
176 ((Doubler *)ptr)->pos_pnoise = 0;
177
178 if ((((Doubler *)ptr)->ring_dnoise =
179 calloc(NOISE_LEN, sizeof(float))) == NULL)
180 return NULL;
181 ((Doubler *)ptr)->buflen_dnoise = NOISE_LEN;
182 ((Doubler *)ptr)->pos_dnoise = 0;
183
184 ((Doubler *)ptr)->d_stretch = sample_rate / 10;
185 ((Doubler *)ptr)->p_stretch = sample_rate / 1000;
186
187 ((Doubler *)ptr)->delay = 0.0f;
188 ((Doubler *)ptr)->d_delay = 0.0f;
189 ((Doubler *)ptr)->p_delay = 0.0f;
190 ((Doubler *)ptr)->n_delay = ((Doubler *)ptr)->d_stretch;
191
192 ((Doubler *)ptr)->pitchmod = 0.0f;
193 ((Doubler *)ptr)->d_pitch = 0.0f;
194 ((Doubler *)ptr)->p_pitch = 0.0f;
195 ((Doubler *)ptr)->n_pitch = ((Doubler *)ptr)->p_stretch;
196
197 return ptr;
198 }
199 return NULL;
200 }
201
202
203 void
activate_Doubler(LV2_Handle Instance)204 activate_Doubler(LV2_Handle Instance) {
205
206 Doubler * ptr = (Doubler *)Instance;
207 unsigned long i;
208
209 for (i = 0; i < BUFLEN * ptr->sample_rate / 192000; i++) {
210 ptr->ring_L[i] = 0.0f;
211 ptr->ring_R[i] = 0.0f;
212 }
213
214 ptr->old_time = -1.0f;
215 ptr->old_pitch = -1.0f;
216 }
217
218 void
deactivate_Doubler(LV2_Handle Instance)219 deactivate_Doubler(LV2_Handle Instance) {
220
221 }
222
223
224
225 /* Connect a port to a data location. */
226 void
connect_port_Doubler(LV2_Handle Instance,uint32_t Port,void * data)227 connect_port_Doubler(LV2_Handle Instance,
228 uint32_t Port,
229 void * data) {
230
231 Doubler * ptr = (Doubler *)Instance;
232
233 switch (Port) {
234 case TIME:
235 ptr->time = (float*) data;
236 break;
237 case PITCH:
238 ptr->pitch = (float*) data;
239 break;
240 case DRYLEVEL:
241 ptr->drylevel = (float*) data;
242 break;
243 case DRYPOSL:
244 ptr->dryposl = (float*) data;
245 break;
246 case DRYPOSR:
247 ptr->dryposr = (float*) data;
248 break;
249 case WETLEVEL:
250 ptr->wetlevel = (float*) data;
251 break;
252 case WETPOSL:
253 ptr->wetposl = (float*) data;
254 break;
255 case WETPOSR:
256 ptr->wetposr = (float*) data;
257 break;
258 case INPUT_L:
259 ptr->input_L = (float*) data;
260 break;
261 case INPUT_R:
262 ptr->input_R = (float*) data;
263 break;
264 case OUTPUT_L:
265 ptr->output_L = (float*) data;
266 break;
267 case OUTPUT_R:
268 ptr->output_R = (float*) data;
269 break;
270 }
271 }
272
273
274
275 void
run_Doubler(LV2_Handle Instance,uint32_t SampleCount)276 run_Doubler(LV2_Handle Instance,
277 uint32_t SampleCount) {
278
279 Doubler * ptr = (Doubler *)Instance;
280
281 float pitch = LIMIT(*(ptr->pitch),0.0f,1.0f) + 0.75f;
282 float depth = LIMIT(((1.0f - LIMIT(*(ptr->pitch),0.0f,1.0f)) * 1.75f + 0.25f) *
283 ptr->sample_rate / 6000.0f / M_PI,
284 0, ptr->buflen_L / 2);
285 float time = LIMIT(*(ptr->time), 0.0f, 1.0f) + 0.5f;
286
287 float calcdry = (*(ptr->drylevel) +ptr->smoothdrylevel)*0.5;
288 ptr->smoothdrylevel = calcdry;
289 float drylevel = db2lin(LIMIT(calcdry,-90.0f,20.0f));
290
291 float calcwet = (*(ptr->wetlevel) +ptr->smoothwetlevel)*0.5;
292 ptr->smoothwetlevel = calcwet;
293 float wetlevel = db2lin(LIMIT(calcwet,-90.0f,20.0f));
294
295 float dryposl = 1.0f - LIMIT(*(ptr->dryposl), 0.0f, 1.0f);
296 float dryposr = LIMIT(*(ptr->dryposr), 0.0f, 1.0f);
297 float wetposl = 1.0f - LIMIT(*(ptr->wetposl), 0.0f, 1.0f);
298 float wetposr = LIMIT(*(ptr->wetposr), 0.0f, 1.0f);
299 float * input_L = ptr->input_L;
300 float * input_R = ptr->input_R;
301 float * output_L = ptr->output_L;
302 float * output_R = ptr->output_R;
303
304 unsigned long sample_index;
305 unsigned long sample_count = SampleCount;
306
307 float in_L = 0.0f;
308 float in_R = 0.0f;
309 float out_L = 0.0f;
310 float out_R = 0.0f;
311
312 float fpos = 0.0f;
313 float n = 0.0f;
314 float rem = 0.0f;
315 float s_a_L, s_a_R, s_b_L, s_b_R;
316 float prev_p_pitch = 0.0f;
317 float prev_p_delay = 0.0f;
318 float delay;
319
320 float drystream_L = 0.0f;
321 float drystream_R = 0.0f;
322 float wetstream_L = 0.0f;
323 float wetstream_R = 0.0f;
324
325 if (ptr->old_pitch != pitch) {
326 ptr->pitchmod = ptr->p_pitch;
327 prev_p_pitch = ptr->p_pitch;
328 fractal(ptr->ring_pnoise, NOISE_LEN, pitch);
329 ptr->pos_pnoise = 0;
330 ptr->p_pitch = push_buffer(0.0f, ptr->ring_pnoise,
331 ptr->buflen_pnoise, &(ptr->pos_pnoise));
332 ptr->d_pitch = (ptr->p_pitch - prev_p_pitch) / (float)(ptr->p_stretch);
333 ptr->n_pitch = 0;
334
335 ptr->old_pitch = pitch;
336 }
337
338 if (ptr->old_time != time) {
339 ptr->delay = ptr->p_delay;
340 prev_p_delay = ptr->p_delay;
341 fractal(ptr->ring_dnoise, NOISE_LEN, time);
342 ptr->pos_dnoise = 0;
343 ptr->p_delay = push_buffer(0.0f, ptr->ring_dnoise,
344 ptr->buflen_dnoise, &(ptr->pos_dnoise));
345 ptr->d_delay = (ptr->p_delay - prev_p_delay) / (float)(ptr->d_stretch);
346 ptr->n_delay = 0;
347
348 ptr->old_time = time;
349 }
350
351
352 for (sample_index = 0; sample_index < sample_count; sample_index++) {
353
354 in_L = *(input_L++);
355 in_R = *(input_R++);
356
357 push_buffer(in_L, ptr->ring_L, ptr->buflen_L, &(ptr->pos_L));
358 push_buffer(in_R, ptr->ring_R, ptr->buflen_R, &(ptr->pos_R));
359
360 if (ptr->n_pitch < ptr->p_stretch) {
361 ptr->pitchmod += ptr->d_pitch;
362 ptr->n_pitch++;
363 } else {
364 ptr->pitchmod = ptr->p_pitch;
365 prev_p_pitch = ptr->p_pitch;
366 if (!ptr->pos_pnoise) {
367 fractal(ptr->ring_pnoise, NOISE_LEN, pitch);
368 }
369 ptr->p_pitch = push_buffer(0.0f, ptr->ring_pnoise,
370 ptr->buflen_pnoise, &(ptr->pos_pnoise));
371 ptr->d_pitch = (ptr->p_pitch - prev_p_pitch) / (float)(ptr->p_stretch);
372 ptr->n_pitch = 0;
373 }
374
375 if (ptr->n_delay < ptr->d_stretch) {
376 ptr->delay += ptr->d_delay;
377 ptr->n_delay++;
378 } else {
379 ptr->delay = ptr->p_delay;
380 prev_p_delay = ptr->p_delay;
381 if (!ptr->pos_dnoise) {
382 fractal(ptr->ring_dnoise, NOISE_LEN, time);
383 }
384 ptr->p_delay = push_buffer(0.0f, ptr->ring_dnoise,
385 ptr->buflen_dnoise, &(ptr->pos_dnoise));
386 ptr->d_delay = (ptr->p_delay - prev_p_delay) / (float)(ptr->d_stretch);
387 ptr->n_delay = 0;
388 }
389
390 delay = (12.5f * ptr->delay + 37.5f) * ptr->sample_rate / 1000.0f;
391 fpos = ptr->buflen_L - depth * (1.0f - ptr->pitchmod) - delay - 1.0f;
392 n = floorf(fpos);
393 rem = fpos - n;
394
395 s_a_L = read_buffer(ptr->ring_L, ptr->buflen_L,
396 ptr->pos_L, (unsigned long) n);
397 s_b_L = read_buffer(ptr->ring_L, ptr->buflen_L,
398 ptr->pos_L, (unsigned long) n + 1);
399
400 s_a_R = read_buffer(ptr->ring_R, ptr->buflen_R,
401 ptr->pos_R, (unsigned long) n);
402 s_b_R = read_buffer(ptr->ring_R, ptr->buflen_R,
403 ptr->pos_R, (unsigned long) n + 1);
404
405 drystream_L = drylevel * in_L;
406 drystream_R = drylevel * in_R;
407 wetstream_L = wetlevel * ((1 - rem) * s_a_L + rem * s_b_L);
408 wetstream_R = wetlevel * ((1 - rem) * s_a_R + rem * s_b_R);
409
410 out_L = dryposl * drystream_L + (1.0f - dryposr) * drystream_R +
411 wetposl * wetstream_L + (1.0f - wetposr) * wetstream_R;
412 out_R = (1.0f - dryposl) * drystream_L + dryposr * drystream_R +
413 (1.0f - wetposl) * wetstream_L + wetposr * wetstream_R;
414
415 *(output_L++) = out_L;
416 *(output_R++) = out_R;
417 }
418 }
419
420
421 /* Throw away a Doubler effect instance. */
422 void
cleanup_Doubler(LV2_Handle Instance)423 cleanup_Doubler(LV2_Handle Instance) {
424
425 Doubler * ptr = (Doubler *)Instance;
426 free(ptr->ring_L);
427 free(ptr->ring_R);
428 free(ptr->ring_pnoise);
429 free(ptr->ring_dnoise);
430 free(Instance);
431 }
432
433 const void*
extension_data_Doubler(const char * uri)434 extension_data_Doubler(const char* uri)
435 {
436 return NULL;
437 }
438
439
440 static const
441 LV2_Descriptor Descriptor = {
442 "http://moddevices.com/plugins/tap/doubler",
443 instantiate_Doubler,
444 connect_port_Doubler,
445 activate_Doubler,
446 run_Doubler,
447 deactivate_Doubler,
448 cleanup_Doubler,
449 extension_data_Doubler
450 };
451
452 LV2_SYMBOL_EXPORT
453 const LV2_Descriptor*
lv2_descriptor(uint32_t index)454 lv2_descriptor(uint32_t index)
455 {
456 if (index == 0) return &Descriptor;
457 else return NULL;
458
459 }
460