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
23 #include <calf/giface.h>
24 #include <calf/modules_filter.h>
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;
40 inline void undiff_ms(float &left
, float &right
) {
41 float tmp
= left
+ right
/ 2;
42 right
= left
- right
/ 2;
46 template<class BaseClass
, bool has_lphp
>
47 equalizerNband_audio_module
<BaseClass
, has_lphp
>::equalizerNband_audio_module()
52 hp_freq_old
= lp_freq_old
= hp_q_old
= 0;
53 hs_freq_old
= ls_freq_old
= lp_q_old
= 0;
54 hs_level_old
= ls_level_old
= 0;
59 for (int i
= 0; i
< AM::PeakBands
; i
++)
65 for (int i
= 0; i
< graph_param_count
; i
++)
66 old_params_for_graph
[i
] = -1;
70 template<class BaseClass
, bool has_lphp
>
71 void equalizerNband_audio_module
<BaseClass
, has_lphp
>::activate()
78 template<class BaseClass
, bool has_lphp
>
79 void equalizerNband_audio_module
<BaseClass
, has_lphp
>::deactivate()
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
++)
89 filters
[i
][j
].copy_coeffs(filters
[0][0]);
92 static inline double glide(double value
, double target
, int &keep_gliding
)
98 return std::min(target
, (value
+ 0.1) * 1.003);
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()
107 // set the params of all filters
109 // lp/hp first (if available)
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
];
116 float hpq
= *params
[AM::param_hp_q
], lpq
= *params
[AM::param_lp_q
];
118 if(hpfreq
!= hp_freq_old
or hpq
!= hp_q_old
) {
119 hpfreq
= glide(hp_freq_old
, hpfreq
, keep_gliding
);
120 hp
[0][0].set_hp_rbj(hpfreq
, hpq
, (float)srate
, 1.0);
122 hp_freq_old
= hpfreq
;
124 if(lpfreq
!= lp_freq_old
or lpq
!= lp_q_old
) {
125 lpfreq
= glide(lp_freq_old
, lpfreq
, keep_gliding
);
126 lp
[0][0].set_lp_rbj(lpfreq
, lpq
, (float)srate
, 1.0);
128 lp_freq_old
= lpfreq
;
133 float hsfreq
= *params
[AM::param_hs_freq
], hslevel
= *params
[AM::param_hs_level
], hsq
=*params
[AM::param_hs_q
];
134 float lsfreq
= *params
[AM::param_ls_freq
], lslevel
= *params
[AM::param_ls_level
], lsq
=*params
[AM::param_ls_q
];
136 if(lsfreq
!= ls_freq_old
or lslevel
!= ls_level_old
or lsq
!= ls_q_old
) {
137 lsfreq
= glide(ls_freq_old
, lsfreq
, keep_gliding
);
138 lsL
.set_lowshelf_rbj(lsfreq
, lsq
, lslevel
, (float)srate
);
139 lsR
.copy_coeffs(lsL
);
140 ls_level_old
= lslevel
;
141 ls_freq_old
= lsfreq
;
144 if(hsfreq
!= hs_freq_old
or hslevel
!= hs_level_old
or hsq
!= hs_q_old
) {
145 hsfreq
= glide(hs_freq_old
, hsfreq
, keep_gliding
);
146 hsL
.set_highshelf_rbj(hsfreq
, hsq
, hslevel
, (float)srate
);
147 hsR
.copy_coeffs(hsL
);
148 hs_level_old
= hslevel
;
149 hs_freq_old
= hsfreq
;
152 for (int i
= 0; i
< AM::PeakBands
; i
++)
154 int offset
= i
* params_per_band
;
155 float freq
= *params
[AM::param_p1_freq
+ offset
];
156 float level
= *params
[AM::param_p1_level
+ offset
];
157 float q
= *params
[AM::param_p1_q
+ offset
];
158 if(freq
!= p_freq_old
[i
] or level
!= p_level_old
[i
] or q
!= p_q_old
[i
]) {
159 freq
= glide(p_freq_old
[i
], freq
, keep_gliding
);
160 pL
[i
].set_peakeq_rbj(freq
, q
, level
, (float)srate
);
161 pR
[i
].copy_coeffs(pL
[i
]);
162 p_freq_old
[i
] = freq
;
163 p_level_old
[i
] = level
;
167 if (*params
[AM::param_individuals
] != indiv_old
) {
168 indiv_old
= *params
[AM::param_individuals
];
172 // check if any important parameter for redrawing the graph changed
173 for (int i
= 0; i
< graph_param_count
; i
++) {
174 if (*params
[AM::first_graph_param
+ i
] != old_params_for_graph
[i
])
176 old_params_for_graph
[i
] = *params
[AM::first_graph_param
+ i
];
179 _analyzer
.set_params(
181 *params
[AM::param_analyzer_mode
] + (*params
[AM::param_analyzer_mode
] >= 3 ? 5 : 1),
185 if ((bool)*params
[AM::param_analyzer_active
] != analyzer_old
) {
187 analyzer_old
= (bool)*params
[AM::param_analyzer_active
];
191 template<class BaseClass
, bool has_lphp
>
192 inline void equalizerNband_audio_module
<BaseClass
, has_lphp
>::process_hplp(float &left
, float &right
)
196 int active
= *params
[AM::param_lp_active
];
199 if (active
> 3) diff_ms(left
, right
);
203 if (active
== 1 or active
== 2 or active
== 4)
204 left
= lp
[0][0].process(left
);
205 if (active
== 1 or active
== 3 or active
== 5)
206 right
= lp
[0][1].process(right
);
209 if (active
== 1 or active
== 2 or active
== 4)
210 left
= lp
[1][0].process(lp
[0][0].process(left
));
211 if (active
== 1 or active
== 3 or active
== 5)
212 right
= lp
[1][1].process(lp
[0][1].process(right
));
215 if (active
== 1 or active
== 2 or active
== 4)
216 left
= lp
[2][0].process(lp
[1][0].process(lp
[0][0].process(left
)));
217 if (active
== 1 or active
== 3 or active
== 5)
218 right
= lp
[2][1].process(lp
[1][1].process(lp
[0][1].process(right
)));
221 if (active
> 3) undiff_ms(left
, right
);
223 active
= *params
[AM::param_hp_active
];
226 if (active
> 3) diff_ms(left
, right
);
230 if (active
== 1 or active
== 2 or active
== 4)
231 left
= hp
[0][0].process(left
);
232 if (active
== 1 or active
== 3 or active
== 5)
233 right
= hp
[0][1].process(right
);
236 if (active
== 1 or active
== 2 or active
== 4)
237 left
= hp
[1][0].process(hp
[0][0].process(left
));
238 if (active
== 1 or active
== 3 or active
== 5)
239 right
= hp
[1][1].process(hp
[0][1].process(right
));
242 if (active
== 1 or active
== 2 or active
== 4)
243 left
= hp
[2][0].process(hp
[1][0].process(hp
[0][0].process(left
)));
244 if (active
== 1 or active
== 3 or active
== 5)
245 right
= hp
[2][1].process(hp
[1][1].process(hp
[0][1].process(right
)));
248 if (active
> 3) undiff_ms(left
, right
);
252 template<class BaseClass
, bool has_lphp
>
253 uint32_t equalizerNband_audio_module
<BaseClass
, has_lphp
>::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
255 bool bypassed
= bypass
.update(*params
[AM::param_bypass
] > 0.5f
, numsamples
);
258 // ensure that if params have changed, the params_changed method is
259 // called every 8 samples to interpolate filter parameters
260 while(numsamples
> 8 && keep_gliding
)
263 outputs_mask
|= process(offset
, 8, inputs_mask
, outputs_mask
);
270 numsamples
+= offset
;
272 // everything bypassed
273 while(offset
< numsamples
) {
274 outs
[0][offset
] = ins
[0][offset
];
275 outs
[1][offset
] = ins
[1][offset
];
276 float values
[] = {0, 0, 0, 0};
277 meters
.process(values
);
278 _analyzer
.process(0, 0);
283 uint32_t orig_numsamples
= numsamples
-offset
;
284 uint32_t orig_offset
= offset
;
285 while(offset
< numsamples
) {
286 // cycle through samples
289 float inL
= ins
[0][offset
];
290 float inR
= ins
[1][offset
];
292 inR
*= *params
[AM::param_level_in
];
293 inL
*= *params
[AM::param_level_in
];
298 // all filters in chain
299 process_hplp(procL
, procR
);
301 int active
= *params
[AM::param_ls_active
];
302 if (active
> 3) diff_ms(procL
, procR
);
303 if (active
== 1 or active
== 2 or active
== 4)
304 procL
= lsL
.process(procL
);
305 if (active
== 1 or active
== 3 or active
== 5)
306 procR
= lsR
.process(procR
);
307 if (active
> 3) undiff_ms(procL
, procR
);
309 active
= *params
[AM::param_hs_active
];
310 if (active
> 3) diff_ms(procL
, procR
);
311 if (active
== 1 or active
== 2 or active
== 4)
312 procL
= hsL
.process(procL
);
313 if (active
== 1 or active
== 3 or active
== 5)
314 procR
= hsR
.process(procR
);
315 if (active
> 3) undiff_ms(procL
, procR
);
317 for (int i
= 0; i
< AM::PeakBands
; i
++)
319 int offset
= i
* params_per_band
;
320 int active
= *params
[AM::param_p1_active
+ offset
];
321 if (active
> 3) diff_ms(procL
, procR
);
322 if (active
== 1 or active
== 2 or active
== 4)
323 procL
= pL
[i
].process(procL
);
324 if (active
== 1 or active
== 3 or active
== 5)
325 procR
= pR
[i
].process(procR
);
326 if (active
> 3) undiff_ms(procL
, procR
);
329 outL
= procL
* *params
[AM::param_level_out
];
330 outR
= procR
* *params
[AM::param_level_out
];
333 _analyzer
.process((inL
+ inR
) / 2.f
, (outL
+ outR
) / 2.f
);
336 outs
[0][offset
] = outL
;
337 outs
[1][offset
] = outR
;
339 float values
[] = {inL
, inR
, outL
, outR
};
340 meters
.process(values
);
344 } // cycle trough samples
345 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
347 for(int i
= 0; i
< 3; ++i
) {
355 for(int i
= 0; i
< AM::PeakBands
; ++i
) {
360 meters
.fall(numsamples
);
364 static inline float adjusted_lphp_gain(const float *const *params
, int param_active
, int param_mode
, const biquad_d2
&filter
, float freq
, float srate
)
366 if(*params
[param_active
] > 0.f
) {
367 float gain
= filter
.freq_gain(freq
, srate
);
368 switch((int)*params
[param_mode
]) {
374 return gain
* gain
* gain
;
380 template<class BaseClass
, bool has_lphp
>
381 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
383 if (phase
and *params
[AM::param_analyzer_active
]) {
384 bool r
= _analyzer
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
385 if (*params
[AM::param_analyzer_mode
] == 2) {
386 set_channel_color(context
, subindex
? 0 : 1, 0.15);
388 context
->set_source_rgba(0,0,0,0.1);
391 } else if (phase
and !*params
[AM::param_analyzer_active
]) {
392 redraw_graph
= false;
395 int max
= PeakBands
+ 2 + (has_lphp
? 2 : 0);
398 or (subindex
and !*params
[AM::param_individuals
])
399 or (subindex
> max
and *params
[AM::param_individuals
])) {
400 redraw_graph
= false;
404 // first graph is the overall frequency response graph
406 return ::get_graph(*this, subindex
, data
, points
, 128 * *params
[AM::param_zoom
], 0);
408 // get out if max band is reached
409 if (last_peak
>= max
) {
411 redraw_graph
= false;
415 // get the next filter to draw a curve for and leave out inactive
417 while (last_peak
< PeakBands
and !*params
[AM::param_p1_active
+ last_peak
* params_per_band
])
419 if (last_peak
== PeakBands
and !*params
[AM::param_ls_active
])
421 if (last_peak
== PeakBands
+ 1 and !*params
[AM::param_hs_active
])
423 if (has_lphp
and last_peak
== PeakBands
+ 2 and !*params
[AM::param_hp_active
])
425 if (has_lphp
and last_peak
== PeakBands
+ 3 and !*params
[AM::param_lp_active
])
428 // get out if max band is reached
429 if (last_peak
>= max
) { // and !*params[param_analyzer_active]) {
431 redraw_graph
= false;
434 //else if *params[param_analyzer_active]) {
435 //bool goon = _analyzer.get_graph(subindex, phase, data, points, context, mode);
441 // draw the individual curve of the actual filter
442 for (int i
= 0; i
< points
; i
++) {
443 double freq
= 20.0 * pow (20000.0 / 20.0, i
* 1.0 / points
);
444 if (last_peak
< PeakBands
) {
445 data
[i
] = pL
[last_peak
].freq_gain(freq
, (float)srate
);
446 } else if (last_peak
== PeakBands
) {
447 data
[i
] = lsL
.freq_gain(freq
, (float)srate
);
448 } else if (last_peak
== PeakBands
+ 1) {
449 data
[i
] = hsL
.freq_gain(freq
, (float)srate
);
450 } else if (last_peak
== PeakBands
+ 2 and has_lphp
) {
451 data
[i
] = adjusted_lphp_gain(params
, AM::param_hp_active
, AM::param_hp_mode
, hp
[0][0], freq
, (float)srate
);
452 } else if (last_peak
== PeakBands
+ 3 and has_lphp
) {
453 data
[i
] = adjusted_lphp_gain(params
, AM::param_lp_active
, AM::param_lp_mode
, lp
[0][0], freq
, (float)srate
);
455 data
[i
] = dB_grid(data
[i
], 128 * *params
[AM::param_zoom
], 0);
460 context
->set_source_rgba(0,0,0,0.075);
464 template<class BaseClass
, bool has_lphp
>
465 bool equalizerNband_audio_module
<BaseClass
, has_lphp
>::get_layers(int index
, int generation
, unsigned int &layers
) const
467 redraw_graph
= redraw_graph
|| !generation
;
468 layers
= *params
[AM::param_analyzer_active
] ? LG_REALTIME_GRAPH
: 0;
469 layers
|= (generation
? LG_NONE
: LG_CACHE_GRID
) | (redraw_graph
? LG_CACHE_GRAPH
: LG_NONE
);
470 redraw_graph
|= (bool)*params
[AM::param_analyzer_active
];
471 return redraw_graph
or !generation
;
474 template<class BaseClass
, bool has_lphp
>
475 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
477 if (!is_active
or phase
)
479 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
, true, 128 * *params
[AM::param_zoom
], 0);
482 template<class BaseClass
, bool has_lphp
>
483 float equalizerNband_audio_module
<BaseClass
, has_lphp
>::freq_gain(int index
, double freq
) const
488 ret
*= adjusted_lphp_gain(params
, AM::param_hp_active
, AM::param_hp_mode
, hp
[0][0], freq
, (float)srate
);
489 ret
*= adjusted_lphp_gain(params
, AM::param_lp_active
, AM::param_lp_mode
, lp
[0][0], freq
, (float)srate
);
491 ret
*= (*params
[AM::param_ls_active
] > 0.f
) ? lsL
.freq_gain(freq
, (float)srate
) : 1;
492 ret
*= (*params
[AM::param_hs_active
] > 0.f
) ? hsL
.freq_gain(freq
, (float)srate
) : 1;
493 for (int i
= 0; i
< PeakBands
; i
++)
494 ret
*= (*params
[AM::param_p1_active
+ i
* params_per_band
] > 0.f
) ? pL
[i
].freq_gain(freq
, (float)srate
) : 1;
498 template<class BaseClass
, bool has_lphp
>
499 inline 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
501 return frequency_crosshair_label(x
, y
, sx
, sy
, q
, dB
, name
, note
, cents
, 128 * *params
[AM::param_zoom
], 0);
504 template class equalizerNband_audio_module
<equalizer5band_metadata
, false>;
505 template class equalizerNband_audio_module
<equalizer8band_metadata
, true>;
506 template class equalizerNband_audio_module
<equalizer12band_metadata
, true>;
508 /**********************************************************************
510 **********************************************************************/
512 void equalizer30band_audio_module::set_freq_grid()
514 //Initialize freq indicators
515 unsigned int param_ptr
= 0;
516 for(unsigned j
= 0; j
< fg
.get_number_of_bands(); j
++)
518 *params
[param_freq11
+ param_ptr
] = fg
.get_rounded_freq(j
);
519 *params
[param_freq21
+ param_ptr
] = fg
.get_rounded_freq(j
);
523 is_freq_grid_init
= true;
526 equalizer30band_audio_module::equalizer30band_audio_module() :
527 conv(orfanidis_eq::eq_min_max_gain_db
),
528 swL(10000), swR(10000)
533 is_freq_grid_init
= false;
535 //Construct equalizers
536 using namespace orfanidis_eq
;
540 eq2
* ptr30L
= new eq2(fg
, butterworth
);
541 eq2
* ptr30R
= new eq2(fg
, butterworth
);
542 eq_arrL
.push_back(ptr30L
);
543 eq_arrR
.push_back(ptr30R
);
545 ptr30L
= new eq2(fg
, chebyshev1
);
546 ptr30R
= new eq2(fg
, chebyshev1
);
547 eq_arrL
.push_back(ptr30L
);
548 eq_arrR
.push_back(ptr30R
);
550 ptr30L
= new eq2(fg
, chebyshev2
);
551 ptr30R
= new eq2(fg
, chebyshev2
);
552 eq_arrL
.push_back(ptr30L
);
553 eq_arrR
.push_back(ptr30R
);
555 flt_type
= butterworth
;
559 swL
.set_previous(butterworth
);
560 swL
.set(butterworth
);
562 swR
.set_previous(butterworth
);
563 swR
.set(butterworth
);
566 equalizer30band_audio_module::~equalizer30band_audio_module()
568 for (unsigned int i
= 0; i
< eq_arrL
.size(); i
++)
571 for (unsigned int i
= 0; i
< eq_arrR
.size(); i
++)
575 void equalizer30band_audio_module::activate()
580 if(is_freq_grid_init
== false)
584 void equalizer30band_audio_module::deactivate()
589 void equalizer30band_audio_module::params_changed()
591 using namespace orfanidis_eq
;
593 //Change gain indicators
594 *params
[param_gain_scale10
] = *params
[param_gain10
] * *params
[param_gainscale1
];
595 *params
[param_gain_scale20
] = *params
[param_gain20
] * *params
[param_gainscale2
];
597 for(unsigned int i
= 0; i
< fg
.get_number_of_bands(); i
++)
598 *params
[param_gain_scale11
+ band_params
*i
] = (*params
[param_gain11
+ band_params
*i
])*
599 *params
[param_gainscale1
];
601 for(unsigned int i
= 0; i
< fg
.get_number_of_bands(); i
++)
602 *params
[param_gain_scale21
+ band_params
*i
] = (*params
[param_gain21
+ band_params
*i
])*
603 *params
[param_gainscale2
];
606 for (unsigned int i
= 0; i
< fg
.get_number_of_bands(); i
++)
607 eq_arrL
[*params
[param_filters
]]->change_band_gain_db(i
,*params
[param_gain_scale11
+ band_params
*i
]);
609 for (unsigned int i
= 0; i
< fg
.get_number_of_bands(); i
++)
610 eq_arrR
[*params
[param_filters
]]->change_band_gain_db(i
,*params
[param_gain_scale21
+ band_params
*i
]);
613 flt_type
= (filter_type
)(*params
[param_filters
] + 1);
616 void equalizer30band_audio_module::set_sample_rate(uint32_t sr
)
620 //Change sample rate for eq's
621 for(unsigned int i
= 0; i
< eq_arrL
.size(); i
++)
623 eq_arrL
[i
]->set_sample_rate(srate
);
624 eq_arrL
[i
]->set_sample_rate(srate
);
627 int meter
[] = {param_level_in_vuL
, param_level_in_vuR
, param_level_out_vuL
, param_level_out_vuR
};
628 int clip
[] = {param_level_in_clipL
, param_level_in_clipR
, param_level_out_clipL
, param_level_out_clipR
};
629 meters
.init(params
, meter
, clip
, 4, sr
);
632 uint32_t equalizer30band_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
634 uint32_t orig_numsamples
= numsamples
;
635 uint32_t orig_offset
= offset
;
636 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
637 numsamples
+= offset
;
639 // everything bypassed
640 while(offset
< numsamples
) {
641 outs
[0][offset
] = ins
[0][offset
];
642 outs
[1][offset
] = ins
[1][offset
];
643 float values
[] = {0, 0, 0, 0};
644 meters
.process(values
);
649 while(offset
< numsamples
) {
651 double inL
= ins
[0][offset
] * *params
[param_level_in
];
652 double inR
= ins
[1][offset
] * *params
[param_level_in
];
657 unsigned int eq_index
= swL
.get_state() - 1;
658 eq_arrL
[eq_index
]->sbs_process(&inL
, &outL
);
659 eq_arrR
[eq_index
]->sbs_process(&inR
, &outR
);
661 //If filter type switched
662 if(flt_type_old
!= flt_type
)
666 flt_type_old
= flt_type
;
669 outL
*= swL
.get_ramp();
670 outR
*= swR
.get_ramp();
672 outL
= outL
* conv
.fast_db_2_lin(*params
[param_gain_scale10
]);
673 outR
= outR
* conv
.fast_db_2_lin(*params
[param_gain_scale20
]);
675 outL
= outL
* *params
[param_level_out
];
676 outR
= outR
* *params
[param_level_out
];
678 outs
[0][offset
] = outL
;
679 outs
[1][offset
] = outR
;
682 float values
[] = {(float)inL
, (float)inR
, (float)outL
, (float)outR
};
683 meters
.process(values
);
687 } // cycle trough samples
688 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
691 meters
.fall(orig_numsamples
);
695 /**********************************************************************
696 * FILTERKLAVIER by Hans Baier
697 **********************************************************************/
699 filterclavier_audio_module::filterclavier_audio_module()
700 : filter_module_with_inertia
<biquad_filter_module
, filterclavier_metadata
>(ins
, outs
, params
)
708 void filterclavier_audio_module::params_changed()
710 inertia_filter_module::inertia_cutoff
.set_inertia(
711 note_to_hz(last_note
+ *params
[par_transpose
], *params
[par_detune
]));
713 float min_resonance
= param_props
[par_max_resonance
].min
;
714 inertia_filter_module::inertia_resonance
.set_inertia(
715 (float(last_velocity
) / 127.0)
717 * (*params
[par_max_resonance
] - min_resonance
+ 0.001)
720 adjust_gain_according_to_filter_mode(last_velocity
);
722 inertia_filter_module::calculate_filter();
726 void filterclavier_audio_module::activate()
728 inertia_filter_module::activate();
731 void filterclavier_audio_module::set_sample_rate(uint32_t sr
)
733 inertia_filter_module::set_sample_rate(sr
);
736 void filterclavier_audio_module::deactivate()
738 inertia_filter_module::deactivate();
742 void filterclavier_audio_module::note_on(int channel
, int note
, int vel
)
746 inertia_filter_module::inertia_cutoff
.set_inertia(
747 note_to_hz(note
+ *params
[par_transpose
], *params
[par_detune
]));
749 float min_resonance
= param_props
[par_max_resonance
].min
;
750 inertia_filter_module::inertia_resonance
.set_inertia(
752 // 0.001: if the difference is equal to zero (which happens
753 // when the max_resonance knom is at minimum position
754 // then the filter gain doesnt seem to snap to zero on most note offs
755 * (*params
[par_max_resonance
] - min_resonance
+ 0.001)
758 adjust_gain_according_to_filter_mode(vel
);
760 inertia_filter_module::calculate_filter();
764 void filterclavier_audio_module::note_off(int channel
, int note
, int vel
)
766 if (note
== last_note
) {
767 inertia_filter_module::inertia_resonance
.set_inertia(param_props
[par_max_resonance
].min
);
768 inertia_filter_module::inertia_gain
.set_inertia(min_gain
);
769 inertia_filter_module::calculate_filter();
775 void filterclavier_audio_module::adjust_gain_according_to_filter_mode(int velocity
)
777 int mode
= dsp::fastf2i_drm(*params
[par_mode
]);
779 // for bandpasses: boost gain for velocities > 0
780 if ( (mode_6db_bp
<= mode
) && (mode
<= mode_18db_bp
) ) {
781 // gain for velocity 0: 1.0
782 // gain for velocity 127: 32.0
783 float mode_max_gain
= max_gain
;
784 // max_gain is right for mode_6db_bp
785 if (mode
== mode_12db_bp
)
786 mode_max_gain
/= 6.0;
787 if (mode
== mode_18db_bp
)
788 mode_max_gain
/= 10.5;
790 inertia_filter_module::inertia_gain
.set_now(
791 (float(velocity
) / 127.0) * (mode_max_gain
- min_gain
) + min_gain
);
793 inertia_filter_module::inertia_gain
.set_now(min_gain
);
797 /**********************************************************************
798 * EMPHASIS by Damien Zammit
799 **********************************************************************/
801 emphasis_audio_module::emphasis_audio_module()
810 void emphasis_audio_module::activate()
817 void emphasis_audio_module::deactivate()
822 void emphasis_audio_module::params_changed()
824 if (mode
!= *params
[param_mode
] or type
!= *params
[param_type
] or bypass_
!= *params
[param_bypass
])
826 mode
= *params
[param_mode
];
827 type
= *params
[param_type
];
828 bypass_
= *params
[param_bypass
];
829 riaacurvL
.set(srate
, mode
, type
);
830 riaacurvR
.set(srate
, mode
, type
);
833 uint32_t emphasis_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
835 uint32_t orig_numsamples
= numsamples
;
836 uint32_t orig_offset
= offset
;
837 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
840 // ensure that if params have changed, the params_changed method is
841 // called every 8 samples to interpolate filter parameters
842 while(numsamples
> 8)
845 outputs_mask
|= process(offset
, 8, inputs_mask
, outputs_mask
);
850 numsamples
+= offset
;
852 // everything bypassed
853 while(offset
< numsamples
) {
854 outs
[0][offset
] = ins
[0][offset
];
855 outs
[1][offset
] = ins
[1][offset
];
856 float values
[] = {0, 0, 0, 0};
857 meters
.process(values
);
862 while(offset
< numsamples
) {
863 // cycle through samples
866 float inL
= ins
[0][offset
];
867 float inR
= ins
[1][offset
];
869 inR
*= *params
[param_level_in
];
870 inL
*= *params
[param_level_in
];
875 procL
= riaacurvL
.process(procL
);
876 procR
= riaacurvR
.process(procR
);
878 outL
= procL
* *params
[param_level_out
];
879 outR
= procR
* *params
[param_level_out
];
882 outs
[0][offset
] = outL
;
883 outs
[1][offset
] = outR
;
885 float values
[] = {inL
, inR
, outL
, outR
};
886 meters
.process(values
);
890 } // cycle trough samples
891 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
893 riaacurvL
.sanitize();
894 riaacurvR
.sanitize();
896 meters
.fall(orig_numsamples
);
899 bool emphasis_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
901 if (phase
or subindex
)
904 context
->set_source_rgba(0.15, 0.2, 0.0, 0.3);
905 return ::get_graph(*this, subindex
, data
, points
, 32, 0);
907 bool emphasis_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
911 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
, true, 32, 0);
914 /**********************************************************************
915 * CROSSOVER N BAND by Markus Schmidt
916 **********************************************************************/
918 template<class XoverBaseClass
>
919 xover_audio_module
<XoverBaseClass
>::xover_audio_module()
924 crossover
.init(AM::channels
, AM::bands
, 44100);
926 template<class XoverBaseClass
>
927 xover_audio_module
<XoverBaseClass
>::~xover_audio_module()
931 template<class XoverBaseClass
>
932 void xover_audio_module
<XoverBaseClass
>::activate()
938 template<class XoverBaseClass
>
939 void xover_audio_module
<XoverBaseClass
>::deactivate()
943 template<class XoverBaseClass
>
944 void xover_audio_module
<XoverBaseClass
>::set_sample_rate(uint32_t sr
)
947 // set srate of crossover
948 crossover
.set_sample_rate(srate
);
950 buffer_size
= (int)(srate
/ 10 * AM::channels
* AM::bands
+ AM::channels
* AM::bands
); // buffer size attack rate multiplied by channels and bands
951 buffer
= (float*) calloc(buffer_size
, sizeof(float));
953 int amount
= AM::bands
* AM::channels
+ AM::channels
;
956 for(int b
= 0; b
< AM::bands
; b
++) {
957 for (int c
= 0; c
< AM::channels
; c
++) {
958 meter
[b
* AM::channels
+ c
] = AM::param_meter_01
+ b
* params_per_band
+ c
;
959 clip
[b
* AM::channels
+ c
] = -1;
962 for (int c
= 0; c
< AM::channels
; c
++) {
963 meter
[c
+ AM::bands
* AM::channels
] = AM::param_meter_0
+ c
;
964 clip
[c
+ AM::bands
* AM::channels
] = -1;
966 meters
.init(params
, meter
, clip
, amount
, srate
);
968 template<class XoverBaseClass
>
969 void xover_audio_module
<XoverBaseClass
>::params_changed()
971 int mode
= *params
[AM::param_mode
];
972 crossover
.set_mode(mode
);
973 for (int i
= 0; i
< AM::bands
- 1; i
++) {
974 crossover
.set_filter(i
, *params
[AM::param_freq0
+ i
]);
976 for (int i
= 0; i
< AM::bands
; i
++) {
977 int offset
= i
* params_per_band
;
978 crossover
.set_level(i
, *params
[AM::param_level1
+ offset
]);
979 crossover
.set_active(i
, *params
[AM::param_active1
+ offset
] > 0.5);
984 template<class XoverBaseClass
>
985 uint32_t xover_audio_module
<XoverBaseClass
>::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
987 unsigned int targ
= numsamples
+ offset
;
989 float values
[AM::bands
* AM::channels
+ AM::channels
];
990 while(offset
< targ
) {
991 // cycle through samples
994 for (int c
= 0; c
< AM::channels
; c
++) {
995 in
[c
] = ins
[c
][offset
] * *params
[AM::param_level
];
997 crossover
.process(in
);
999 for (int b
= 0; b
< AM::bands
; b
++) {
1001 int off
= b
* params_per_band
;
1002 // calc position in delay buffer
1003 if (*params
[AM::param_delay1
+ off
]) {
1004 nbuf
= srate
* (fabs(*params
[AM::param_delay1
+ off
]) / 1000.f
) * AM::bands
* AM::channels
;
1005 nbuf
-= nbuf
% (AM::bands
* AM::channels
);
1007 for (int c
= 0; c
< AM::channels
; c
++) {
1008 // define a pointer between 0 and channels * bands
1009 int ptr
= b
* AM::channels
+ c
;
1011 // get output from crossover module if active
1012 xval
= *params
[AM::param_active1
+ off
] > 0.5 ? crossover
.get_value(c
, b
) : 0.f
;
1014 // fill delay buffer
1015 buffer
[pos
+ ptr
] = xval
;
1017 // get value from delay buffer if neccessary
1018 if (*params
[AM::param_delay1
+ off
])
1019 xval
= buffer
[(pos
- (int)nbuf
+ ptr
+ buffer_size
) % buffer_size
];
1021 // set value with phase to output
1022 outs
[ptr
][offset
] = *params
[AM::param_phase1
+ off
] > 0.5 ? xval
* -1 : xval
;
1025 values
[b
* AM::channels
+ c
] = outs
[ptr
][offset
];
1029 for (int c
= 0; c
< AM::channels
; c
++) {
1030 values
[c
+ AM::bands
* AM::channels
] = ins
[c
][offset
];
1032 meters
.process(values
);
1035 // delay buffer pos forward
1036 pos
= (pos
+ AM::channels
* AM::bands
) % buffer_size
;
1038 } // cycle trough samples
1039 meters
.fall(numsamples
);
1040 return outputs_mask
;
1043 template<class XoverBaseClass
>
1044 bool xover_audio_module
<XoverBaseClass
>::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1046 return crossover
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
1048 template<class XoverBaseClass
>
1049 bool xover_audio_module
<XoverBaseClass
>::get_layers(int index
, int generation
, unsigned int &layers
) const
1051 return crossover
.get_layers(index
, generation
, layers
);
1054 template class xover_audio_module
<xover2_metadata
>;
1055 template class xover_audio_module
<xover3_metadata
>;
1056 template class xover_audio_module
<xover4_metadata
>;
1059 /**********************************************************************
1060 * Vocoder by Markus Schmidt and Christian Holschuh
1061 **********************************************************************/
1063 vocoder_audio_module::vocoder_audio_module()
1074 fcoeff
= log10(20.f
);
1076 memset(env_mods
, 0, 32 * 2 * sizeof(double));
1079 void vocoder_audio_module::activate()
1084 void vocoder_audio_module::deactivate()
1089 void vocoder_audio_module::params_changed()
1091 attack
= exp(log(0.01)/( *params
[param_attack
] * srate
* 0.001));
1092 release
= exp(log(0.01)/( *params
[param_release
] * srate
* 0.001));
1094 int b
= *params
[param_bands
];
1095 bands
= (b
+ 2) * 4 + (b
> 1 ? (b
- 2) * 4 : 0);
1096 order
= std::min(8.f
, *params
[param_order
]);
1097 float q
= pow(10, (fmodf(std::min(8.999f
, *params
[param_order
]), 1.f
) * (7.f
/ pow(1.3, order
))) / 20);
1098 if (bands
!= bands_old
or *params
[param_order
] != order_old
) {
1100 order_old
= *params
[param_order
];
1101 for (int i
= 0; i
< bands
; i
++) {
1102 // set all actually used filters
1103 detector
[0][0][i
].set_bp_rbj(pow(10, fcoeff
+ (0.5f
+ (float)i
) * 3.f
/ (float)bands
), q
, (double)srate
);
1104 for (int j
= 0; j
< order
; j
++) {
1106 detector
[0][j
][i
].copy_coeffs(detector
[0][0][i
]);
1107 detector
[1][j
][i
].copy_coeffs(detector
[0][0][i
]);
1108 modulator
[0][j
][i
].copy_coeffs(detector
[0][0][i
]);
1109 modulator
[1][j
][i
].copy_coeffs(detector
[0][0][i
]);
1112 redraw_graph
= true;
1114 _analyzer
.set_params(256, 1, 6, 0, 1, 0, 0, 0, 15, 2, 0, 0);
1115 redraw_graph
= true;
1118 int vocoder_audio_module::get_solo() const {
1119 for (int i
= 0; i
< bands
; i
++)
1120 if (*params
[param_solo0
+ i
* band_params
])
1125 uint32_t vocoder_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1127 uint32_t orig_numsamples
= numsamples
;
1128 uint32_t orig_offset
= offset
;
1129 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
1130 int solo
= get_solo();
1131 numsamples
+= offset
;
1132 float led
[32] = {0};
1134 // everything bypassed
1135 while(offset
< numsamples
) {
1136 outs
[0][offset
] = ins
[0][offset
];
1137 outs
[1][offset
] = ins
[1][offset
];
1138 float values
[] = {0, 0, 0, 0, 0, 0};
1139 meters
.process(values
);
1144 while(offset
< numsamples
) {
1145 // cycle through samples
1151 // carrier with level
1152 double cL
= ins
[0][offset
] * *params
[param_carrier_in
];
1153 double cR
= ins
[1][offset
] * *params
[param_carrier_in
];
1155 // modulator with level
1156 double mL
= ins
[2][offset
] * *params
[param_mod_in
];
1157 double mR
= ins
[3][offset
] * *params
[param_mod_in
];
1160 double nL
= (float)rand() / (float)RAND_MAX
;
1161 double nR
= (float)rand() / (float)RAND_MAX
;
1163 for (int i
= 0; i
< bands
; i
++) {
1166 double cL_
= cL
+ nL
* *params
[param_noise0
+ i
* band_params
];
1167 double cR_
= cR
+ nR
* *params
[param_noise0
+ i
* band_params
];
1169 if ((solo
and *params
[param_solo0
+ i
* band_params
]) or !solo
) {
1170 for (int j
= 0; j
< order
; j
++) {
1172 if (*params
[param_link
] > 0.5) {
1173 mL_
= detector
[0][j
][i
].process(std::max(mL_
, mR_
));
1176 mL_
= detector
[0][j
][i
].process(mL_
);
1177 mR_
= detector
[1][j
][i
].process(mR_
);
1179 // filter carrier with noise
1180 cL_
= modulator
[0][j
][i
].process(cL_
);
1181 cR_
= modulator
[1][j
][i
].process(cR_
);
1183 // level by envelope with levelling
1184 cL_
*= env_mods
[0][i
] * ((float)order
/ 2 + 4) * 4;
1185 cR_
*= env_mods
[1][i
] * ((float)order
/ 2 + 4) * 4;
1187 // add band volume setting
1188 cL_
*= *params
[param_volume0
+ i
* band_params
];
1189 cR_
*= *params
[param_volume0
+ i
* band_params
];
1191 // add filtered modulator
1192 cL_
+= mL_
* *params
[param_mod0
+ i
* band_params
];
1193 cR_
+= mR_
* *params
[param_mod0
+ i
* band_params
];
1196 cL_
*= (*params
[param_pan0
+ i
* band_params
] > 0
1197 ? -*params
[param_pan0
+ i
* band_params
] + 1 : 1);
1198 cR_
*= (*params
[param_pan0
+ i
* band_params
] < 0
1199 ? *params
[param_pan0
+ i
* band_params
] + 1 : 1);
1201 // add to outputs with proc level
1202 pL
+= cL_
* *params
[param_proc
];
1203 pR
+= cR_
* *params
[param_proc
];
1206 if (*params
[param_detectors
] > 0.5)
1207 if (env_mods
[0][i
] + env_mods
[1][i
] > led
[i
])
1208 led
[i
] = env_mods
[0][i
] + env_mods
[1][i
];
1210 // advance envelopes
1211 env_mods
[0][i
] = (fabs(mL_
) > env_mods
[0][i
] ? attack
: release
) * (env_mods
[0][i
] - fabs(mL_
)) + fabs(mL_
);
1212 env_mods
[1][i
] = (fabs(mR_
) > env_mods
[1][i
] ? attack
: release
) * (env_mods
[1][i
] - fabs(mR_
)) + fabs(mR_
);
1219 outL
+= cL
* *params
[param_carrier
];
1220 outR
+= cR
* *params
[param_carrier
];
1223 outL
+= mL
* *params
[param_mod
];
1224 outR
+= mR
* *params
[param_mod
];
1227 switch ((int)*params
[param_analyzer
]) {
1232 _analyzer
.process((float)cL
, (float)cR
);
1235 _analyzer
.process((float)mL
, (float)mR
);
1238 _analyzer
.process((float)pL
, (float)pR
);
1241 _analyzer
.process((float)outL
, (float)outR
);
1246 outL
*= *params
[param_out
];
1247 outR
*= *params
[param_out
];
1250 outs
[0][offset
] = outL
;
1251 outs
[1][offset
] = outR
;
1254 float values
[] = {(float)cL
, (float)cR
, (float)mL
, (float)mR
, (float)outL
, (float)outR
};
1255 meters
.process(values
);
1259 } // cycle trough samples
1260 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
1262 for (int i
= 0; i
< bands
; i
++) {
1263 for (int j
= 0; j
< order
; j
++) {
1264 detector
[0][j
][i
].sanitize();
1265 detector
[1][j
][i
].sanitize();
1266 modulator
[0][j
][i
].sanitize();
1267 modulator
[1][j
][i
].sanitize();
1273 for (int i
= 0; i
< 32; i
++) {
1275 if (*params
[param_detectors
] > 0.5)
1276 val
= std::max(0.0, 1 + log((led
[i
] / 2) * order
) / log2_
/ 10);
1277 *params
[param_level0
+ i
* band_params
] = val
;
1279 meters
.fall(orig_numsamples
);
1280 return outputs_mask
;
1282 bool vocoder_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1284 if (phase
and *params
[param_analyzer
]) {
1288 bool r
= _analyzer
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
1289 context
->set_source_rgba(0,0,0,0.25);
1295 if (subindex
>= bands
) {
1296 redraw_graph
= false;
1299 int solo
= get_solo();
1300 if (solo
and !*params
[param_solo0
+ subindex
* band_params
])
1301 context
->set_source_rgba(0,0,0,0.15);
1302 context
->set_line_width(0.99);
1304 double fq
= pow(10, fcoeff
+ (0.5f
+ (float)subindex
) * 3.f
/ (float)bands
);
1305 for (int i
= 0; i
< points
; i
++) {
1306 double freq
= 20.0 * pow (20000.0 / 20.0, i
* 1.0 / points
);
1308 for (int j
= 0; j
< order
; j
++)
1309 level
*= detector
[0][0][subindex
].freq_gain(freq
, srate
);
1310 level
*= *params
[param_volume0
+ subindex
* band_params
];
1311 data
[i
] = dB_grid(level
, 256, 0.4);
1312 if (!drawn
and freq
> fq
) {
1315 sprintf(str
, "%d", subindex
+ 1);
1316 draw_cairo_label(context
, str
, i
, context
->size_y
* (1 - (data
[i
] + 1) / 2.f
), 0, 0, 0.5);
1322 bool vocoder_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1324 redraw_graph
= redraw_graph
|| !generation
;
1325 layers
= *params
[param_analyzer
] ? LG_REALTIME_GRAPH
: 0;
1326 layers
|= (generation
? LG_NONE
: LG_CACHE_GRID
) | (redraw_graph
? LG_CACHE_GRAPH
: LG_NONE
);
1327 redraw_graph
|= (bool)*params
[param_analyzer
];
1328 return redraw_graph
or !generation
;