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