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_eqbw.c,v 1.6 2009/08/17 11:16:19 tszilagyi Exp $
19 */
20 
21 
22 /* This plugin is identical to TAP Equalizer (2141), but it has
23  * separate user controls for setting the bandwidth of every filter.
24  */
25 
26 #include <stdlib.h>
27 #include <string.h>
28 #include <math.h>
29 
30 #include <lv2.h>
31 #include "tap_utils.h"
32 
33 /* The Unique ID of the plugin */
34 #define ID_MONO        2151
35 
36 
37 /* Default bandwidth of EQ filters in octaves */
38 #define BWIDTH        1.0f
39 
40 
41 /* Port numbers */
42 
43 #define EQ_CH0G                     0
44 #define EQ_CH1G                     1
45 #define EQ_CH2G                     2
46 #define EQ_CH3G                     3
47 #define EQ_CH4G                     4
48 #define EQ_CH5G                     5
49 #define EQ_CH6G                     6
50 #define EQ_CH7G                     7
51 
52 #define EQ_CH0F                     8
53 #define EQ_CH1F                     9
54 #define EQ_CH2F                     10
55 #define EQ_CH3F                     11
56 #define EQ_CH4F                     12
57 #define EQ_CH5F                     13
58 #define EQ_CH6F                     14
59 #define EQ_CH7F                     15
60 
61 #define EQ_CH0B                     16
62 #define EQ_CH1B                     17
63 #define EQ_CH2B                     18
64 #define EQ_CH3B                     19
65 #define EQ_CH4B                     20
66 #define EQ_CH5B                     21
67 #define EQ_CH6B                     22
68 #define EQ_CH7B                     23
69 
70 #define EQ_INPUT                    24
71 #define EQ_OUTPUT                   25
72 
73 
74 /* Total number of ports */
75 #define PORTCOUNT_MONO  26
76 
77 typedef struct {
78 	float *ch0f;
79 	float *ch0g;
80 	float *ch0b;
81 	float *ch1f;
82 	float *ch1g;
83 	float *ch1b;
84 	float *ch2f;
85 	float *ch2g;
86 	float *ch2b;
87 	float *ch3f;
88 	float *ch3g;
89 	float *ch3b;
90 	float *ch4f;
91 	float *ch4g;
92 	float *ch4b;
93 	float *ch5f;
94 	float *ch5g;
95 	float *ch5b;
96 	float *ch6f;
97 	float *ch6g;
98 	float *ch6b;
99 	float *ch7f;
100 	float *ch7g;
101 	float *ch7b;
102 	float *input;
103 	float *output;
104 	biquad *     filters;
105 	float        fs;
106 	float old_ch0f;
107 	float old_ch0g;
108 	float old_ch0b;
109 	float old_ch1f;
110 	float old_ch1g;
111 	float old_ch1b;
112 	float old_ch2f;
113 	float old_ch2g;
114 	float old_ch2b;
115 	float old_ch3f;
116 	float old_ch3g;
117 	float old_ch3b;
118 	float old_ch4f;
119 	float old_ch4g;
120 	float old_ch4b;
121 	float old_ch5f;
122 	float old_ch5g;
123 	float old_ch5b;
124 	float old_ch6f;
125 	float old_ch6g;
126 	float old_ch6b;
127 	float old_ch7f;
128 	float old_ch7g;
129 	float old_ch7b;
130 } eq;
131 
132 
133 static
134 void
activate_eq(LV2_Handle instance)135 activate_eq(LV2_Handle instance) {
136 
137 	eq *ptr = (eq *)instance;
138 	biquad *filters = ptr->filters;
139 
140 	biquad_init(&filters[0]);
141 	biquad_init(&filters[1]);
142 	biquad_init(&filters[2]);
143 	biquad_init(&filters[3]);
144 	biquad_init(&filters[4]);
145 	biquad_init(&filters[5]);
146 	biquad_init(&filters[6]);
147 	biquad_init(&filters[7]);
148 }
149 
150 void
deactivate_eq(LV2_Handle Instance)151 deactivate_eq(LV2_Handle Instance) {
152 
153 
154 }
155 
156 static
157 void
cleanup_eq(LV2_Handle instance)158 cleanup_eq(LV2_Handle instance) {
159 
160 	eq *ptr = (eq *)instance;
161 	free(ptr->filters);
162 	free(instance);
163 }
164 
165 
166 static
167 void
connectPort_eq(LV2_Handle instance,uint32_t port,void * data)168 connectPort_eq(LV2_Handle instance, uint32_t port, void *data) {
169 
170 	eq *plugin;
171 
172 	plugin = (eq *)instance;
173 	switch (port) {
174 	case EQ_CH0F:
175 		plugin->ch0f = (float*) data;
176 		break;
177 	case EQ_CH0G:
178 		plugin->ch0g = (float*) data;
179 		break;
180 	case EQ_CH0B:
181 		plugin->ch0b = (float*) data;
182 		break;
183 	case EQ_CH1F:
184 		plugin->ch1f = (float*) data;
185 		break;
186 	case EQ_CH1G:
187 		plugin->ch1g = (float*) data;
188 		break;
189 	case EQ_CH1B:
190 		plugin->ch1b = (float*) data;
191 		break;
192 	case EQ_CH2F:
193 		plugin->ch2f = (float*) data;
194 		break;
195 	case EQ_CH2G:
196 		plugin->ch2g = (float*) data;
197 		break;
198 	case EQ_CH2B:
199 		plugin->ch2b = (float*) data;
200 		break;
201 	case EQ_CH3F:
202 		plugin->ch3f = (float*) data;
203 		break;
204 	case EQ_CH3G:
205 		plugin->ch3g = (float*) data;
206 		break;
207 	case EQ_CH3B:
208 		plugin->ch3b = (float*) data;
209 		break;
210 	case EQ_CH4F:
211 		plugin->ch4f = (float*) data;
212 		break;
213 	case EQ_CH4G:
214 		plugin->ch4g = (float*) data;
215 		break;
216 	case EQ_CH4B:
217 		plugin->ch4b = (float*) data;
218 		break;
219 	case EQ_CH5F:
220 		plugin->ch5f = (float*) data;
221 		break;
222 	case EQ_CH5G:
223 		plugin->ch5g = (float*) data;
224 		break;
225 	case EQ_CH5B:
226 		plugin->ch5b = (float*) data;
227 		break;
228 	case EQ_CH6F:
229 		plugin->ch6f = (float*) data;
230 		break;
231 	case EQ_CH6G:
232 		plugin->ch6g = (float*) data;
233 		break;
234 	case EQ_CH6B:
235 		plugin->ch6b = (float*) data;
236 		break;
237 	case EQ_CH7F:
238 		plugin->ch7f = (float*) data;
239 		break;
240 	case EQ_CH7G:
241 		plugin->ch7g = (float*) data;
242 		break;
243 	case EQ_CH7B:
244 		plugin->ch7b = (float*) data;
245 		break;
246 	case EQ_INPUT:
247 		plugin->input = (float*) data;
248 		break;
249 	case EQ_OUTPUT:
250 		plugin->output = (float*) data;
251 		break;
252 	}
253 }
254 
255 static
256 LV2_Handle
instantiate_eq(const LV2_Descriptor * descriptor,double s_rate,const char * bundle_path,const LV2_Feature * const * features)257 instantiate_eq(const LV2_Descriptor *descriptor, double s_rate, const char* bundle_path, const LV2_Feature* const* features) {
258 
259 	eq *ptr = (eq *)malloc(sizeof(eq));
260 	biquad *filters = NULL;
261 	float fs;
262 
263 	fs = s_rate;
264 
265 	memset(ptr, 0, sizeof(eq));
266 
267 	filters = calloc(8, sizeof(biquad));
268 
269 	ptr->filters = filters;
270 	ptr->fs = fs;
271 
272 	ptr->old_ch0f = 100.0f;
273 	ptr->old_ch0g = 0.0f;
274 	ptr->old_ch0b = BWIDTH;
275 
276 	ptr->old_ch1f = 200.0f;
277 	ptr->old_ch1g = 0.0f;
278 	ptr->old_ch1b = BWIDTH;
279 
280 	ptr->old_ch2f = 400.0f;
281 	ptr->old_ch2g = 0.0f;
282 	ptr->old_ch2b = BWIDTH;
283 
284 	ptr->old_ch3f = 1000.0f;
285 	ptr->old_ch3g = 0.0f;
286 	ptr->old_ch3b = BWIDTH;
287 
288 	ptr->old_ch4f = 3000.0f;
289 	ptr->old_ch4g = 0.0f;
290 	ptr->old_ch4b = BWIDTH;
291 
292 	ptr->old_ch5f = 6000.0f;
293 	ptr->old_ch5g = 0.0f;
294 	ptr->old_ch5b = BWIDTH;
295 
296 	ptr->old_ch6f = 12000.0f;
297 	ptr->old_ch6g = 0.0f;
298 	ptr->old_ch6b = BWIDTH;
299 
300 	ptr->old_ch7f = 15000.0f;
301 	ptr->old_ch7g = 0.0f;
302 	ptr->old_ch7b = BWIDTH;
303 
304 	eq_set_params(&filters[0], 100.0f, 0.0f, BWIDTH, fs);
305 	eq_set_params(&filters[1], 200.0f, 0.0f, BWIDTH, fs);
306 	eq_set_params(&filters[2], 400.0f, 0.0f, BWIDTH, fs);
307 	eq_set_params(&filters[3], 1000.0f, 0.0f, BWIDTH, fs);
308 	eq_set_params(&filters[4], 3000.0f, 0.0f, BWIDTH, fs);
309 	eq_set_params(&filters[5], 6000.0f, 0.0f, BWIDTH, fs);
310 	eq_set_params(&filters[6], 12000.0f, 0.0f, BWIDTH, fs);
311 	eq_set_params(&filters[7], 15000.0f, 0.0f, BWIDTH, fs);
312 
313 	return (LV2_Handle)ptr;
314 }
315 
316 
317 static
318 void
run_eq(LV2_Handle instance,uint32_t sample_count)319 run_eq(LV2_Handle instance, uint32_t sample_count) {
320 
321 	eq * ptr = (eq *)instance;
322 
323 	const float ch0f = LIMIT(*(ptr->ch0f),40.0f,280.0f);
324 	const float ch0g = LIMIT(*(ptr->ch0g),-50.0f,20.0f);
325 	const float ch0b = LIMIT(*(ptr->ch0b),0.1f,5.0f);
326 	const float ch1f = LIMIT(*(ptr->ch1f),100.0f,500.0f);
327 	const float ch1g = LIMIT(*(ptr->ch1g),-50.0f,20.0f);
328 	const float ch1b = LIMIT(*(ptr->ch1b),0.1f,5.0f);
329 	const float ch2f = LIMIT(*(ptr->ch2f),200.0f,1000.0f);
330 	const float ch2g = LIMIT(*(ptr->ch2g),-50.0f,20.0f);
331 	const float ch2b = LIMIT(*(ptr->ch2b),0.1f,5.0f);
332 	const float ch3f = LIMIT(*(ptr->ch3f),400.0f,2800.0f);
333 	const float ch3g = LIMIT(*(ptr->ch3g),-50.0f,20.0f);
334 	const float ch3b = LIMIT(*(ptr->ch3b),0.1f,5.0f);
335 	const float ch4f = LIMIT(*(ptr->ch4f),1000.0f,5000.0f);
336 	const float ch4g = LIMIT(*(ptr->ch4g),-50.0f,20.0f);
337 	const float ch4b = LIMIT(*(ptr->ch4b),0.1f,5.0f);
338 	const float ch5f = LIMIT(*(ptr->ch5f),3000.0f,9000.0f);
339 	const float ch5g = LIMIT(*(ptr->ch5g),-50.0f,20.0f);
340 	const float ch5b = LIMIT(*(ptr->ch5b),0.1f,5.0f);
341 	const float ch6f = LIMIT(*(ptr->ch6f),6000.0f,18000.0f);
342 	const float ch6g = LIMIT(*(ptr->ch6g),-50.0f,20.0f);
343 	const float ch6b = LIMIT(*(ptr->ch6b),0.1f,5.0f);
344 	const float ch7f = LIMIT(*(ptr->ch7f),10000.0f,20000.0f);
345 	const float ch7g = LIMIT(*(ptr->ch7g),-50.0f,20.0f);
346 	const float ch7b = LIMIT(*(ptr->ch7b),0.1f,5.0f);
347 
348 	const float * input = ptr->input;
349 	float * output = ptr->output;
350 
351 	biquad * filters = ptr->filters;
352 	float fs = ptr->fs;
353 
354 	unsigned long pos;
355 	float samp;
356 
357 
358 	if ((ch0f != ptr->old_ch0f) ||
359 	    (ch0g != ptr->old_ch0g) ||
360 	    (ch0b != ptr->old_ch0b)) {
361 		ptr->old_ch0f = ch0f;
362 		ptr->old_ch0g = ch0g;
363 		ptr->old_ch0b = ch0b;
364 		eq_set_params(&filters[0], ch0f, ch0g, ch0b, fs);
365 	}
366 	if ((ch1f != ptr->old_ch1f) ||
367 	    (ch1g != ptr->old_ch1g) ||
368 	    (ch1b != ptr->old_ch1b)) {
369 		ptr->old_ch1f = ch1f;
370 		ptr->old_ch1g = ch1g;
371 		ptr->old_ch1b = ch1b;
372 		eq_set_params(&filters[1], ch1f, ch1g, ch1b, fs);
373 	}
374 	if ((ch2f != ptr->old_ch2f) ||
375 	    (ch2g != ptr->old_ch2g) ||
376 	    (ch2b != ptr->old_ch2b)) {
377 		ptr->old_ch2f = ch2f;
378 		ptr->old_ch2g = ch2g;
379 		ptr->old_ch2b = ch2b;
380 		eq_set_params(&filters[2], ch2f, ch2g, ch2b, fs);
381 	}
382 	if ((ch3f != ptr->old_ch3f) ||
383 	    (ch3g != ptr->old_ch3g) ||
384 	    (ch3b != ptr->old_ch3b)) {
385 		ptr->old_ch3f = ch3f;
386 		ptr->old_ch3g = ch3g;
387 		ptr->old_ch3b = ch3b;
388 		eq_set_params(&filters[3], ch3f, ch3g, ch3b, fs);
389 	}
390 	if ((ch4f != ptr->old_ch4f) ||
391 	    (ch4g != ptr->old_ch4g) ||
392 	    (ch4b != ptr->old_ch4b)) {
393 		ptr->old_ch4f = ch4f;
394 		ptr->old_ch4g = ch4g;
395 		ptr->old_ch4b = ch4b;
396 		eq_set_params(&filters[4], ch4f, ch4g, ch4b, fs);
397 	}
398 	if ((ch5f != ptr->old_ch5f) ||
399 	    (ch5g != ptr->old_ch5g) ||
400 	    (ch5b != ptr->old_ch5b)) {
401 		ptr->old_ch5f = ch5f;
402 		ptr->old_ch5g = ch5g;
403 		ptr->old_ch5b = ch5b;
404 		eq_set_params(&filters[5], ch5f, ch5g, ch5b, fs);
405 	}
406 	if ((ch6f != ptr->old_ch6f) ||
407 	    (ch6g != ptr->old_ch6g) ||
408 	    (ch6b != ptr->old_ch6b)) {
409 		ptr->old_ch6f = ch6f;
410 		ptr->old_ch6g = ch6g;
411 		ptr->old_ch6b = ch6b;
412 		eq_set_params(&filters[6], ch6f, ch6g, ch6b, fs);
413 	}
414 	if ((ch7f != ptr->old_ch7f) ||
415 	    (ch7g != ptr->old_ch7g) ||
416 	    (ch7b != ptr->old_ch7b)) {
417 		ptr->old_ch7f = ch7f;
418 		ptr->old_ch7g = ch7g;
419 		ptr->old_ch7b = ch7b;
420 		eq_set_params(&filters[7], ch7f, ch7g, ch7b, fs);
421 	}
422 
423 	for (pos = 0; pos < sample_count; pos++) {
424 		samp = input[pos];
425 		if (ch0g != 0.0f)
426 			samp = biquad_run(&filters[0], samp);
427 		if (ch1g != 0.0f)
428 			samp = biquad_run(&filters[1], samp);
429 		if (ch2g != 0.0f)
430 			samp = biquad_run(&filters[2], samp);
431 		if (ch3g != 0.0f)
432 			samp = biquad_run(&filters[3], samp);
433 		if (ch4g != 0.0f)
434 			samp = biquad_run(&filters[4], samp);
435 		if (ch5g != 0.0f)
436 			samp = biquad_run(&filters[5], samp);
437 		if (ch6g != 0.0f)
438 			samp = biquad_run(&filters[6], samp);
439 		if (ch7g != 0.0f)
440 			samp = biquad_run(&filters[7], samp);
441 		output[pos] = samp;
442 	}
443 }
444 
445 const void*
extension_data_eq(const char * uri)446 extension_data_eq(const char* uri)
447 {
448     return NULL;
449 }
450 
451 
452 static const
453 LV2_Descriptor Descriptor = {
454     "http://moddevices.com/plugins/tap/eqbw",
455     instantiate_eq,
456     connectPort_eq,
457     activate_eq,
458     run_eq,
459     deactivate_eq,
460     cleanup_eq,
461     extension_data_eq
462 };
463 
464 LV2_SYMBOL_EXPORT
465 const LV2_Descriptor*
lv2_descriptor(uint32_t index)466 lv2_descriptor(uint32_t index)
467 {
468     if (index == 0) return &Descriptor;
469     else return NULL;
470 
471 }
472