1 /* Calf DSP plugin pack
2 * Compression 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/audio_fx.h>
24 #include <calf/giface.h>
25 #include <calf/modules_comp.h>
28 using namespace calf_plugins
;
30 #define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name;
33 /**********************************************************************
34 * GAIN REDUCTION by Thor Harald Johanssen
35 **********************************************************************/
37 gain_reduction_audio_module::gain_reduction_audio_module()
62 void gain_reduction_audio_module::activate()
73 void gain_reduction_audio_module::deactivate()
78 void gain_reduction_audio_module::update_curve()
80 float linThreshold
= threshold
;
81 float linKneeSqrt
= sqrt(knee
);
82 linKneeStart
= linThreshold
/ linKneeSqrt
;
83 adjKneeStart
= linKneeStart
*linKneeStart
;
84 float linKneeStop
= linThreshold
* linKneeSqrt
;
85 thres
= log(linThreshold
);
86 kneeStart
= log(linKneeStart
);
87 kneeStop
= log(linKneeStop
);
88 compressedKneeStop
= (kneeStop
- thres
) / ratio
+ thres
;
91 void gain_reduction_audio_module::process(float &left
, float &right
, const float *det_left
, const float *det_right
)
100 // this routine is mainly copied from thor's compressor module
101 // greatest sounding compressor I've heard!
102 bool rms
= (detection
== 0);
103 bool average
= (stereo_link
== 0);
104 float attack_coeff
= std::min(1.f
, 1.f
/ (attack
* srate
/ 4000.f
));
105 float release_coeff
= std::min(1.f
, 1.f
/ (release
* srate
/ 4000.f
));
107 float absample
= average
? (fabs(*det_left
) + fabs(*det_right
)) * 0.5f
: std::max(fabs(*det_left
), fabs(*det_right
));
108 if(rms
) absample
*= absample
;
110 dsp::sanitize(linSlope
);
112 linSlope
+= (absample
- linSlope
) * (absample
> linSlope
? attack_coeff
: release_coeff
);
115 gain
= output_gain(linSlope
, rms
);
118 left
*= gain
* makeup
;
119 right
*= gain
* makeup
;
120 meter_out
= std::max(fabs(left
), fabs(right
));;
122 detected
= rms
? sqrt(linSlope
) : linSlope
;
126 float gain_reduction_audio_module::output_level(float slope
) const {
127 return slope
* output_gain(slope
, false) * makeup
;
130 float gain_reduction_audio_module::output_gain(float linSlope
, bool rms
) const {
131 //this calculation is also thor's work
132 if(linSlope
> (rms
? adjKneeStart
: linKneeStart
)) {
133 float slope
= log(linSlope
);
134 if(rms
) slope
*= 0.5f
;
138 if(IS_FAKE_INFINITY(ratio
)) {
142 gain
= (slope
- thres
) / ratio
+ thres
;
146 if(knee
> 1.f
&& slope
< kneeStop
) {
147 gain
= hermite_interpolation(slope
, kneeStart
, kneeStop
, kneeStart
, compressedKneeStop
, 1.f
, delta
);
150 return exp(gain
- slope
);
156 void gain_reduction_audio_module::set_sample_rate(uint32_t sr
)
160 void gain_reduction_audio_module::set_params(float att
, float rel
, float thr
, float rat
, float kn
, float mak
, float det
, float stl
, float byp
, float mu
)
178 if (fabs(threshold
-old_threshold
) + fabs(ratio
- old_ratio
) + fabs(knee
- old_knee
) + fabs(makeup
- old_makeup
) + fabs(detection
- old_detection
) + fabs(bypass
- old_bypass
) + fabs(mute
- old_mute
) > 0.000001f
) {
179 old_threshold
= threshold
;
183 old_detection
= detection
;
189 float gain_reduction_audio_module::get_output_level() {
190 // returns output level (max(left, right))
193 float gain_reduction_audio_module::get_comp_level() {
194 // returns amount of compression
198 bool gain_reduction_audio_module::get_graph(int subindex
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
200 redraw_graph
= false;
201 if (!is_active
or subindex
> 1)
204 for (int i
= 0; i
< points
; i
++)
206 float input
= dB_grid_inv(-1.0 + i
* 2.0 / (points
- 1));
208 if (i
== 0 or i
>= points
- 1)
209 data
[i
] = dB_grid(input
);
213 float output
= output_level(input
);
214 data
[i
] = dB_grid(output
);
217 if (subindex
== (bypass
> 0.5f
? 1 : 0) or mute
> 0.1f
)
218 context
->set_source_rgba(0.15, 0.2, 0.0, 0.3);
220 context
->set_source_rgba(0.15, 0.2, 0.0, 0.8);
223 context
->set_line_width(1.);
227 bool gain_reduction_audio_module::get_dot(int subindex
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
229 if (!is_active
or bypass
> 0.5f
or mute
> 0.f
or subindex
)
232 bool rms
= (detection
== 0);
233 float det
= rms
? sqrt(detected
) : detected
;
234 x
= 0.5 + 0.5 * dB_grid(det
);
235 y
= dB_grid(bypass
> 0.5f
or mute
> 0.f
? det
: output_level(det
));
239 bool gain_reduction_audio_module::get_gridline(int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
244 vertical
= (subindex
& 1) != 0;
245 bool result
= get_freq_gridline(subindex
>> 1, pos
, tmp
, legend
, context
, false);
246 if (result
&& vertical
) {
247 if ((subindex
& 4) && !legend
.empty()) {
251 size_t pos
= legend
.find(" dB");
252 if (pos
!= std::string::npos
)
255 pos
= 0.5 + 0.5 * pos
;
260 bool gain_reduction_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
262 layers
= LG_REALTIME_DOT
| (generation
? 0 : LG_CACHE_GRID
) | ((redraw_graph
|| !generation
) ? LG_CACHE_GRAPH
: 0);
266 /**********************************************************************
267 * GAIN REDUCTION 2 by Damien Zammit
268 **********************************************************************/
270 gain_reduction2_audio_module::gain_reduction2_audio_module()
298 void gain_reduction2_audio_module::activate()
309 void gain_reduction2_audio_module::deactivate()
314 void gain_reduction2_audio_module::update_curve()
319 void gain_reduction2_audio_module::process(float &left
)
322 float width
=(knee
-0.99f
)*8.f
;
324 float attack_coeff
= exp(-1000.f
/(attack
* srate
));
325 float release_coeff
= exp(-1000.f
/(release
* srate
));
326 float thresdb
=20.f
*log10(threshold
);
329 float xg
, xl
, yg
, yl
, y1
;
331 xg
= (left
==0.f
) ? -160.f
: 20.f
*log10(fabs(left
));
333 if (2.f
*(xg
-thresdb
)<-width
) {
336 if (2.f
*fabs(xg
-thresdb
)<=width
) {
337 yg
= xg
+ (1.f
/ratio
-1.f
)*(xg
-thresdb
+width
/2.f
)*(xg
-thresdb
+width
/2.f
)/(2.f
*width
);
339 if (2.f
*(xg
-thresdb
)>width
) {
340 yg
= thresdb
+ (xg
-thresdb
)/ratio
;
345 y1
= std::max(xl
, release_coeff
*old_y1
+(1.f
-release_coeff
)*xl
);
346 yl
= attack_coeff
*old_yl
+(1.f
-attack_coeff
)*y1
;
349 gain
= exp(cdb
/20.f
*log(10.f
));
351 left
*= gain
* makeup
;
352 meter_out
= (fabs(left
));
354 detected
= (exp(yg
/20.f
*log(10.f
))+old_detected
)/2.f
;
355 old_detected
= detected
;
362 float gain_reduction2_audio_module::output_level(float inputt
) const {
363 return (output_gain(inputt
) * makeup
);
366 float gain_reduction2_audio_module::output_gain(float inputt
) const {
367 float width
=(knee
-0.99f
)*8.f
;
368 float thresdb
=20.f
*log10(threshold
);
372 xg
= (inputt
==0.f
) ? -160.f
: 20.f
*log10(fabs(inputt
));
374 if (2.f
*(xg
-thresdb
)<-width
) {
377 if (2.f
*fabs(xg
-thresdb
)<=width
) {
378 yg
= xg
+ (1.f
/ratio
-1.f
)*(xg
-thresdb
+width
/2.f
)*(xg
-thresdb
+width
/2.f
)/(2.f
*width
);
380 if (2.f
*(xg
-thresdb
)>width
) {
381 yg
= thresdb
+ (xg
-thresdb
)/ratio
;
384 return(exp(yg
/20.f
*log(10.f
)));
387 void gain_reduction2_audio_module::set_sample_rate(uint32_t sr
)
391 void gain_reduction2_audio_module::set_params(float att
, float rel
, float thr
, float rat
, float kn
, float mak
, float byp
, float mu
)
406 if (fabs(threshold
-old_threshold
) + fabs(ratio
- old_ratio
) + fabs(knee
- old_knee
) + fabs(makeup
- old_makeup
) + fabs(detection
- old_detection
) + fabs(bypass
- old_bypass
) + fabs(mute
- old_mute
) > 0.000001f
) {
407 old_threshold
= threshold
;
411 old_detection
= detection
;
417 float gain_reduction2_audio_module::get_output_level() {
418 // returns output level (max(left, right))
421 float gain_reduction2_audio_module::get_comp_level() {
422 // returns amount of compression
426 bool gain_reduction2_audio_module::get_graph(int subindex
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
428 redraw_graph
= false;
429 if (!is_active
or subindex
> 1)
432 for (int i
= 0; i
< points
; i
++)
434 float input
= dB_grid_inv(-1.0 + i
* 2.0 / (points
- 1));
436 if (i
== 0 or i
>= points
- 1)
437 data
[i
] = dB_grid(input
);
441 float output
= output_level(input
);
442 data
[i
] = dB_grid(output
);
445 if (subindex
== (bypass
> 0.5f
? 1 : 0) or mute
> 0.1f
)
446 context
->set_source_rgba(0.15, 0.2, 0.0, 0.15);
448 context
->set_source_rgba(0.15, 0.2, 0.0, 0.5);
451 context
->set_line_width(1.);
455 bool gain_reduction2_audio_module::get_dot(int subindex
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
457 if (!is_active
or bypass
> 0.5f
or mute
> 0.f
or subindex
)
460 bool rms
= (detection
== 0);
461 float det
= rms
? sqrt(detected
) : detected
;
462 x
= 0.5 + 0.5 * dB_grid(det
);
463 y
= dB_grid(bypass
> 0.5f
or mute
> 0.f
? det
: output_level(det
));
467 bool gain_reduction2_audio_module::get_gridline(int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
470 vertical
= (subindex
& 1) != 0;
471 bool result
= get_freq_gridline(subindex
>> 1, pos
, tmp
, legend
, context
, false);
472 if (result
&& vertical
) {
473 if ((subindex
& 4) && !legend
.empty()) {
477 size_t pos
= legend
.find(" dB");
478 if (pos
!= std::string::npos
)
481 pos
= 0.5 + 0.5 * pos
;
486 bool gain_reduction2_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
488 layers
= LG_REALTIME_DOT
| (generation
? 0 : LG_CACHE_GRID
) | ((redraw_graph
|| !generation
) ? LG_CACHE_GRAPH
: 0);
493 /**********************************************************************
494 * EXPANDER by Damien Zammit
495 **********************************************************************/
497 expander_audio_module::expander_audio_module()
519 old_stereo_link
= 0.f
;
525 void expander_audio_module::activate()
537 void expander_audio_module::deactivate()
542 void expander_audio_module::update_curve()
544 bool rms
= (detection
== 0);
545 float linThreshold
= threshold
;
547 linThreshold
= linThreshold
* linThreshold
;
548 attack_coeff
= std::min(1.f
, 1.f
/ (attack
* srate
/ 4000.f
));
549 release_coeff
= std::min(1.f
, 1.f
/ (release
* srate
/ 4000.f
));
550 float linKneeSqrt
= sqrt(knee
);
551 linKneeStart
= linThreshold
/ linKneeSqrt
;
552 adjKneeStart
= linKneeStart
*linKneeStart
;
553 linKneeStop
= linThreshold
* linKneeSqrt
;
554 thres
= log(linThreshold
);
555 kneeStart
= log(linKneeStart
);
556 kneeStop
= log(linKneeStop
);
557 compressedKneeStop
= (kneeStop
- thres
) / ratio
+ thres
;
560 void expander_audio_module::process(float &left
, float &right
, const float *det_left
, const float *det_right
)
569 // this routine is mainly copied from Damien's expander module based on Thor's compressor
570 bool rms
= (detection
== 0);
571 bool average
= (stereo_link
== 0);
572 float absample
= average
? (fabs(*det_left
) + fabs(*det_right
)) * 0.5f
: std::max(fabs(*det_left
), fabs(*det_right
));
573 if(rms
) absample
*= absample
;
575 dsp::sanitize(linSlope
);
577 linSlope
+= (absample
- linSlope
) * (absample
> linSlope
? attack_coeff
: release_coeff
);
580 gain
= output_gain(linSlope
, rms
);
582 left
*= gain
* makeup
;
583 right
*= gain
* makeup
;
584 meter_out
= std::max(fabs(left
), fabs(right
));
590 float expander_audio_module::output_level(float slope
) const {
591 bool rms
= (detection
== 0);
592 return slope
* output_gain(rms
? slope
*slope
: slope
, rms
) * makeup
;
595 float expander_audio_module::output_gain(float linSlope
, bool rms
) const {
596 //this calculation is also Damiens's work based on Thor's compressor
597 if(linSlope
< linKneeStop
) {
598 float slope
= log(linSlope
);
599 //float tratio = rms ? sqrt(ratio) : ratio;
600 float tratio
= ratio
;
603 if(IS_FAKE_INFINITY(ratio
))
605 gain
= (slope
-thres
) * tratio
+ thres
;
608 if(knee
> 1.f
&& slope
> kneeStart
) {
609 gain
= dsp::hermite_interpolation(slope
, kneeStart
, kneeStop
, ((kneeStart
- thres
) * tratio
+ thres
), kneeStop
, delta
,1.f
);
611 return std::max(range
, expf(gain
-slope
));
616 void expander_audio_module::set_sample_rate(uint32_t sr
)
621 void expander_audio_module::set_params(float att
, float rel
, float thr
, float rat
, float kn
, float mak
, float det
, float stl
, float byp
, float mu
, float ran
)
639 if (fabs(range
- old_range
) + fabs(threshold
- old_threshold
) + fabs(ratio
- old_ratio
) + fabs(knee
- old_knee
) + fabs(makeup
- old_makeup
) + fabs(detection
- old_detection
) + fabs(bypass
- old_bypass
) + fabs(mute
- old_mute
) > 0.000001f
) {
641 old_threshold
= threshold
;
645 old_detection
= detection
;
652 float expander_audio_module::get_output_level() {
653 // returns output level (max(left, right))
656 float expander_audio_module::get_expander_level() {
657 // returns amount of gating
661 bool expander_audio_module::get_graph(int subindex
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
663 redraw_graph
= false;
664 if (!is_active
or subindex
> 1)
667 for (int i
= 0; i
< points
; i
++) {
668 float input
= dB_grid_inv(-1.0 + i
* 2.0 / (points
- 1));
670 if (i
== 0 or i
>= points
- 1)
671 data
[i
] = dB_grid(input
);
675 float output
= output_level(input
);
676 data
[i
] = dB_grid(output
);
679 if (subindex
== (bypass
> 0.5f
? 1 : 0) or mute
> 0.1f
)
680 context
->set_source_rgba(0.15, 0.2, 0.0, 0.15);
682 context
->set_source_rgba(0.15, 0.2, 0.0, 0.5);
685 context
->set_line_width(1.);
689 bool expander_audio_module::get_dot(int subindex
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
691 if (!is_active
or bypass
> 0.5f
or mute
> 0.f
or subindex
)
694 bool rms
= (detection
== 0);
695 float det
= rms
? sqrt(detected
) : detected
;
696 x
= 0.5 + 0.5 * dB_grid(det
);
697 y
= dB_grid(bypass
> 0.5f
or mute
> 0.f
? det
: output_level(det
));
701 bool expander_audio_module::get_gridline(int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
704 vertical
= (subindex
& 1) != 0;
705 bool result
= get_freq_gridline(subindex
>> 1, pos
, tmp
, legend
, context
, false);
706 if (result
&& vertical
) {
707 if ((subindex
& 4) && !legend
.empty()) {
711 size_t pos
= legend
.find(" dB");
712 if (pos
!= std::string::npos
)
715 pos
= 0.5 + 0.5 * pos
;
720 bool expander_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
722 layers
= LG_REALTIME_DOT
| (generation
? 0 : LG_CACHE_GRID
) | ((redraw_graph
|| !generation
) ? LG_CACHE_GRAPH
: 0);
727 /**********************************************************************
728 * COMPRESSOR by Thor Harald Johanssen
729 **********************************************************************/
731 compressor_audio_module::compressor_audio_module()
737 void compressor_audio_module::activate()
740 // set all filters and strips
741 compressor
.activate();
744 void compressor_audio_module::deactivate()
747 compressor
.deactivate();
750 void compressor_audio_module::params_changed()
752 compressor
.set_params(*params
[param_attack
], *params
[param_release
], *params
[param_threshold
], *params
[param_ratio
], *params
[param_knee
], *params
[param_makeup
], *params
[param_detection
], *params
[param_stereo_link
], *params
[param_bypass
], 0.f
);
755 void compressor_audio_module::set_sample_rate(uint32_t sr
)
758 compressor
.set_sample_rate(srate
);
759 int meter
[] = {param_meter_in
, param_meter_out
, -param_compression
};
760 int clip
[] = {param_clip_in
, param_clip_out
, -1};
761 meters
.init(params
, meter
, clip
, 3, srate
);
764 uint32_t compressor_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
766 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
767 numsamples
+= offset
;
769 // everything bypassed
770 while(offset
< numsamples
) {
771 outs
[0][offset
] = ins
[0][offset
];
772 outs
[1][offset
] = ins
[1][offset
];
773 float values
[] = {0, 0, 1};
774 meters
.process(values
);
780 uint32_t orig_offset
= offset
;
781 compressor
.update_curve();
783 while(offset
< numsamples
) {
784 // cycle through samples
787 float inL
= ins
[0][offset
];
788 float inR
= ins
[1][offset
];
789 float Lin
= ins
[0][offset
];
790 float Rin
= ins
[1][offset
];
793 inR
*= *params
[param_level_in
];
794 inL
*= *params
[param_level_in
];
799 compressor
.process(leftAC
, rightAC
);
805 outL
= outL
* *params
[param_mix
] + Lin
* (*params
[param_mix
] * -1 + 1);
806 outR
= outR
* *params
[param_mix
] + Rin
* (*params
[param_mix
] * -1 + 1);
809 outs
[0][offset
] = outL
;
810 outs
[1][offset
] = outR
;
812 float values
[] = {std::max(inL
, inR
), std::max(outL
, outR
), compressor
.get_comp_level()};
813 meters
.process(values
);
817 } // cycle trough samples
818 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
820 meters
.fall(numsamples
);
823 bool compressor_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
825 return compressor
.get_graph(subindex
, data
, points
, context
, mode
);
828 bool compressor_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
830 return compressor
.get_dot(subindex
, x
, y
, size
, context
);
833 bool compressor_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
835 return compressor
.get_gridline(subindex
, pos
, vertical
, legend
, context
);
838 bool compressor_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
840 return compressor
.get_layers(index
, generation
, layers
);
843 /**********************************************************************
844 * SIDECHAIN COMPRESSOR by Markus Schmidt
845 **********************************************************************/
847 sidechaincompressor_audio_module::sidechaincompressor_audio_module()
859 sc_mode_old1
= WIDEBAND
;
863 void sidechaincompressor_audio_module::activate()
866 // set all filters and strips
867 compressor
.activate();
870 void sidechaincompressor_audio_module::deactivate()
873 compressor
.deactivate();
876 sidechaincompressor_audio_module::cfloat
sidechaincompressor_audio_module::h_z(const cfloat
&z
) const
878 switch ((CalfScModes
)sc_mode
) {
889 return f1L
.h_z(z
) * f2L
.h_z(z
);
894 case DERUMBLER_SPLIT
:
901 float sidechaincompressor_audio_module::freq_gain(int index
, double freq
) const
903 typedef std::complex<double> cfloat
;
904 freq
*= 2.0 * M_PI
/ srate
;
905 cfloat z
= 1.0 / exp(cfloat(0.0, freq
));
907 return std::abs(h_z(z
));
910 void sidechaincompressor_audio_module::params_changed()
912 // set the params of all filters
913 if(*params
[param_f1_freq
] != f1_freq_old
or *params
[param_f1_level
] != f1_level_old
914 or *params
[param_f2_freq
] != f2_freq_old
or *params
[param_f2_level
] != f2_level_old
915 or *params
[param_sc_mode
] != sc_mode
) {
917 switch ((CalfScModes
)*params
[param_sc_mode
]) {
920 f1L
.set_hp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
921 f1R
.copy_coeffs(f1L
);
922 f2L
.set_lp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
923 f2R
.copy_coeffs(f2L
);
928 f1L
.set_peakeq_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
929 f1R
.copy_coeffs(f1L
);
930 f2L
.set_hp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
931 f2R
.copy_coeffs(f2L
);
936 f1L
.set_lp_rbj((float)*params
[param_f2_freq
] * (1 + 0.17), q
, (float)srate
);
937 f1R
.copy_coeffs(f1L
);
938 f2L
.set_hp_rbj((float)*params
[param_f2_freq
] * (1 - 0.17), q
, (float)srate
, *params
[param_f2_level
]);
939 f2R
.copy_coeffs(f2L
);
944 f1L
.set_lp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
945 f1R
.copy_coeffs(f1L
);
946 f2L
.set_peakeq_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
947 f2R
.copy_coeffs(f2L
);
951 case DERUMBLER_SPLIT
:
952 f1L
.set_lp_rbj((float)*params
[param_f1_freq
] * (1 + 0.17), q
, (float)srate
, *params
[param_f1_level
]);
953 f1R
.copy_coeffs(f1L
);
954 f2L
.set_hp_rbj((float)*params
[param_f1_freq
] * (1 - 0.17), q
, (float)srate
);
955 f2R
.copy_coeffs(f2L
);
960 f1L
.set_lowshelf_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
961 f1R
.copy_coeffs(f1L
);
962 f2L
.set_highshelf_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
963 f2R
.copy_coeffs(f2L
);
968 f1L
.set_lowshelf_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
969 f1R
.copy_coeffs(f1L
);
970 f2L
.set_peakeq_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
971 f2R
.copy_coeffs(f2L
);
976 f1L
.set_peakeq_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
977 f1R
.copy_coeffs(f1L
);
978 f2L
.set_highshelf_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
979 f2R
.copy_coeffs(f2L
);
984 f1L
.set_bp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
985 f1R
.copy_coeffs(f1L
);
986 f2L
.set_hp_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
987 f2R
.copy_coeffs(f2L
);
992 f1L
.set_hp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
993 f1R
.copy_coeffs(f1L
);
994 f2L
.set_lp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
995 f2R
.copy_coeffs(f2L
);
1000 f1_freq_old
= *params
[param_f1_freq
];
1001 f1_level_old
= *params
[param_f1_level
];
1002 f2_freq_old
= *params
[param_f2_freq
];
1003 f2_level_old
= *params
[param_f2_level
];
1004 sc_mode
= (CalfScModes
)*params
[param_sc_mode
];
1007 if(params
[param_f1_active
] != NULL
) {
1008 *params
[param_f1_active
] = f1_active
;
1010 if(params
[param_f2_active
] != NULL
) {
1011 *params
[param_f2_active
] = f2_active
;
1013 // and set the compressor module
1014 compressor
.set_params(*params
[param_attack
], *params
[param_release
], *params
[param_threshold
], *params
[param_ratio
], *params
[param_knee
], *params
[param_makeup
], *params
[param_detection
], *params
[param_stereo_link
], *params
[param_bypass
], 0.f
);
1016 if (*params
[param_f1_freq
] != f1_freq_old1
1017 or *params
[param_f2_freq
] != f2_freq_old1
1018 or *params
[param_f1_level
] != f1_level_old1
1019 or *params
[param_f2_level
] != f2_level_old1
1020 or *params
[param_sc_mode
] != sc_mode_old1
)
1022 f1_freq_old1
= *params
[param_f1_freq
];
1023 f2_freq_old1
= *params
[param_f2_freq
];
1024 f1_level_old1
= *params
[param_f1_level
];
1025 f2_level_old1
= *params
[param_f2_level
];
1026 sc_mode_old1
= (CalfScModes
)*params
[param_sc_mode
];
1027 redraw_graph
= true;
1031 void sidechaincompressor_audio_module::set_sample_rate(uint32_t sr
)
1034 compressor
.set_sample_rate(srate
);
1035 int meter
[] = {param_meter_in
, param_meter_out
, -param_compression
};
1036 int clip
[] = {param_clip_in
, param_clip_out
, -1};
1037 meters
.init(params
, meter
, clip
, 3, srate
);
1040 uint32_t sidechaincompressor_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1042 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
1043 numsamples
+= offset
;
1045 // everything bypassed
1046 while(offset
< numsamples
) {
1047 outs
[0][offset
] = ins
[0][offset
];
1048 outs
[1][offset
] = ins
[1][offset
];
1049 float values
[] = {0, 0, 1};
1050 meters
.process(values
);
1055 uint32_t orig_offset
= offset
;
1056 compressor
.update_curve();
1058 while(offset
< numsamples
) {
1059 // cycle through samples
1062 float inL
= ins
[0][offset
];
1063 float inR
= ins
[1][offset
];
1064 float Lin
= ins
[0][offset
];
1065 float Rin
= ins
[1][offset
];
1067 float in2L
= ins
[2] ? ins
[2][offset
] : 0;
1068 float in2R
= ins
[3] ? ins
[3][offset
] : 0;
1071 inR
*= *params
[param_level_in
];
1072 inL
*= *params
[param_level_in
];
1075 float rightAC
= inR
;
1077 float rightSC
= inR
;
1079 float rightMC
= inR
;
1081 if (*params
[param_sc_route
] > 0.5) {
1084 leftSC
= in2L
* *params
[param_sc_level
];
1085 rightSC
= in2R
* *params
[param_sc_level
];
1090 switch ((CalfScModes
)*params
[param_sc_mode
]) {
1093 compressor
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
1098 case DERUMBLER_WIDE
:
1103 leftSC
= f2L
.process(f1L
.process(leftSC
));
1104 rightSC
= f2R
.process(f1R
.process(rightSC
));
1107 compressor
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
1110 leftSC
= f2L
.process(leftSC
);
1111 rightSC
= f2R
.process(rightSC
);
1114 compressor
.process(leftSC
, rightSC
, &leftSC
, &rightSC
);
1115 leftAC
= f1L
.process(leftAC
);
1116 rightAC
= f1R
.process(rightAC
);
1120 case DERUMBLER_SPLIT
:
1121 leftSC
= f1L
.process(leftSC
);
1122 rightSC
= f1R
.process(rightSC
);
1125 compressor
.process(leftSC
, rightSC
, &leftSC
, &rightSC
);
1126 leftAC
= f2L
.process(leftAC
);
1127 rightAC
= f2R
.process(rightAC
);
1132 leftSC
= f1L
.process(leftSC
);
1133 rightSC
= f1R
.process(rightSC
);
1136 compressor
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
1140 if(*params
[param_sc_listen
] > 0.f
) {
1147 outL
= outL
* *params
[param_mix
] + Lin
* (*params
[param_mix
] * -1 + 1);
1148 outR
= outR
* *params
[param_mix
] + Rin
* (*params
[param_mix
] * -1 + 1);
1152 outs
[0][offset
] = outL
;
1153 outs
[1][offset
] = outR
;
1155 float values
[] = {std::max(inL
, inR
), std::max(outL
, outR
), compressor
.get_comp_level()};
1156 meters
.process(values
);
1160 } // cycle trough samples
1161 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
1167 meters
.fall(numsamples
);
1168 return outputs_mask
;
1170 bool sidechaincompressor_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1172 if (!is_active
or phase
)
1174 if (index
== param_sc_listen
&& !subindex
) {
1175 return ::get_graph(*this, subindex
, data
, points
);
1176 } else if(index
== param_bypass
) {
1177 return compressor
.get_graph(subindex
, data
, points
, context
, mode
);
1182 bool sidechaincompressor_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
1184 if (!is_active
or !phase
)
1186 if (index
== param_bypass
) {
1187 return compressor
.get_dot(subindex
, x
, y
, size
, context
);
1192 bool sidechaincompressor_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
1194 if (!is_active
or phase
)
1196 if (index
== param_bypass
) {
1197 return compressor
.get_gridline(subindex
, pos
, vertical
, legend
, context
);
1199 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
1204 bool sidechaincompressor_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1206 if(index
== param_bypass
)
1207 return compressor
.get_layers(index
, generation
, layers
);
1208 bool redraw
= redraw_graph
|| !generation
;
1209 layers
= 0 | (generation
? 0 : LG_CACHE_GRID
) | (redraw
? LG_CACHE_GRAPH
: 0);
1210 redraw_graph
= false;
1214 /**********************************************************************
1215 * MULTIBAND COMPRESSOR by Markus Schmidt
1216 **********************************************************************/
1218 multibandcompressor_audio_module::multibandcompressor_audio_module()
1226 crossover
.init(2, 4, 44100);
1229 void multibandcompressor_audio_module::activate()
1232 // set all filters and strips
1234 // activate all strips
1235 for (int j
= 0; j
< strips
; j
++) {
1236 strip
[j
].activate();
1241 void multibandcompressor_audio_module::deactivate()
1244 // deactivate all strips
1245 for (int j
= 0; j
< strips
; j
++) {
1246 strip
[j
].deactivate();
1250 void multibandcompressor_audio_module::params_changed()
1252 // determine mute/solo states
1253 solo
[0] = *params
[param_solo0
] > 0.f
? true : false;
1254 solo
[1] = *params
[param_solo1
] > 0.f
? true : false;
1255 solo
[2] = *params
[param_solo2
] > 0.f
? true : false;
1256 solo
[3] = *params
[param_solo3
] > 0.f
? true : false;
1257 no_solo
= (*params
[param_solo0
] > 0.f
||
1258 *params
[param_solo1
] > 0.f
||
1259 *params
[param_solo2
] > 0.f
||
1260 *params
[param_solo3
] > 0.f
) ? false : true;
1263 int m
= *params
[param_mode
];
1265 mode
= *params
[param_mode
];
1268 int p
= (int)*params
[param_notebook
];
1271 redraw
= strips
* 2 + strips
;
1274 int b
= (int)*params
[param_bypass0
] + (int)*params
[param_bypass1
] + (int)*params
[param_bypass2
] + (int)*params
[param_bypass3
];
1276 redraw
= strips
* 2 + strips
;
1280 crossover
.set_mode(mode
+ 1);
1281 crossover
.set_filter(0, *params
[param_freq0
]);
1282 crossover
.set_filter(1, *params
[param_freq1
]);
1283 crossover
.set_filter(2, *params
[param_freq2
]);
1285 // set the params of all strips
1286 strip
[0].set_params(*params
[param_attack0
], *params
[param_release0
], *params
[param_threshold0
], *params
[param_ratio0
], *params
[param_knee0
], *params
[param_makeup0
], *params
[param_detection0
], 1.f
, *params
[param_bypass0
], !(solo
[0] || no_solo
));
1287 strip
[1].set_params(*params
[param_attack1
], *params
[param_release1
], *params
[param_threshold1
], *params
[param_ratio1
], *params
[param_knee1
], *params
[param_makeup1
], *params
[param_detection1
], 1.f
, *params
[param_bypass1
], !(solo
[1] || no_solo
));
1288 strip
[2].set_params(*params
[param_attack2
], *params
[param_release2
], *params
[param_threshold2
], *params
[param_ratio2
], *params
[param_knee2
], *params
[param_makeup2
], *params
[param_detection2
], 1.f
, *params
[param_bypass2
], !(solo
[2] || no_solo
));
1289 strip
[3].set_params(*params
[param_attack3
], *params
[param_release3
], *params
[param_threshold3
], *params
[param_ratio3
], *params
[param_knee3
], *params
[param_makeup3
], *params
[param_detection3
], 1.f
, *params
[param_bypass3
], !(solo
[3] || no_solo
));
1292 void multibandcompressor_audio_module::set_sample_rate(uint32_t sr
)
1295 // set srate of all strips
1296 for (int j
= 0; j
< strips
; j
++) {
1297 strip
[j
].set_sample_rate(srate
);
1299 // set srate of crossover
1300 crossover
.set_sample_rate(srate
);
1301 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
,
1302 param_output0
, -param_compression0
,
1303 param_output1
, -param_compression1
,
1304 param_output2
, -param_compression2
,
1305 param_output3
, -param_compression3
};
1306 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
, -1, -1, -1, -1, -1, -1, -1, -1};
1307 meters
.init(params
, meter
, clip
, 12, srate
);
1310 uint32_t multibandcompressor_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1312 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
1313 numsamples
+= offset
;
1315 for (int i
= 0; i
< strips
; i
++)
1316 strip
[i
].update_curve();
1318 // everything bypassed
1319 while(offset
< numsamples
) {
1320 outs
[0][offset
] = ins
[0][offset
];
1321 outs
[1][offset
] = ins
[1][offset
];
1322 float values
[] = {0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1};
1323 meters
.process(values
);
1327 // process all strips
1328 uint32_t orig_offset
= offset
;
1329 while(offset
< numsamples
) {
1330 // cycle through samples
1331 float inL
= ins
[0][offset
];
1332 float inR
= ins
[1][offset
];
1334 inR
*= *params
[param_level_in
];
1335 inL
*= *params
[param_level_in
];
1336 // process crossover
1339 crossover
.process(xin
);
1343 for (int i
= 0; i
< strips
; i
++) {
1344 // cycle trough strips
1345 if (solo
[i
] || no_solo
) {
1347 float left
= crossover
.get_value(0, i
);
1348 float right
= crossover
.get_value(1, i
);
1349 // process gain reduction
1350 strip
[i
].process(left
, right
);
1355 } // process single strip
1358 outL
*= *params
[param_level_out
];
1359 outR
*= *params
[param_level_out
];
1362 outs
[0][offset
] = outL
;
1363 outs
[1][offset
] = outR
;
1365 float values
[] = {inL
, inR
, outL
, outR
,
1366 *params
[param_bypass0
] > 0.5f
? 0 : strip
[0].get_output_level(), *params
[param_bypass0
] > 0.5f
? 1 : strip
[0].get_comp_level(),
1367 *params
[param_bypass1
] > 0.5f
? 0 : strip
[1].get_output_level(), *params
[param_bypass1
] > 0.5f
? 1 : strip
[1].get_comp_level(),
1368 *params
[param_bypass2
] > 0.5f
? 0 : strip
[2].get_output_level(), *params
[param_bypass2
] > 0.5f
? 1 : strip
[2].get_comp_level(),
1369 *params
[param_bypass3
] > 0.5f
? 0 : strip
[3].get_output_level(), *params
[param_bypass3
] > 0.5f
? 1 : strip
[3].get_comp_level() };
1370 meters
.process(values
);
1374 } // cycle trough samples
1375 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
1376 } // process all strips (no bypass)
1377 meters
.fall(numsamples
);
1378 return outputs_mask
;
1381 const gain_reduction_audio_module
*multibandcompressor_audio_module::get_strip_by_param_index(int index
) const
1383 // let's handle by the corresponding strip
1397 bool multibandcompressor_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1402 redraw
= std::max(0, redraw
- 1);
1404 const gain_reduction_audio_module
*m
= get_strip_by_param_index(index
);
1406 r
= m
->get_graph(subindex
, data
, points
, context
, mode
);
1408 r
= crossover
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
1410 if ((index
== param_solo0
+ 11 * page
and subindex
== 1)
1411 or (index
== param_bypass
and subindex
== page
)) {
1414 if ((subindex
== 1 and index
!= param_bypass
)
1415 or (index
== param_bypass
)) {
1417 and ((index
!= param_bypass
and *params
[index
- 1])
1418 or (index
== param_bypass
and *params
[param_bypass0
+ 11 * subindex
])))
1419 context
->set_source_rgba(0.15, 0.2, 0.0, 0.15);
1421 context
->set_source_rgba(0.15, 0.2, 0.0, 0.5);
1426 bool multibandcompressor_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
1428 const gain_reduction_audio_module
*m
= get_strip_by_param_index(index
);
1430 return m
->get_dot(subindex
, x
, y
, size
, context
);
1434 bool multibandcompressor_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
1436 const gain_reduction_audio_module
*m
= get_strip_by_param_index(index
);
1438 return m
->get_gridline(subindex
, pos
, vertical
, legend
, context
);
1439 if (phase
) return false;
1440 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
1443 bool multibandcompressor_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1446 const gain_reduction_audio_module
*m
= get_strip_by_param_index(index
);
1448 r
= m
->get_layers(index
, generation
, layers
);
1450 r
= crossover
.get_layers(index
, generation
, layers
);
1453 layers
|= LG_CACHE_GRAPH
;
1460 /**********************************************************************
1461 * MONO COMPRESSOR by Damien Zammit
1462 **********************************************************************/
1464 monocompressor_audio_module::monocompressor_audio_module()
1470 void monocompressor_audio_module::activate()
1473 // set all filters and strips
1474 monocompressor
.activate();
1477 void monocompressor_audio_module::deactivate()
1480 monocompressor
.deactivate();
1483 void monocompressor_audio_module::params_changed()
1485 monocompressor
.set_params(*params
[param_attack
], *params
[param_release
], *params
[param_threshold
], *params
[param_ratio
], *params
[param_knee
], *params
[param_makeup
], *params
[param_bypass
], 0.f
);
1488 void monocompressor_audio_module::set_sample_rate(uint32_t sr
)
1491 monocompressor
.set_sample_rate(srate
);
1492 int meter
[] = {param_meter_in
, param_meter_out
, -param_compression
};
1493 int clip
[] = {param_clip_in
, param_clip_out
, -1};
1494 meters
.init(params
, meter
, clip
, 3, srate
);
1497 uint32_t monocompressor_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1499 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
1500 numsamples
+= offset
;
1502 // everything bypassed
1503 while(offset
< numsamples
) {
1504 outs
[0][offset
] = ins
[0][offset
];
1505 float values
[] = {0, 0, 1};
1506 meters
.process(values
);
1511 uint32_t orig_offset
= offset
;
1512 monocompressor
.update_curve();
1514 while(offset
< numsamples
) {
1515 // cycle through samples
1518 float inL
= ins
[0][offset
];
1519 //float inR = ins[1][offset];
1520 float Lin
= ins
[0][offset
];
1521 //float Rin = ins[1][offset];
1524 //inR *= *params[param_level_in];
1525 inL
*= *params
[param_level_in
];
1528 //float rightAC = inR;
1530 monocompressor
.process(leftAC
);
1536 outL
= outL
* *params
[param_mix
] + Lin
* (*params
[param_mix
] * -1 + 1);
1537 //outR = outR * *params[param_mix] + Rin * (*params[param_mix] * -1 + 1);
1540 outs
[0][offset
] = outL
;
1541 //outs[1][offset] = 0.f;
1543 float values
[] = {inL
, outL
, monocompressor
.get_comp_level()};
1544 meters
.process(values
);
1548 } // cycle trough samples
1549 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
1551 meters
.fall(numsamples
);
1552 return outputs_mask
;
1554 bool monocompressor_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1556 return monocompressor
.get_graph(subindex
, data
, points
, context
, mode
);
1559 bool monocompressor_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
1561 return monocompressor
.get_dot(subindex
, x
, y
, size
, context
);
1564 bool monocompressor_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
1566 return monocompressor
.get_gridline(subindex
, pos
, vertical
, legend
, context
);
1569 bool monocompressor_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1571 return monocompressor
.get_layers(index
, generation
, layers
);
1574 /**********************************************************************
1575 * DEESSER by Markus Schmidt
1576 **********************************************************************/
1578 deesser_audio_module::deesser_audio_module()
1584 f1_level_old1
= 0.f
;
1585 f2_level_old1
= 0.f
;
1593 redraw_graph
= true;
1596 void deesser_audio_module::activate()
1599 // set all filters and strips
1600 compressor
.activate();
1605 void deesser_audio_module::deactivate()
1608 compressor
.deactivate();
1611 void deesser_audio_module::params_changed()
1613 // set the params of all filters
1614 if(*params
[param_f1_freq
] != f1_freq_old
or *params
[param_f1_level
] != f1_level_old
1615 or *params
[param_f2_freq
] != f2_freq_old
or *params
[param_f2_level
] != f2_level_old
1616 or *params
[param_f2_q
] != f2_q_old
) {
1619 hpL
.set_hp_rbj((float)*params
[param_f1_freq
] * (1 - 0.17), q
, (float)srate
, *params
[param_f1_level
]);
1620 hpR
.copy_coeffs(hpL
);
1621 lpL
.set_lp_rbj((float)*params
[param_f1_freq
] * (1 + 0.17), q
, (float)srate
);
1622 lpR
.copy_coeffs(lpL
);
1623 pL
.set_peakeq_rbj((float)*params
[param_f2_freq
], *params
[param_f2_q
], *params
[param_f2_level
], (float)srate
);
1625 f1_freq_old
= *params
[param_f1_freq
];
1626 f1_level_old
= *params
[param_f1_level
];
1627 f2_freq_old
= *params
[param_f2_freq
];
1628 f2_level_old
= *params
[param_f2_level
];
1629 f2_q_old
= *params
[param_f2_q
];
1631 // and set the compressor module
1632 compressor
.set_params((float)*params
[param_laxity
], (float)*params
[param_laxity
] * 1.33, *params
[param_threshold
], *params
[param_ratio
], 2.8, *params
[param_makeup
], *params
[param_detection
], 0.f
, *params
[param_bypass
], 0.f
);
1633 if (*params
[param_f1_freq
] != f1_freq_old1
1634 or *params
[param_f2_freq
] != f2_freq_old1
1635 or *params
[param_f1_level
] != f1_level_old1
1636 or *params
[param_f2_level
] != f2_level_old1
1637 or *params
[param_f2_q
] !=f2_q_old1
)
1639 f1_freq_old1
= *params
[param_f1_freq
];
1640 f2_freq_old1
= *params
[param_f2_freq
];
1641 f1_level_old1
= *params
[param_f1_level
];
1642 f2_level_old1
= *params
[param_f2_level
];
1643 f2_q_old1
= *params
[param_f2_q
];
1644 redraw_graph
= true;
1648 void deesser_audio_module::set_sample_rate(uint32_t sr
)
1651 compressor
.set_sample_rate(srate
);
1652 int meter
[] = {param_detected
, -param_compression
};
1653 int clip
[] = {param_clip_out
, -1};
1654 meters
.init(params
, meter
, clip
, 2, srate
);
1657 uint32_t deesser_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1659 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
1660 numsamples
+= offset
;
1662 // everything bypassed81e8da266
1663 while(offset
< numsamples
) {
1664 outs
[0][offset
] = ins
[0][offset
];
1665 outs
[1][offset
] = ins
[1][offset
];
1666 float values
[] = {0, 1};
1667 meters
.process(values
);
1672 uint32_t orig_offset
= offset
;
1673 detected_led
-= std::min(detected_led
, numsamples
);
1674 compressor
.update_curve();
1676 while(offset
< numsamples
) {
1677 // cycle through samples
1680 float inL
= ins
[0][offset
];
1681 float inR
= ins
[1][offset
];
1685 float rightAC
= inR
;
1687 float rightSC
= inR
;
1689 float rightRC
= inR
;
1691 float rightMC
= inR
;
1693 leftSC
= pL
.process(hpL
.process(leftSC
));
1694 rightSC
= pR
.process(hpR
.process(rightSC
));
1698 switch ((int)*params
[param_mode
]) {
1701 compressor
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
1706 leftRC
= hpL
.process(leftRC
);
1707 rightRC
= hpR
.process(rightRC
);
1708 compressor
.process(leftRC
, rightRC
, &leftSC
, &rightSC
);
1709 leftAC
= lpL
.process(leftAC
);
1710 rightAC
= lpR
.process(rightAC
);
1716 if(*params
[param_sc_listen
] > 0.f
) {
1725 outs
[0][offset
] = outL
;
1726 outs
[1][offset
] = outR
;
1728 if(std::max(fabs(leftSC
), fabs(rightSC
)) > *params
[param_threshold
]) {
1729 detected_led
= srate
>> 3;
1731 detected
= std::max(fabs(leftMC
), fabs(rightMC
));
1733 float values
[] = {detected
, compressor
.get_comp_level()};
1734 meters
.process(values
);
1738 } // cycle trough samples
1739 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
1748 if(params
[param_detected_led
] != NULL
) {
1749 *params
[param_detected_led
] = detected_led
;
1751 meters
.fall(numsamples
);
1752 return outputs_mask
;
1756 /**********************************************************************
1757 * GATE AUDIO MODULE Damien Zammit
1758 **********************************************************************/
1760 gate_audio_module::gate_audio_module()
1766 void gate_audio_module::activate()
1769 // set all filters and strips
1773 void gate_audio_module::deactivate()
1779 void gate_audio_module::params_changed()
1781 gate
.set_params(*params
[param_attack
], *params
[param_release
], *params
[param_threshold
], *params
[param_ratio
], *params
[param_knee
], *params
[param_makeup
], *params
[param_detection
], *params
[param_stereo_link
], *params
[param_bypass
], 0.f
, *params
[param_range
]);
1784 void gate_audio_module::set_sample_rate(uint32_t sr
)
1787 gate
.set_sample_rate(srate
);
1788 int meter
[] = {param_meter_in
, param_meter_out
, -param_gating
};
1789 int clip
[] = {param_clip_in
, param_clip_out
, -1};
1790 meters
.init(params
, meter
, clip
, 3, srate
);
1793 uint32_t gate_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1795 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
1796 numsamples
+= offset
;
1798 // everything bypassed
1799 while(offset
< numsamples
) {
1800 outs
[0][offset
] = ins
[0][offset
];
1801 outs
[1][offset
] = ins
[1][offset
];
1802 float values
[] = {0, 0, 1};
1803 meters
.process(values
);
1808 gate
.update_curve();
1809 uint32_t orig_offset
= offset
;
1810 while(offset
< numsamples
) {
1811 // cycle through samples
1814 float inL
= ins
[0][offset
];
1815 float inR
= ins
[1][offset
];
1817 inR
*= *params
[param_level_in
];
1818 inL
*= *params
[param_level_in
];
1821 float rightAC
= inR
;
1823 gate
.process(leftAC
, rightAC
);
1829 outs
[0][offset
] = outL
;
1830 outs
[1][offset
] = outR
;
1832 float values
[] = {std::max(inL
, inR
), std::max(outL
, outR
), gate
.get_expander_level()};
1833 meters
.process(values
);
1837 } // cycle trough samples
1838 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
1840 meters
.fall(numsamples
);
1841 return outputs_mask
;
1843 bool gate_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1845 return gate
.get_graph(subindex
, data
, points
, context
, mode
);
1848 bool gate_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
1850 return gate
.get_dot(subindex
, x
, y
, size
, context
);
1853 bool gate_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
1855 return gate
.get_gridline(subindex
, pos
, vertical
, legend
, context
);
1858 bool gate_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1860 return gate
.get_layers(index
, generation
, layers
);
1863 /**********************************************************************
1864 * SIDECHAIN GATE by Markus Schmidt
1865 **********************************************************************/
1867 sidechaingate_audio_module::sidechaingate_audio_module()
1871 redraw_graph
= true;
1872 f1_freq_old
= f2_freq_old
= f1_level_old
= f2_level_old
= 0;
1873 f1_freq_old1
= f2_freq_old1
= f1_level_old1
= f2_level_old1
= 0;
1874 sc_mode_old
= sc_mode_old1
= WIDEBAND
; // doesn't matter as long as it's sane
1877 void sidechaingate_audio_module::activate()
1880 // set all filters and strips
1884 void sidechaingate_audio_module::deactivate()
1890 sidechaingate_audio_module::cfloat
sidechaingate_audio_module::h_z(const cfloat
&z
) const
1892 switch ((CalfScModes
)sc_mode
) {
1903 return f1L
.h_z(z
) * f2L
.h_z(z
);
1905 case HIGHGATE_SPLIT
:
1915 float sidechaingate_audio_module::freq_gain(int index
, double freq
) const
1917 typedef std::complex<double> cfloat
;
1918 freq
*= 2.0 * M_PI
/ srate
;
1919 cfloat z
= 1.0 / exp(cfloat(0.0, freq
));
1921 return std::abs(h_z(z
));
1924 void sidechaingate_audio_module::params_changed()
1926 // set the params of all filters
1927 if(*params
[param_f1_freq
] != f1_freq_old
or *params
[param_f1_level
] != f1_level_old
1928 or *params
[param_f2_freq
] != f2_freq_old
or *params
[param_f2_level
] != f2_level_old
1929 or *params
[param_sc_mode
] != sc_mode
) {
1931 switch ((CalfScModes
)*params
[param_sc_mode
]) {
1934 f1L
.set_hp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
1935 f1R
.copy_coeffs(f1L
);
1936 f2L
.set_lp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
1937 f2R
.copy_coeffs(f2L
);
1942 f1L
.set_peakeq_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
1943 f1R
.copy_coeffs(f1L
);
1944 f2L
.set_hp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
1945 f2R
.copy_coeffs(f2L
);
1949 case HIGHGATE_SPLIT
:
1950 f1L
.set_lp_rbj((float)*params
[param_f2_freq
] * (1 + 0.17), q
, (float)srate
);
1951 f1R
.copy_coeffs(f1L
);
1952 f2L
.set_hp_rbj((float)*params
[param_f2_freq
] * (1 - 0.17), q
, (float)srate
, *params
[param_f2_level
]);
1953 f2R
.copy_coeffs(f2L
);
1958 f1L
.set_lp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
1959 f1R
.copy_coeffs(f1L
);
1960 f2L
.set_peakeq_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1961 f2R
.copy_coeffs(f2L
);
1966 f1L
.set_lp_rbj((float)*params
[param_f1_freq
] * (1 + 0.17), q
, (float)srate
, *params
[param_f1_level
]);
1967 f1R
.copy_coeffs(f1L
);
1968 f2L
.set_hp_rbj((float)*params
[param_f1_freq
] * (1 - 0.17), q
, (float)srate
);
1969 f2R
.copy_coeffs(f2L
);
1974 f1L
.set_lowshelf_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
1975 f1R
.copy_coeffs(f1L
);
1976 f2L
.set_highshelf_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1977 f2R
.copy_coeffs(f2L
);
1982 f1L
.set_lowshelf_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
1983 f1R
.copy_coeffs(f1L
);
1984 f2L
.set_peakeq_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1985 f2R
.copy_coeffs(f2L
);
1990 f1L
.set_peakeq_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
1991 f1R
.copy_coeffs(f1L
);
1992 f2L
.set_highshelf_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1993 f2R
.copy_coeffs(f2L
);
1998 f1L
.set_bp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
1999 f1R
.copy_coeffs(f1L
);
2000 f2L
.set_hp_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
2001 f2R
.copy_coeffs(f2L
);
2006 f1L
.set_hp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
2007 f1R
.copy_coeffs(f1L
);
2008 f2L
.set_lp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
2009 f2R
.copy_coeffs(f2L
);
2014 f1_freq_old
= *params
[param_f1_freq
];
2015 f1_level_old
= *params
[param_f1_level
];
2016 f2_freq_old
= *params
[param_f2_freq
];
2017 f2_level_old
= *params
[param_f2_level
];
2018 sc_mode
= (CalfScModes
)*params
[param_sc_mode
];
2021 if(params
[param_f1_active
] != NULL
) {
2022 *params
[param_f1_active
] = f1_active
;
2024 if(params
[param_f2_active
] != NULL
) {
2025 *params
[param_f2_active
] = f2_active
;
2027 // and set the expander module
2028 gate
.set_params(*params
[param_attack
], *params
[param_release
], *params
[param_threshold
], *params
[param_ratio
], *params
[param_knee
], *params
[param_makeup
], *params
[param_detection
], *params
[param_stereo_link
], *params
[param_bypass
], 0.f
, *params
[param_range
]);
2030 if (*params
[param_f1_freq
] != f1_freq_old1
2031 or *params
[param_f2_freq
] != f2_freq_old1
2032 or *params
[param_f1_level
] != f1_level_old1
2033 or *params
[param_f2_level
] != f2_level_old1
2034 or *params
[param_sc_mode
] != sc_mode_old1
)
2036 f1_freq_old1
= *params
[param_f1_freq
];
2037 f2_freq_old1
= *params
[param_f2_freq
];
2038 f1_level_old1
= *params
[param_f1_level
];
2039 f2_level_old1
= *params
[param_f2_level
];
2040 sc_mode_old1
= (CalfScModes
)*params
[param_sc_mode
];
2041 redraw_graph
= true;
2045 void sidechaingate_audio_module::set_sample_rate(uint32_t sr
)
2048 gate
.set_sample_rate(srate
);
2049 int meter
[] = {param_meter_in
, param_meter_out
, -param_gating
};
2050 int clip
[] = {param_clip_in
, param_clip_out
, -1};
2051 meters
.init(params
, meter
, clip
, 3, srate
);
2054 uint32_t sidechaingate_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
2056 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
2057 numsamples
+= offset
;
2059 // everything bypassed
2060 while(offset
< numsamples
) {
2061 outs
[0][offset
] = ins
[0][offset
];
2062 outs
[1][offset
] = ins
[1][offset
];
2063 float values
[] = {0, 0, 1};
2064 meters
.process(values
);
2069 uint32_t orig_offset
= offset
;
2070 gate
.update_curve();
2072 while(offset
< numsamples
) {
2073 // cycle through samples
2076 float inL
= ins
[0][offset
];
2077 float inR
= ins
[1][offset
];
2079 float in2L
= ins
[2] ? ins
[2][offset
] : 0;
2080 float in2R
= ins
[3] ? ins
[3][offset
] : 0;
2083 inR
*= *params
[param_level_in
];
2084 inL
*= *params
[param_level_in
];
2087 float rightAC
= inR
;
2089 float rightSC
= inR
;
2091 float rightMC
= inR
;
2093 if (*params
[param_sc_route
] > 0.5) {
2096 leftSC
= in2L
* *params
[param_sc_level
];
2097 rightSC
= in2R
* *params
[param_sc_level
];
2102 switch ((CalfScModes
)*params
[param_sc_mode
]) {
2105 gate
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
2115 leftSC
= f2L
.process(f1L
.process(leftSC
));
2116 rightSC
= f2R
.process(f1R
.process(rightSC
));
2119 gate
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
2121 case HIGHGATE_SPLIT
:
2122 leftSC
= f2L
.process(leftSC
);
2123 rightSC
= f2R
.process(rightSC
);
2126 gate
.process(leftSC
, rightSC
, &leftSC
, &rightSC
);
2127 leftAC
= f1L
.process(leftAC
);
2128 rightAC
= f1R
.process(rightAC
);
2133 leftSC
= f1L
.process(leftSC
);
2134 rightSC
= f1R
.process(rightSC
);
2137 gate
.process(leftSC
, rightSC
, &leftSC
, &rightSC
);
2138 leftAC
= f2L
.process(leftAC
);
2139 rightAC
= f2R
.process(rightAC
);
2144 leftSC
= f1L
.process(leftSC
);
2145 rightSC
= f1R
.process(rightSC
);
2148 gate
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
2152 if(*params
[param_sc_listen
] > 0.f
) {
2161 outs
[0][offset
] = outL
;
2162 outs
[1][offset
] = outR
;
2164 float values
[] = {std::max(inL
, inR
), std::max(outL
, outR
), gate
.get_expander_level()};
2165 meters
.process(values
);
2169 } // cycle trough samples
2170 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
2177 meters
.fall(numsamples
);
2178 return outputs_mask
;
2180 bool sidechaingate_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
2182 if (!is_active
or phase
)
2184 if (index
== param_sc_listen
&& !subindex
) {
2185 return ::get_graph(*this, subindex
, data
, points
);
2186 } else if(index
== param_bypass
) {
2187 return gate
.get_graph(subindex
, data
, points
, context
, mode
);
2192 bool sidechaingate_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
2194 if (!is_active
or !phase
)
2196 if (index
== param_bypass
) {
2197 return gate
.get_dot(subindex
, x
, y
, size
, context
);
2202 bool sidechaingate_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
2204 if (!is_active
or phase
)
2206 if (index
== param_bypass
) {
2207 return gate
.get_gridline(subindex
, pos
, vertical
, legend
, context
);
2209 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
2213 bool sidechaingate_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
2215 if(index
== param_bypass
)
2216 return gate
.get_layers(index
, generation
, layers
);
2217 bool redraw
= redraw_graph
|| !generation
;
2218 layers
= 0 | (generation
? 0 : LG_CACHE_GRID
) | (redraw
? LG_CACHE_GRAPH
: 0);
2219 redraw_graph
= false;
2224 /**********************************************************************
2225 * MULTIBAND GATE by Markus Schmidt
2226 **********************************************************************/
2228 multibandgate_audio_module::multibandgate_audio_module()
2236 crossover
.init(2, 4, 44100);
2239 void multibandgate_audio_module::activate()
2242 // set all filters and strips
2244 // activate all strips
2245 for (int j
= 0; j
< strips
; j
++) {
2251 void multibandgate_audio_module::deactivate()
2254 // deactivate all strips
2255 for (int j
= 0; j
< strips
; j
++) {
2256 gate
[j
].deactivate();
2260 void multibandgate_audio_module::params_changed()
2262 // determine mute/solo states
2263 solo
[0] = *params
[param_solo0
] > 0.f
? true : false;
2264 solo
[1] = *params
[param_solo1
] > 0.f
? true : false;
2265 solo
[2] = *params
[param_solo2
] > 0.f
? true : false;
2266 solo
[3] = *params
[param_solo3
] > 0.f
? true : false;
2267 no_solo
= (*params
[param_solo0
] > 0.f
||
2268 *params
[param_solo1
] > 0.f
||
2269 *params
[param_solo2
] > 0.f
||
2270 *params
[param_solo3
] > 0.f
) ? false : true;
2272 int m
= *params
[param_mode
];
2274 mode
= *params
[param_mode
];
2277 int p
= (int)*params
[param_notebook
];
2280 redraw
= strips
* 2 + strips
;
2283 int b
= (int)*params
[param_bypass0
] + (int)*params
[param_bypass1
] + (int)*params
[param_bypass2
] + (int)*params
[param_bypass3
];
2285 redraw
= strips
* 2 + strips
;
2289 crossover
.set_mode(mode
+ 1);
2290 crossover
.set_filter(0, *params
[param_freq0
]);
2291 crossover
.set_filter(1, *params
[param_freq1
]);
2292 crossover
.set_filter(2, *params
[param_freq2
]);
2294 // set the params of all strips
2295 gate
[0].set_params(*params
[param_attack0
], *params
[param_release0
], *params
[param_threshold0
], *params
[param_ratio0
], *params
[param_knee0
], *params
[param_makeup0
], *params
[param_detection0
], 1.f
, *params
[param_bypass0
], !(solo
[0] || no_solo
), *params
[param_range0
]);
2296 gate
[1].set_params(*params
[param_attack1
], *params
[param_release1
], *params
[param_threshold1
], *params
[param_ratio1
], *params
[param_knee1
], *params
[param_makeup1
], *params
[param_detection1
], 1.f
, *params
[param_bypass1
], !(solo
[1] || no_solo
), *params
[param_range1
]);
2297 gate
[2].set_params(*params
[param_attack2
], *params
[param_release2
], *params
[param_threshold2
], *params
[param_ratio2
], *params
[param_knee2
], *params
[param_makeup2
], *params
[param_detection2
], 1.f
, *params
[param_bypass2
], !(solo
[2] || no_solo
), *params
[param_range2
]);
2298 gate
[3].set_params(*params
[param_attack3
], *params
[param_release3
], *params
[param_threshold3
], *params
[param_ratio3
], *params
[param_knee3
], *params
[param_makeup3
], *params
[param_detection3
], 1.f
, *params
[param_bypass3
], !(solo
[3] || no_solo
), *params
[param_range3
]);
2301 void multibandgate_audio_module::set_sample_rate(uint32_t sr
)
2304 // set srate of all strips
2305 for (int j
= 0; j
< strips
; j
++) {
2306 gate
[j
].set_sample_rate(srate
);
2308 // set srate of crossover
2309 crossover
.set_sample_rate(srate
);
2310 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
,
2311 param_output0
, -param_gating0
,
2312 param_output1
, -param_gating1
,
2313 param_output2
, -param_gating2
,
2314 param_output3
, -param_gating3
};
2315 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
, -1, -1, -1, -1, -1, -1, -1, -1};
2316 meters
.init(params
, meter
, clip
, 12, srate
);
2319 uint32_t multibandgate_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
2321 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
2322 numsamples
+= offset
;
2323 for (int i
= 0; i
< strips
; i
++)
2324 gate
[i
].update_curve();
2326 // everything bypassed
2327 while(offset
< numsamples
) {
2328 outs
[0][offset
] = ins
[0][offset
];
2329 outs
[1][offset
] = ins
[1][offset
];
2330 float values
[] = {0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1};
2331 meters
.process(values
);
2335 // process all strips
2336 uint32_t orig_offset
= offset
;
2337 while(offset
< numsamples
) {
2338 // cycle through samples
2339 float inL
= ins
[0][offset
];
2340 float inR
= ins
[1][offset
];
2342 inR
*= *params
[param_level_in
];
2343 inL
*= *params
[param_level_in
];
2344 // process crossover
2347 crossover
.process(xin
);
2351 for (int i
= 0; i
< strips
; i
++) {
2352 // cycle trough strips
2353 if (solo
[i
] || no_solo
) {
2355 float left
= crossover
.get_value(0, i
);
2356 float right
= crossover
.get_value(1, i
);
2357 gate
[i
].process(left
, right
);
2362 } // process single strip
2365 outL
*= *params
[param_level_out
];
2366 outR
*= *params
[param_level_out
];
2369 outs
[0][offset
] = outL
;
2370 outs
[1][offset
] = outR
;
2372 float values
[] = {inL
, inR
, outL
, outR
,
2373 *params
[param_bypass0
] > 0.5f
? 0 : gate
[0].get_output_level(), *params
[param_bypass0
] > 0.5f
? 1 : gate
[0].get_expander_level(),
2374 *params
[param_bypass1
] > 0.5f
? 0 : gate
[1].get_output_level(), *params
[param_bypass1
] > 0.5f
? 1 : gate
[1].get_expander_level(),
2375 *params
[param_bypass2
] > 0.5f
? 0 : gate
[2].get_output_level(), *params
[param_bypass2
] > 0.5f
? 1 : gate
[2].get_expander_level(),
2376 *params
[param_bypass3
] > 0.5f
? 0 : gate
[3].get_output_level(), *params
[param_bypass3
] > 0.5f
? 1 : gate
[3].get_expander_level() };
2377 meters
.process(values
);
2381 } // cycle trough samples
2382 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
2384 } // process all strips (no bypass)
2385 meters
.fall(numsamples
);
2386 return outputs_mask
;
2389 const expander_audio_module
*multibandgate_audio_module::get_strip_by_param_index(int index
) const
2391 // let's handle by the corresponding strip
2405 bool multibandgate_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
2409 redraw
= std::max(0, redraw
- 1);
2411 const expander_audio_module
*m
= get_strip_by_param_index(index
);
2413 r
= m
->get_graph(subindex
, data
, points
, context
, mode
);
2415 r
= crossover
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
2417 if ((index
== param_solo0
+ 12 * page
and subindex
== 1)
2418 or (index
== param_bypass
and subindex
== page
)) {
2421 if ((subindex
== 1 and index
!= param_bypass
)
2422 or (index
== param_bypass
)) {
2424 and ((index
!= param_bypass
and *params
[index
- 1])
2425 or (index
== param_bypass
and *params
[param_bypass0
+ 12 * subindex
])))
2426 context
->set_source_rgba(0.15, 0.2, 0.0, 0.15);
2428 context
->set_source_rgba(0.15, 0.2, 0.0, 0.5);
2433 bool multibandgate_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
2435 const expander_audio_module
*m
= get_strip_by_param_index(index
);
2437 return m
->get_dot(subindex
, x
, y
, size
, context
);
2441 bool multibandgate_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
2443 const expander_audio_module
*m
= get_strip_by_param_index(index
);
2445 return m
->get_gridline(subindex
, pos
, vertical
, legend
, context
);
2446 if (phase
) return false;
2447 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
2450 bool multibandgate_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
2453 const expander_audio_module
*m
= get_strip_by_param_index(index
);
2455 r
= m
->get_layers(index
, generation
, layers
);
2457 r
= crossover
.get_layers(index
, generation
, layers
);
2460 layers
|= LG_CACHE_GRAPH
;
2467 /**********************************************************************
2468 * TRANSIENT DESIGNER by Christian Holschuh and Markus Schmidt
2469 **********************************************************************/
2472 transientdesigner_audio_module::transientdesigner_audio_module() {
2482 pbuffer_available
= false;
2484 display_max
= pow(2,-12);
2485 transients
.set_channels(channels
);
2487 transientdesigner_audio_module::~transientdesigner_audio_module()
2491 void transientdesigner_audio_module::activate() {
2495 void transientdesigner_audio_module::deactivate() {
2499 void transientdesigner_audio_module::params_changed() {
2500 if (*params
[param_display
] != display_old
) {
2501 dsp::zero(pbuffer
, (int)(pixels
* 2));
2502 display_old
= *params
[param_display
];
2504 transients
.set_params(*params
[param_attack_time
],
2505 *params
[param_attack_boost
],
2506 *params
[param_release_time
],
2507 *params
[param_release_boost
],
2508 *params
[param_sustain_threshold
],
2509 *params
[param_lookahead
],
2510 *params
[param_mix
]);
2513 uint32_t transientdesigner_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
) {
2514 uint32_t orig_offset
= offset
;
2515 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
2516 for(uint32_t i
= offset
; i
< offset
+ numsamples
; i
++) {
2517 float L
= ins
[0][i
];
2518 float R
= ins
[1][i
];
2523 float s
= (fabs(L
) + fabs(R
)) / 2;
2525 outs
[0][i
] = ins
[0][i
];
2526 outs
[1][i
] = ins
[1][i
];
2530 L
*= *params
[param_level_in
];
2531 R
*= *params
[param_level_in
];
2537 // transient designer
2538 float values
[] = {L
, R
};
2539 transients
.process(values
);
2544 L
*= *params
[param_level_out
];
2545 R
*= *params
[param_level_out
];
2554 // fill pixel buffer
2555 if (pbuffer_available
) {
2556 // sanitize the buffer position if enough samples have
2557 // been captured. This is recognized by a negative value
2558 for (int i
= 0; i
< 5; i
++) {
2559 pbuffer
[pbuffer_pos
+ i
] = std::max(pbuffer
[pbuffer_pos
+ i
], 0.f
);
2562 // add samples to the buffer at the actual address
2563 pbuffer
[pbuffer_pos
] = std::max(s
, pbuffer
[pbuffer_pos
]);
2564 pbuffer
[pbuffer_pos
+ 1] = std::max((float)(fabs(L
) + fabs(R
)), (float)pbuffer
[pbuffer_pos
+ 1]);
2565 pbuffer
[pbuffer_pos
+ 2] = transients
.envelope
;
2566 pbuffer
[pbuffer_pos
+ 3] = transients
.attack
;
2567 pbuffer
[pbuffer_pos
+ 4] = transients
.release
;
2569 pbuffer_sample
+= 1;
2571 if (pbuffer_sample
>= (int)(srate
* *params
[param_display
] / 1000.f
/ pixels
)) {
2572 // we captured enough samples for one pixel on this
2573 // address. to keep track of the finalization invert
2574 // its values as a marker to sanitize in the next
2575 // cycle before adding samples again
2576 pbuffer
[pbuffer_pos
] *= -1.f
* *params
[param_level_in
];
2577 pbuffer
[pbuffer_pos
+ 1] /= -2.f
;
2579 // advance the buffer position
2580 pbuffer_pos
= (pbuffer_pos
+ 5) % pbuffer_size
;
2582 // reset sample counter
2588 if ( transients
.envelope
== transients
.release
2589 and transients
.envelope
> *params
[param_display_threshold
]
2590 and attcount
>= srate
/ 100
2591 and pbuffer_available
) {
2592 int diff
= (int)(srate
/ 10 / pixels
);
2594 attack_pos
= (pbuffer_pos
- diff
+ pbuffer_size
) % pbuffer_size
;
2597 float values
[] = {meter_inL
, meter_inR
, meter_outL
, meter_outR
};
2598 meters
.process(values
);
2601 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
2602 meters
.fall(numsamples
);
2603 return outputs_mask
;
2606 void transientdesigner_audio_module::set_sample_rate(uint32_t sr
)
2609 attcount
= srate
/ 5;
2610 transients
.set_sample_rate(srate
);
2611 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
};
2612 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
};
2613 meters
.init(params
, meter
, clip
, 4, srate
);
2615 bool transientdesigner_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
2619 if (points
!= pixels
) {
2620 // the zoom level changed or it's the first time we want to draw
2623 // buffer size is the amount of pixels for the max display value
2624 // if drawn in the min display zoom level multiplied by 5 for
2625 // keeping the input and the output fabs signals and all graphs
2627 pbuffer_size
= (int)(points
* 5.f
* 100.f
);
2629 pbuffer
= (float*) calloc(pbuffer_size
, sizeof(float));
2631 // sanitize some indexes and addresses
2635 pbuffer_available
= true;
2638 // check if threshold is above minimum - we want to see trigger hold
2639 bool hold
= *params
[param_display_threshold
] > display_max
;
2640 // set the address to start from in both drawing cycles
2641 // to amount of pixels before pbuffer_pos or to attack_pos
2642 if (subindex
== 0) {
2643 int pos
= hold
? attack_pos
: pbuffer_pos
;
2644 pbuffer_draw
= *params
[param_display_threshold
] > display_max
? pos
2645 : (pbuffer_size
+ pos
- pixels
* 5) % pbuffer_size
;
2648 // get outa here if max graph is reached
2649 if (last_drawn
>= 5) {
2654 // get the next graph to draw leaving out inactive
2655 while (last_drawn
< 5 and !*params
[param_input
+ last_drawn
] > 0.5)
2658 // get outa here if max graph is reached
2659 if (last_drawn
>= 5) {
2664 // input is drawn as bars with less opacity
2666 context
->set_source_rgba(0.15, 0.2, 0.0, 0.2);
2667 } else if (last_drawn
== 1) {
2668 // output is a precise line
2669 context
->set_line_width(0.75);
2671 // envelope, attack and release are dotted
2672 set_channel_dash(context
, last_drawn
- 2);
2673 context
->set_line_width(1);
2677 for (int i
= 0; i
<= points
; i
++) {
2678 int pos
= (pbuffer_draw
+ i
* 5) % pbuffer_size
+ last_drawn
;
2680 and ((pos
> pbuffer_pos
and ((pbuffer_pos
> attack_pos
and pos
> attack_pos
)
2681 or (pbuffer_pos
< attack_pos
and pos
< attack_pos
)))
2682 or (pbuffer_pos
> attack_pos
and pos
< attack_pos
))) {
2683 // we are drawing trigger hold stuff outside the hold window
2684 // so we don't want to see old data - zero it out.
2685 data
[i
] = dB_grid(2.51e-10, 128, 0.6);
2688 data
[i
] = dB_grid(fabs(pbuffer
[pos
]) + 2.51e-10, 128, 0.6);
2694 bool transientdesigner_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
2696 if (subindex
>= 16 or phase
)
2698 float gain
= 16.f
/ (1 << subindex
);
2699 pos
= dB_grid(gain
, 128, 0.6);
2700 context
->set_source_rgba(0, 0, 0, subindex
& 1 ? 0.1 : 0.2);
2701 if (!(subindex
& 1) and subindex
) {
2702 std::stringstream ss
;
2703 ss
<< (24 - 6 * subindex
) << " dB";
2709 bool transientdesigner_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
2711 layers
= LG_REALTIME_GRAPH
| (generation
? 0 : LG_CACHE_GRID
);