1 /* Calf DSP plugin pack
2 * Equalization related plugins
3 *
4 * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
20 */
21 #include <limits.h>
22 #include <memory.h>
23 #include <calf/utils.h>
24 #include <calf/giface.h>
25 #include <calf/modules_filter.h>
26
27 using namespace dsp;
28 using namespace calf_plugins;
29
30 FORWARD_DECLARE_METADATA(equalizer5band)
FORWARD_DECLARE_METADATA(equalizer8band)31 FORWARD_DECLARE_METADATA(equalizer8band)
32 FORWARD_DECLARE_METADATA(equalizer12band)
33 FORWARD_DECLARE_METADATA(equalizer30band)
34 FORWARD_DECLARE_METADATA(envelopefilter)
35 FORWARD_DECLARE_METADATA(filter)
36 FORWARD_DECLARE_METADATA(filterclavier)
37 FORWARD_DECLARE_METADATA(emphasis)
38 FORWARD_DECLARE_METADATA(xover2)
39 FORWARD_DECLARE_METADATA(xover3)
40 FORWARD_DECLARE_METADATA(xover4)
41 FORWARD_DECLARE_METADATA(vocoder)
42
43 #define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name;
44
45 /**********************************************************************
46 * EQUALIZER N BAND by Markus Schmidt and Krzysztof Foltman
47 **********************************************************************/
48
49 inline void diff_ms(float &left, float &right) {
50 float tmp = (left + right) / 2;
51 right = left - right;
52 left = tmp;
53 }
undiff_ms(float & left,float & right)54 inline void undiff_ms(float &left, float &right) {
55 float tmp = left + right / 2;
56 right = left - right / 2;
57 left = tmp;
58 }
59
60 template<class BaseClass, bool has_lphp>
equalizerNband_audio_module()61 equalizerNband_audio_module<BaseClass, has_lphp>::equalizerNband_audio_module()
62 {
63 is_active = false;
64 srate = 0;
65 last_generation = 0;
66 hp_freq_old = lp_freq_old = hp_q_old = 0;
67 hs_freq_old = ls_freq_old = lp_q_old = 0;
68 hs_level_old = ls_level_old = 0;
69 hs_q_old = ls_q_old = 0;
70 keep_gliding = 0;
71 last_peak = 0;
72 indiv_old = -1;
73 analyzer_old = false;
74 for (int i = 0; i < AM::PeakBands; i++)
75 {
76 p_freq_old[i] = 0;
77 p_level_old[i] = 0;
78 p_q_old[i] = 0;
79 }
80 for (int i = 0; i < graph_param_count; i++)
81 old_params_for_graph[i] = -1;
82 redraw_graph = true;
83 }
84
85 template<class BaseClass, bool has_lphp>
activate()86 void equalizerNband_audio_module<BaseClass, has_lphp>::activate()
87 {
88 is_active = true;
89 // set all filters
90 params_changed();
91 }
92
93 template<class BaseClass, bool has_lphp>
deactivate()94 void equalizerNband_audio_module<BaseClass, has_lphp>::deactivate()
95 {
96 is_active = false;
97 }
98
copy_lphp(biquad_d2 filters[3][2])99 static inline void copy_lphp(biquad_d2 filters[3][2])
100 {
101 for (int i = 0; i < 3; i++)
102 for (int j = 0; j < 2; j++)
103 if (i || j)
104 filters[i][j].copy_coeffs(filters[0][0]);
105 }
106
glide(double value,double target,int & keep_gliding)107 static inline double glide(double value, double target, int &keep_gliding)
108 {
109 if (target == value)
110 return value;
111 keep_gliding = 1;
112 if (target > value)
113 return std::min(target, (value + 0.1) * 1.003);
114 else
115 return std::max(target, (value / 1.003) - 0.1);
116 }
117
118 template<class BaseClass, bool has_lphp>
params_changed()119 void equalizerNband_audio_module<BaseClass, has_lphp>::params_changed()
120 {
121 keep_gliding = 0;
122 // set the params of all filters
123
124 // lp/hp first (if available)
125 if (has_lphp)
126 {
127 hp_mode = (CalfEqMode)(int)*params[AM::param_hp_mode];
128 lp_mode = (CalfEqMode)(int)*params[AM::param_lp_mode];
129
130 float hpfreq = *params[AM::param_hp_freq], lpfreq = *params[AM::param_lp_freq];
131 float hpq = *params[AM::param_hp_q], lpq = *params[AM::param_lp_q];
132
133 if(hpfreq != hp_freq_old || hpq != hp_q_old) {
134 hpfreq = glide(hp_freq_old, hpfreq, keep_gliding);
135 hp[0][0].set_hp_rbj(hpfreq, hpq, (float)srate, 1.0);
136 copy_lphp(hp);
137 hp_freq_old = hpfreq;
138 }
139 if(lpfreq != lp_freq_old || lpq != lp_q_old) {
140 lpfreq = glide(lp_freq_old, lpfreq, keep_gliding);
141 lp[0][0].set_lp_rbj(lpfreq, lpq, (float)srate, 1.0);
142 copy_lphp(lp);
143 lp_freq_old = lpfreq;
144 }
145 }
146
147 // then shelves
148 float hsfreq = *params[AM::param_hs_freq], hslevel = *params[AM::param_hs_level], hsq =*params[AM::param_hs_q];
149 float lsfreq = *params[AM::param_ls_freq], lslevel = *params[AM::param_ls_level], lsq =*params[AM::param_ls_q];
150
151 if(lsfreq != ls_freq_old || lslevel != ls_level_old || lsq != ls_q_old) {
152 lsfreq = glide(ls_freq_old, lsfreq, keep_gliding);
153 lsL.set_lowshelf_rbj(lsfreq, lsq, lslevel, (float)srate);
154 lsR.copy_coeffs(lsL);
155 ls_level_old = lslevel;
156 ls_freq_old = lsfreq;
157 ls_q_old = lsq;
158 }
159 if(hsfreq != hs_freq_old || hslevel != hs_level_old || hsq != hs_q_old) {
160 hsfreq = glide(hs_freq_old, hsfreq, keep_gliding);
161 hsL.set_highshelf_rbj(hsfreq, hsq, hslevel, (float)srate);
162 hsR.copy_coeffs(hsL);
163 hs_level_old = hslevel;
164 hs_freq_old = hsfreq;
165 hs_q_old = hsq;
166 }
167 for (int i = 0; i < AM::PeakBands; i++)
168 {
169 int offset = i * params_per_band;
170 float freq = *params[AM::param_p1_freq + offset];
171 float level = *params[AM::param_p1_level + offset];
172 float q = *params[AM::param_p1_q + offset];
173 if(freq != p_freq_old[i] || level != p_level_old[i] || q != p_q_old[i]) {
174 freq = glide(p_freq_old[i], freq, keep_gliding);
175 pL[i].set_peakeq_rbj(freq, q, level, (float)srate);
176 pR[i].copy_coeffs(pL[i]);
177 p_freq_old[i] = freq;
178 p_level_old[i] = level;
179 p_q_old[i] = q;
180 }
181 }
182 if (*params[AM::param_individuals] != indiv_old) {
183 indiv_old = *params[AM::param_individuals];
184 redraw_graph = true;
185 }
186
187 // check if any important parameter for redrawing the graph changed
188 for (int i = 0; i < graph_param_count; i++) {
189 if (*params[AM::first_graph_param + i] != old_params_for_graph[i])
190 redraw_graph = true;
191 old_params_for_graph[i] = *params[AM::first_graph_param + i];
192 }
193
194 _analyzer.set_params(
195 256, 1, 6, 0, 1,
196 *params[AM::param_analyzer_mode] + (*params[AM::param_analyzer_mode] >= 3 ? 5 : 1),
197 0, 0, 15, 2, 0, 0
198 );
199
200 if ((bool)*params[AM::param_analyzer_active] != analyzer_old) {
201 redraw_graph = true;
202 analyzer_old = (bool)*params[AM::param_analyzer_active];
203 }
204 }
205
206 template<class BaseClass, bool has_lphp>
process_hplp(float & left,float & right)207 inline void equalizerNband_audio_module<BaseClass, has_lphp>::process_hplp(float &left, float &right)
208 {
209 if (!has_lphp)
210 return;
211 int active = *params[AM::param_lp_active];
212 if (active > 0.f)
213 {
214 if (active > 3) diff_ms(left, right);
215 switch(lp_mode)
216 {
217 case MODE12DB:
218 if (active == 1 || active == 2 || active == 4)
219 left = lp[0][0].process(left);
220 if (active == 1 || active == 3 || active == 5)
221 right = lp[0][1].process(right);
222 break;
223 case MODE24DB:
224 if (active == 1 || active == 2 || active == 4)
225 left = lp[1][0].process(lp[0][0].process(left));
226 if (active == 1 || active == 3 || active == 5)
227 right = lp[1][1].process(lp[0][1].process(right));
228 break;
229 case MODE36DB:
230 if (active == 1 || active == 2 || active == 4)
231 left = lp[2][0].process(lp[1][0].process(lp[0][0].process(left)));
232 if (active == 1 || active == 3 || active == 5)
233 right = lp[2][1].process(lp[1][1].process(lp[0][1].process(right)));
234 break;
235 }
236 if (active > 3) undiff_ms(left, right);
237 }
238 active = *params[AM::param_hp_active];
239 if (active > 0.f)
240 {
241 if (active > 3) diff_ms(left, right);
242 switch(hp_mode)
243 {
244 case MODE12DB:
245 if (active == 1 || active == 2 || active == 4)
246 left = hp[0][0].process(left);
247 if (active == 1 || active == 3 || active == 5)
248 right = hp[0][1].process(right);
249 break;
250 case MODE24DB:
251 if (active == 1 || active == 2 || active == 4)
252 left = hp[1][0].process(hp[0][0].process(left));
253 if (active == 1 || active == 3 || active == 5)
254 right = hp[1][1].process(hp[0][1].process(right));
255 break;
256 case MODE36DB:
257 if (active == 1 || active == 2 || active == 4)
258 left = hp[2][0].process(hp[1][0].process(hp[0][0].process(left)));
259 if (active == 1 || active == 3 || active == 5)
260 right = hp[2][1].process(hp[1][1].process(hp[0][1].process(right)));
261 break;
262 }
263 if (active > 3) undiff_ms(left, right);
264 }
265 }
266
267 template<class BaseClass, bool has_lphp>
process(uint32_t offset,uint32_t numsamples,uint32_t inputs_mask,uint32_t outputs_mask)268 uint32_t equalizerNband_audio_module<BaseClass, has_lphp>::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
269 {
270 bool bypassed = bypass.update(*params[AM::param_bypass] > 0.5f, numsamples);
271 if (keep_gliding)
272 {
273 // ensure that if params have changed, the params_changed method is
274 // called every 8 samples to interpolate filter parameters
275 while(numsamples > 8 && keep_gliding)
276 {
277 params_changed();
278 outputs_mask |= process(offset, 8, inputs_mask, outputs_mask);
279 offset += 8;
280 numsamples -= 8;
281 }
282 if (keep_gliding)
283 params_changed();
284 }
285 numsamples += offset;
286 if(bypassed) {
287 // everything bypassed
288 while(offset < numsamples) {
289 outs[0][offset] = ins[0][offset];
290 outs[1][offset] = ins[1][offset];
291 float values[] = {0, 0, 0, 0};
292 meters.process(values);
293 _analyzer.process(0, 0);
294 ++offset;
295 }
296 } else {
297 // process
298 uint32_t orig_numsamples = numsamples-offset;
299 uint32_t orig_offset = offset;
300 while(offset < numsamples) {
301 // cycle through samples
302 float outL = 0.f;
303 float outR = 0.f;
304 float inL = ins[0][offset];
305 float inR = ins[1][offset];
306 // in level
307 inR *= *params[AM::param_level_in];
308 inL *= *params[AM::param_level_in];
309
310 float procL = inL;
311 float procR = inR;
312
313 // all filters in chain
314 process_hplp(procL, procR);
315
316 int active = *params[AM::param_ls_active];
317 if (active > 3) diff_ms(procL, procR);
318 if (active == 1 || active == 2 || active == 4)
319 procL = lsL.process(procL);
320 if (active == 1 || active == 3 || active == 5)
321 procR = lsR.process(procR);
322 if (active > 3) undiff_ms(procL, procR);
323
324 active = *params[AM::param_hs_active];
325 if (active > 3) diff_ms(procL, procR);
326 if (active == 1 || active == 2 || active == 4)
327 procL = hsL.process(procL);
328 if (active == 1 || active == 3 || active == 5)
329 procR = hsR.process(procR);
330 if (active > 3) undiff_ms(procL, procR);
331
332 for (int i = 0; i < AM::PeakBands; i++)
333 {
334 int offset = i * params_per_band;
335 int active = *params[AM::param_p1_active + offset];
336 if (active > 3) diff_ms(procL, procR);
337 if (active == 1 || active == 2 || active == 4)
338 procL = pL[i].process(procL);
339 if (active == 1 || active == 3 || active == 5)
340 procR = pR[i].process(procR);
341 if (active > 3) undiff_ms(procL, procR);
342 }
343
344 outL = procL * *params[AM::param_level_out];
345 outR = procR * *params[AM::param_level_out];
346
347 // analyzer
348 _analyzer.process((inL + inR) / 2.f, (outL + outR) / 2.f);
349
350 // send to output
351 outs[0][offset] = outL;
352 outs[1][offset] = outR;
353
354 float values[] = {inL, inR, outL, outR};
355 meters.process(values);
356
357 // next sample
358 ++offset;
359 } // cycle trough samples
360 bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples);
361 // clean up
362 for(int i = 0; i < 3; ++i) {
363 hp[i][0].sanitize();
364 hp[i][1].sanitize();
365 lp[i][0].sanitize();
366 lp[i][1].sanitize();
367 }
368 lsL.sanitize();
369 hsR.sanitize();
370 for(int i = 0; i < AM::PeakBands; ++i) {
371 pL[i].sanitize();
372 pR[i].sanitize();
373 }
374 }
375 meters.fall(numsamples);
376 return outputs_mask;
377 }
378
adjusted_lphp_gain(const float * const * params,int param_active,int param_mode,const biquad_d2 & filter,float freq,float srate)379 static inline float adjusted_lphp_gain(const float *const *params, int param_active, int param_mode, const biquad_d2 &filter, float freq, float srate)
380 {
381 if(*params[param_active] > 0.f) {
382 float gain = filter.freq_gain(freq, srate);
383 switch((int)*params[param_mode]) {
384 case MODE12DB:
385 return gain;
386 case MODE24DB:
387 return gain * gain;
388 case MODE36DB:
389 return gain * gain * gain;
390 }
391 }
392 return 1;
393 }
394
395 template<class BaseClass, bool has_lphp>
get_graph(int index,int subindex,int phase,float * data,int points,cairo_iface * context,int * mode) const396 bool equalizerNband_audio_module<BaseClass, has_lphp>::get_graph(int index, int subindex, int phase, float *data, int points, cairo_iface *context, int *mode) const
397 {
398 if (phase && *params[AM::param_analyzer_active]) {
399 bool r = _analyzer.get_graph(subindex, phase, data, points, context, mode);
400 if (*params[AM::param_analyzer_mode] == 2) {
401 set_channel_color(context, subindex ? 0 : 1, 0.15);
402 } else {
403 context->set_source_rgba(0,0,0,0.1);
404 }
405 return r;
406 } else if (phase && !*params[AM::param_analyzer_active]) {
407 last_peak = 0;
408 redraw_graph = false;
409 return false;
410 } else {
411 int max = PeakBands + 2 + (has_lphp ? 2 : 0);
412
413 if (!is_active
414 || (subindex && !*params[AM::param_individuals])
415 || (subindex > max && *params[AM::param_individuals])) {
416 last_peak = 0;
417 redraw_graph = false;
418 return false;
419 }
420
421 // first graph is the overall frequency response graph
422 if (!subindex)
423 return ::get_graph(*this, subindex, data, points, 128 * *params[AM::param_zoom], 0);
424
425 // get out if max band is reached
426 if (last_peak >= max) {
427 last_peak = 0;
428 redraw_graph = false;
429 return false;
430 }
431
432 // get the next filter to draw a curve for and leave out inactive
433 // filters
434 while (last_peak < PeakBands && !*params[AM::param_p1_active + last_peak * params_per_band])
435 last_peak ++;
436 if (last_peak == PeakBands && !*params[AM::param_ls_active])
437 last_peak ++;
438 if (last_peak == PeakBands + 1 && !*params[AM::param_hs_active])
439 last_peak ++;
440 if (has_lphp && last_peak == PeakBands + 2 && !*params[AM::param_hp_active])
441 last_peak ++;
442 if (has_lphp && last_peak == PeakBands + 3 && !*params[AM::param_lp_active])
443 last_peak ++;
444
445 // get out if max band is reached
446 if (last_peak >= max) { // and !*params[param_analyzer_active]) {
447 last_peak = 0;
448 redraw_graph = false;
449 return false;
450 }
451 //else if *params[param_analyzer_active]) {
452 //bool goon = _analyzer.get_graph(subindex, phase, data, points, context, mode);
453 //if (!goon)
454 //last_peak = 0;
455 //return goon;
456 //}
457
458 // draw the individual curve of the actual filter
459 for (int i = 0; i < points; i++) {
460 double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points);
461 if (last_peak < PeakBands) {
462 data[i] = pL[last_peak].freq_gain(freq, (float)srate);
463 } else if (last_peak == PeakBands) {
464 data[i] = lsL.freq_gain(freq, (float)srate);
465 } else if (last_peak == PeakBands + 1) {
466 data[i] = hsL.freq_gain(freq, (float)srate);
467 } else if (last_peak == PeakBands + 2 && has_lphp) {
468 data[i] = adjusted_lphp_gain(params, AM::param_hp_active, AM::param_hp_mode, hp[0][0], freq, (float)srate);
469 } else if (last_peak == PeakBands + 3 && has_lphp) {
470 data[i] = adjusted_lphp_gain(params, AM::param_lp_active, AM::param_lp_mode, lp[0][0], freq, (float)srate);
471 }
472 data[i] = dB_grid(data[i], 128 * *params[AM::param_zoom], 0);
473 }
474
475 last_peak ++;
476 *mode = 4;
477 context->set_source_rgba(0,0,0,0.075);
478 return true;
479 }
480 }
481 template<class BaseClass, bool has_lphp>
get_layers(int index,int generation,unsigned int & layers) const482 bool equalizerNband_audio_module<BaseClass, has_lphp>::get_layers(int index, int generation, unsigned int &layers) const
483 {
484 redraw_graph = redraw_graph || !generation;
485 layers = *params[AM::param_analyzer_active] ? LG_REALTIME_GRAPH : 0;
486 layers |= (generation ? LG_NONE : LG_CACHE_GRID) | (redraw_graph ? LG_CACHE_GRAPH : LG_NONE);
487 redraw_graph |= (bool)*params[AM::param_analyzer_active];
488 return redraw_graph || !generation;
489 }
490
491 template<class BaseClass, bool has_lphp>
get_gridline(int index,int subindex,int phase,float & pos,bool & vertical,std::string & legend,cairo_iface * context) const492 bool equalizerNband_audio_module<BaseClass, has_lphp>::get_gridline(int index, int subindex, int phase, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
493 {
494 if (!is_active || phase)
495 return false;
496 return get_freq_gridline(subindex, pos, vertical, legend, context, true, 128 * *params[AM::param_zoom], 0);
497 }
498
499 template<class BaseClass, bool has_lphp>
freq_gain(int index,double freq) const500 float equalizerNband_audio_module<BaseClass, has_lphp>::freq_gain(int index, double freq) const
501 {
502 float ret = 1.f;
503 if (has_lphp)
504 {
505 ret *= adjusted_lphp_gain(params, AM::param_hp_active, AM::param_hp_mode, hp[0][0], freq, (float)srate);
506 ret *= adjusted_lphp_gain(params, AM::param_lp_active, AM::param_lp_mode, lp[0][0], freq, (float)srate);
507 }
508 ret *= (*params[AM::param_ls_active] > 0.f) ? lsL.freq_gain(freq, (float)srate) : 1;
509 ret *= (*params[AM::param_hs_active] > 0.f) ? hsL.freq_gain(freq, (float)srate) : 1;
510 for (int i = 0; i < PeakBands; i++)
511 ret *= (*params[AM::param_p1_active + i * params_per_band] > 0.f) ? pL[i].freq_gain(freq, (float)srate) : 1;
512 return ret;
513 }
514
515 template<class BaseClass, bool has_lphp>
get_crosshair_label(int x,int y,int sx,int sy,float q,int dB,int name,int note,int cents) const516 inline std::string equalizerNband_audio_module<BaseClass, has_lphp>::get_crosshair_label(int x, int y, int sx, int sy, float q, int dB, int name, int note, int cents) const
517 {
518 return frequency_crosshair_label(x, y, sx, sy, q, dB, name, note, cents, 128 * *params[AM::param_zoom], 0);
519 }
520
521 namespace calf_plugins {
522 template class equalizerNband_audio_module<equalizer5band_metadata, false>;
523 template class equalizerNband_audio_module<equalizer8band_metadata, true>;
524 template class equalizerNband_audio_module<equalizer12band_metadata, true>;
525 }
526
527 /**********************************************************************
528 * EQUALIZER 30 BAND
529 **********************************************************************/
530
equalizer30band_audio_module()531 equalizer30band_audio_module::equalizer30band_audio_module() :
532 conv(OrfanidisEq::eqGainRangeDb),
533 swL(10000), swR(10000)
534 {
535 is_active = false;
536 srate = 0;
537
538 //Construct equalizers
539 using namespace OrfanidisEq;
540
541 fg.set30Bands();
542
543 Eq* ptr30L = new Eq(fg, butterworth);
544 Eq* ptr30R = new Eq(fg, butterworth);
545 eq_arrL.push_back(ptr30L);
546 eq_arrR.push_back(ptr30R);
547
548 ptr30L = new Eq(fg, chebyshev1);
549 ptr30R = new Eq(fg, chebyshev1);
550 eq_arrL.push_back(ptr30L);
551 eq_arrR.push_back(ptr30R);
552
553 ptr30L = new Eq(fg, chebyshev2);
554 ptr30R = new Eq(fg, chebyshev2);
555 eq_arrL.push_back(ptr30L);
556 eq_arrR.push_back(ptr30R);
557
558 ptr30L = new Eq(fg, elliptic);
559 ptr30R = new Eq(fg, elliptic);
560 eq_arrL.push_back(ptr30L);
561 eq_arrR.push_back(ptr30R);
562
563 flt_type = butterworth;
564 flt_type_old = none;
565
566 //Set switcher
567 swL.set_previous(butterworth);
568 swL.set(butterworth);
569
570 swR.set_previous(butterworth);
571 swR.set(butterworth);
572 }
573
~equalizer30band_audio_module()574 equalizer30band_audio_module::~equalizer30band_audio_module()
575 {
576 for (unsigned int i = 0; i < eq_arrL.size(); i++)
577 delete eq_arrL[i];
578
579 for (unsigned int i = 0; i < eq_arrR.size(); i++)
580 delete eq_arrR[i];
581 }
582
activate()583 void equalizer30band_audio_module::activate()
584 {
585 is_active = true;
586 }
587
deactivate()588 void equalizer30band_audio_module::deactivate()
589 {
590 is_active = false;
591 }
592
params_changed()593 void equalizer30band_audio_module::params_changed()
594 {
595 using namespace OrfanidisEq;
596
597 int psl=0, psr=0, pgl=0, pgr=0, pql=0, pqr=0;
598
599 switch (int(*params[param_linked])) {
600 case 0:
601 psl = param_gain_scale11;
602 pgl = param_gain10;
603 pql = param_gainscale1;
604 psr = param_gain_scale21;
605 pgr = param_gain20;
606 pqr = param_gainscale2;
607 *params[param_l_active] = 0.5;
608 *params[param_r_active] = 0.5;
609 break;
610 case 1:
611 psl = param_gain_scale11;
612 pgl = param_gain10;
613 pql = param_gainscale1;
614 psr = param_gain_scale11;
615 pgr = param_gain10;
616 pqr = param_gainscale1;
617 *params[param_l_active] = 1;
618 *params[param_r_active] = 0;
619 break;
620 case 2:
621 psl = param_gain_scale21;
622 pgl = param_gain20;
623 pql = param_gainscale2;
624 psr = param_gain_scale21;
625 pgr = param_gain20;
626 pqr = param_gainscale2;
627 *params[param_l_active] = 0;
628 *params[param_r_active] = 1;
629 break;
630 }
631
632 //Change gain indicators
633 *params[param_gain_scale10] = *params[pgl] * *params[pql];
634 *params[param_gain_scale20] = *params[pgr] * *params[pqr];
635
636 for(unsigned int i = 0; i < fg.getNumberOfBands(); i++) {
637 *params[param_gain_scale11 + band_params*i] = (*params[param_gain11 + band_params*i])*
638 *params[param_gainscale1];
639 *params[param_gain_scale21 + band_params*i] = (*params[param_gain21 + band_params*i])*
640 *params[param_gainscale2];
641 }
642
643 //Pass gains to eq's
644 for (unsigned int i = 0; i < fg.getNumberOfBands(); i++) {
645 eq_arrL[*params[param_filters]]->changeBandGainDb(i,*params[psl + band_params*i]);
646 eq_arrR[*params[param_filters]]->changeBandGainDb(i,*params[psr + band_params*i]);
647 }
648
649 //Upadte filter type
650 flt_type = (filter_type)int((*params[param_filters] + 1));
651 }
652
set_sample_rate(uint32_t sr)653 void equalizer30band_audio_module::set_sample_rate(uint32_t sr)
654 {
655 srate = sr;
656
657 //Change sample rate for eq's
658 for(unsigned int i = 0; i < eq_arrL.size(); i++)
659 {
660 eq_arrL[i]->setSampleRate(srate);
661 eq_arrR[i]->setSampleRate(srate);//maybe a typo flaw, by vlee78
662 }
663
664 int meter[] = {param_level_in_vuL, param_level_in_vuR, param_level_out_vuL, param_level_out_vuR};
665 int clip[] = {param_level_in_clipL, param_level_in_clipR, param_level_out_clipL, param_level_out_clipR};
666 meters.init(params, meter, clip, 4, sr);
667 }
668
process(uint32_t offset,uint32_t numsamples,uint32_t inputs_mask,uint32_t outputs_mask)669 uint32_t equalizer30band_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
670 {
671 uint32_t orig_numsamples = numsamples;
672 uint32_t orig_offset = offset;
673 bool bypassed = bypass.update(*params[param_bypass] > 0.5f, numsamples);
674 numsamples += offset;
675 if(bypassed) {
676 // everything bypassed
677 while(offset < numsamples) {
678 outs[0][offset] = ins[0][offset];
679 outs[1][offset] = ins[1][offset];
680 float values[] = {0, 0, 0, 0};
681 meters.process(values);
682 ++offset;
683 }
684 } else {
685 // process
686 while(offset < numsamples) {
687
688 double inL = ins[0][offset] * *params[param_level_in];
689 double inR = ins[1][offset] * *params[param_level_in];
690
691 double outL = inL;
692 double outR = inR;
693
694 unsigned int eq_index = swL.get_state() - 1;
695 eq_arrL[eq_index]->SBSProcess(&inL, &outL);
696 eq_arrR[eq_index]->SBSProcess(&inR, &outR);
697
698 //If filter type switched
699 if(flt_type_old != flt_type)
700 {
701 swL.set(flt_type);
702 swR.set(flt_type);
703 flt_type_old = flt_type;
704 }
705
706 outL *= swL.get_ramp();
707 outR *= swR.get_ramp();
708
709 outL = outL* conv.fastDb2Lin(*params[param_gain_scale10]);
710 outR = outR* conv.fastDb2Lin(*params[param_gain_scale20]);
711
712 outL = outL* *params[param_level_out];
713 outR = outR* *params[param_level_out];
714
715 outs[0][offset] = outL;
716 outs[1][offset] = outR;
717
718 // meters
719 float values[] = {(float)inL, (float)inR, (float)outL, (float)outR};
720 meters.process(values);
721
722 // next sample
723 ++offset;
724 } // cycle trough samples
725 bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples);
726 }
727
728 meters.fall(orig_numsamples);
729 return outputs_mask;
730 }
731
732 /**********************************************************************
733 * FILTERKLAVIER by Hans Baier
734 **********************************************************************/
735
filterclavier_audio_module()736 filterclavier_audio_module::filterclavier_audio_module()
737 : min_gain(1.0)
738 , max_gain(32.0)
739 , last_note(-1)
740 , last_velocity(-1)
741 {
742 }
743
params_changed()744 void filterclavier_audio_module::params_changed()
745 {
746 inertia_filter_module::inertia_cutoff.set_inertia(
747 note_to_hz(last_note + *params[par_transpose], *params[par_detune]));
748
749 float min_resonance = param_props[par_max_resonance].min;
750 inertia_filter_module::inertia_resonance.set_inertia(
751 (float(last_velocity) / 127.0)
752 // 0.001: see below
753 * (*params[par_max_resonance] - min_resonance + 0.001)
754 + min_resonance);
755
756 adjust_gain_according_to_filter_mode(last_velocity);
757
758 inertia_filter_module::calculate_filter();
759 redraw_graph = true;
760 }
761
activate()762 void filterclavier_audio_module::activate()
763 {
764 inertia_filter_module::activate();
765 }
766
set_sample_rate(uint32_t sr)767 void filterclavier_audio_module::set_sample_rate(uint32_t sr)
768 {
769 inertia_filter_module::set_sample_rate(sr);
770 }
771
deactivate()772 void filterclavier_audio_module::deactivate()
773 {
774 inertia_filter_module::deactivate();
775 }
776
777
note_on(int channel,int note,int vel)778 void filterclavier_audio_module::note_on(int channel, int note, int vel)
779 {
780 last_note = note;
781 last_velocity = vel;
782 inertia_filter_module::inertia_cutoff.set_inertia(
783 note_to_hz(note + *params[par_transpose], *params[par_detune]));
784
785 float min_resonance = param_props[par_max_resonance].min;
786 inertia_filter_module::inertia_resonance.set_inertia(
787 (float(vel) / 127.0)
788 // 0.001: if the difference is equal to zero (which happens
789 // when the max_resonance knom is at minimum position
790 // then the filter gain doesnt seem to snap to zero on most note offs
791 * (*params[par_max_resonance] - min_resonance + 0.001)
792 + min_resonance);
793
794 adjust_gain_according_to_filter_mode(vel);
795
796 inertia_filter_module::calculate_filter();
797 redraw_graph = true;
798 }
799
note_off(int channel,int note,int vel)800 void filterclavier_audio_module::note_off(int channel, int note, int vel)
801 {
802 if (note == last_note) {
803 inertia_filter_module::inertia_resonance.set_inertia(param_props[par_max_resonance].min);
804 inertia_filter_module::inertia_gain.set_inertia(min_gain);
805 inertia_filter_module::calculate_filter();
806 last_velocity = 0;
807 redraw_graph = true;
808 }
809 }
810
adjust_gain_according_to_filter_mode(int velocity)811 void filterclavier_audio_module::adjust_gain_according_to_filter_mode(int velocity)
812 {
813 int mode = dsp::fastf2i_drm(*params[par_mode]);
814
815 // for bandpasses: boost gain for velocities > 0
816 if ( (mode_6db_bp <= mode) && (mode <= mode_18db_bp) ) {
817 // gain for velocity 0: 1.0
818 // gain for velocity 127: 32.0
819 float mode_max_gain = max_gain;
820 // max_gain is right for mode_6db_bp
821 if (mode == mode_12db_bp)
822 mode_max_gain /= 6.0;
823 if (mode == mode_18db_bp)
824 mode_max_gain /= 10.5;
825
826 inertia_filter_module::inertia_gain.set_now(
827 (float(velocity) / 127.0) * (mode_max_gain - min_gain) + min_gain);
828 } else {
829 inertia_filter_module::inertia_gain.set_now(min_gain);
830 }
831 }
832
833 /**********************************************************************
834 * EMPHASIS by Damien Zammit
835 **********************************************************************/
836
emphasis_audio_module()837 emphasis_audio_module::emphasis_audio_module()
838 {
839 is_active = false;
840 srate = 0;
841 redraw_graph = true;
842 mode = -1;
843 type = -1;
844 }
845
activate()846 void emphasis_audio_module::activate()
847 {
848 is_active = true;
849 // set all filters
850 params_changed();
851 }
852
deactivate()853 void emphasis_audio_module::deactivate()
854 {
855 is_active = false;
856 }
857
params_changed()858 void emphasis_audio_module::params_changed()
859 {
860 if (mode != *params[param_mode] || type != *params[param_type] || bypass_ != *params[param_bypass])
861 redraw_graph = true;
862 mode = *params[param_mode];
863 type = *params[param_type];
864 bypass_ = *params[param_bypass];
865 riaacurvL.set(srate, mode, type);
866 riaacurvR.set(srate, mode, type);
867 }
868
process(uint32_t offset,uint32_t numsamples,uint32_t inputs_mask,uint32_t outputs_mask)869 uint32_t emphasis_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
870 {
871 uint32_t orig_numsamples = numsamples;
872 uint32_t orig_offset = offset;
873 bool bypassed = bypass.update(*params[param_bypass] > 0.5f, numsamples);
874 if (!bypassed)
875 {
876 // ensure that if params have changed, the params_changed method is
877 // called every 8 samples to interpolate filter parameters
878 while(numsamples > 8)
879 {
880 params_changed();
881 outputs_mask |= process(offset, 8, inputs_mask, outputs_mask);
882 offset += 8;
883 numsamples -= 8;
884 }
885 }
886 numsamples += offset;
887 if(bypassed) {
888 // everything bypassed
889 while(offset < numsamples) {
890 outs[0][offset] = ins[0][offset];
891 outs[1][offset] = ins[1][offset];
892 float values[] = {0, 0, 0, 0};
893 meters.process(values);
894 ++offset;
895 }
896 } else {
897 // process
898 while(offset < numsamples) {
899 // cycle through samples
900 float outL = 0.f;
901 float outR = 0.f;
902 float inL = ins[0][offset];
903 float inR = ins[1][offset];
904 // in level
905 inR *= *params[param_level_in];
906 inL *= *params[param_level_in];
907
908 float procL = inL;
909 float procR = inR;
910
911 procL = riaacurvL.process(procL);
912 procR = riaacurvR.process(procR);
913
914 outL = procL * *params[param_level_out];
915 outR = procR * *params[param_level_out];
916
917 // send to output
918 outs[0][offset] = outL;
919 outs[1][offset] = outR;
920
921 float values[] = {inL, inR, outL, outR};
922 meters.process(values);
923
924 // next sample
925 ++offset;
926 } // cycle trough samples
927 bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples);
928 // clean up
929 riaacurvL.sanitize();
930 riaacurvR.sanitize();
931 }
932 meters.fall(orig_numsamples);
933 return outputs_mask;
934 }
get_graph(int index,int subindex,int phase,float * data,int points,cairo_iface * context,int * mode) const935 bool emphasis_audio_module::get_graph(int index, int subindex, int phase, float *data, int points, cairo_iface *context, int *mode) const
936 {
937 if (phase || subindex)
938 return false;
939 if (bypass_)
940 context->set_source_rgba(0.15, 0.2, 0.0, 0.3);
941 return ::get_graph(*this, subindex, data, points, 32, 0);
942 }
get_gridline(int index,int subindex,int phase,float & pos,bool & vertical,std::string & legend,cairo_iface * context) const943 bool emphasis_audio_module::get_gridline(int index, int subindex, int phase, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
944 {
945 if (phase)
946 return false;
947 return get_freq_gridline(subindex, pos, vertical, legend, context, true, 32, 0);
948 }
949
950 /**********************************************************************
951 * CROSSOVER N BAND by Markus Schmidt
952 **********************************************************************/
953
954 template<class XoverBaseClass>
xover_audio_module()955 xover_audio_module<XoverBaseClass>::xover_audio_module()
956 {
957 is_active = false;
958 srate = 0;
959 redraw_graph = true;
960 buffer = NULL;
961 crossover.init(AM::channels, AM::bands, 44100);
962 }
963 template<class XoverBaseClass>
~xover_audio_module()964 xover_audio_module<XoverBaseClass>::~xover_audio_module()
965 {
966 free(buffer);
967 }
968 template<class XoverBaseClass>
activate()969 void xover_audio_module<XoverBaseClass>::activate()
970 {
971 is_active = true;
972 params_changed();
973 }
974
975 template<class XoverBaseClass>
deactivate()976 void xover_audio_module<XoverBaseClass>::deactivate()
977 {
978 is_active = false;
979 }
980 template<class XoverBaseClass>
set_sample_rate(uint32_t sr)981 void xover_audio_module<XoverBaseClass>::set_sample_rate(uint32_t sr)
982 {
983 srate = sr;
984 // set srate of crossover
985 crossover.set_sample_rate(srate);
986 // rebuild buffer
987 buffer_size = (int)(srate / 10 * AM::channels * AM::bands + AM::channels * AM::bands); // buffer size attack rate multiplied by channels and bands
988 buffer = (float*) calloc(buffer_size, sizeof(float));
989 pos = 0;
990 int amount = AM::bands * AM::channels + AM::channels;
991 STACKALLOC(int, meter,amount);
992 STACKALLOC(int, clip, amount);
993 for(int b = 0; b < AM::bands; b++) {
994 for (int c = 0; c < AM::channels; c++) {
995 meter[b * AM::channels + c] = AM::param_meter_01 + b * params_per_band + c;
996 clip[b * AM::channels + c] = -1;
997 }
998 }
999 for (int c = 0; c < AM::channels; c++) {
1000 meter[c + AM::bands * AM::channels] = AM::param_meter_0 + c;
1001 clip[c + AM::bands * AM::channels] = -1;
1002 }
1003 meters.init(params, meter, clip, amount, srate);
1004 }
1005 template<class XoverBaseClass>
params_changed()1006 void xover_audio_module<XoverBaseClass>::params_changed()
1007 {
1008 int mode = *params[AM::param_mode];
1009 crossover.set_mode(mode);
1010 for (int i = 0; i < AM::bands - 1; i++) {
1011 crossover.set_filter(i, *params[AM::param_freq0 + i]);
1012 }
1013 for (int i = 0; i < AM::bands; i++) {
1014 int offset = i * params_per_band;
1015 crossover.set_level(i, *params[AM::param_level1 + offset]);
1016 crossover.set_active(i, *params[AM::param_active1 + offset] > 0.5);
1017 }
1018 redraw_graph = true;
1019 }
1020
1021 template<class XoverBaseClass>
process(uint32_t offset,uint32_t numsamples,uint32_t inputs_mask,uint32_t outputs_mask)1022 uint32_t xover_audio_module<XoverBaseClass>::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
1023 {
1024 unsigned int targ = numsamples + offset;
1025 float xval;
1026 float values[AM::bands * AM::channels + AM::channels];
1027 while(offset < targ) {
1028 // cycle through samples
1029
1030 // level
1031 for (int c = 0; c < AM::channels; c++) {
1032 in[c] = ins[c][offset] * *params[AM::param_level];
1033 }
1034 crossover.process(in);
1035
1036 for (int b = 0; b < AM::bands; b++) {
1037 int nbuf = 0;
1038 int off = b * params_per_band;
1039 // calc position in delay buffer
1040 if (*params[AM::param_delay1 + off]) {
1041 nbuf = srate * (fabs(*params[AM::param_delay1 + off]) / 1000.f) * AM::bands * AM::channels;
1042 nbuf -= nbuf % (AM::bands * AM::channels);
1043 }
1044 for (int c = 0; c < AM::channels; c++) {
1045 // define a pointer between 0 and channels * bands
1046 int ptr = b * AM::channels + c;
1047
1048 // get output from crossover module if active
1049 xval = *params[AM::param_active1 + off] > 0.5 ? crossover.get_value(c, b) : 0.f;
1050
1051 // fill delay buffer
1052 buffer[pos + ptr] = xval;
1053
1054 // get value from delay buffer if neccessary
1055 if (*params[AM::param_delay1 + off])
1056 xval = buffer[(pos - (int)nbuf + ptr + buffer_size) % buffer_size];
1057
1058 // set value with phase to output
1059 outs[ptr][offset] = *params[AM::param_phase1 + off] > 0.5 ? xval * -1 : xval;
1060
1061 // band meters
1062 values[b * AM::channels + c] = outs[ptr][offset];
1063 }
1064 }
1065 // in meters
1066 for (int c = 0; c < AM::channels; c++) {
1067 values[c + AM::bands * AM::channels] = ins[c][offset];
1068 }
1069 meters.process(values);
1070 // next sample
1071 ++offset;
1072 // delay buffer pos forward
1073 pos = (pos + AM::channels * AM::bands) % buffer_size;
1074
1075 } // cycle trough samples
1076 meters.fall(numsamples);
1077 return outputs_mask;
1078 }
1079
1080 template<class XoverBaseClass>
get_graph(int index,int subindex,int phase,float * data,int points,cairo_iface * context,int * mode) const1081 bool xover_audio_module<XoverBaseClass>::get_graph(int index, int subindex, int phase, float *data, int points, cairo_iface *context, int *mode) const
1082 {
1083 return crossover.get_graph(subindex, phase, data, points, context, mode);
1084 }
1085 template<class XoverBaseClass>
get_layers(int index,int generation,unsigned int & layers) const1086 bool xover_audio_module<XoverBaseClass>::get_layers(int index, int generation, unsigned int &layers) const
1087 {
1088 return crossover.get_layers(index, generation, layers);
1089 }
1090
1091 namespace calf_plugins {
1092 template class xover_audio_module<xover2_metadata>;
1093 template class xover_audio_module<xover3_metadata>;
1094 template class xover_audio_module<xover4_metadata>;
1095 }
1096
1097
1098 /**********************************************************************
1099 * Vocoder by Markus Schmidt and Christian Holschuh
1100 **********************************************************************/
1101
vocoder_audio_module()1102 vocoder_audio_module::vocoder_audio_module()
1103 {
1104 is_active = false;
1105 srate = 0;
1106 attack = 0;
1107 release = 0;
1108 fcoeff = 0;
1109 bands = 0;
1110 bands_old = -1;
1111 order = 0;
1112 order_old = -1;
1113 lower_old = upper_old = tilt_old = 0;
1114 fcoeff = log10(20.f);
1115 log2_ = log(2);
1116 memset(env_mods, 0, 32 * 2 * sizeof(double));
1117 }
1118
activate()1119 void vocoder_audio_module::activate()
1120 {
1121 is_active = true;
1122 }
1123
deactivate()1124 void vocoder_audio_module::deactivate()
1125 {
1126 is_active = false;
1127 }
1128
params_changed()1129 void vocoder_audio_module::params_changed()
1130 {
1131 attack = exp(log(0.01)/( *params[param_attack] * srate * 0.001));
1132 release = exp(log(0.01)/( *params[param_release] * srate * 0.001));
1133
1134 int b = *params[param_bands];
1135 bands = (b + 2) * 4 + (b > 1 ? (b - 2) * 4 : 0);
1136 order = std::min(8.f, *params[param_order]);
1137 bool draw = false;
1138 for (int i = 0; i < 32; i++) {
1139 if (q_old[i] != *params[param_q0 + i * band_params]) {
1140 draw = true;
1141 q_old[i] = *params[param_q0 + i * band_params];
1142 }
1143 }
1144 if (draw || bands != bands_old || *params[param_order] != order_old
1145 || *params[param_hiq] != hiq_old || *params[param_lower] != lower_old
1146 || *params[param_upper] != upper_old || *params[param_tilt] != tilt_old) {
1147 float q = pow(10, (fmodf(std::min(8.999f, *params[param_order]), 1.f) * (7.f / pow(1.3, order))) / 20);
1148 q += *params[param_hiq];
1149 bands_old = bands;
1150 order_old = *params[param_order];
1151 hiq_old = *params[param_hiq];
1152 lower_old = *params[param_lower];
1153 upper_old = *params[param_upper];
1154 tilt_old = *params[param_tilt];
1155 float to = *params[param_tilt] < 0 ? *params[param_lower] : *params[param_upper];
1156 float from = *params[param_tilt] < 0 ? *params[param_upper] : *params[param_lower];
1157 float tilt = fabs(*params[param_tilt]);
1158 float freq = from;
1159 for (int i = 0; i < bands; i++) {
1160 int _i = *params[param_tilt] < 0 ? bands - i - 1 : i;
1161 float _freq = log10(freq);
1162 float _q = q * *params[param_q0 + _i * band_params];
1163 //detector[0][0][i].set_bp_rbj(pow(10, fcoeff + (0.5f + (float)i) * 3.f / (float)bands), _q, (double)srate);
1164 float step = (log10(to) - _freq) / (bands - i) * (1 + tilt);
1165 float f = pow(10, _freq + (0.5 * step));
1166 bandfreq[_i] = f;
1167 detector[0][0][_i].set_bp_rbj(f, _q, (double)srate);
1168 for (int j = 0; j < order; j++) {
1169 if (j)
1170 detector[0][j][_i].copy_coeffs(detector[0][0][_i]);
1171 detector[1][j][_i].copy_coeffs(detector[0][0][_i]);
1172 modulator[0][j][_i].copy_coeffs(detector[0][0][_i]);
1173 modulator[1][j][_i].copy_coeffs(detector[0][0][_i]);
1174 }
1175 freq = pow(10, _freq + step);
1176 }
1177 redraw_graph = true;
1178 }
1179 _analyzer.set_params(256, 1, 6, 0, 1, 0, 0, 0, 15, 2, 0, 0);
1180 redraw_graph = true;
1181 }
1182
get_solo() const1183 int vocoder_audio_module::get_solo() const {
1184 for (int i = 0; i < bands; i++)
1185 if (*params[param_solo0 + i * band_params])
1186 return 1;
1187 return 0;
1188 }
1189
process(uint32_t offset,uint32_t numsamples,uint32_t inputs_mask,uint32_t outputs_mask)1190 uint32_t vocoder_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
1191 {
1192 uint32_t orig_numsamples = numsamples;
1193 uint32_t orig_offset = offset;
1194 bool bypassed = bypass.update(*params[param_bypass] > 0.5f, numsamples);
1195 int solo = get_solo();
1196 numsamples += offset;
1197 float led[32] = {0};
1198 if(bypassed) {
1199 // everything bypassed
1200 while(offset < numsamples) {
1201 outs[0][offset] = ins[0][offset];
1202 outs[1][offset] = ins[1][offset];
1203 float values[] = {0, 0, 0, 0, 0, 0};
1204 meters.process(values);
1205 ++offset;
1206 }
1207 } else {
1208 // process
1209 while(offset < numsamples) {
1210 // cycle through samples
1211 double outL = 0;
1212 double outR = 0;
1213 double pL = 0;
1214 double pR = 0;
1215
1216 // carrier with level
1217 double cL = ins[0][offset] * *params[param_carrier_in];
1218 double cR = ins[1][offset] * *params[param_carrier_in];
1219
1220 // modulator with level
1221 double mL = ins[2][offset] * *params[param_mod_in];
1222 double mR = ins[3][offset] * *params[param_mod_in];
1223
1224 // noise generator
1225 double nL = (float)rand() / (float)RAND_MAX;
1226 double nR = (float)rand() / (float)RAND_MAX;
1227
1228 for (int i = 0; i < bands; i++) {
1229 double mL_ = mL;
1230 double mR_ = mR;
1231 double cL_ = cL + nL * *params[param_noise0 + i * band_params];
1232 double cR_ = cR + nR * *params[param_noise0 + i * band_params];
1233
1234 if ((solo && *params[param_solo0 + i * band_params]) || !solo) {
1235 for (int j = 0; j < order; j++) {
1236 // filter modulator
1237 if (*params[param_link] > 0.5) {
1238 mL_ = detector[0][j][i].process(std::max(mL_, mR_));
1239 mR_ = mL_;
1240 } else {
1241 mL_ = detector[0][j][i].process(mL_);
1242 mR_ = detector[1][j][i].process(mR_);
1243 }
1244 // filter carrier with noise
1245 cL_ = modulator[0][j][i].process(cL_);
1246 cR_ = modulator[1][j][i].process(cR_);
1247 }
1248 // level by envelope with levelling
1249 cL_ *= env_mods[0][i] * ((float)order / 2 + 4) * 4;
1250 cR_ *= env_mods[1][i] * ((float)order / 2 + 4) * 4;
1251
1252 // add band volume setting
1253 cL_ *= *params[param_volume0 + i * band_params];
1254 cR_ *= *params[param_volume0 + i * band_params];
1255
1256 // add filtered modulator
1257 cL_ += mL_ * *params[param_mod0 + i * band_params];
1258 cR_ += mR_ * *params[param_mod0 + i * band_params];
1259
1260 // Balance
1261 cL_ *= (*params[param_pan0 + i * band_params] > 0
1262 ? -*params[param_pan0 + i * band_params] + 1 : 1);
1263 cR_ *= (*params[param_pan0 + i * band_params] < 0
1264 ? *params[param_pan0 + i * band_params] + 1 : 1);
1265
1266 // add to outputs with proc level
1267 pL += cL_ * *params[param_proc];
1268 pR += cR_ * *params[param_proc];
1269 }
1270 // LED
1271 if (*params[param_detectors] > 0.5)
1272 if (env_mods[0][i] + env_mods[1][i] > led[i])
1273 led[i] = env_mods[0][i] + env_mods[1][i];
1274
1275 // advance envelopes
1276 env_mods[0][i] = _sanitize((fabs(mL_) > env_mods[0][i] ? attack : release) * (env_mods[0][i] - fabs(mL_)) + fabs(mL_));
1277 env_mods[1][i] = _sanitize((fabs(mR_) > env_mods[1][i] ? attack : release) * (env_mods[1][i] - fabs(mR_)) + fabs(mR_));
1278 }
1279
1280 outL = pL;
1281 outR = pR;
1282
1283 // dry carrier
1284 outL += cL * *params[param_carrier];
1285 outR += cR * *params[param_carrier];
1286
1287 // dry modulator
1288 outL += mL * *params[param_mod];
1289 outR += mR * *params[param_mod];
1290
1291 // analyzer
1292 switch ((int)*params[param_analyzer]) {
1293 case 0:
1294 default:
1295 break;
1296 case 1:
1297 _analyzer.process((float)cL, (float)cR);
1298 break;
1299 case 2:
1300 _analyzer.process((float)mL, (float)mR);
1301 break;
1302 case 3:
1303 _analyzer.process((float)pL, (float)pR);
1304 break;
1305 case 4:
1306 _analyzer.process((float)outL, (float)outR);
1307 break;
1308 }
1309
1310 // out level
1311 outL *= *params[param_out];
1312 outR *= *params[param_out];
1313
1314 // send to outputs
1315 outs[0][offset] = outL;
1316 outs[1][offset] = outR;
1317
1318 // meters
1319 float values[] = {(float)cL, (float)cR, (float)mL, (float)mR, (float)outL, (float)outR};
1320 meters.process(values);
1321
1322 // next sample
1323 ++offset;
1324 } // cycle trough samples
1325 bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples);
1326 // clean up
1327 for (int i = 0; i < bands; i++) {
1328 for (int j = 0; j < order; j++) {
1329 detector[0][j][i].sanitize();
1330 detector[1][j][i].sanitize();
1331 modulator[0][j][i].sanitize();
1332 modulator[1][j][i].sanitize();
1333 }
1334 }
1335 }
1336
1337 // LED
1338 for (int i = 0; i < 32; i++) {
1339 float val = 0;
1340 if (*params[param_detectors] > 0.5)
1341 val = std::max(0.0, 1 + log((led[i] / 2) * order) / log2_ / 10);
1342 *params[param_level0 + i * band_params] = val;
1343 }
1344 meters.fall(orig_numsamples);
1345 return outputs_mask;
1346 }
get_graph(int index,int subindex,int phase,float * data,int points,cairo_iface * context,int * mode) const1347 bool vocoder_audio_module::get_graph(int index, int subindex, int phase, float *data, int points, cairo_iface *context, int *mode) const
1348 {
1349 if (phase && *params[param_analyzer]) {
1350 if (subindex) {
1351 return false;
1352 }
1353 bool r = _analyzer.get_graph(subindex, phase, data, points, context, mode);
1354 context->set_source_rgba(0,0,0,0.25);
1355 return r;
1356 } else if (phase) {
1357 return false;
1358 } else {
1359 // quit
1360 if (subindex >= bands) {
1361 redraw_graph = false;
1362 return false;
1363 }
1364 int solo = get_solo();
1365 if (solo && !*params[param_solo0 + subindex * band_params])
1366 context->set_source_rgba(0,0,0,0.15);
1367 context->set_line_width(0.99);
1368 int drawn = 0;
1369 for (int i = 0; i < points; i++) {
1370 double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points);
1371 float level = 1;
1372 for (int j = 0; j < order; j++)
1373 level *= detector[0][0][subindex].freq_gain(freq, srate);
1374 level *= *params[param_volume0 + subindex * band_params];
1375 data[i] = dB_grid(level, 256, 0.4);
1376 if (!drawn && freq > bandfreq[subindex]) {
1377 drawn = 1;
1378 char str[32];
1379 sprintf(str, "%d", subindex + 1);
1380 draw_cairo_label(context, str, i, context->size_y * (1 - (data[i] + 1) / 2.f), 0, 0, 0.5);
1381 }
1382 }
1383 }
1384 return true;
1385 }
get_layers(int index,int generation,unsigned int & layers) const1386 bool vocoder_audio_module::get_layers(int index, int generation, unsigned int &layers) const
1387 {
1388 redraw_graph = redraw_graph || !generation;
1389 layers = *params[param_analyzer] ? LG_REALTIME_GRAPH : 0;
1390 layers |= (generation ? LG_NONE : LG_CACHE_GRID) | (redraw_graph ? LG_CACHE_GRAPH : LG_NONE);
1391 redraw_graph |= (bool)*params[param_analyzer];
1392 return redraw_graph || !generation;
1393 }
1394