LineGraph: background for labels
[calf.git] / src / modules_filter.cpp
bloba835ed00b41c70e8ac3b6faf6fd3687e75d05e81
1 /* Calf DSP plugin pack
2 * Equalization related plugins
4 * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others
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.
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.
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
21 #include <limits.h>
22 #include <memory.h>
23 #include <calf/giface.h>
24 #include <calf/modules_filter.h>
26 using namespace dsp;
27 using namespace calf_plugins;
29 #define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name;
31 /**********************************************************************
32 * EQUALIZER N BAND by Markus Schmidt and Krzysztof Foltman
33 **********************************************************************/
35 inline void diff_ms(float &left, float &right) {
36 float tmp = (left + right) / 2;
37 right = left - right;
38 left = tmp;
40 inline void undiff_ms(float &left, float &right) {
41 float tmp = left + right / 2;
42 right = left - right / 2;
43 left = tmp;
46 template<class BaseClass, bool has_lphp>
47 equalizerNband_audio_module<BaseClass, has_lphp>::equalizerNband_audio_module()
49 is_active = false;
50 srate = 0;
51 last_generation = 0;
52 hp_freq_old = lp_freq_old = 0;
53 hs_freq_old = ls_freq_old = 0;
54 hs_level_old = ls_level_old = 0;
55 keep_gliding = 0;
56 last_peak = 0;
57 indiv_old = -1;
58 analyzer_old = false;
59 for (int i = 0; i < AM::PeakBands; i++)
61 p_freq_old[i] = 0;
62 p_level_old[i] = 0;
63 p_q_old[i] = 0;
65 for (int i = 0; i < graph_param_count; i++)
66 old_params_for_graph[i] = -1;
67 redraw_graph = true;
70 template<class BaseClass, bool has_lphp>
71 void equalizerNband_audio_module<BaseClass, has_lphp>::activate()
73 is_active = true;
74 // set all filters
75 params_changed();
78 template<class BaseClass, bool has_lphp>
79 void equalizerNband_audio_module<BaseClass, has_lphp>::deactivate()
81 is_active = false;
84 static inline void copy_lphp(biquad_d2 filters[3][2])
86 for (int i = 0; i < 3; i++)
87 for (int j = 0; j < 2; j++)
88 if (i || j)
89 filters[i][j].copy_coeffs(filters[0][0]);
92 static inline double glide(double value, double target, int &keep_gliding)
94 if (target == value)
95 return value;
96 keep_gliding = 1;
97 if (target > value)
98 return std::min(target, (value + 0.1) * 1.003);
99 else
100 return std::max(target, (value / 1.003) - 0.1);
103 template<class BaseClass, bool has_lphp>
104 void equalizerNband_audio_module<BaseClass, has_lphp>::params_changed()
106 keep_gliding = 0;
107 // set the params of all filters
109 // lp/hp first (if available)
110 if (has_lphp)
112 hp_mode = (CalfEqMode)(int)*params[AM::param_hp_mode];
113 lp_mode = (CalfEqMode)(int)*params[AM::param_lp_mode];
115 float hpfreq = *params[AM::param_hp_freq], lpfreq = *params[AM::param_lp_freq];
117 if(hpfreq != hp_freq_old) {
118 hpfreq = glide(hp_freq_old, hpfreq, keep_gliding);
119 hp[0][0].set_hp_rbj(hpfreq, 0.707, (float)srate, 1.0);
120 copy_lphp(hp);
121 hp_freq_old = hpfreq;
123 if(lpfreq != lp_freq_old) {
124 lpfreq = glide(lp_freq_old, lpfreq, keep_gliding);
125 lp[0][0].set_lp_rbj(lpfreq, 0.707, (float)srate, 1.0);
126 copy_lphp(lp);
127 lp_freq_old = lpfreq;
131 // then shelves
132 float hsfreq = *params[AM::param_hs_freq], hslevel = *params[AM::param_hs_level], hsq =*params[AM::param_hs_q];
133 float lsfreq = *params[AM::param_ls_freq], lslevel = *params[AM::param_ls_level], lsq =*params[AM::param_ls_q];
135 if(lsfreq != ls_freq_old or lslevel != ls_level_old or lsq != ls_q_old) {
136 lsfreq = glide(ls_freq_old, lsfreq, keep_gliding);
137 lsL.set_lowshelf_rbj(lsfreq, lsq, lslevel, (float)srate);
138 lsR.copy_coeffs(lsL);
139 ls_level_old = lslevel;
140 ls_freq_old = lsfreq;
141 ls_q_old = lsq;
143 if(hsfreq != hs_freq_old or hslevel != hs_level_old or hsq != hs_q_old) {
144 hsfreq = glide(hs_freq_old, hsfreq, keep_gliding);
145 hsL.set_highshelf_rbj(hsfreq, hsq, hslevel, (float)srate);
146 hsR.copy_coeffs(hsL);
147 hs_level_old = hslevel;
148 hs_freq_old = hsfreq;
149 hs_q_old = hsq;
151 for (int i = 0; i < AM::PeakBands; i++)
153 int offset = i * params_per_band;
154 float freq = *params[AM::param_p1_freq + offset];
155 float level = *params[AM::param_p1_level + offset];
156 float q = *params[AM::param_p1_q + offset];
157 if(freq != p_freq_old[i] or level != p_level_old[i] or q != p_q_old[i]) {
158 freq = glide(p_freq_old[i], freq, keep_gliding);
159 pL[i].set_peakeq_rbj(freq, q, level, (float)srate);
160 pR[i].copy_coeffs(pL[i]);
161 p_freq_old[i] = freq;
162 p_level_old[i] = level;
163 p_q_old[i] = q;
166 if (*params[AM::param_individuals] != indiv_old) {
167 indiv_old = *params[AM::param_individuals];
168 redraw_graph = true;
171 // check if any important parameter for redrawing the graph changed
172 for (int i = 0; i < graph_param_count; i++) {
173 if (*params[AM::first_graph_param + i] != old_params_for_graph[i])
174 redraw_graph = true;
175 old_params_for_graph[i] = *params[AM::first_graph_param + i];
178 _analyzer.set_params(
179 256, 1, 6, 0, 1,
180 *params[AM::param_analyzer_mode] + (*params[AM::param_analyzer_mode] >= 3 ? 5 : 1),
181 0, 0, 15, 2, 0, 0
184 if ((bool)*params[AM::param_analyzer_active] != analyzer_old) {
185 redraw_graph = true;
186 analyzer_old = (bool)*params[AM::param_analyzer_active];
190 template<class BaseClass, bool has_lphp>
191 inline void equalizerNband_audio_module<BaseClass, has_lphp>::process_hplp(float &left, float &right)
193 if (!has_lphp)
194 return;
195 int active = *params[AM::param_lp_active];
196 if (active > 0.f)
198 if (active > 3) diff_ms(left, right);
199 switch(lp_mode)
201 case MODE12DB:
202 if (active == 1 or active == 2 or active == 4)
203 left = lp[0][0].process(left);
204 if (active == 1 or active == 3 or active == 5)
205 right = lp[0][1].process(right);
206 break;
207 case MODE24DB:
208 if (active == 1 or active == 2 or active == 4)
209 left = lp[1][0].process(lp[0][0].process(left));
210 if (active == 1 or active == 3 or active == 5)
211 right = lp[1][1].process(lp[0][1].process(right));
212 break;
213 case MODE36DB:
214 if (active == 1 or active == 2 or active == 4)
215 left = lp[2][0].process(lp[1][0].process(lp[0][0].process(left)));
216 if (active == 1 or active == 3 or active == 5)
217 right = lp[2][1].process(lp[1][1].process(lp[0][1].process(right)));
218 break;
220 if (active > 3) undiff_ms(left, right);
222 active = *params[AM::param_hp_active];
223 if (active > 0.f)
225 if (active > 3) diff_ms(left, right);
226 switch(hp_mode)
228 case MODE12DB:
229 if (active == 1 or active == 2 or active == 4)
230 left = hp[0][0].process(left);
231 if (active == 1 or active == 3 or active == 5)
232 right = hp[0][1].process(right);
233 break;
234 case MODE24DB:
235 if (active == 1 or active == 2 or active == 4)
236 left = hp[1][0].process(hp[0][0].process(left));
237 if (active == 1 or active == 3 or active == 5)
238 right = hp[1][1].process(hp[0][1].process(right));
239 break;
240 case MODE36DB:
241 if (active == 1 or active == 2 or active == 4)
242 left = hp[2][0].process(hp[1][0].process(hp[0][0].process(left)));
243 if (active == 1 or active == 3 or active == 5)
244 right = hp[2][1].process(hp[1][1].process(hp[0][1].process(right)));
245 break;
247 if (active > 3) undiff_ms(left, right);
251 template<class BaseClass, bool has_lphp>
252 uint32_t equalizerNband_audio_module<BaseClass, has_lphp>::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
254 bool bypassed = bypass.update(*params[AM::param_bypass] > 0.5f, numsamples);
255 if (keep_gliding)
257 // ensure that if params have changed, the params_changed method is
258 // called every 8 samples to interpolate filter parameters
259 while(numsamples > 8 && keep_gliding)
261 params_changed();
262 outputs_mask |= process(offset, 8, inputs_mask, outputs_mask);
263 offset += 8;
264 numsamples -= 8;
266 if (keep_gliding)
267 params_changed();
269 numsamples += offset;
270 if(bypassed) {
271 // everything bypassed
272 while(offset < numsamples) {
273 outs[0][offset] = ins[0][offset];
274 outs[1][offset] = ins[1][offset];
275 float values[] = {0, 0, 0, 0};
276 meters.process(values);
277 _analyzer.process(0, 0);
278 ++offset;
280 } else {
281 // process
282 uint32_t orig_numsamples = numsamples-offset;
283 uint32_t orig_offset = offset;
284 while(offset < numsamples) {
285 // cycle through samples
286 float outL = 0.f;
287 float outR = 0.f;
288 float inL = ins[0][offset];
289 float inR = ins[1][offset];
290 // in level
291 inR *= *params[AM::param_level_in];
292 inL *= *params[AM::param_level_in];
294 float procL = inL;
295 float procR = inR;
297 // all filters in chain
298 process_hplp(procL, procR);
300 int active = *params[AM::param_ls_active];
301 if (active > 3) diff_ms(procL, procR);
302 if (active == 1 or active == 2 or active == 4)
303 procL = lsL.process(procL);
304 if (active == 1 or active == 3 or active == 5)
305 procR = lsR.process(procR);
306 if (active > 3) undiff_ms(procL, procR);
308 active = *params[AM::param_hs_active];
309 if (active > 3) diff_ms(procL, procR);
310 if (active == 1 or active == 2 or active == 4)
311 procL = hsL.process(procL);
312 if (active == 1 or active == 3 or active == 5)
313 procR = hsR.process(procR);
314 if (active > 3) undiff_ms(procL, procR);
316 for (int i = 0; i < AM::PeakBands; i++)
318 int offset = i * params_per_band;
319 int active = *params[AM::param_p1_active + offset];
320 if (active > 3) diff_ms(procL, procR);
321 if (active == 1 or active == 2 or active == 4)
322 procL = pL[i].process(procL);
323 if (active == 1 or active == 3 or active == 5)
324 procR = pR[i].process(procR);
325 if (active > 3) undiff_ms(procL, procR);
328 outL = procL * *params[AM::param_level_out];
329 outR = procR * *params[AM::param_level_out];
331 // analyzer
332 _analyzer.process((inL + inR) / 2.f, (outL + outR) / 2.f);
334 // send to output
335 outs[0][offset] = outL;
336 outs[1][offset] = outR;
338 float values[] = {inL, inR, outL, outR};
339 meters.process(values);
341 // next sample
342 ++offset;
343 } // cycle trough samples
344 bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples);
345 // clean up
346 for(int i = 0; i < 3; ++i) {
347 hp[i][0].sanitize();
348 hp[i][1].sanitize();
349 lp[i][0].sanitize();
350 lp[i][1].sanitize();
352 lsL.sanitize();
353 hsR.sanitize();
354 for(int i = 0; i < AM::PeakBands; ++i) {
355 pL[i].sanitize();
356 pR[i].sanitize();
359 meters.fall(numsamples);
360 return outputs_mask;
363 static inline float adjusted_lphp_gain(const float *const *params, int param_active, int param_mode, const biquad_d2 &filter, float freq, float srate)
365 if(*params[param_active] > 0.f) {
366 float gain = filter.freq_gain(freq, srate);
367 switch((int)*params[param_mode]) {
368 case MODE12DB:
369 return gain;
370 case MODE24DB:
371 return gain * gain;
372 case MODE36DB:
373 return gain * gain * gain;
376 return 1;
379 template<class BaseClass, bool has_lphp>
380 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
382 if (phase and *params[AM::param_analyzer_active]) {
383 bool r = _analyzer.get_graph(subindex, phase, data, points, context, mode);
384 if (*params[AM::param_analyzer_mode] == 2) {
385 set_channel_color(context, subindex ? 0 : 1, 0.15);
386 } else {
387 context->set_source_rgba(0,0,0,0.1);
389 return r;
390 } else if (phase and !*params[AM::param_analyzer_active]) {
391 redraw_graph = false;
392 return false;
393 } else {
394 int max = PeakBands + 2 + (has_lphp ? 2 : 0);
396 if (!is_active
397 or (subindex and !*params[AM::param_individuals])
398 or (subindex > max and *params[AM::param_individuals])) {
399 redraw_graph = false;
400 return false;
403 // first graph is the overall frequency response graph
404 if (!subindex)
405 return ::get_graph(*this, subindex, data, points, 128 * *params[AM::param_zoom], 0);
407 // get out if max band is reached
408 if (last_peak >= max) {
409 last_peak = 0;
410 redraw_graph = false;
411 return false;
414 // get the next filter to draw a curve for and leave out inactive
415 // filters
416 while (last_peak < PeakBands and !*params[AM::param_p1_active + last_peak * params_per_band])
417 last_peak ++;
418 if (last_peak == PeakBands and !*params[AM::param_ls_active])
419 last_peak ++;
420 if (last_peak == PeakBands + 1 and !*params[AM::param_hs_active])
421 last_peak ++;
422 if (has_lphp and last_peak == PeakBands + 2 and !*params[AM::param_hp_active])
423 last_peak ++;
424 if (has_lphp and last_peak == PeakBands + 3 and !*params[AM::param_lp_active])
425 last_peak ++;
427 // get out if max band is reached
428 if (last_peak >= max) { // and !*params[param_analyzer_active]) {
429 last_peak = 0;
430 redraw_graph = false;
431 return false;
433 //else if *params[param_analyzer_active]) {
434 //bool goon = _analyzer.get_graph(subindex, phase, data, points, context, mode);
435 //if (!goon)
436 //last_peak = 0;
437 //return goon;
440 // draw the individual curve of the actual filter
441 for (int i = 0; i < points; i++) {
442 double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points);
443 if (last_peak < PeakBands) {
444 data[i] = pL[last_peak].freq_gain(freq, (float)srate);
445 } else if (last_peak == PeakBands) {
446 data[i] = lsL.freq_gain(freq, (float)srate);
447 } else if (last_peak == PeakBands + 1) {
448 data[i] = hsL.freq_gain(freq, (float)srate);
449 } else if (last_peak == PeakBands + 2 and has_lphp) {
450 data[i] = adjusted_lphp_gain(params, AM::param_hp_active, AM::param_hp_mode, hp[0][0], freq, (float)srate);
451 } else if (last_peak == PeakBands + 3 and has_lphp) {
452 data[i] = adjusted_lphp_gain(params, AM::param_lp_active, AM::param_lp_mode, lp[0][0], freq, (float)srate);
454 data[i] = dB_grid(data[i], 128 * *params[AM::param_zoom], 0);
457 last_peak ++;
458 *mode = 4;
459 context->set_source_rgba(0,0,0,0.075);
460 return true;
463 template<class BaseClass, bool has_lphp>
464 bool equalizerNband_audio_module<BaseClass, has_lphp>::get_layers(int index, int generation, unsigned int &layers) const
466 redraw_graph = redraw_graph || !generation;
467 layers = *params[AM::param_analyzer_active] ? LG_REALTIME_GRAPH : 0;
468 layers |= (generation ? LG_NONE : LG_CACHE_GRID) | (redraw_graph ? LG_CACHE_GRAPH : LG_NONE);
469 redraw_graph |= (bool)*params[AM::param_analyzer_active];
470 return redraw_graph or !generation;
473 template<class BaseClass, bool has_lphp>
474 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
476 if (!is_active or phase)
477 return false;
478 return get_freq_gridline(subindex, pos, vertical, legend, context, true, 128 * *params[AM::param_zoom], 0);
481 template<class BaseClass, bool has_lphp>
482 float equalizerNband_audio_module<BaseClass, has_lphp>::freq_gain(int index, double freq) const
484 float ret = 1.f;
485 if (has_lphp)
487 ret *= adjusted_lphp_gain(params, AM::param_hp_active, AM::param_hp_mode, hp[0][0], freq, (float)srate);
488 ret *= adjusted_lphp_gain(params, AM::param_lp_active, AM::param_lp_mode, lp[0][0], freq, (float)srate);
490 ret *= (*params[AM::param_ls_active] > 0.f) ? lsL.freq_gain(freq, (float)srate) : 1;
491 ret *= (*params[AM::param_hs_active] > 0.f) ? hsL.freq_gain(freq, (float)srate) : 1;
492 for (int i = 0; i < PeakBands; i++)
493 ret *= (*params[AM::param_p1_active + i * params_per_band] > 0.f) ? pL[i].freq_gain(freq, (float)srate) : 1;
494 return ret;
497 template<class BaseClass, bool has_lphp>
498 inline string equalizerNband_audio_module<BaseClass, has_lphp>::get_crosshair_label(int x, int y, int sx, int sy, int dB, int name, int note, int cents) const
500 return frequency_crosshair_label(x, y, sx, sy, dB, name, note, cents, 128 * *params[AM::param_zoom], 0);
503 template class equalizerNband_audio_module<equalizer5band_metadata, false>;
504 template class equalizerNband_audio_module<equalizer8band_metadata, true>;
505 template class equalizerNband_audio_module<equalizer12band_metadata, true>;
507 /**********************************************************************
508 * EQUALIZER 30 BAND
509 **********************************************************************/
511 void equalizer30band_audio_module::set_freq_grid()
513 //Initialize freq indicators
514 unsigned int param_ptr = 0;
515 for(unsigned j = 0; j < fg.get_number_of_bands(); j++)
517 *params[param_freq11 + param_ptr] = fg.get_rounded_freq(j);
518 *params[param_freq21 + param_ptr] = fg.get_rounded_freq(j);
519 param_ptr += 3;
522 is_freq_grid_init = true;
525 equalizer30band_audio_module::equalizer30band_audio_module() :
526 conv(orfanidis_eq::eq_min_max_gain_db),
527 swL(10000), swR(10000)
529 is_active = false;
530 srate = 0;
532 is_freq_grid_init = false;
534 //Construct equalizers
535 using namespace orfanidis_eq;
537 fg.set_30_bands();
539 eq2* ptr30L = new eq2(fg, butterworth);
540 eq2* ptr30R = new eq2(fg, butterworth);
541 eq_arrL.push_back(ptr30L);
542 eq_arrR.push_back(ptr30R);
544 ptr30L = new eq2(fg, chebyshev1);
545 ptr30R = new eq2(fg, chebyshev1);
546 eq_arrL.push_back(ptr30L);
547 eq_arrR.push_back(ptr30R);
549 ptr30L = new eq2(fg, chebyshev2);
550 ptr30R = new eq2(fg, chebyshev2);
551 eq_arrL.push_back(ptr30L);
552 eq_arrR.push_back(ptr30R);
554 flt_type = butterworth;
555 flt_type_old = none;
557 //Set switcher
558 swL.set_previous(butterworth);
559 swL.set(butterworth);
561 swR.set_previous(butterworth);
562 swR.set(butterworth);
565 equalizer30band_audio_module::~equalizer30band_audio_module()
567 for (unsigned int i = 0; i < eq_arrL.size(); i++)
568 delete eq_arrL[i];
570 for (unsigned int i = 0; i < eq_arrR.size(); i++)
571 delete eq_arrR[i];
574 void equalizer30band_audio_module::activate()
576 is_active = true;
578 //Update freq grid
579 if(is_freq_grid_init == false)
580 set_freq_grid();
583 void equalizer30band_audio_module::deactivate()
585 is_active = false;
588 void equalizer30band_audio_module::params_changed()
590 using namespace orfanidis_eq;
592 //Change gain indicators
593 *params[param_gain_scale10] = *params[param_gain10] * *params[param_gainscale1];
594 *params[param_gain_scale20] = *params[param_gain20] * *params[param_gainscale2];
596 for(unsigned int i = 0; i < fg.get_number_of_bands(); i++)
597 *params[param_gain_scale11 + band_params*i] = (*params[param_gain11 + band_params*i])*
598 *params[param_gainscale1];
600 for(unsigned int i = 0; i < fg.get_number_of_bands(); i++)
601 *params[param_gain_scale21 + band_params*i] = (*params[param_gain21 + band_params*i])*
602 *params[param_gainscale2];
604 //Pass gains to eq's
605 for (unsigned int i = 0; i < fg.get_number_of_bands(); i++)
606 eq_arrL[*params[param_filters]]->change_band_gain_db(i,*params[param_gain_scale11 + band_params*i]);
608 for (unsigned int i = 0; i < fg.get_number_of_bands(); i++)
609 eq_arrR[*params[param_filters]]->change_band_gain_db(i,*params[param_gain_scale21 + band_params*i]);
611 //Upadte filter type
612 flt_type = (filter_type)(*params[param_filters] + 1);
615 void equalizer30band_audio_module::set_sample_rate(uint32_t sr)
617 srate = sr;
619 //Change sample rate for eq's
620 for(unsigned int i = 0; i < eq_arrL.size(); i++)
622 eq_arrL[i]->set_sample_rate(srate);
623 eq_arrL[i]->set_sample_rate(srate);
626 int meter[] = {param_level_in_vuL, param_level_in_vuR, param_level_out_vuL, param_level_out_vuR};
627 int clip[] = {param_level_in_clipL, param_level_in_clipR, param_level_out_clipL, param_level_out_clipR};
628 meters.init(params, meter, clip, 4, sr);
631 uint32_t equalizer30band_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
633 uint32_t orig_numsamples = numsamples;
634 uint32_t orig_offset = offset;
635 bool bypassed = bypass.update(*params[param_bypass] > 0.5f, numsamples);
636 numsamples += offset;
637 if(bypassed) {
638 // everything bypassed
639 while(offset < numsamples) {
640 outs[0][offset] = ins[0][offset];
641 outs[1][offset] = ins[1][offset];
642 float values[] = {0, 0, 0, 0};
643 meters.process(values);
644 ++offset;
646 } else {
647 // process
648 while(offset < numsamples) {
650 double inL = ins[0][offset] * *params[param_level_in];
651 double inR = ins[1][offset] * *params[param_level_in];
653 double outL = inL;
654 double outR = inR;
656 unsigned int eq_index = swL.get_state() - 1;
657 eq_arrL[eq_index]->sbs_process(&inL, &outL);
658 eq_arrR[eq_index]->sbs_process(&inR, &outR);
660 //If filter type switched
661 if(flt_type_old != flt_type)
663 swL.set(flt_type);
664 swR.set(flt_type);
665 flt_type_old = flt_type;
668 outL *= swL.get_ramp();
669 outR *= swR.get_ramp();
671 outL = outL* conv.fast_db_2_lin(*params[param_gain_scale10]);
672 outR = outR* conv.fast_db_2_lin(*params[param_gain_scale20]);
674 outL = outL* *params[param_level_out];
675 outR = outR* *params[param_level_out];
677 outs[0][offset] = outL;
678 outs[1][offset] = outR;
680 // meters
681 float values[] = {(float)inL, (float)inR, (float)outL, (float)outR};
682 meters.process(values);
684 // next sample
685 ++offset;
686 } // cycle trough samples
687 bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples);
690 meters.fall(orig_numsamples);
691 return outputs_mask;
694 /**********************************************************************
695 * FILTERKLAVIER by Hans Baier
696 **********************************************************************/
698 filterclavier_audio_module::filterclavier_audio_module()
699 : filter_module_with_inertia<biquad_filter_module, filterclavier_metadata>(ins, outs, params)
700 , min_gain(1.0)
701 , max_gain(32.0)
702 , last_note(-1)
703 , last_velocity(-1)
707 void filterclavier_audio_module::params_changed()
709 inertia_filter_module::inertia_cutoff.set_inertia(
710 note_to_hz(last_note + *params[par_transpose], *params[par_detune]));
712 float min_resonance = param_props[par_max_resonance].min;
713 inertia_filter_module::inertia_resonance.set_inertia(
714 (float(last_velocity) / 127.0)
715 // 0.001: see below
716 * (*params[par_max_resonance] - min_resonance + 0.001)
717 + min_resonance);
719 adjust_gain_according_to_filter_mode(last_velocity);
721 inertia_filter_module::calculate_filter();
722 redraw_graph = true;
725 void filterclavier_audio_module::activate()
727 inertia_filter_module::activate();
730 void filterclavier_audio_module::set_sample_rate(uint32_t sr)
732 inertia_filter_module::set_sample_rate(sr);
735 void filterclavier_audio_module::deactivate()
737 inertia_filter_module::deactivate();
741 void filterclavier_audio_module::note_on(int channel, int note, int vel)
743 last_note = note;
744 last_velocity = vel;
745 inertia_filter_module::inertia_cutoff.set_inertia(
746 note_to_hz(note + *params[par_transpose], *params[par_detune]));
748 float min_resonance = param_props[par_max_resonance].min;
749 inertia_filter_module::inertia_resonance.set_inertia(
750 (float(vel) / 127.0)
751 // 0.001: if the difference is equal to zero (which happens
752 // when the max_resonance knom is at minimum position
753 // then the filter gain doesnt seem to snap to zero on most note offs
754 * (*params[par_max_resonance] - min_resonance + 0.001)
755 + min_resonance);
757 adjust_gain_according_to_filter_mode(vel);
759 inertia_filter_module::calculate_filter();
760 redraw_graph = true;
763 void filterclavier_audio_module::note_off(int channel, int note, int vel)
765 if (note == last_note) {
766 inertia_filter_module::inertia_resonance.set_inertia(param_props[par_max_resonance].min);
767 inertia_filter_module::inertia_gain.set_inertia(min_gain);
768 inertia_filter_module::calculate_filter();
769 last_velocity = 0;
770 redraw_graph = true;
774 void filterclavier_audio_module::adjust_gain_according_to_filter_mode(int velocity)
776 int mode = dsp::fastf2i_drm(*params[par_mode]);
778 // for bandpasses: boost gain for velocities > 0
779 if ( (mode_6db_bp <= mode) && (mode <= mode_18db_bp) ) {
780 // gain for velocity 0: 1.0
781 // gain for velocity 127: 32.0
782 float mode_max_gain = max_gain;
783 // max_gain is right for mode_6db_bp
784 if (mode == mode_12db_bp)
785 mode_max_gain /= 6.0;
786 if (mode == mode_18db_bp)
787 mode_max_gain /= 10.5;
789 inertia_filter_module::inertia_gain.set_now(
790 (float(velocity) / 127.0) * (mode_max_gain - min_gain) + min_gain);
791 } else {
792 inertia_filter_module::inertia_gain.set_now(min_gain);
796 /**********************************************************************
797 * EMPHASIS by Damien Zammit
798 **********************************************************************/
800 emphasis_audio_module::emphasis_audio_module()
802 is_active = false;
803 srate = 0;
804 redraw_graph = true;
805 mode = -1;
806 type = -1;
809 void emphasis_audio_module::activate()
811 is_active = true;
812 // set all filters
813 params_changed();
816 void emphasis_audio_module::deactivate()
818 is_active = false;
821 void emphasis_audio_module::params_changed()
823 if (mode != *params[param_mode] or type != *params[param_type] or bypass_ != *params[param_bypass])
824 redraw_graph = true;
825 mode = *params[param_mode];
826 type = *params[param_type];
827 bypass_ = *params[param_bypass];
828 riaacurvL.set(srate, mode, type);
829 riaacurvR.set(srate, mode, type);
832 uint32_t emphasis_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
834 uint32_t orig_numsamples = numsamples;
835 uint32_t orig_offset = offset;
836 bool bypassed = bypass.update(*params[param_bypass] > 0.5f, numsamples);
837 if (!bypassed)
839 // ensure that if params have changed, the params_changed method is
840 // called every 8 samples to interpolate filter parameters
841 while(numsamples > 8)
843 params_changed();
844 outputs_mask |= process(offset, 8, inputs_mask, outputs_mask);
845 offset += 8;
846 numsamples -= 8;
849 numsamples += offset;
850 if(bypassed) {
851 // everything bypassed
852 while(offset < numsamples) {
853 outs[0][offset] = ins[0][offset];
854 outs[1][offset] = ins[1][offset];
855 float values[] = {0, 0, 0, 0};
856 meters.process(values);
857 ++offset;
859 } else {
860 // process
861 while(offset < numsamples) {
862 // cycle through samples
863 float outL = 0.f;
864 float outR = 0.f;
865 float inL = ins[0][offset];
866 float inR = ins[1][offset];
867 // in level
868 inR *= *params[param_level_in];
869 inL *= *params[param_level_in];
871 float procL = inL;
872 float procR = inR;
874 procL = riaacurvL.process(procL);
875 procR = riaacurvR.process(procR);
877 outL = procL * *params[param_level_out];
878 outR = procR * *params[param_level_out];
880 // send to output
881 outs[0][offset] = outL;
882 outs[1][offset] = outR;
884 float values[] = {inL, inR, outL, outR};
885 meters.process(values);
887 // next sample
888 ++offset;
889 } // cycle trough samples
890 bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples);
891 // clean up
892 riaacurvL.sanitize();
893 riaacurvR.sanitize();
895 meters.fall(orig_numsamples);
896 return outputs_mask;
898 bool emphasis_audio_module::get_graph(int index, int subindex, int phase, float *data, int points, cairo_iface *context, int *mode) const
900 if (phase or subindex)
901 return false;
902 if (bypass_)
903 context->set_source_rgba(0.15, 0.2, 0.0, 0.3);
904 return ::get_graph(*this, subindex, data, points, 32, 0);
906 bool emphasis_audio_module::get_gridline(int index, int subindex, int phase, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
908 if (phase)
909 return false;
910 return get_freq_gridline(subindex, pos, vertical, legend, context, true, 32, 0);
913 /**********************************************************************
914 * CROSSOVER N BAND by Markus Schmidt
915 **********************************************************************/
917 template<class XoverBaseClass>
918 xover_audio_module<XoverBaseClass>::xover_audio_module()
920 is_active = false;
921 srate = 0;
922 redraw_graph = true;
923 crossover.init(AM::channels, AM::bands, 44100);
925 template<class XoverBaseClass>
926 xover_audio_module<XoverBaseClass>::~xover_audio_module()
928 free(buffer);
930 template<class XoverBaseClass>
931 void xover_audio_module<XoverBaseClass>::activate()
933 is_active = true;
934 params_changed();
937 template<class XoverBaseClass>
938 void xover_audio_module<XoverBaseClass>::deactivate()
940 is_active = false;
942 template<class XoverBaseClass>
943 void xover_audio_module<XoverBaseClass>::set_sample_rate(uint32_t sr)
945 srate = sr;
946 // set srate of crossover
947 crossover.set_sample_rate(srate);
948 // rebuild buffer
949 buffer_size = (int)(srate / 10 * AM::channels * AM::bands + AM::channels * AM::bands); // buffer size attack rate multiplied by channels and bands
950 buffer = (float*) calloc(buffer_size, sizeof(float));
951 pos = 0;
952 int amount = AM::bands * AM::channels + AM::channels;
953 int meter[amount];
954 int clip[amount];
955 for(int b = 0; b < AM::bands; b++) {
956 for (int c = 0; c < AM::channels; c++) {
957 meter[b * AM::channels + c] = AM::param_meter_01 + b * params_per_band + c;
958 clip[b * AM::channels + c] = -1;
961 for (int c = 0; c < AM::channels; c++) {
962 meter[c + AM::bands * AM::channels] = AM::param_meter_0 + c;
963 clip[c + AM::bands * AM::channels] = -1;
965 meters.init(params, meter, clip, amount, srate);
967 template<class XoverBaseClass>
968 void xover_audio_module<XoverBaseClass>::params_changed()
970 int mode = *params[AM::param_mode];
971 crossover.set_mode(mode);
972 for (int i = 0; i < AM::bands - 1; i++) {
973 crossover.set_filter(i, *params[AM::param_freq0 + i]);
975 for (int i = 0; i < AM::bands; i++) {
976 int offset = i * params_per_band;
977 crossover.set_level(i, *params[AM::param_level1 + offset]);
978 crossover.set_active(i, *params[AM::param_active1 + offset] > 0.5);
980 redraw_graph = true;
983 template<class XoverBaseClass>
984 uint32_t xover_audio_module<XoverBaseClass>::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
986 unsigned int targ = numsamples + offset;
987 float xval;
988 float values[AM::bands * AM::channels + AM::channels];
989 while(offset < targ) {
990 // cycle through samples
992 // level
993 for (int c = 0; c < AM::channels; c++) {
994 in[c] = ins[c][offset] * *params[AM::param_level];
996 crossover.process(in);
998 for (int b = 0; b < AM::bands; b++) {
999 int nbuf = 0;
1000 int off = b * params_per_band;
1001 // calc position in delay buffer
1002 if (*params[AM::param_delay1 + off]) {
1003 nbuf = srate * (fabs(*params[AM::param_delay1 + off]) / 1000.f) * AM::bands * AM::channels;
1004 nbuf -= nbuf % (AM::bands * AM::channels);
1006 for (int c = 0; c < AM::channels; c++) {
1007 // define a pointer between 0 and channels * bands
1008 int ptr = b * AM::channels + c;
1010 // get output from crossover module if active
1011 xval = *params[AM::param_active1 + off] > 0.5 ? crossover.get_value(c, b) : 0.f;
1013 // fill delay buffer
1014 buffer[pos + ptr] = xval;
1016 // get value from delay buffer if neccessary
1017 if (*params[AM::param_delay1 + off])
1018 xval = buffer[(pos - (int)nbuf + ptr + buffer_size) % buffer_size];
1020 // set value with phase to output
1021 outs[ptr][offset] = *params[AM::param_phase1 + off] > 0.5 ? xval * -1 : xval;
1023 // band meters
1024 values[b * AM::channels + c] = outs[ptr][offset];
1027 // in meters
1028 for (int c = 0; c < AM::channels; c++) {
1029 values[c + AM::bands * AM::channels] = ins[c][offset];
1031 meters.process(values);
1032 // next sample
1033 ++offset;
1034 // delay buffer pos forward
1035 pos = (pos + AM::channels * AM::bands) % buffer_size;
1037 } // cycle trough samples
1038 meters.fall(numsamples);
1039 return outputs_mask;
1042 template<class XoverBaseClass>
1043 bool xover_audio_module<XoverBaseClass>::get_graph(int index, int subindex, int phase, float *data, int points, cairo_iface *context, int *mode) const
1045 return crossover.get_graph(subindex, phase, data, points, context, mode);
1047 template<class XoverBaseClass>
1048 bool xover_audio_module<XoverBaseClass>::get_layers(int index, int generation, unsigned int &layers) const
1050 return crossover.get_layers(index, generation, layers);
1053 template class xover_audio_module<xover2_metadata>;
1054 template class xover_audio_module<xover3_metadata>;
1055 template class xover_audio_module<xover4_metadata>;
1058 /**********************************************************************
1059 * Vocoder by Markus Schmidt and Christian Holschuh
1060 **********************************************************************/
1062 vocoder_audio_module::vocoder_audio_module()
1064 is_active = false;
1065 srate = 0;
1066 attack = 0;
1067 release = 0;
1068 fcoeff = 0;
1069 bands = 0;
1070 bands_old = -1;
1071 order = 0;
1072 order_old = -1;
1073 fcoeff = log10(20.f);
1074 log2_ = log(2);
1075 memset(env_mods, 0, 32 * 2 * sizeof(double));
1078 void vocoder_audio_module::activate()
1080 is_active = true;
1083 void vocoder_audio_module::deactivate()
1085 is_active = false;
1088 void vocoder_audio_module::params_changed()
1090 attack = exp(log(0.01)/( *params[param_attack] * srate * 0.001));
1091 release = exp(log(0.01)/( *params[param_release] * srate * 0.001));
1093 int b = *params[param_bands];
1094 bands = (b + 2) * 4 + (b > 1 ? (b - 2) * 4 : 0);
1095 order = std::min(8.f, *params[param_order]);
1096 float q = pow(10, (fmodf(std::min(8.999f, *params[param_order]), 1.f) * (7.f / pow(1.3, order))) / 20);
1097 if (bands != bands_old or *params[param_order] != order_old) {
1098 bands_old = bands;
1099 order_old = *params[param_order];
1100 for (int i = 0; i < bands; i++) {
1101 // set all actually used filters
1102 detector[0][0][i].set_bp_rbj(pow(10, fcoeff + (0.5f + (float)i) * 3.f / (float)bands), q, (double)srate);
1103 for (int j = 0; j < order; j++) {
1104 if (j)
1105 detector[0][j][i].copy_coeffs(detector[0][0][i]);
1106 detector[1][j][i].copy_coeffs(detector[0][0][i]);
1107 modulator[0][j][i].copy_coeffs(detector[0][0][i]);
1108 modulator[1][j][i].copy_coeffs(detector[0][0][i]);
1111 redraw_graph = true;
1113 _analyzer.set_params(256, 1, 6, 0, 1, 0, 0, 0, 15, 2, 0, 0);
1114 redraw_graph = true;
1117 int vocoder_audio_module::get_solo() const {
1118 for (int i = 0; i < bands; i++)
1119 if (*params[param_solo0 + i * band_params])
1120 return 1;
1121 return 0;
1124 uint32_t vocoder_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
1126 uint32_t orig_numsamples = numsamples;
1127 uint32_t orig_offset = offset;
1128 bool bypassed = bypass.update(*params[param_bypass] > 0.5f, numsamples);
1129 int solo = get_solo();
1130 numsamples += offset;
1131 float led[32] = {0};
1132 if(bypassed) {
1133 // everything bypassed
1134 while(offset < numsamples) {
1135 outs[0][offset] = ins[0][offset];
1136 outs[1][offset] = ins[1][offset];
1137 float values[] = {0, 0, 0, 0, 0, 0};
1138 meters.process(values);
1139 ++offset;
1141 } else {
1142 // process
1143 while(offset < numsamples) {
1144 // cycle through samples
1145 double outL = 0;
1146 double outR = 0;
1147 double pL = 0;
1148 double pR = 0;
1150 // carrier with level
1151 double cL = ins[0][offset] * *params[param_carrier_in];
1152 double cR = ins[1][offset] * *params[param_carrier_in];
1154 // modulator with level
1155 double mL = ins[2][offset] * *params[param_mod_in];
1156 double mR = ins[3][offset] * *params[param_mod_in];
1158 // noise generator
1159 double nL = (float)rand() / (float)RAND_MAX;
1160 double nR = (float)rand() / (float)RAND_MAX;
1162 for (int i = 0; i < bands; i++) {
1163 double mL_ = mL;
1164 double mR_ = mR;
1165 double cL_ = cL + nL * *params[param_noise0 + i * band_params];
1166 double cR_ = cR + nR * *params[param_noise0 + i * band_params];
1168 if ((solo and *params[param_solo0 + i * band_params]) or !solo) {
1169 for (int j = 0; j < order; j++) {
1170 // filter modulator
1171 if (*params[param_link] > 0.5) {
1172 mL_ = detector[0][j][i].process(std::max(mL_, mR_));
1173 mR_ = mL_;
1174 } else {
1175 mL_ = detector[0][j][i].process(mL_);
1176 mR_ = detector[1][j][i].process(mR_);
1178 // filter carrier with noise
1179 cL_ = modulator[0][j][i].process(cL_);
1180 cR_ = modulator[1][j][i].process(cR_);
1182 // level by envelope with levelling
1183 cL_ *= env_mods[0][i] * ((float)order / 2 + 4) * 4;
1184 cR_ *= env_mods[1][i] * ((float)order / 2 + 4) * 4;
1186 // add band volume setting
1187 cL_ *= *params[param_volume0 + i * band_params];
1188 cR_ *= *params[param_volume0 + i * band_params];
1190 // add filtered modulator
1191 cL_ += mL_ * *params[param_mod0 + i * band_params];
1192 cR_ += mR_ * *params[param_mod0 + i * band_params];
1194 // Balance
1195 cL_ *= (*params[param_pan0 + i * band_params] > 0
1196 ? -*params[param_pan0 + i * band_params] + 1 : 1);
1197 cR_ *= (*params[param_pan0 + i * band_params] < 0
1198 ? *params[param_pan0 + i * band_params] + 1 : 1);
1200 // add to outputs with proc level
1201 pL += cL_ * *params[param_proc];
1202 pR += cR_ * *params[param_proc];
1204 // LED
1205 if (*params[param_detectors] > 0.5)
1206 if (env_mods[0][i] + env_mods[1][i] > led[i])
1207 led[i] = env_mods[0][i] + env_mods[1][i];
1209 // advance envelopes
1210 env_mods[0][i] = (fabs(mL_) > env_mods[0][i] ? attack : release) * (env_mods[0][i] - fabs(mL_)) + fabs(mL_);
1211 env_mods[1][i] = (fabs(mR_) > env_mods[1][i] ? attack : release) * (env_mods[1][i] - fabs(mR_)) + fabs(mR_);
1214 outL = pL;
1215 outR = pR;
1217 // dry carrier
1218 outL += cL * *params[param_carrier];
1219 outR += cR * *params[param_carrier];
1221 // dry modulator
1222 outL += mL * *params[param_mod];
1223 outR += mR * *params[param_mod];
1225 // analyzer
1226 switch ((int)*params[param_analyzer]) {
1227 case 0:
1228 default:
1229 break;
1230 case 1:
1231 _analyzer.process((float)cL, (float)cR);
1232 break;
1233 case 2:
1234 _analyzer.process((float)mL, (float)mR);
1235 break;
1236 case 3:
1237 _analyzer.process((float)pL, (float)pR);
1238 break;
1239 case 4:
1240 _analyzer.process((float)outL, (float)outR);
1241 break;
1244 // out level
1245 outL *= *params[param_out];
1246 outR *= *params[param_out];
1248 // send to outputs
1249 outs[0][offset] = outL;
1250 outs[1][offset] = outR;
1252 // meters
1253 float values[] = {(float)cL, (float)cR, (float)mL, (float)mR, (float)outL, (float)outR};
1254 meters.process(values);
1256 // next sample
1257 ++offset;
1258 } // cycle trough samples
1259 bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples);
1260 // clean up
1261 for (int i = 0; i < bands; i++) {
1262 for (int j = 0; j < order; j++) {
1263 detector[0][j][i].sanitize();
1264 detector[1][j][i].sanitize();
1265 modulator[0][j][i].sanitize();
1266 modulator[1][j][i].sanitize();
1271 // LED
1272 for (int i = 0; i < 32; i++) {
1273 float val = 0;
1274 if (*params[param_detectors] > 0.5)
1275 val = std::max(0.0, 1 + log((led[i] / 2) * order) / log2_ / 10);
1276 *params[param_level0 + i * band_params] = val;
1278 meters.fall(orig_numsamples);
1279 return outputs_mask;
1281 bool vocoder_audio_module::get_graph(int index, int subindex, int phase, float *data, int points, cairo_iface *context, int *mode) const
1283 if (phase and *params[param_analyzer]) {
1284 if (subindex) {
1285 return false;
1287 bool r = _analyzer.get_graph(subindex, phase, data, points, context, mode);
1288 context->set_source_rgba(0,0,0,0.25);
1289 return r;
1290 } else if (phase) {
1291 return false;
1292 } else {
1293 // quit
1294 if (subindex >= bands) {
1295 redraw_graph = false;
1296 return false;
1298 int solo = get_solo();
1299 if (solo and !*params[param_solo0 + subindex * band_params])
1300 context->set_source_rgba(0,0,0,0.15);
1301 context->set_line_width(0.99);
1302 int drawn = 0;
1303 double fq = pow(10, fcoeff + (0.5f + (float)subindex) * 3.f / (float)bands);
1304 for (int i = 0; i < points; i++) {
1305 double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points);
1306 float level = 1;
1307 for (int j = 0; j < order; j++)
1308 level *= detector[0][0][subindex].freq_gain(freq, srate);
1309 level *= *params[param_volume0 + subindex * band_params];
1310 data[i] = dB_grid(level, 256, 0.4);
1311 if (!drawn and freq > fq) {
1312 drawn = 1;
1313 char str[32];
1314 sprintf(str, "%d", subindex + 1);
1315 draw_cairo_label(context, str, i, context->size_y * (1 - (data[i] + 1) / 2.f), 0, 0, 0.5);
1319 return true;
1321 bool vocoder_audio_module::get_layers(int index, int generation, unsigned int &layers) const
1323 redraw_graph = redraw_graph || !generation;
1324 layers = *params[param_analyzer] ? LG_REALTIME_GRAPH : 0;
1325 layers |= (generation ? LG_NONE : LG_CACHE_GRID) | (redraw_graph ? LG_CACHE_GRAPH : LG_NONE);
1326 redraw_graph |= (bool)*params[param_analyzer];
1327 return redraw_graph or !generation;