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