1 /***************************************************************************
2 * Copyright (C) 2011 by Pere Ràfols Soler *
3 * sapista2@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21 /***************************************************************************
22 This file is the implementation of the EQ plugin
23 This plugin is inside the Sapista Plugins Bundle
24 This file implements functionalities for a large numbers of equalizers
25 ****************************************************************************/
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <fftw3.h>
30
31 #include <lv2/lv2plug.in/ns/lv2core/lv2.h>
32 #include <lv2/lv2plug.in/ns/ext/atom/forge.h>
33 #include <lv2/lv2plug.in/ns/ext/atom/util.h>
34 #include <lv2/lv2plug.in/ns/ext/urid/urid.h>
35
36
37 #include "uris.h"
38
39 #include "gui/eq_defines.h"
40 #include "dsp/vu.h"
41 #include "dsp/db.h"
42 #include "dsp/filter.h"
43 #include "dsp/midside.h"
44
45 //Data from CMake
46 #define NUM_BANDS @Eq_Bands_Count@
47 #define NUM_CHANNELS @Eq_Channels_Count@
48 #define EQ_URI @Eq_Uri@
49
50
51 typedef struct {
52 //Plugin ports
53 float *fBypass;
54 float *fInGain;
55 float *fOutGain;
56 float *fBandGain[NUM_BANDS];
57 float *fBandFreq[NUM_BANDS];
58 float *fBandParam[NUM_BANDS];
59 float *fBandType[NUM_BANDS];
60 float *fBandEnabled[NUM_BANDS];
61 #if NUM_CHANNELS == 2
62 float *fMidSideEnable;
63 int iMidSideMode[NUM_BANDS];
64 #endif
65 float *fInput[NUM_CHANNELS];
66 float *fOutput[NUM_CHANNELS];
67 float *fVuIn[NUM_CHANNELS];
68 float *fVuOut[NUM_CHANNELS];
69 LV2_Atom_Sequence *notify_port;
70 const LV2_Atom_Sequence* control_port;
71
72
73 //Features
74 LV2_URID_Map *map;
75
76 //Forge for creating atoms
77 LV2_Atom_Forge forge;
78 LV2_Atom_Forge_Frame notify_frame;
79
80 //Atom URID
81 Eq10qURIs uris;
82 double sampleRate;
83
84 //Plugin DSP
85 Filter *ProcFilter[NUM_BANDS][NUM_CHANNELS]; //Dummy pointers to Filter structures, used in processing loop. Can point to PortFilter or FlatFilter depending on the MidSide option
86 Filter *PortFilter[NUM_BANDS]; //Filter used for reading LV2 ports and containing the actual coeficients
87 Filter *FlatFilter; //Allways contains coeficients for a flat filter in order to be used as a bypass in MidSide processing option
88 Buffers buf[NUM_BANDS][NUM_CHANNELS];
89 Vu *InputVu[NUM_CHANNELS];
90 Vu *OutputVu[NUM_CHANNELS];
91
92 //FFT Analysis
93 int fft_ix, fft_ix2; //Index to follow buffers
94 double *fft_in, *fft_out;
95 double *fft_in2, *fft_out2; //Time shifted-seconf-fft-vectors
96 fftw_plan fft_p, fft_p2;
97 int fft_on;
98 double fft_normalization;
99 } EQ;
100
cleanupEQ(LV2_Handle instance)101 static void cleanupEQ(LV2_Handle instance)
102 {
103 EQ *plugin = (EQ *)instance;
104 int i;
105
106 FilterClean(plugin->FlatFilter);
107 for(i=0; i<NUM_BANDS; i++)
108 {
109 FilterClean(plugin->PortFilter[i]);
110 }
111
112 for(i=0; i<NUM_CHANNELS; i++)
113 {
114 VuClean(plugin->InputVu[i]);
115 VuClean(plugin->OutputVu[i]);
116 }
117
118 fftw_destroy_plan(plugin->fft_p);
119 fftw_free(plugin->fft_in); fftw_free(plugin->fft_out);
120 fftw_destroy_plan(plugin->fft_p2);
121 fftw_free(plugin->fft_in2); fftw_free(plugin->fft_out2);
122 free(instance);
123 }
124
connectPortEQ(LV2_Handle instance,uint32_t port,void * data)125 static void connectPortEQ(LV2_Handle instance, uint32_t port, void *data)
126 {
127 EQ *plugin = (EQ *)instance;
128
129 //Connect standar ports
130 switch (port)
131 {
132 case EQ_BYPASS:
133 plugin->fBypass = data;
134 break;
135
136 case EQ_INGAIN:
137 plugin->fInGain = data;
138 break;
139
140 case EQ_OUTGAIN:
141 plugin->fOutGain = data;
142 break;
143
144 default:
145 //Connect audio input ports
146 if(port >= PORT_OFFSET && port < (PORT_OFFSET + NUM_CHANNELS))
147 {
148 plugin->fInput[port - PORT_OFFSET] = data;
149 }
150
151 //Connect audio output ports
152 if(port >= (PORT_OFFSET + NUM_CHANNELS) && port < (PORT_OFFSET + 2*NUM_CHANNELS))
153 {
154 plugin->fOutput[port - PORT_OFFSET - NUM_CHANNELS] = data;
155 }
156
157 //Connect BandGain ports
158 else if(port >= (PORT_OFFSET + 2*NUM_CHANNELS) && port < (PORT_OFFSET + 2*NUM_CHANNELS + NUM_BANDS))
159 {
160 plugin->fBandGain[port - PORT_OFFSET - 2*NUM_CHANNELS] = data;
161 }
162
163 //Connect BandFreq ports
164 else if(port >= (PORT_OFFSET + 2*NUM_CHANNELS + NUM_BANDS) && port < (PORT_OFFSET + 2*NUM_CHANNELS + 2*NUM_BANDS))
165 {
166 plugin->fBandFreq[port - PORT_OFFSET - 2*NUM_CHANNELS - NUM_BANDS] = data;
167 }
168
169 //Connect BandParam ports
170 else if(port >= (PORT_OFFSET + 2*NUM_CHANNELS + 2*NUM_BANDS) && port < (PORT_OFFSET + 2*NUM_CHANNELS + 3*NUM_BANDS))
171 {
172 plugin->fBandParam[port - PORT_OFFSET - 2*NUM_CHANNELS - 2*NUM_BANDS] = data;
173 }
174
175 //Connect BandType ports
176 else if(port >= (PORT_OFFSET + 2*NUM_CHANNELS + 3*NUM_BANDS) && port < (PORT_OFFSET + 2*NUM_CHANNELS + 4*NUM_BANDS))
177 {
178 plugin->fBandType[port - PORT_OFFSET - 2*NUM_CHANNELS - 3*NUM_BANDS] = data;
179 }
180
181 //Connect BandEnabled ports
182 else if(port >= (PORT_OFFSET + 2*NUM_CHANNELS + 4*NUM_BANDS) && port < (PORT_OFFSET + 2*NUM_CHANNELS + 5*NUM_BANDS))
183 {
184 plugin->fBandEnabled[port - PORT_OFFSET - 2*NUM_CHANNELS - 4*NUM_BANDS] = data;
185 }
186
187 //Connect VuInput ports
188 else if(port >= (PORT_OFFSET + 2*NUM_CHANNELS + 5*NUM_BANDS) && port < (PORT_OFFSET + 2*NUM_CHANNELS + 5*NUM_BANDS + NUM_CHANNELS))
189 {
190 plugin->fVuIn[port - PORT_OFFSET - 2*NUM_CHANNELS - 5*NUM_BANDS] = data;
191 }
192
193 //Connect VuOutput ports
194 else if(port >= (PORT_OFFSET + 2*NUM_CHANNELS + 5*NUM_BANDS + NUM_CHANNELS) && port < (PORT_OFFSET + 2*NUM_CHANNELS + 5*NUM_BANDS + 2*NUM_CHANNELS))
195 {
196 plugin->fVuOut[port - PORT_OFFSET - 2*NUM_CHANNELS - 5*NUM_BANDS - NUM_CHANNELS] = data;
197 }
198
199 //Connect Atom notify_port output port to GUI
200 else if(port == PORT_OFFSET + 2*NUM_CHANNELS + 5*NUM_BANDS + 2*NUM_CHANNELS)
201 {
202 plugin->notify_port = (LV2_Atom_Sequence*)data;
203 }
204
205 //Connect Atom control_port input port from GUI
206 else if (port == PORT_OFFSET + 2*NUM_CHANNELS + 5*NUM_BANDS + 2*NUM_CHANNELS + 1)
207 {
208 plugin->control_port = (const LV2_Atom_Sequence*)data;
209 }
210
211 //Connect the MidSide Mode port only for stereo versions
212 else if (port == PORT_OFFSET + 2*NUM_CHANNELS + 5*NUM_BANDS + 2*NUM_CHANNELS + 2)
213 {
214 #if NUM_CHANNELS == 2
215 plugin->fMidSideEnable = data;
216 #endif
217 }
218 break;
219 }
220 }
221
instantiateEQ(const LV2_Descriptor * descriptor,double s_rate,const char * path,const LV2_Feature * const * features)222 static LV2_Handle instantiateEQ(const LV2_Descriptor *descriptor, double s_rate, const char *path, const LV2_Feature *const * features)
223 {
224 int i,ch;
225 EQ *plugin_data = (EQ *)malloc(sizeof(EQ));
226 plugin_data->sampleRate = s_rate;
227
228 plugin_data->FlatFilter = FilterInit(s_rate);
229 calcCoefs(plugin_data->FlatFilter, 0.0, 20.0, 1.0, F_PEAK, 0.0); //Create a always-flat filter in FlatFilter
230
231 for(i=0; i<NUM_BANDS; i++)
232 {
233 plugin_data->PortFilter[i] = FilterInit(s_rate);
234 for(ch=0; ch<NUM_CHANNELS; ch++)
235 {
236 flushBuffers(&plugin_data->buf[i][ch]);
237 plugin_data->ProcFilter[i][ch] = plugin_data->PortFilter[i]; //Initially all filters points to LV2 Port controlled filters
238 }
239 #if NUM_CHANNELS == 2
240 plugin_data->iMidSideMode[i] = MS_DUAL_CHANNEL;
241 #endif
242 }
243
244
245 for(ch=0; ch<NUM_CHANNELS; ch++)
246 {
247 plugin_data->InputVu[ch] = VuInit(s_rate);
248 plugin_data->OutputVu[ch] = VuInit(s_rate);
249 }
250
251
252 // Get host features
253 for (i = 0; features[i]; ++i)
254 {
255 if (!strcmp(features[i]->URI, LV2_URID__map))
256 {
257 plugin_data->map = (LV2_URID_Map*)features[i]->data;
258 }
259 }
260 if (!plugin_data->map)
261 {
262 printf("EQ10Q Error: Host does not support urid:map\n");
263 goto fail;
264 }
265
266 // Map URIs and initialise forge
267 map_eq10q_uris(plugin_data->map, &plugin_data->uris);
268 lv2_atom_forge_init(&plugin_data->forge, plugin_data->map);
269
270 //Initialize FFT objects
271 plugin_data->fft_ix = 0;
272 plugin_data->fft_ix2 = FFT_N/2;
273 plugin_data->fft_in = (double*) fftw_malloc(sizeof(double) * FFT_N);
274 plugin_data->fft_in2 = (double*) fftw_malloc(sizeof(double) * FFT_N);
275 plugin_data->fft_out = (double*) fftw_malloc(sizeof(double) * FFT_N);
276 plugin_data->fft_out2 = (double*) fftw_malloc(sizeof(double) * FFT_N);
277 plugin_data->fft_p = fftw_plan_r2r_1d(FFT_N, plugin_data->fft_in, plugin_data->fft_out, FFTW_R2HC, FFTW_ESTIMATE);
278 plugin_data->fft_p2 = fftw_plan_r2r_1d(FFT_N, plugin_data->fft_in2, plugin_data->fft_out2, FFTW_R2HC, FFTW_ESTIMATE);
279 plugin_data->fft_on = 0; //Initialy no GUI then no need to compute FFT
280 plugin_data->fft_normalization = pow(2.0/ ((double) FFT_N), 2.0);
281 for(i = 0; i< FFT_N; i++)
282 {
283 plugin_data->fft_in[i] = 0;
284 plugin_data->fft_in2[i] = 0;
285 plugin_data->fft_out[i] = 0;
286 plugin_data->fft_out2[i] = 0; //First fft_out2 samples will not be calculated by FFT (first-time shift)
287 }
288 return (LV2_Handle)plugin_data;
289
290 fail:
291 free(plugin_data);
292 return 0;
293 }
294
runEQ_v2(LV2_Handle instance,uint32_t sample_count)295 static void runEQ_v2(LV2_Handle instance, uint32_t sample_count)
296 {
297
298 EQ *plugin_data = (EQ *)instance;
299
300 //Get values of control ports
301 const int iBypass = *(plugin_data->fBypass) > 0.0f ? 1 : 0;
302 const float fInGain = dB2Lin(*(plugin_data->fInGain));
303 const float fOutGain = dB2Lin(*(plugin_data->fOutGain));
304 #if NUM_CHANNELS == 2
305 const double dMidSideModeIdOn = (double)(*(plugin_data->fMidSideEnable));
306 #endif
307 int bd, pos; //loop index
308
309
310 //Set up forge to write directly to notify output port.
311 const uint32_t notify_capacity = plugin_data->notify_port->atom.size;
312 lv2_atom_forge_set_buffer(&plugin_data->forge, (uint8_t*)plugin_data->notify_port, notify_capacity);
313 lv2_atom_forge_sequence_head(&plugin_data->forge, &plugin_data->notify_frame, 0);
314 //printf("Notify port size %d\n", notify_capacity);
315
316 //Interpolation coefs force to recompute
317 int recalcCoefs[NUM_BANDS];
318 int forceRecalcCoefs = 0;
319
320 double fftInSample; //Sample to push throught the FFT buffer
321 double sampleL; //Current processing sample left signal
322 #if NUM_CHANNELS == 2
323 double sampleR; //Current processing sample right signal
324 #endif
325
326 //Read EQ Ports and mark to recompute if changed
327 for(bd = 0; bd<NUM_BANDS; bd++)
328 {
329 if(dB2Lin(*(plugin_data->fBandGain[bd])) != plugin_data->PortFilter[bd]->gain ||
330 *plugin_data->fBandFreq[bd] != plugin_data->PortFilter[bd]->freq ||
331 *plugin_data->fBandParam[bd] != plugin_data->PortFilter[bd]->q ||
332 ((int)(*plugin_data->fBandType[bd])) != plugin_data->PortFilter[bd]->iType ||
333 ((float)(0x01 & ((int)(*plugin_data->fBandEnabled[bd])))) != plugin_data->PortFilter[bd]->enable)
334 {
335 recalcCoefs[bd] = 1;
336 forceRecalcCoefs = 1;
337 }
338 else
339 {
340 recalcCoefs[bd] = 0;
341 }
342
343 //Check mid-side ports
344 #if NUM_CHANNELS == 2
345 if((((int)(*plugin_data->fBandEnabled[bd])) >> 1) != plugin_data->iMidSideMode[bd])
346 {
347 plugin_data->iMidSideMode[bd] = ((int)(*plugin_data->fBandEnabled[bd])) >> 1;
348
349 switch(plugin_data->iMidSideMode[bd])
350 {
351 case MS_DUAL_CHANNEL:
352 plugin_data->ProcFilter[bd][0] = plugin_data->PortFilter[bd];
353 plugin_data->ProcFilter[bd][1] = plugin_data->PortFilter[bd];
354 break;
355
356 case MS_L_MID_MODE:
357 plugin_data->ProcFilter[bd][0] = plugin_data->PortFilter[bd];
358 plugin_data->ProcFilter[bd][1] = plugin_data->FlatFilter;
359 break;
360
361 case MS_R_SIDE_MODE:
362 plugin_data->ProcFilter[bd][0] = plugin_data->FlatFilter;
363 plugin_data->ProcFilter[bd][1] = plugin_data->PortFilter[bd];
364 break;
365 }
366
367 }
368 #endif
369 }
370
371 //Read input Atom control port (Data from GUI)
372 if(plugin_data->control_port)
373 {
374 const LV2_Atom_Event* ev = lv2_atom_sequence_begin(&(plugin_data->control_port)->body);
375 // For each incoming message...
376 while (!lv2_atom_sequence_is_end(&plugin_data->control_port->body, plugin_data->control_port->atom.size, ev))
377 {
378 // If the event is an atom:Object
379 if (ev->body.type == plugin_data->uris.atom_Object)
380 {
381 const LV2_Atom_Object* obj = (const LV2_Atom_Object*)&ev->body;
382 if (obj->body.otype == plugin_data->uris.atom_fft_on)
383 {
384 plugin_data->fft_on = 1;
385 }
386 else if(obj->body.otype == plugin_data->uris.atom_fft_off)
387 {
388 plugin_data->fft_on = 0;
389 plugin_data->fft_ix = 0;
390 plugin_data->fft_ix2 = FFT_N/2;
391 }
392 else if(obj->body.otype == plugin_data->uris.atom_sample_rate_request)
393 {
394 //Send sample rate
395 LV2_Atom_Forge_Frame frameSR;
396 lv2_atom_forge_frame_time(&plugin_data->forge, 0);
397 lv2_atom_forge_object( &plugin_data->forge, &frameSR, 0, plugin_data->uris.atom_sample_rate_response);
398 lv2_atom_forge_key(&plugin_data->forge, plugin_data->uris.atom_sample_rate_key);
399 lv2_atom_forge_double(&plugin_data->forge, plugin_data->sampleRate);
400 lv2_atom_forge_pop(&plugin_data->forge, &frameSR);
401
402 // Close off sequence
403 lv2_atom_forge_pop(&plugin_data->forge, &plugin_data->notify_frame);
404 }
405 }
406 ev = lv2_atom_sequence_next(ev);
407 }
408 }
409
410 //Compute the filter
411 for (pos = 0; pos < sample_count; pos++)
412 {
413 //Get input
414 sampleL = (double)plugin_data->fInput[0][pos];
415 DENORMAL_TO_ZERO(sampleL);
416
417 #if NUM_CHANNELS == 2
418 sampleR = (double)plugin_data->fInput[1][pos];
419 DENORMAL_TO_ZERO(sampleR);
420 #endif
421
422 //The input amplifier
423 sampleL *= fInGain;
424 fftInSample = sampleL;
425 //Update VU input sample
426 SetSample(plugin_data->InputVu[0], sampleL);
427
428 #if NUM_CHANNELS == 2
429 //The input amplifier
430 sampleR *= fInGain;
431 fftInSample = 0.5*sampleL + 0.5*sampleR;
432 //Update VU input sample
433 SetSample(plugin_data->InputVu[1], sampleR);
434 #endif
435
436 //Process every band
437 if(!iBypass)
438 {
439
440 //FFT of input data after input gain
441 if(plugin_data->fft_on)
442 {
443 //Hanning Windowing
444 plugin_data->fft_in[plugin_data->fft_ix] = fftInSample* 0.5 * (1.0-cos((2.0*PI*((double)plugin_data->fft_ix))/((double)(FFT_N-1))));
445 plugin_data->fft_in2[plugin_data->fft_ix2] = fftInSample* 0.5 * (1.0-cos((2.0*PI*((double)plugin_data->fft_ix2))/((double)(FFT_N-1))));
446
447 plugin_data->fft_ix++;
448 plugin_data->fft_ix2++;
449
450 if(plugin_data->fft_ix == FFT_N)
451 {
452 //FFT inout buffer full compute
453 fftw_execute(plugin_data->fft_p);
454
455 //Compute FFT Normalized Magnitude^2
456 double real, img;
457 int ffti;
458 for(ffti = 0; ffti<= FFT_N/2; ffti++)
459 {
460 real = plugin_data->fft_out[ffti];
461 if(ffti > 0 && ffti < (FFT_N/2))
462 {
463 img = plugin_data->fft_out[FFT_N -ffti];
464 }
465 else
466 {
467 img = 0.0;
468 }
469 plugin_data->fft_out[ffti] = 0.5*(plugin_data->fft_normalization*(real*real + img*img) + plugin_data->fft_out2[ffti]);
470 }
471
472 plugin_data->fft_ix = 0;
473
474
475 //Send FFT data vector
476 LV2_Atom_Forge_Frame frameFft;
477 lv2_atom_forge_frame_time(&plugin_data->forge, 0);
478 lv2_atom_forge_object( &plugin_data->forge, &frameFft, 0, plugin_data->uris.atom_fft_data_event);
479 lv2_atom_forge_key(&plugin_data->forge, plugin_data->uris.atom_fft_data_key);
480 lv2_atom_forge_vector(&plugin_data->forge, sizeof(double), plugin_data->uris.atom_Double, ((FFT_N/2) + 1), plugin_data->fft_out);
481 lv2_atom_forge_pop(&plugin_data->forge, &frameFft);
482
483 // Close off sequence
484 lv2_atom_forge_pop(&plugin_data->forge, &plugin_data->notify_frame);
485 }
486
487 if(plugin_data->fft_ix2 == FFT_N)
488 {
489 //FFT inout buffer full compute
490 fftw_execute(plugin_data->fft_p2);
491
492 //Compute FFT Normalized Magnitude^2
493 double real, img;
494 int ffti;
495 for(ffti = 0; ffti<= FFT_N/2; ffti++)
496 {
497 real = plugin_data->fft_out2[ffti];
498 if(ffti > 0 && ffti < (FFT_N/2))
499 {
500 img = plugin_data->fft_out2[FFT_N -ffti];
501 }
502 else
503 {
504 img = 0.0;
505 }
506 plugin_data->fft_out2[ffti] = plugin_data->fft_normalization*(real*real + img*img);
507 }
508
509 plugin_data->fft_ix2 = 0;
510 }
511 }
512
513 //Coefs Interpolation
514 if(forceRecalcCoefs)
515 {
516 for(bd = 0; bd<NUM_BANDS; bd++)
517 {
518 if(recalcCoefs[bd])
519 {
520 calcCoefs(plugin_data->PortFilter[bd],
521 dB2Lin(*(plugin_data->fBandGain[bd])),
522 *plugin_data->fBandFreq[bd],
523 *plugin_data->fBandParam[bd],
524 (int)(*plugin_data->fBandType[bd]),
525 ((float)(0x01 & ((int)(*plugin_data->fBandEnabled[bd])))));
526 }
527 }
528 }
529
530
531 //EQ PROCESSOR
532
533 //Band0
534 #if NUM_CHANNELS == 2
535 LR2MS(&sampleL, &sampleR, dMidSideModeIdOn);
536 #endif
537 computeFilter(plugin_data->ProcFilter[0][0], &plugin_data->buf[0][0],&sampleL);
538 #if NUM_CHANNELS == 2
539 computeFilter(plugin_data->ProcFilter[0][1], &plugin_data->buf[0][1],&sampleR);
540 #endif
541
542 #if NUM_BANDS >= 4
543 //BAND 1
544 computeFilter(plugin_data->ProcFilter[1][0], &plugin_data->buf[1][0],&sampleL);
545 #if NUM_CHANNELS == 2
546 computeFilter(plugin_data->ProcFilter[1][1], &plugin_data->buf[1][1],&sampleR);
547 #endif
548
549 //BAND 2
550 computeFilter(plugin_data->ProcFilter[2][0], &plugin_data->buf[2][0],&sampleL);
551 #if NUM_CHANNELS == 2
552 computeFilter(plugin_data->ProcFilter[2][1], &plugin_data->buf[2][1],&sampleR);
553 #endif
554
555 //BAND 3
556 computeFilter(plugin_data->ProcFilter[3][0], &plugin_data->buf[3][0],&sampleL);
557 #if NUM_CHANNELS == 2
558 computeFilter(plugin_data->ProcFilter[3][1], &plugin_data->buf[3][1],&sampleR);
559 #endif
560 #endif
561
562 #if NUM_BANDS >= 6
563 //BAND 4
564 computeFilter(plugin_data->ProcFilter[4][0], &plugin_data->buf[4][0],&sampleL);
565 #if NUM_CHANNELS == 2
566 computeFilter(plugin_data->ProcFilter[4][1], &plugin_data->buf[4][1],&sampleR);
567 #endif
568
569 //BAND 5
570 computeFilter(plugin_data->ProcFilter[5][0], &plugin_data->buf[5][0],&sampleL);
571 #if NUM_CHANNELS == 2
572 computeFilter(plugin_data->ProcFilter[5][1], &plugin_data->buf[5][1],&sampleR);
573 #endif
574 #endif
575
576 #if NUM_BANDS ==10
577 //BAND 6
578 computeFilter(plugin_data->ProcFilter[6][0], &plugin_data->buf[6][0],&sampleL);
579 #if NUM_CHANNELS == 2
580 computeFilter(plugin_data->ProcFilter[6][1], &plugin_data->buf[6][1],&sampleR);
581 #endif
582
583 //BAND 7
584 computeFilter(plugin_data->ProcFilter[7][0], &plugin_data->buf[7][0],&sampleL);
585 #if NUM_CHANNELS == 2
586 computeFilter(plugin_data->ProcFilter[7][1], &plugin_data->buf[7][1],&sampleR);
587 #endif
588
589 //BAND 8
590 computeFilter(plugin_data->ProcFilter[8][0], &plugin_data->buf[8][0],&sampleL);
591 #if NUM_CHANNELS == 2
592 computeFilter(plugin_data->ProcFilter[8][1], &plugin_data->buf[8][1],&sampleR);
593 #endif
594
595 //BAND 9
596 computeFilter(plugin_data->ProcFilter[9][0], &plugin_data->buf[9][0],&sampleL);
597 #if NUM_CHANNELS == 2
598 computeFilter(plugin_data->ProcFilter[9][1], &plugin_data->buf[9][1],&sampleR);
599 #endif
600 #endif
601
602
603 //The output amplifier
604 sampleL *= fOutGain;
605 //Update VU output sample
606 SetSample(plugin_data->OutputVu[0], sampleL);
607
608 #if NUM_CHANNELS == 2
609 //The output amplifier
610 sampleR *= fOutGain;
611 //Update VU output sample
612 SetSample(plugin_data->OutputVu[1], sampleR);
613
614 //Go back to LR signals, be aware that out gains and Vumeters Are M/S or L/R depending on MidSide selected mode
615 MS2LR(&sampleL, &sampleR, dMidSideModeIdOn);
616 #endif
617 }
618
619 //Write on output
620 plugin_data->fOutput[0][pos] = (float)sampleL;
621 #if NUM_CHANNELS == 2
622 plugin_data->fOutput[1][pos] = (float)sampleR;
623 #endif
624 }
625
626 //Update VU ports
627 *(plugin_data->fVuIn[0]) = ComputeVu(plugin_data->InputVu[0], sample_count);
628 *(plugin_data->fVuOut[0]) = ComputeVu(plugin_data->OutputVu[0], sample_count);
629 #if NUM_CHANNELS == 2
630 *(plugin_data->fVuIn[1]) = ComputeVu(plugin_data->InputVu[1], sample_count);
631 *(plugin_data->fVuOut[1]) = ComputeVu(plugin_data->OutputVu[1], sample_count);
632 #endif
633 }
634
635 static const LV2_Descriptor eqDescriptor = {
636 EQ_URI,
637 instantiateEQ,
638 connectPortEQ,
639 NULL,
640 runEQ_v2,
641 NULL,
642 cleanupEQ,
643 NULL
644 };
645
646 LV2_SYMBOL_EXPORT
lv2_descriptor(uint32_t index)647 const LV2_Descriptor *lv2_descriptor(uint32_t index)
648 {
649 switch (index) {
650 case 0:
651 return &eqDescriptor;
652 default:
653 return NULL;
654 }
655 }
656