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_rotspeak.c,v 1.3 2004/02/21 17:33:36 tszilagyi Exp $
19 */
20
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <math.h>
26
27 #include "ladspa.h"
28 #include "tap_utils.h"
29
30 /* The Unique ID of the plugin: */
31
32 #define ID_STEREO 2149
33
34 /* The port numbers for the plugin: */
35
36 #define BASSFREQ 0
37 #define HORNFREQ 1
38 #define STWIDTH 2
39 #define HRBAL 3
40 #define LATENCY 4
41 #define INPUT_L 5
42 #define INPUT_R 6
43 #define OUTPUT_L 7
44 #define OUTPUT_R 8
45
46
47 /* Total number of ports */
48
49 #define PORTCOUNT_STEREO 9
50
51 /*
52 * This has to be bigger than 0.3f * sample_rate / (2*PI) for any sample rate.
53 * At 192 kHz 9168 is needed so this should be enough.
54 */
55 #define PM_DEPTH 9200
56
57 /* maximum phase mod freq */
58 #define PM_FREQ 30.0f
59
60
61 /* splitting input signals into low and high freq components */
62 #define SPLIT_FREQ 1000.0f
63 #define SPLIT_BW 1.0f
64
65
66 /* approx. sound velocity in air [m/s] */
67 #define C_AIR 340.0f
68
69 /* coefficient between rotating frequency and pitch mod depth (aka. Doppler effect) */
70 #define FREQ_PITCH 1.6f
71
72 /* cosine table for fast computations */
73 LADSPA_Data cos_table[1024];
74
75
76 /* The structure used to hold port connection information and state */
77
78 typedef struct {
79 LADSPA_Data * hornfreq;
80 LADSPA_Data * bassfreq;
81 LADSPA_Data * stwidth;
82 LADSPA_Data * hrbal;
83 LADSPA_Data * latency;
84 LADSPA_Data * input_L;
85 LADSPA_Data * input_R;
86 LADSPA_Data * output_L;
87 LADSPA_Data * output_R;
88
89 LADSPA_Data * ringbuffer_h_L;
90 unsigned long buflen_h_L;
91 unsigned long pos_h_L;
92 LADSPA_Data * ringbuffer_h_R;
93 unsigned long buflen_h_R;
94 unsigned long pos_h_R;
95
96 LADSPA_Data * ringbuffer_b_L;
97 unsigned long buflen_b_L;
98 unsigned long pos_b_L;
99 LADSPA_Data * ringbuffer_b_R;
100 unsigned long buflen_b_R;
101 unsigned long pos_b_R;
102
103 biquad * eq_filter_L;
104 biquad * lp_filter_L;
105 biquad * hp_filter_L;
106
107 biquad * eq_filter_R;
108 biquad * lp_filter_R;
109 biquad * hp_filter_R;
110
111 unsigned long sample_rate;
112 LADSPA_Data phase_h;
113 LADSPA_Data phase_b;
114
115 LADSPA_Data run_adding_gain;
116 } RotSpkr;
117
118
119
120 /* Construct a new plugin instance. */
121 LADSPA_Handle
instantiate_RotSpkr(const LADSPA_Descriptor * Descriptor,unsigned long sample_rate)122 instantiate_RotSpkr(const LADSPA_Descriptor * Descriptor,
123 unsigned long sample_rate) {
124
125 LADSPA_Handle * ptr;
126
127 if ((ptr = malloc(sizeof(RotSpkr))) != NULL) {
128 ((RotSpkr *)ptr)->sample_rate = sample_rate;
129 ((RotSpkr *)ptr)->run_adding_gain = 1.0;
130
131 if ((((RotSpkr *)ptr)->ringbuffer_h_L =
132 calloc(2 * PM_DEPTH, sizeof(LADSPA_Data))) == NULL)
133 return NULL;
134 if ((((RotSpkr *)ptr)->ringbuffer_h_R =
135 calloc(2 * PM_DEPTH, sizeof(LADSPA_Data))) == NULL)
136 return NULL;
137 ((RotSpkr *)ptr)->buflen_h_L = ceil(0.3f * sample_rate / M_PI);
138 ((RotSpkr *)ptr)->buflen_h_R = ceil(0.3f * sample_rate / M_PI);
139 ((RotSpkr *)ptr)->pos_h_L = 0;
140 ((RotSpkr *)ptr)->pos_h_R = 0;
141
142 if ((((RotSpkr *)ptr)->ringbuffer_b_L =
143 calloc(2 * PM_DEPTH, sizeof(LADSPA_Data))) == NULL)
144 return NULL;
145 if ((((RotSpkr *)ptr)->ringbuffer_b_R =
146 calloc(2 * PM_DEPTH, sizeof(LADSPA_Data))) == NULL)
147 return NULL;
148 ((RotSpkr *)ptr)->buflen_b_L = ceil(0.3f * sample_rate / M_PI);
149 ((RotSpkr *)ptr)->buflen_b_R = ceil(0.3f * sample_rate / M_PI);
150 ((RotSpkr *)ptr)->pos_b_L = 0;
151 ((RotSpkr *)ptr)->pos_b_R = 0;
152
153 if ((((RotSpkr *)ptr)->eq_filter_L = calloc(1, sizeof(biquad))) == NULL)
154 return NULL;
155 if ((((RotSpkr *)ptr)->lp_filter_L = calloc(1, sizeof(biquad))) == NULL)
156 return NULL;
157 if ((((RotSpkr *)ptr)->hp_filter_L = calloc(1, sizeof(biquad))) == NULL)
158 return NULL;
159
160 if ((((RotSpkr *)ptr)->eq_filter_R = calloc(1, sizeof(biquad))) == NULL)
161 return NULL;
162 if ((((RotSpkr *)ptr)->lp_filter_R = calloc(1, sizeof(biquad))) == NULL)
163 return NULL;
164 if ((((RotSpkr *)ptr)->hp_filter_R = calloc(1, sizeof(biquad))) == NULL)
165 return NULL;
166
167 return ptr;
168 }
169
170 return NULL;
171 }
172
173 void
activate_RotSpkr(LADSPA_Handle Instance)174 activate_RotSpkr(LADSPA_Handle Instance) {
175
176 int i;
177 RotSpkr * ptr;
178
179 ptr = (RotSpkr *)Instance;
180
181 for (i = 0; i < 2 * PM_DEPTH; i++) {
182 ptr->ringbuffer_h_L[i] = 0.0f;
183 ptr->ringbuffer_h_R[i] = 0.0f;
184 ptr->ringbuffer_b_L[i] = 0.0f;
185 ptr->ringbuffer_b_R[i] = 0.0f;
186 }
187
188 ptr->phase_h = 0.0f;
189 ptr->phase_b = 0.0f;
190
191 biquad_init(ptr->eq_filter_L);
192 biquad_init(ptr->lp_filter_L);
193 biquad_init(ptr->hp_filter_L);
194 biquad_init(ptr->eq_filter_R);
195 biquad_init(ptr->lp_filter_R);
196 biquad_init(ptr->hp_filter_R);
197
198 eq_set_params(ptr->eq_filter_L, SPLIT_FREQ, +8.0f, SPLIT_BW, ptr->sample_rate);
199 eq_set_params(ptr->eq_filter_R, SPLIT_FREQ, +8.0f, SPLIT_BW, ptr->sample_rate);
200 lp_set_params(ptr->lp_filter_L, SPLIT_FREQ, SPLIT_BW, ptr->sample_rate);
201 lp_set_params(ptr->lp_filter_R, SPLIT_FREQ, SPLIT_BW, ptr->sample_rate);
202 hp_set_params(ptr->hp_filter_L, SPLIT_FREQ, SPLIT_BW, ptr->sample_rate);
203 hp_set_params(ptr->hp_filter_R, SPLIT_FREQ, SPLIT_BW, ptr->sample_rate);
204 }
205
206
207
208 /* Connect a port to a data location. */
209 void
connect_port_RotSpkr(LADSPA_Handle Instance,unsigned long Port,LADSPA_Data * DataLocation)210 connect_port_RotSpkr(LADSPA_Handle Instance,
211 unsigned long Port,
212 LADSPA_Data * DataLocation) {
213
214 RotSpkr * ptr;
215
216 ptr = (RotSpkr *)Instance;
217 switch (Port) {
218 case HORNFREQ:
219 ptr->hornfreq = DataLocation;
220 break;
221 case BASSFREQ:
222 ptr->bassfreq = DataLocation;
223 break;
224 case STWIDTH:
225 ptr->stwidth = DataLocation;
226 break;
227 case HRBAL:
228 ptr->hrbal = DataLocation;
229 break;
230 case LATENCY:
231 ptr->latency = DataLocation;
232 *(ptr->latency) = ptr->buflen_h_L / 2; /* IS THIS LEGAL? */
233 break;
234 case INPUT_L:
235 ptr->input_L = DataLocation;
236 break;
237 case INPUT_R:
238 ptr->input_R = DataLocation;
239 break;
240 case OUTPUT_L:
241 ptr->output_L = DataLocation;
242 break;
243 case OUTPUT_R:
244 ptr->output_R = DataLocation;
245 break;
246 }
247 }
248
249
250
251 void
run_RotSpkr(LADSPA_Handle Instance,unsigned long SampleCount)252 run_RotSpkr(LADSPA_Handle Instance,
253 unsigned long SampleCount) {
254
255 RotSpkr * ptr = (RotSpkr *)Instance;
256
257 LADSPA_Data * input_L = ptr->input_L;
258 LADSPA_Data * input_R = ptr->input_R;
259 LADSPA_Data * output_L = ptr->output_L;
260 LADSPA_Data * output_R = ptr->output_R;
261 LADSPA_Data freq_h = LIMIT(*(ptr->hornfreq),0.0f,PM_FREQ);
262 LADSPA_Data freq_b = LIMIT(*(ptr->bassfreq),0.0f,PM_FREQ);
263 LADSPA_Data stwidth = LIMIT(*(ptr->stwidth),0.0f,100.0f);
264 LADSPA_Data hrbal = LIMIT(*(ptr->hrbal),0.0f,1.0f);
265 LADSPA_Data pmdepth_h =
266 LIMIT(1.0f/(1.0f+FREQ_PITCH*freq_h/C_AIR) * ptr->sample_rate
267 / 200.0f / M_PI / freq_h, 0, ptr->buflen_h_L / 2);
268 LADSPA_Data pmdepth_b =
269 LIMIT(1.0f/(1.0f+FREQ_PITCH*freq_b/C_AIR) * ptr->sample_rate
270 / 200.0f / M_PI / freq_b, 0, ptr->buflen_b_L / 2);
271 unsigned long sample_index;
272
273 LADSPA_Data in_L = 0.0f, in_R = 0.0f;
274 LADSPA_Data lo_L = 0.0f, lo_R = 0.0f;
275 LADSPA_Data hi_L = 0.0f, hi_R = 0.0f;
276
277 LADSPA_Data phase_h_L = 0.0f, phase_b_L = 0.0f;
278 LADSPA_Data phase_h_R = 0.0f, phase_b_R = 0.0f;
279 LADSPA_Data phase_pm_h_L = 0.0f, phase_pm_b_L = 0.0f;
280 LADSPA_Data phase_pm_h_R = 0.0f, phase_pm_b_R = 0.0f;
281 LADSPA_Data pm_h_L = 0.0f, pm_b_L = 0.0f;
282 LADSPA_Data pm_h_R = 0.0f, pm_b_R = 0.0f;
283
284 LADSPA_Data fpos_h_L = 0.0f, fpos_b_L = 0.0f, fpos_h_R = 0.0f, fpos_b_R = 0.0f;
285 LADSPA_Data n_h_L = 0.0f, n_b_L = 0.0f, n_h_R = 0.0f, n_b_R = 0.0f;
286 LADSPA_Data rem_h_L = 0.0f, rem_b_L = 0.0f, rem_h_R = 0.0f, rem_b_R = 0.0f;
287 LADSPA_Data sa_h_L = 0.0f, sa_b_L = 0.0f, sb_h_L = 0.0f, sb_b_L = 0.0f;
288 LADSPA_Data sa_h_R = 0.0f, sa_b_R = 0.0f, sb_h_R = 0.0f, sb_b_R = 0.0f;
289
290
291 for (sample_index = 0; sample_index < SampleCount; sample_index++) {
292
293 in_L = *(input_L++);
294 in_R = *(input_R++);
295
296 in_L = biquad_run(ptr->eq_filter_L, in_L);
297 in_R = biquad_run(ptr->eq_filter_R, in_R);
298 lo_L = biquad_run(ptr->lp_filter_L, in_L);
299 lo_R = biquad_run(ptr->lp_filter_R, in_R);
300 hi_L = biquad_run(ptr->hp_filter_L, in_L);
301 hi_R = biquad_run(ptr->hp_filter_R, in_R);
302
303
304 phase_h_L = 1024.0f * freq_h * sample_index / ptr->sample_rate + ptr->phase_h;
305 while (phase_h_L >= 1024.0f)
306 phase_h_L -= 1024.0f;
307 phase_pm_h_L = phase_h_L + 256.0f;
308 while (phase_pm_h_L >= 1024.0f)
309 phase_pm_h_L -= 1024.0f;
310 phase_h_R = phase_h_L + 512.0f;
311 while (phase_h_R >= 1024.0f)
312 phase_h_R -= 1024.0f;
313 phase_pm_h_R = phase_h_R + 256.0f;
314 while (phase_pm_h_R >= 1024.0f)
315 phase_pm_h_R -= 1024.0f;
316
317 phase_b_L = 1024.0f * freq_b * sample_index / ptr->sample_rate + ptr->phase_b;
318 while (phase_b_L >= 1024.0f)
319 phase_b_L -= 1024.0f;
320 phase_pm_b_L = phase_b_L + 256.0f;
321 while (phase_pm_b_L >= 1024.0f)
322 phase_pm_b_L -= 1024.0f;
323 phase_b_R = phase_b_L + 512.0f;
324 while (phase_b_R >= 1024.0f)
325 phase_b_R -= 1024.0f;
326 phase_pm_b_R = phase_b_R + 256.0f;
327 while (phase_pm_b_R >= 1024.0f)
328 phase_pm_b_R -= 1024.0f;
329
330 push_buffer(hi_L, ptr->ringbuffer_h_L, ptr->buflen_h_L, &(ptr->pos_h_L));
331 push_buffer(hi_R, ptr->ringbuffer_h_R, ptr->buflen_h_R, &(ptr->pos_h_R));
332 push_buffer(lo_L, ptr->ringbuffer_b_L, ptr->buflen_b_L, &(ptr->pos_b_L));
333 push_buffer(lo_R, ptr->ringbuffer_b_R, ptr->buflen_b_R, &(ptr->pos_b_R));
334
335 fpos_h_L = pmdepth_h * (1.0f - cos_table[(unsigned long) phase_pm_h_L]);
336 n_h_L = floorf(fpos_h_L);
337 rem_h_L = fpos_h_L - n_h_L;
338 sa_h_L = read_buffer(ptr->ringbuffer_h_L,
339 ptr->buflen_h_L, ptr->pos_h_L, (unsigned long) n_h_L);
340 sb_h_L = read_buffer(ptr->ringbuffer_h_L,
341 ptr->buflen_h_L, ptr->pos_h_L, (unsigned long) n_h_L + 1);
342 pm_h_L = (1 - rem_h_L) * sa_h_L + rem_h_L * sb_h_L;
343
344 fpos_h_R = pmdepth_h * (1.0f - cos_table[(unsigned long) phase_pm_h_R]);
345 n_h_R = floorf(fpos_h_R);
346 rem_h_R = fpos_h_R - n_h_R;
347 sa_h_R = read_buffer(ptr->ringbuffer_h_R,
348 ptr->buflen_h_R, ptr->pos_h_R, (unsigned long) n_h_R);
349 sb_h_R = read_buffer(ptr->ringbuffer_h_R,
350 ptr->buflen_h_R, ptr->pos_h_R, (unsigned long) n_h_R + 1);
351 pm_h_R = (1 - rem_h_R) * sa_h_R + rem_h_R * sb_h_R;
352
353
354 fpos_b_L = pmdepth_b * (1.0f - cos_table[(unsigned long) phase_pm_b_L]);
355 n_b_L = floorf(fpos_b_L);
356 rem_b_L = fpos_b_L - n_b_L;
357 sa_b_L = read_buffer(ptr->ringbuffer_b_L,
358 ptr->buflen_b_L, ptr->pos_b_L, (unsigned long) n_b_L);
359 sb_b_L = read_buffer(ptr->ringbuffer_b_L,
360 ptr->buflen_b_L, ptr->pos_b_L, (unsigned long) n_b_L + 1);
361 pm_b_L = (1 - rem_b_L) * sa_b_L + rem_b_L * sb_b_L;
362
363 fpos_b_R = pmdepth_b * (1.0f - cos_table[(unsigned long) phase_pm_b_R]);
364 n_b_R = floorf(fpos_b_R);
365 rem_b_R = fpos_b_R - n_b_R;
366 sa_b_R = read_buffer(ptr->ringbuffer_b_R,
367 ptr->buflen_b_R, ptr->pos_b_R, (unsigned long) n_b_R);
368 sb_b_R = read_buffer(ptr->ringbuffer_b_R,
369 ptr->buflen_b_R, ptr->pos_b_R, (unsigned long) n_b_R + 1);
370 pm_b_R = (1 - rem_b_R) * sa_b_R + rem_b_R * sb_b_R;
371
372
373 *(output_L++) =
374 hrbal * pm_h_L * (1.0f + 0.5f * stwidth/100.0f *
375 cos_table[(unsigned long) phase_h_L]) +
376 (1.0f - hrbal) * pm_b_L * (1.0f + 0.5f * stwidth/100.0f *
377 cos_table[(unsigned long) phase_b_L]);
378
379 *(output_R++) =
380 hrbal * pm_h_R * (1.0f + 0.5f * stwidth/100.0f *
381 cos_table[(unsigned long) phase_h_R]) +
382 (1.0f - hrbal) * pm_b_R * (1.0f + 0.5f * stwidth/100.0f *
383 cos_table[(unsigned long) phase_b_R]);
384 }
385
386 ptr->phase_h += 1024.0f * freq_h * sample_index / ptr->sample_rate;
387 while (ptr->phase_h >= 1024.0f)
388 ptr->phase_h -= 1024.0f;
389 ptr->phase_b += 1024.0f * freq_b * sample_index / ptr->sample_rate;
390 while (ptr->phase_b >= 1024.0f)
391 ptr->phase_b -= 1024.0f;
392
393 *(ptr->latency) = ptr->buflen_h_L / 2;
394 }
395
396
397 void
set_run_adding_gain_RotSpkr(LADSPA_Handle Instance,LADSPA_Data gain)398 set_run_adding_gain_RotSpkr(LADSPA_Handle Instance, LADSPA_Data gain) {
399
400 RotSpkr * ptr = (RotSpkr *)Instance;
401
402 ptr->run_adding_gain = gain;
403 }
404
405
406
407 void
run_adding_RotSpkr(LADSPA_Handle Instance,unsigned long SampleCount)408 run_adding_RotSpkr(LADSPA_Handle Instance,
409 unsigned long SampleCount) {
410
411 RotSpkr * ptr = (RotSpkr *)Instance;
412
413 LADSPA_Data * input_L = ptr->input_L;
414 LADSPA_Data * input_R = ptr->input_R;
415 LADSPA_Data * output_L = ptr->output_L;
416 LADSPA_Data * output_R = ptr->output_R;
417 LADSPA_Data freq_h = LIMIT(*(ptr->hornfreq),0.0f,PM_FREQ);
418 LADSPA_Data freq_b = LIMIT(*(ptr->bassfreq),0.0f,PM_FREQ);
419 LADSPA_Data stwidth = LIMIT(*(ptr->stwidth),0.0f,100.0f);
420 LADSPA_Data hrbal = LIMIT(*(ptr->hrbal),0.0f,1.0f);
421 LADSPA_Data pmdepth_h =
422 LIMIT(1.0f/(1.0f+FREQ_PITCH*freq_h/C_AIR) * ptr->sample_rate
423 / 200.0f / M_PI / freq_h, 0, ptr->buflen_h_L / 2);
424 LADSPA_Data pmdepth_b =
425 LIMIT(1.0f/(1.0f+FREQ_PITCH*freq_b/C_AIR) * ptr->sample_rate
426 / 200.0f / M_PI / freq_b, 0, ptr->buflen_b_L / 2);
427 unsigned long sample_index;
428
429 LADSPA_Data in_L = 0.0f, in_R = 0.0f;
430 LADSPA_Data lo_L = 0.0f, lo_R = 0.0f;
431 LADSPA_Data hi_L = 0.0f, hi_R = 0.0f;
432
433 LADSPA_Data phase_h_L = 0.0f, phase_b_L = 0.0f;
434 LADSPA_Data phase_h_R = 0.0f, phase_b_R = 0.0f;
435 LADSPA_Data phase_pm_h_L = 0.0f, phase_pm_b_L = 0.0f;
436 LADSPA_Data phase_pm_h_R = 0.0f, phase_pm_b_R = 0.0f;
437 LADSPA_Data pm_h_L = 0.0f, pm_b_L = 0.0f;
438 LADSPA_Data pm_h_R = 0.0f, pm_b_R = 0.0f;
439
440 LADSPA_Data fpos_h_L = 0.0f, fpos_b_L = 0.0f, fpos_h_R = 0.0f, fpos_b_R = 0.0f;
441 LADSPA_Data n_h_L = 0.0f, n_b_L = 0.0f, n_h_R = 0.0f, n_b_R = 0.0f;
442 LADSPA_Data rem_h_L = 0.0f, rem_b_L = 0.0f, rem_h_R = 0.0f, rem_b_R = 0.0f;
443 LADSPA_Data sa_h_L = 0.0f, sa_b_L = 0.0f, sb_h_L = 0.0f, sb_b_L = 0.0f;
444 LADSPA_Data sa_h_R = 0.0f, sa_b_R = 0.0f, sb_h_R = 0.0f, sb_b_R = 0.0f;
445
446
447 for (sample_index = 0; sample_index < SampleCount; sample_index++) {
448
449 in_L = *(input_L++);
450 in_R = *(input_R++);
451
452 in_L = biquad_run(ptr->eq_filter_L, in_L);
453 in_R = biquad_run(ptr->eq_filter_R, in_R);
454 lo_L = biquad_run(ptr->lp_filter_L, in_L);
455 lo_R = biquad_run(ptr->lp_filter_R, in_R);
456 hi_L = biquad_run(ptr->hp_filter_L, in_L);
457 hi_R = biquad_run(ptr->hp_filter_R, in_R);
458
459
460 phase_h_L = 1024.0f * freq_h * sample_index / ptr->sample_rate + ptr->phase_h;
461 while (phase_h_L >= 1024.0f)
462 phase_h_L -= 1024.0f;
463 phase_pm_h_L = phase_h_L + 256.0f;
464 while (phase_pm_h_L >= 1024.0f)
465 phase_pm_h_L -= 1024.0f;
466 phase_h_R = phase_h_L + 512.0f;
467 while (phase_h_R >= 1024.0f)
468 phase_h_R -= 1024.0f;
469 phase_pm_h_R = phase_h_R + 256.0f;
470 while (phase_pm_h_R >= 1024.0f)
471 phase_pm_h_R -= 1024.0f;
472
473 phase_b_L = 1024.0f * freq_b * sample_index / ptr->sample_rate + ptr->phase_b;
474 while (phase_b_L >= 1024.0f)
475 phase_b_L -= 1024.0f;
476 phase_pm_b_L = phase_b_L + 256.0f;
477 while (phase_pm_b_L >= 1024.0f)
478 phase_pm_b_L -= 1024.0f;
479 phase_b_R = phase_b_L + 512.0f;
480 while (phase_b_R >= 1024.0f)
481 phase_b_R -= 1024.0f;
482 phase_pm_b_R = phase_b_R + 256.0f;
483 while (phase_pm_b_R >= 1024.0f)
484 phase_pm_b_R -= 1024.0f;
485
486 push_buffer(hi_L, ptr->ringbuffer_h_L, ptr->buflen_h_L, &(ptr->pos_h_L));
487 push_buffer(hi_R, ptr->ringbuffer_h_R, ptr->buflen_h_R, &(ptr->pos_h_R));
488 push_buffer(lo_L, ptr->ringbuffer_b_L, ptr->buflen_b_L, &(ptr->pos_b_L));
489 push_buffer(lo_R, ptr->ringbuffer_b_R, ptr->buflen_b_R, &(ptr->pos_b_R));
490
491 fpos_h_L = pmdepth_h * (1.0f - cos_table[(unsigned long) phase_pm_h_L]);
492 n_h_L = floorf(fpos_h_L);
493 rem_h_L = fpos_h_L - n_h_L;
494 sa_h_L = read_buffer(ptr->ringbuffer_h_L,
495 ptr->buflen_h_L, ptr->pos_h_L, (unsigned long) n_h_L);
496 sb_h_L = read_buffer(ptr->ringbuffer_h_L,
497 ptr->buflen_h_L, ptr->pos_h_L, (unsigned long) n_h_L + 1);
498 pm_h_L = (1 - rem_h_L) * sa_h_L + rem_h_L * sb_h_L;
499
500 fpos_h_R = pmdepth_h * (1.0f - cos_table[(unsigned long) phase_pm_h_R]);
501 n_h_R = floorf(fpos_h_R);
502 rem_h_R = fpos_h_R - n_h_R;
503 sa_h_R = read_buffer(ptr->ringbuffer_h_R,
504 ptr->buflen_h_R, ptr->pos_h_R, (unsigned long) n_h_R);
505 sb_h_R = read_buffer(ptr->ringbuffer_h_R,
506 ptr->buflen_h_R, ptr->pos_h_R, (unsigned long) n_h_R + 1);
507 pm_h_R = (1 - rem_h_R) * sa_h_R + rem_h_R * sb_h_R;
508
509
510 fpos_b_L = pmdepth_b * (1.0f - cos_table[(unsigned long) phase_pm_b_L]);
511 n_b_L = floorf(fpos_b_L);
512 rem_b_L = fpos_b_L - n_b_L;
513 sa_b_L = read_buffer(ptr->ringbuffer_b_L,
514 ptr->buflen_b_L, ptr->pos_b_L, (unsigned long) n_b_L);
515 sb_b_L = read_buffer(ptr->ringbuffer_b_L,
516 ptr->buflen_b_L, ptr->pos_b_L, (unsigned long) n_b_L + 1);
517 pm_b_L = (1 - rem_b_L) * sa_b_L + rem_b_L * sb_b_L;
518
519 fpos_b_R = pmdepth_b * (1.0f - cos_table[(unsigned long) phase_pm_b_R]);
520 n_b_R = floorf(fpos_b_R);
521 rem_b_R = fpos_b_R - n_b_R;
522 sa_b_R = read_buffer(ptr->ringbuffer_b_R,
523 ptr->buflen_b_R, ptr->pos_b_R, (unsigned long) n_b_R);
524 sb_b_R = read_buffer(ptr->ringbuffer_b_R,
525 ptr->buflen_b_R, ptr->pos_b_R, (unsigned long) n_b_R + 1);
526 pm_b_R = (1 - rem_b_R) * sa_b_R + rem_b_R * sb_b_R;
527
528
529 *(output_L++) += ptr->run_adding_gain *
530 hrbal * pm_h_L * (1.0f + 0.5f * stwidth/100.0f *
531 cos_table[(unsigned long) phase_h_L]) +
532 (1.0f - hrbal) * pm_b_L * (1.0f + 0.5f * stwidth/100.0f *
533 cos_table[(unsigned long) phase_b_L]);
534
535 *(output_R++) += ptr->run_adding_gain *
536 hrbal * pm_h_R * (1.0f + 0.5f * stwidth/100.0f *
537 cos_table[(unsigned long) phase_h_R]) +
538 (1.0f - hrbal) * pm_b_R * (1.0f + 0.5f * stwidth/100.0f *
539 cos_table[(unsigned long) phase_b_R]);
540 }
541
542 ptr->phase_h += 1024.0f * freq_h * sample_index / ptr->sample_rate;
543 while (ptr->phase_h >= 1024.0f)
544 ptr->phase_h -= 1024.0f;
545 ptr->phase_b += 1024.0f * freq_b * sample_index / ptr->sample_rate;
546 while (ptr->phase_b >= 1024.0f)
547 ptr->phase_b -= 1024.0f;
548
549 *(ptr->latency) = ptr->buflen_h_L / 2;
550 }
551
552
553
554 /* Throw away an RotSpkr effect instance. */
555 void
cleanup_RotSpkr(LADSPA_Handle Instance)556 cleanup_RotSpkr(LADSPA_Handle Instance) {
557
558 RotSpkr * ptr = (RotSpkr *)Instance;
559
560 free(ptr->ringbuffer_h_L);
561 free(ptr->ringbuffer_h_R);
562 free(ptr->ringbuffer_b_L);
563 free(ptr->ringbuffer_b_R);
564 free(ptr->eq_filter_L);
565 free(ptr->eq_filter_R);
566 free(ptr->lp_filter_L);
567 free(ptr->lp_filter_R);
568 free(ptr->hp_filter_L);
569 free(ptr->hp_filter_R);
570 free(Instance);
571 }
572
573
574
575 LADSPA_Descriptor * stereo_descriptor = NULL;
576
577
578
579 /* _init() is called automatically when the plugin library is first
580 loaded. */
581 void
_init()582 _init() {
583
584 int i;
585 char ** port_names;
586 LADSPA_PortDescriptor * port_descriptors;
587 LADSPA_PortRangeHint * port_range_hints;
588
589 if ((stereo_descriptor =
590 (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
591 exit(1);
592
593 for (i = 0; i < 1024; i++)
594 cos_table[i] = cosf(i * M_PI / 512.0f);
595
596
597 stereo_descriptor->UniqueID = ID_STEREO;
598 stereo_descriptor->Label = strdup("tap_rotspeak");
599 stereo_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
600 stereo_descriptor->Name = strdup("TAP Rotary Speaker");
601 stereo_descriptor->Maker = strdup("Tom Szilagyi");
602 stereo_descriptor->Copyright = strdup("GPL");
603 stereo_descriptor->PortCount = PORTCOUNT_STEREO;
604
605 if ((port_descriptors =
606 (LADSPA_PortDescriptor *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortDescriptor))) == NULL)
607 exit(1);
608
609 stereo_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
610 port_descriptors[HORNFREQ] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
611 port_descriptors[BASSFREQ] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
612 port_descriptors[STWIDTH] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
613 port_descriptors[HRBAL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
614 port_descriptors[LATENCY] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
615 port_descriptors[INPUT_L] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
616 port_descriptors[INPUT_R] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
617 port_descriptors[OUTPUT_L] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
618 port_descriptors[OUTPUT_R] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
619
620 if ((port_names =
621 (char **)calloc(PORTCOUNT_STEREO, sizeof(char *))) == NULL)
622 exit(1);
623
624 stereo_descriptor->PortNames = (const char **)port_names;
625 port_names[HORNFREQ] = strdup("Horn Frequency [Hz]");
626 port_names[BASSFREQ] = strdup("Rotor Frequency [Hz]");
627 port_names[STWIDTH] = strdup("Mic Distance [%]");
628 port_names[HRBAL] = strdup("Rotor/Horn Mix");
629 port_names[LATENCY] = strdup("latency");
630 port_names[INPUT_L] = strdup("Input L");
631 port_names[INPUT_R] = strdup("Input R");
632 port_names[OUTPUT_L] = strdup("Output L");
633 port_names[OUTPUT_R] = strdup("Output R");
634
635 if ((port_range_hints =
636 ((LADSPA_PortRangeHint *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortRangeHint)))) == NULL)
637 exit(1);
638
639 stereo_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
640 port_range_hints[HORNFREQ].HintDescriptor =
641 (LADSPA_HINT_BOUNDED_BELOW |
642 LADSPA_HINT_BOUNDED_ABOVE |
643 LADSPA_HINT_DEFAULT_0);
644 port_range_hints[BASSFREQ].HintDescriptor =
645 (LADSPA_HINT_BOUNDED_BELOW |
646 LADSPA_HINT_BOUNDED_ABOVE |
647 LADSPA_HINT_DEFAULT_0);
648 port_range_hints[STWIDTH].HintDescriptor =
649 (LADSPA_HINT_BOUNDED_BELOW |
650 LADSPA_HINT_BOUNDED_ABOVE |
651 LADSPA_HINT_DEFAULT_LOW);
652 port_range_hints[HRBAL].HintDescriptor =
653 (LADSPA_HINT_BOUNDED_BELOW |
654 LADSPA_HINT_BOUNDED_ABOVE |
655 LADSPA_HINT_DEFAULT_MIDDLE);
656 port_range_hints[LATENCY].HintDescriptor =
657 (LADSPA_HINT_BOUNDED_BELOW |
658 LADSPA_HINT_BOUNDED_ABOVE |
659 LADSPA_HINT_DEFAULT_MAXIMUM);
660 port_range_hints[HORNFREQ].LowerBound = 0;
661 port_range_hints[HORNFREQ].UpperBound = PM_FREQ;
662 port_range_hints[BASSFREQ].LowerBound = 0;
663 port_range_hints[BASSFREQ].UpperBound = PM_FREQ;
664 port_range_hints[STWIDTH].LowerBound = 0;
665 port_range_hints[STWIDTH].UpperBound = 100.0f;
666 port_range_hints[HRBAL].LowerBound = 0;
667 port_range_hints[HRBAL].UpperBound = 1.0f;
668 port_range_hints[LATENCY].LowerBound = 0;
669 port_range_hints[LATENCY].UpperBound = PM_DEPTH;
670 port_range_hints[INPUT_L].HintDescriptor = 0;
671 port_range_hints[INPUT_R].HintDescriptor = 0;
672 port_range_hints[OUTPUT_L].HintDescriptor = 0;
673 port_range_hints[OUTPUT_R].HintDescriptor = 0;
674 stereo_descriptor->instantiate = instantiate_RotSpkr;
675 stereo_descriptor->connect_port = connect_port_RotSpkr;
676 stereo_descriptor->activate = activate_RotSpkr;
677 stereo_descriptor->run = run_RotSpkr;
678 stereo_descriptor->run_adding = run_adding_RotSpkr;
679 stereo_descriptor->set_run_adding_gain = set_run_adding_gain_RotSpkr;
680 stereo_descriptor->deactivate = NULL;
681 stereo_descriptor->cleanup = cleanup_RotSpkr;
682 }
683
684
685 void
delete_descriptor(LADSPA_Descriptor * descriptor)686 delete_descriptor(LADSPA_Descriptor * descriptor) {
687 unsigned long index;
688 if (descriptor) {
689 free((char *)descriptor->Label);
690 free((char *)descriptor->Name);
691 free((char *)descriptor->Maker);
692 free((char *)descriptor->Copyright);
693 free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
694 for (index = 0; index < descriptor->PortCount; index++)
695 free((char *)(descriptor->PortNames[index]));
696 free((char **)descriptor->PortNames);
697 free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
698 free(descriptor);
699 }
700 }
701
702
703 /* _fini() is called automatically when the library is unloaded. */
704 void
_fini()705 _fini() {
706 delete_descriptor(stereo_descriptor);
707 }
708
709
710 /* Return a descriptor of the requested plugin type. */
711 const LADSPA_Descriptor *
ladspa_descriptor(unsigned long Index)712 ladspa_descriptor(unsigned long Index) {
713
714 switch (Index) {
715 case 0:
716 return stereo_descriptor;
717 default:
718 return NULL;
719 }
720 }
721