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 bypass
= *params
[param_bypass
] > 0.5f
;
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
);
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
819 meters
.fall(numsamples
);
822 bool compressor_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
824 return compressor
.get_graph(subindex
, data
, points
, context
, mode
);
827 bool compressor_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
829 return compressor
.get_dot(subindex
, x
, y
, size
, context
);
832 bool compressor_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
834 return compressor
.get_gridline(subindex
, pos
, vertical
, legend
, context
);
837 bool compressor_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
839 return compressor
.get_layers(index
, generation
, layers
);
842 /**********************************************************************
843 * SIDECHAIN COMPRESSOR by Markus Schmidt
844 **********************************************************************/
846 sidechaincompressor_audio_module::sidechaincompressor_audio_module()
858 sc_mode_old1
= WIDEBAND
;
862 void sidechaincompressor_audio_module::activate()
865 // set all filters and strips
866 compressor
.activate();
869 void sidechaincompressor_audio_module::deactivate()
872 compressor
.deactivate();
875 sidechaincompressor_audio_module::cfloat
sidechaincompressor_audio_module::h_z(const cfloat
&z
) const
877 switch ((CalfScModes
)sc_mode
) {
888 return f1L
.h_z(z
) * f2L
.h_z(z
);
893 case DERUMBLER_SPLIT
:
900 float sidechaincompressor_audio_module::freq_gain(int index
, double freq
) const
902 typedef std::complex<double> cfloat
;
903 freq
*= 2.0 * M_PI
/ srate
;
904 cfloat z
= 1.0 / exp(cfloat(0.0, freq
));
906 return std::abs(h_z(z
));
909 void sidechaincompressor_audio_module::params_changed()
911 // set the params of all filters
912 if(*params
[param_f1_freq
] != f1_freq_old
or *params
[param_f1_level
] != f1_level_old
913 or *params
[param_f2_freq
] != f2_freq_old
or *params
[param_f2_level
] != f2_level_old
914 or *params
[param_sc_mode
] != sc_mode
) {
916 switch ((CalfScModes
)*params
[param_sc_mode
]) {
919 f1L
.set_hp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
920 f1R
.copy_coeffs(f1L
);
921 f2L
.set_lp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
922 f2R
.copy_coeffs(f2L
);
927 f1L
.set_peakeq_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
928 f1R
.copy_coeffs(f1L
);
929 f2L
.set_hp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
930 f2R
.copy_coeffs(f2L
);
935 f1L
.set_lp_rbj((float)*params
[param_f2_freq
] * (1 + 0.17), q
, (float)srate
);
936 f1R
.copy_coeffs(f1L
);
937 f2L
.set_hp_rbj((float)*params
[param_f2_freq
] * (1 - 0.17), q
, (float)srate
, *params
[param_f2_level
]);
938 f2R
.copy_coeffs(f2L
);
943 f1L
.set_lp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
944 f1R
.copy_coeffs(f1L
);
945 f2L
.set_peakeq_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
946 f2R
.copy_coeffs(f2L
);
950 case DERUMBLER_SPLIT
:
951 f1L
.set_lp_rbj((float)*params
[param_f1_freq
] * (1 + 0.17), q
, (float)srate
, *params
[param_f1_level
]);
952 f1R
.copy_coeffs(f1L
);
953 f2L
.set_hp_rbj((float)*params
[param_f1_freq
] * (1 - 0.17), q
, (float)srate
);
954 f2R
.copy_coeffs(f2L
);
959 f1L
.set_lowshelf_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
960 f1R
.copy_coeffs(f1L
);
961 f2L
.set_highshelf_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
962 f2R
.copy_coeffs(f2L
);
967 f1L
.set_lowshelf_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
968 f1R
.copy_coeffs(f1L
);
969 f2L
.set_peakeq_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
970 f2R
.copy_coeffs(f2L
);
975 f1L
.set_peakeq_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
976 f1R
.copy_coeffs(f1L
);
977 f2L
.set_highshelf_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
978 f2R
.copy_coeffs(f2L
);
983 f1L
.set_bp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
984 f1R
.copy_coeffs(f1L
);
985 f2L
.set_hp_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
986 f2R
.copy_coeffs(f2L
);
991 f1L
.set_hp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
992 f1R
.copy_coeffs(f1L
);
993 f2L
.set_lp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
994 f2R
.copy_coeffs(f2L
);
999 f1_freq_old
= *params
[param_f1_freq
];
1000 f1_level_old
= *params
[param_f1_level
];
1001 f2_freq_old
= *params
[param_f2_freq
];
1002 f2_level_old
= *params
[param_f2_level
];
1003 sc_mode
= (CalfScModes
)*params
[param_sc_mode
];
1006 if(params
[param_f1_active
] != NULL
) {
1007 *params
[param_f1_active
] = f1_active
;
1009 if(params
[param_f2_active
] != NULL
) {
1010 *params
[param_f2_active
] = f2_active
;
1012 // and set the compressor module
1013 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
);
1015 if (*params
[param_f1_freq
] != f1_freq_old1
1016 or *params
[param_f2_freq
] != f2_freq_old1
1017 or *params
[param_f1_level
] != f1_level_old1
1018 or *params
[param_f2_level
] != f2_level_old1
1019 or *params
[param_sc_mode
] != sc_mode_old1
)
1021 f1_freq_old1
= *params
[param_f1_freq
];
1022 f2_freq_old1
= *params
[param_f2_freq
];
1023 f1_level_old1
= *params
[param_f1_level
];
1024 f2_level_old1
= *params
[param_f2_level
];
1025 sc_mode_old1
= (CalfScModes
)*params
[param_sc_mode
];
1026 redraw_graph
= true;
1030 void sidechaincompressor_audio_module::set_sample_rate(uint32_t sr
)
1033 compressor
.set_sample_rate(srate
);
1034 int meter
[] = {param_meter_in
, param_meter_out
, -param_compression
};
1035 int clip
[] = {param_clip_in
, param_clip_out
, -1};
1036 meters
.init(params
, meter
, clip
, 3, srate
);
1039 uint32_t sidechaincompressor_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1041 bool bypass
= *params
[param_bypass
] > 0.5f
;
1042 numsamples
+= offset
;
1044 // everything bypassed
1045 while(offset
< numsamples
) {
1046 outs
[0][offset
] = ins
[0][offset
];
1047 outs
[1][offset
] = ins
[1][offset
];
1048 float values
[] = {0, 0, 1};
1049 meters
.process(values
);
1055 compressor
.update_curve();
1057 while(offset
< numsamples
) {
1058 // cycle through samples
1061 float inL
= ins
[0][offset
];
1062 float inR
= ins
[1][offset
];
1063 float Lin
= ins
[0][offset
];
1064 float Rin
= ins
[1][offset
];
1066 float in2L
= ins
[2] ? ins
[2][offset
] : 0;
1067 float in2R
= ins
[3] ? ins
[3][offset
] : 0;
1070 inR
*= *params
[param_level_in
];
1071 inL
*= *params
[param_level_in
];
1074 float rightAC
= inR
;
1076 float rightSC
= inR
;
1078 float rightMC
= inR
;
1080 if (*params
[param_sc_route
] > 0.5) {
1083 leftSC
= in2L
* *params
[param_sc_level
];
1084 rightSC
= in2R
* *params
[param_sc_level
];
1089 switch ((CalfScModes
)*params
[param_sc_mode
]) {
1092 compressor
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
1097 case DERUMBLER_WIDE
:
1102 leftSC
= f2L
.process(f1L
.process(leftSC
));
1103 rightSC
= f2R
.process(f1R
.process(rightSC
));
1106 compressor
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
1109 leftSC
= f2L
.process(leftSC
);
1110 rightSC
= f2R
.process(rightSC
);
1113 compressor
.process(leftSC
, rightSC
, &leftSC
, &rightSC
);
1114 leftAC
= f1L
.process(leftAC
);
1115 rightAC
= f1R
.process(rightAC
);
1119 case DERUMBLER_SPLIT
:
1120 leftSC
= f1L
.process(leftSC
);
1121 rightSC
= f1R
.process(rightSC
);
1124 compressor
.process(leftSC
, rightSC
, &leftSC
, &rightSC
);
1125 leftAC
= f2L
.process(leftAC
);
1126 rightAC
= f2R
.process(rightAC
);
1131 leftSC
= f1L
.process(leftSC
);
1132 rightSC
= f1R
.process(rightSC
);
1135 compressor
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
1139 if(*params
[param_sc_listen
] > 0.f
) {
1146 outL
= outL
* *params
[param_mix
] + Lin
* (*params
[param_mix
] * -1 + 1);
1147 outR
= outR
* *params
[param_mix
] + Rin
* (*params
[param_mix
] * -1 + 1);
1151 outs
[0][offset
] = outL
;
1152 outs
[1][offset
] = outR
;
1154 float values
[] = {std::max(inL
, inR
), std::max(outL
, outR
), compressor
.get_comp_level()};
1155 meters
.process(values
);
1159 } // cycle trough samples
1165 meters
.fall(numsamples
);
1166 return outputs_mask
;
1168 bool sidechaincompressor_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1170 if (!is_active
or phase
)
1172 if (index
== param_sc_listen
&& !subindex
) {
1173 return ::get_graph(*this, subindex
, data
, points
);
1174 } else if(index
== param_bypass
) {
1175 return compressor
.get_graph(subindex
, data
, points
, context
, mode
);
1180 bool sidechaincompressor_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
1182 if (!is_active
or !phase
)
1184 if (index
== param_bypass
) {
1185 return compressor
.get_dot(subindex
, x
, y
, size
, context
);
1190 bool sidechaincompressor_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
1192 if (!is_active
or phase
)
1194 if (index
== param_bypass
) {
1195 return compressor
.get_gridline(subindex
, pos
, vertical
, legend
, context
);
1197 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
1202 bool sidechaincompressor_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1204 if(index
== param_bypass
)
1205 return compressor
.get_layers(index
, generation
, layers
);
1206 bool redraw
= redraw_graph
|| !generation
;
1207 layers
= 0 | (generation
? 0 : LG_CACHE_GRID
) | (redraw
? LG_CACHE_GRAPH
: 0);
1208 redraw_graph
= false;
1212 /**********************************************************************
1213 * MULTIBAND COMPRESSOR by Markus Schmidt
1214 **********************************************************************/
1216 multibandcompressor_audio_module::multibandcompressor_audio_module()
1224 crossover
.init(2, 4, 44100);
1227 void multibandcompressor_audio_module::activate()
1230 // set all filters and strips
1232 // activate all strips
1233 for (int j
= 0; j
< strips
; j
++) {
1234 strip
[j
].activate();
1239 void multibandcompressor_audio_module::deactivate()
1242 // deactivate all strips
1243 for (int j
= 0; j
< strips
; j
++) {
1244 strip
[j
].deactivate();
1248 void multibandcompressor_audio_module::params_changed()
1250 // determine mute/solo states
1251 solo
[0] = *params
[param_solo0
] > 0.f
? true : false;
1252 solo
[1] = *params
[param_solo1
] > 0.f
? true : false;
1253 solo
[2] = *params
[param_solo2
] > 0.f
? true : false;
1254 solo
[3] = *params
[param_solo3
] > 0.f
? true : false;
1255 no_solo
= (*params
[param_solo0
] > 0.f
||
1256 *params
[param_solo1
] > 0.f
||
1257 *params
[param_solo2
] > 0.f
||
1258 *params
[param_solo3
] > 0.f
) ? false : true;
1261 int m
= *params
[param_mode
];
1263 mode
= *params
[param_mode
];
1266 int p
= (int)*params
[param_notebook
];
1269 redraw
= strips
* 2 + strips
;
1272 int b
= (int)*params
[param_bypass0
] + (int)*params
[param_bypass1
] + (int)*params
[param_bypass2
] + (int)*params
[param_bypass3
];
1274 redraw
= strips
* 2 + strips
;
1278 crossover
.set_mode(mode
+ 1);
1279 crossover
.set_filter(0, *params
[param_freq0
]);
1280 crossover
.set_filter(1, *params
[param_freq1
]);
1281 crossover
.set_filter(2, *params
[param_freq2
]);
1283 // set the params of all strips
1284 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
));
1285 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
));
1286 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
));
1287 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
));
1290 void multibandcompressor_audio_module::set_sample_rate(uint32_t sr
)
1293 // set srate of all strips
1294 for (int j
= 0; j
< strips
; j
++) {
1295 strip
[j
].set_sample_rate(srate
);
1297 // set srate of crossover
1298 crossover
.set_sample_rate(srate
);
1299 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
,
1300 param_output0
, -param_compression0
,
1301 param_output1
, -param_compression1
,
1302 param_output2
, -param_compression2
,
1303 param_output3
, -param_compression3
};
1304 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
, -1, -1, -1, -1, -1, -1, -1, -1};
1305 meters
.init(params
, meter
, clip
, 12, srate
);
1308 uint32_t multibandcompressor_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1310 bool bypass
= *params
[param_bypass
] > 0.5f
;
1311 numsamples
+= offset
;
1313 for (int i
= 0; i
< strips
; i
++)
1314 strip
[i
].update_curve();
1316 // everything bypassed
1317 while(offset
< numsamples
) {
1318 outs
[0][offset
] = ins
[0][offset
];
1319 outs
[1][offset
] = ins
[1][offset
];
1320 float values
[] = {0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1};
1321 meters
.process(values
);
1325 // process all strips
1326 while(offset
< numsamples
) {
1327 // cycle through samples
1328 float inL
= ins
[0][offset
];
1329 float inR
= ins
[1][offset
];
1331 inR
*= *params
[param_level_in
];
1332 inL
*= *params
[param_level_in
];
1333 // process crossover
1336 crossover
.process(xin
);
1340 for (int i
= 0; i
< strips
; i
++) {
1341 // cycle trough strips
1342 if (solo
[i
] || no_solo
) {
1344 float left
= crossover
.get_value(0, i
);
1345 float right
= crossover
.get_value(1, i
);
1346 // process gain reduction
1347 strip
[i
].process(left
, right
);
1352 } // process single strip
1355 outL
*= *params
[param_level_out
];
1356 outR
*= *params
[param_level_out
];
1359 outs
[0][offset
] = outL
;
1360 outs
[1][offset
] = outR
;
1362 float values
[] = {inL
, inR
, outL
, outR
,
1363 *params
[param_bypass0
] > 0.5f
? 0 : strip
[0].get_output_level(), *params
[param_bypass0
] > 0.5f
? 1 : strip
[0].get_comp_level(),
1364 *params
[param_bypass1
] > 0.5f
? 0 : strip
[1].get_output_level(), *params
[param_bypass1
] > 0.5f
? 1 : strip
[1].get_comp_level(),
1365 *params
[param_bypass2
] > 0.5f
? 0 : strip
[2].get_output_level(), *params
[param_bypass2
] > 0.5f
? 1 : strip
[2].get_comp_level(),
1366 *params
[param_bypass3
] > 0.5f
? 0 : strip
[3].get_output_level(), *params
[param_bypass3
] > 0.5f
? 1 : strip
[3].get_comp_level() };
1367 meters
.process(values
);
1371 } // cycle trough samples
1372 } // process all strips (no bypass)
1373 meters
.fall(numsamples
);
1374 return outputs_mask
;
1377 const gain_reduction_audio_module
*multibandcompressor_audio_module::get_strip_by_param_index(int index
) const
1379 // let's handle by the corresponding strip
1393 bool multibandcompressor_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1398 redraw
= std::max(0, redraw
- 1);
1400 const gain_reduction_audio_module
*m
= get_strip_by_param_index(index
);
1402 r
= m
->get_graph(subindex
, data
, points
, context
, mode
);
1404 r
= crossover
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
1406 if ((index
== param_solo0
+ 11 * page
and subindex
== 1)
1407 or (index
== param_bypass
and subindex
== page
)) {
1410 if ((subindex
== 1 and index
!= param_bypass
)
1411 or (index
== param_bypass
)) {
1413 and ((index
!= param_bypass
and *params
[index
- 1])
1414 or (index
== param_bypass
and *params
[param_bypass0
+ 11 * subindex
])))
1415 context
->set_source_rgba(0.15, 0.2, 0.0, 0.15);
1417 context
->set_source_rgba(0.15, 0.2, 0.0, 0.5);
1422 bool multibandcompressor_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
1424 const gain_reduction_audio_module
*m
= get_strip_by_param_index(index
);
1426 return m
->get_dot(subindex
, x
, y
, size
, context
);
1430 bool multibandcompressor_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
1432 const gain_reduction_audio_module
*m
= get_strip_by_param_index(index
);
1434 return m
->get_gridline(subindex
, pos
, vertical
, legend
, context
);
1435 if (phase
) return false;
1436 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
1439 bool multibandcompressor_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1442 const gain_reduction_audio_module
*m
= get_strip_by_param_index(index
);
1444 r
= m
->get_layers(index
, generation
, layers
);
1446 r
= crossover
.get_layers(index
, generation
, layers
);
1449 layers
|= LG_CACHE_GRAPH
;
1456 /**********************************************************************
1457 * MONO COMPRESSOR by Damien Zammit
1458 **********************************************************************/
1460 monocompressor_audio_module::monocompressor_audio_module()
1466 void monocompressor_audio_module::activate()
1469 // set all filters and strips
1470 monocompressor
.activate();
1473 void monocompressor_audio_module::deactivate()
1476 monocompressor
.deactivate();
1479 void monocompressor_audio_module::params_changed()
1481 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
);
1484 void monocompressor_audio_module::set_sample_rate(uint32_t sr
)
1487 monocompressor
.set_sample_rate(srate
);
1488 int meter
[] = {param_meter_in
, param_meter_out
, -param_compression
};
1489 int clip
[] = {param_clip_in
, param_clip_out
, -1};
1490 meters
.init(params
, meter
, clip
, 3, srate
);
1493 uint32_t monocompressor_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1495 bool bypass
= *params
[param_bypass
] > 0.5f
;
1496 numsamples
+= offset
;
1498 // everything bypassed
1499 while(offset
< numsamples
) {
1500 outs
[0][offset
] = ins
[0][offset
];
1501 float values
[] = {0, 0, 1};
1502 meters
.process(values
);
1508 monocompressor
.update_curve();
1510 while(offset
< numsamples
) {
1511 // cycle through samples
1514 float inL
= ins
[0][offset
];
1515 //float inR = ins[1][offset];
1516 float Lin
= ins
[0][offset
];
1517 //float Rin = ins[1][offset];
1520 //inR *= *params[param_level_in];
1521 inL
*= *params
[param_level_in
];
1524 //float rightAC = inR;
1526 monocompressor
.process(leftAC
);
1532 outL
= outL
* *params
[param_mix
] + Lin
* (*params
[param_mix
] * -1 + 1);
1533 //outR = outR * *params[param_mix] + Rin * (*params[param_mix] * -1 + 1);
1536 outs
[0][offset
] = outL
;
1537 //outs[1][offset] = 0.f;
1539 float values
[] = {inL
, outL
, monocompressor
.get_comp_level()};
1540 meters
.process(values
);
1544 } // cycle trough samples
1546 meters
.fall(numsamples
);
1547 return outputs_mask
;
1549 bool monocompressor_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1551 return monocompressor
.get_graph(subindex
, data
, points
, context
, mode
);
1554 bool monocompressor_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
1556 return monocompressor
.get_dot(subindex
, x
, y
, size
, context
);
1559 bool monocompressor_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
1561 return monocompressor
.get_gridline(subindex
, pos
, vertical
, legend
, context
);
1564 bool monocompressor_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1566 return monocompressor
.get_layers(index
, generation
, layers
);
1569 /**********************************************************************
1570 * DEESSER by Markus Schmidt
1571 **********************************************************************/
1573 deesser_audio_module::deesser_audio_module()
1579 f1_level_old1
= 0.f
;
1580 f2_level_old1
= 0.f
;
1588 redraw_graph
= true;
1591 void deesser_audio_module::activate()
1594 // set all filters and strips
1595 compressor
.activate();
1600 void deesser_audio_module::deactivate()
1603 compressor
.deactivate();
1606 void deesser_audio_module::params_changed()
1608 // set the params of all filters
1609 if(*params
[param_f1_freq
] != f1_freq_old
or *params
[param_f1_level
] != f1_level_old
1610 or *params
[param_f2_freq
] != f2_freq_old
or *params
[param_f2_level
] != f2_level_old
1611 or *params
[param_f2_q
] != f2_q_old
) {
1614 hpL
.set_hp_rbj((float)*params
[param_f1_freq
] * (1 - 0.17), q
, (float)srate
, *params
[param_f1_level
]);
1615 hpR
.copy_coeffs(hpL
);
1616 lpL
.set_lp_rbj((float)*params
[param_f1_freq
] * (1 + 0.17), q
, (float)srate
);
1617 lpR
.copy_coeffs(lpL
);
1618 pL
.set_peakeq_rbj((float)*params
[param_f2_freq
], *params
[param_f2_q
], *params
[param_f2_level
], (float)srate
);
1620 f1_freq_old
= *params
[param_f1_freq
];
1621 f1_level_old
= *params
[param_f1_level
];
1622 f2_freq_old
= *params
[param_f2_freq
];
1623 f2_level_old
= *params
[param_f2_level
];
1624 f2_q_old
= *params
[param_f2_q
];
1626 // and set the compressor module
1627 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
);
1628 if (*params
[param_f1_freq
] != f1_freq_old1
1629 or *params
[param_f2_freq
] != f2_freq_old1
1630 or *params
[param_f1_level
] != f1_level_old1
1631 or *params
[param_f2_level
] != f2_level_old1
1632 or *params
[param_f2_q
] !=f2_q_old1
)
1634 f1_freq_old1
= *params
[param_f1_freq
];
1635 f2_freq_old1
= *params
[param_f2_freq
];
1636 f1_level_old1
= *params
[param_f1_level
];
1637 f2_level_old1
= *params
[param_f2_level
];
1638 f2_q_old1
= *params
[param_f2_q
];
1639 redraw_graph
= true;
1643 void deesser_audio_module::set_sample_rate(uint32_t sr
)
1646 compressor
.set_sample_rate(srate
);
1647 int meter
[] = {param_detected
, -param_compression
};
1648 int clip
[] = {param_clip_out
, -1};
1649 meters
.init(params
, meter
, clip
, 2, srate
);
1652 uint32_t deesser_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1654 bool bypass
= *params
[param_bypass
] > 0.5f
;
1655 numsamples
+= offset
;
1657 // everything bypassed81e8da266
1658 while(offset
< numsamples
) {
1659 outs
[0][offset
] = ins
[0][offset
];
1660 outs
[1][offset
] = ins
[1][offset
];
1661 float values
[] = {0, 1};
1662 meters
.process(values
);
1668 detected_led
-= std::min(detected_led
, numsamples
);
1669 compressor
.update_curve();
1671 while(offset
< numsamples
) {
1672 // cycle through samples
1675 float inL
= ins
[0][offset
];
1676 float inR
= ins
[1][offset
];
1680 float rightAC
= inR
;
1682 float rightSC
= inR
;
1684 float rightRC
= inR
;
1686 float rightMC
= inR
;
1688 leftSC
= pL
.process(hpL
.process(leftSC
));
1689 rightSC
= pR
.process(hpR
.process(rightSC
));
1693 switch ((int)*params
[param_mode
]) {
1696 compressor
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
1701 leftRC
= hpL
.process(leftRC
);
1702 rightRC
= hpR
.process(rightRC
);
1703 compressor
.process(leftRC
, rightRC
, &leftSC
, &rightSC
);
1704 leftAC
= lpL
.process(leftAC
);
1705 rightAC
= lpR
.process(rightAC
);
1711 if(*params
[param_sc_listen
] > 0.f
) {
1720 outs
[0][offset
] = outL
;
1721 outs
[1][offset
] = outR
;
1723 if(std::max(fabs(leftSC
), fabs(rightSC
)) > *params
[param_threshold
]) {
1724 detected_led
= srate
>> 3;
1726 detected
= std::max(fabs(leftMC
), fabs(rightMC
));
1728 float values
[] = {detected
, compressor
.get_comp_level()};
1729 meters
.process(values
);
1733 } // cycle trough samples
1742 if(params
[param_detected_led
] != NULL
) {
1743 *params
[param_detected_led
] = detected_led
;
1745 meters
.fall(numsamples
);
1746 return outputs_mask
;
1750 /**********************************************************************
1751 * GATE AUDIO MODULE Damien Zammit
1752 **********************************************************************/
1754 gate_audio_module::gate_audio_module()
1760 void gate_audio_module::activate()
1763 // set all filters and strips
1767 void gate_audio_module::deactivate()
1773 void gate_audio_module::params_changed()
1775 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
]);
1778 void gate_audio_module::set_sample_rate(uint32_t sr
)
1781 gate
.set_sample_rate(srate
);
1782 int meter
[] = {param_meter_in
, param_meter_out
, -param_gating
};
1783 int clip
[] = {param_clip_in
, param_clip_out
, -1};
1784 meters
.init(params
, meter
, clip
, 3, srate
);
1787 uint32_t gate_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1789 bool bypass
= *params
[param_bypass
] > 0.5f
;
1790 numsamples
+= offset
;
1792 // everything bypassed
1793 while(offset
< numsamples
) {
1794 outs
[0][offset
] = ins
[0][offset
];
1795 outs
[1][offset
] = ins
[1][offset
];
1796 float values
[] = {0, 0, 1};
1797 meters
.process(values
);
1802 gate
.update_curve();
1804 while(offset
< numsamples
) {
1805 // cycle through samples
1808 float inL
= ins
[0][offset
];
1809 float inR
= ins
[1][offset
];
1811 inR
*= *params
[param_level_in
];
1812 inL
*= *params
[param_level_in
];
1815 float rightAC
= inR
;
1817 gate
.process(leftAC
, rightAC
);
1823 outs
[0][offset
] = outL
;
1824 outs
[1][offset
] = outR
;
1826 float values
[] = {std::max(inL
, inR
), std::max(outL
, outR
), gate
.get_expander_level()};
1827 meters
.process(values
);
1831 } // cycle trough samples
1833 meters
.fall(numsamples
);
1834 return outputs_mask
;
1836 bool gate_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1838 return gate
.get_graph(subindex
, data
, points
, context
, mode
);
1841 bool gate_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
1843 return gate
.get_dot(subindex
, x
, y
, size
, context
);
1846 bool gate_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
1848 return gate
.get_gridline(subindex
, pos
, vertical
, legend
, context
);
1851 bool gate_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1853 return gate
.get_layers(index
, generation
, layers
);
1856 /**********************************************************************
1857 * SIDECHAIN GATE by Markus Schmidt
1858 **********************************************************************/
1860 sidechaingate_audio_module::sidechaingate_audio_module()
1864 redraw_graph
= true;
1865 f1_freq_old
= f2_freq_old
= f1_level_old
= f2_level_old
= 0;
1866 f1_freq_old1
= f2_freq_old1
= f1_level_old1
= f2_level_old1
= 0;
1867 sc_mode_old
= sc_mode_old1
= WIDEBAND
; // doesn't matter as long as it's sane
1870 void sidechaingate_audio_module::activate()
1873 // set all filters and strips
1877 void sidechaingate_audio_module::deactivate()
1883 sidechaingate_audio_module::cfloat
sidechaingate_audio_module::h_z(const cfloat
&z
) const
1885 switch ((CalfScModes
)sc_mode
) {
1896 return f1L
.h_z(z
) * f2L
.h_z(z
);
1898 case HIGHGATE_SPLIT
:
1908 float sidechaingate_audio_module::freq_gain(int index
, double freq
) const
1910 typedef std::complex<double> cfloat
;
1911 freq
*= 2.0 * M_PI
/ srate
;
1912 cfloat z
= 1.0 / exp(cfloat(0.0, freq
));
1914 return std::abs(h_z(z
));
1917 void sidechaingate_audio_module::params_changed()
1919 // set the params of all filters
1920 if(*params
[param_f1_freq
] != f1_freq_old
or *params
[param_f1_level
] != f1_level_old
1921 or *params
[param_f2_freq
] != f2_freq_old
or *params
[param_f2_level
] != f2_level_old
1922 or *params
[param_sc_mode
] != sc_mode
) {
1924 switch ((CalfScModes
)*params
[param_sc_mode
]) {
1927 f1L
.set_hp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
1928 f1R
.copy_coeffs(f1L
);
1929 f2L
.set_lp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
1930 f2R
.copy_coeffs(f2L
);
1935 f1L
.set_peakeq_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
1936 f1R
.copy_coeffs(f1L
);
1937 f2L
.set_hp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
1938 f2R
.copy_coeffs(f2L
);
1942 case HIGHGATE_SPLIT
:
1943 f1L
.set_lp_rbj((float)*params
[param_f2_freq
] * (1 + 0.17), q
, (float)srate
);
1944 f1R
.copy_coeffs(f1L
);
1945 f2L
.set_hp_rbj((float)*params
[param_f2_freq
] * (1 - 0.17), q
, (float)srate
, *params
[param_f2_level
]);
1946 f2R
.copy_coeffs(f2L
);
1951 f1L
.set_lp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
1952 f1R
.copy_coeffs(f1L
);
1953 f2L
.set_peakeq_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1954 f2R
.copy_coeffs(f2L
);
1959 f1L
.set_lp_rbj((float)*params
[param_f1_freq
] * (1 + 0.17), q
, (float)srate
, *params
[param_f1_level
]);
1960 f1R
.copy_coeffs(f1L
);
1961 f2L
.set_hp_rbj((float)*params
[param_f1_freq
] * (1 - 0.17), q
, (float)srate
);
1962 f2R
.copy_coeffs(f2L
);
1967 f1L
.set_lowshelf_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
1968 f1R
.copy_coeffs(f1L
);
1969 f2L
.set_highshelf_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1970 f2R
.copy_coeffs(f2L
);
1975 f1L
.set_lowshelf_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
1976 f1R
.copy_coeffs(f1L
);
1977 f2L
.set_peakeq_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1978 f2R
.copy_coeffs(f2L
);
1983 f1L
.set_peakeq_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
1984 f1R
.copy_coeffs(f1L
);
1985 f2L
.set_highshelf_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1986 f2R
.copy_coeffs(f2L
);
1991 f1L
.set_bp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
1992 f1R
.copy_coeffs(f1L
);
1993 f2L
.set_hp_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1994 f2R
.copy_coeffs(f2L
);
1999 f1L
.set_hp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
2000 f1R
.copy_coeffs(f1L
);
2001 f2L
.set_lp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
2002 f2R
.copy_coeffs(f2L
);
2007 f1_freq_old
= *params
[param_f1_freq
];
2008 f1_level_old
= *params
[param_f1_level
];
2009 f2_freq_old
= *params
[param_f2_freq
];
2010 f2_level_old
= *params
[param_f2_level
];
2011 sc_mode
= (CalfScModes
)*params
[param_sc_mode
];
2014 if(params
[param_f1_active
] != NULL
) {
2015 *params
[param_f1_active
] = f1_active
;
2017 if(params
[param_f2_active
] != NULL
) {
2018 *params
[param_f2_active
] = f2_active
;
2020 // and set the expander module
2021 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
]);
2023 if (*params
[param_f1_freq
] != f1_freq_old1
2024 or *params
[param_f2_freq
] != f2_freq_old1
2025 or *params
[param_f1_level
] != f1_level_old1
2026 or *params
[param_f2_level
] != f2_level_old1
2027 or *params
[param_sc_mode
] != sc_mode_old1
)
2029 f1_freq_old1
= *params
[param_f1_freq
];
2030 f2_freq_old1
= *params
[param_f2_freq
];
2031 f1_level_old1
= *params
[param_f1_level
];
2032 f2_level_old1
= *params
[param_f2_level
];
2033 sc_mode_old1
= (CalfScModes
)*params
[param_sc_mode
];
2034 redraw_graph
= true;
2038 void sidechaingate_audio_module::set_sample_rate(uint32_t sr
)
2041 gate
.set_sample_rate(srate
);
2042 int meter
[] = {param_meter_in
, param_meter_out
, -param_gating
};
2043 int clip
[] = {param_clip_in
, param_clip_out
, -1};
2044 meters
.init(params
, meter
, clip
, 3, srate
);
2047 uint32_t sidechaingate_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
2049 bool bypass
= *params
[param_bypass
] > 0.5f
;
2050 numsamples
+= offset
;
2052 // everything bypassed
2053 while(offset
< numsamples
) {
2054 outs
[0][offset
] = ins
[0][offset
];
2055 outs
[1][offset
] = ins
[1][offset
];
2056 float values
[] = {0, 0, 1};
2057 meters
.process(values
);
2063 gate
.update_curve();
2065 while(offset
< numsamples
) {
2066 // cycle through samples
2069 float inL
= ins
[0][offset
];
2070 float inR
= ins
[1][offset
];
2072 float in2L
= ins
[2] ? ins
[2][offset
] : 0;
2073 float in2R
= ins
[3] ? ins
[3][offset
] : 0;
2076 inR
*= *params
[param_level_in
];
2077 inL
*= *params
[param_level_in
];
2080 float rightAC
= inR
;
2082 float rightSC
= inR
;
2084 float rightMC
= inR
;
2086 if (*params
[param_sc_route
] > 0.5) {
2089 leftSC
= in2L
* *params
[param_sc_level
];
2090 rightSC
= in2R
* *params
[param_sc_level
];
2095 switch ((CalfScModes
)*params
[param_sc_mode
]) {
2098 gate
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
2108 leftSC
= f2L
.process(f1L
.process(leftSC
));
2109 rightSC
= f2R
.process(f1R
.process(rightSC
));
2112 gate
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
2114 case HIGHGATE_SPLIT
:
2115 leftSC
= f2L
.process(leftSC
);
2116 rightSC
= f2R
.process(rightSC
);
2119 gate
.process(leftSC
, rightSC
, &leftSC
, &rightSC
);
2120 leftAC
= f1L
.process(leftAC
);
2121 rightAC
= f1R
.process(rightAC
);
2126 leftSC
= f1L
.process(leftSC
);
2127 rightSC
= f1R
.process(rightSC
);
2130 gate
.process(leftSC
, rightSC
, &leftSC
, &rightSC
);
2131 leftAC
= f2L
.process(leftAC
);
2132 rightAC
= f2R
.process(rightAC
);
2137 leftSC
= f1L
.process(leftSC
);
2138 rightSC
= f1R
.process(rightSC
);
2141 gate
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
2145 if(*params
[param_sc_listen
] > 0.f
) {
2154 outs
[0][offset
] = outL
;
2155 outs
[1][offset
] = outR
;
2157 float values
[] = {std::max(inL
, inR
), std::max(outL
, outR
), gate
.get_expander_level()};
2158 meters
.process(values
);
2162 } // cycle trough samples
2169 meters
.fall(numsamples
);
2170 return outputs_mask
;
2172 bool sidechaingate_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
2174 if (!is_active
or phase
)
2176 if (index
== param_sc_listen
&& !subindex
) {
2177 return ::get_graph(*this, subindex
, data
, points
);
2178 } else if(index
== param_bypass
) {
2179 return gate
.get_graph(subindex
, data
, points
, context
, mode
);
2184 bool sidechaingate_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
2186 if (!is_active
or !phase
)
2188 if (index
== param_bypass
) {
2189 return gate
.get_dot(subindex
, x
, y
, size
, context
);
2194 bool sidechaingate_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
2196 if (!is_active
or phase
)
2198 if (index
== param_bypass
) {
2199 return gate
.get_gridline(subindex
, pos
, vertical
, legend
, context
);
2201 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
2205 bool sidechaingate_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
2207 if(index
== param_bypass
)
2208 return gate
.get_layers(index
, generation
, layers
);
2209 bool redraw
= redraw_graph
|| !generation
;
2210 layers
= 0 | (generation
? 0 : LG_CACHE_GRID
) | (redraw
? LG_CACHE_GRAPH
: 0);
2211 redraw_graph
= false;
2216 /**********************************************************************
2217 * MULTIBAND GATE by Markus Schmidt
2218 **********************************************************************/
2220 multibandgate_audio_module::multibandgate_audio_module()
2228 crossover
.init(2, 4, 44100);
2231 void multibandgate_audio_module::activate()
2234 // set all filters and strips
2236 // activate all strips
2237 for (int j
= 0; j
< strips
; j
++) {
2243 void multibandgate_audio_module::deactivate()
2246 // deactivate all strips
2247 for (int j
= 0; j
< strips
; j
++) {
2248 gate
[j
].deactivate();
2252 void multibandgate_audio_module::params_changed()
2254 // determine mute/solo states
2255 solo
[0] = *params
[param_solo0
] > 0.f
? true : false;
2256 solo
[1] = *params
[param_solo1
] > 0.f
? true : false;
2257 solo
[2] = *params
[param_solo2
] > 0.f
? true : false;
2258 solo
[3] = *params
[param_solo3
] > 0.f
? true : false;
2259 no_solo
= (*params
[param_solo0
] > 0.f
||
2260 *params
[param_solo1
] > 0.f
||
2261 *params
[param_solo2
] > 0.f
||
2262 *params
[param_solo3
] > 0.f
) ? false : true;
2264 int m
= *params
[param_mode
];
2266 mode
= *params
[param_mode
];
2269 int p
= (int)*params
[param_notebook
];
2272 redraw
= strips
* 2 + strips
;
2275 int b
= (int)*params
[param_bypass0
] + (int)*params
[param_bypass1
] + (int)*params
[param_bypass2
] + (int)*params
[param_bypass3
];
2277 redraw
= strips
* 2 + strips
;
2281 crossover
.set_mode(mode
+ 1);
2282 crossover
.set_filter(0, *params
[param_freq0
]);
2283 crossover
.set_filter(1, *params
[param_freq1
]);
2284 crossover
.set_filter(2, *params
[param_freq2
]);
2286 // set the params of all strips
2287 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
]);
2288 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
]);
2289 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
]);
2290 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
]);
2293 void multibandgate_audio_module::set_sample_rate(uint32_t sr
)
2296 // set srate of all strips
2297 for (int j
= 0; j
< strips
; j
++) {
2298 gate
[j
].set_sample_rate(srate
);
2300 // set srate of crossover
2301 crossover
.set_sample_rate(srate
);
2302 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
,
2303 param_output0
, -param_gating0
,
2304 param_output1
, -param_gating1
,
2305 param_output2
, -param_gating2
,
2306 param_output3
, -param_gating3
};
2307 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
, -1, -1, -1, -1, -1, -1, -1, -1};
2308 meters
.init(params
, meter
, clip
, 12, srate
);
2311 uint32_t multibandgate_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
2313 bool bypass
= *params
[param_bypass
] > 0.5f
;
2314 numsamples
+= offset
;
2315 for (int i
= 0; i
< strips
; i
++)
2316 gate
[i
].update_curve();
2318 // everything bypassed
2319 while(offset
< numsamples
) {
2320 outs
[0][offset
] = ins
[0][offset
];
2321 outs
[1][offset
] = ins
[1][offset
];
2322 float values
[] = {0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1};
2323 meters
.process(values
);
2327 // process all strips
2328 while(offset
< numsamples
) {
2329 // cycle through samples
2330 float inL
= ins
[0][offset
];
2331 float inR
= ins
[1][offset
];
2333 inR
*= *params
[param_level_in
];
2334 inL
*= *params
[param_level_in
];
2335 // process crossover
2338 crossover
.process(xin
);
2342 for (int i
= 0; i
< strips
; i
++) {
2343 // cycle trough strips
2344 if (solo
[i
] || no_solo
) {
2346 float left
= crossover
.get_value(0, i
);
2347 float right
= crossover
.get_value(1, i
);
2348 gate
[i
].process(left
, right
);
2353 } // process single strip
2356 outL
*= *params
[param_level_out
];
2357 outR
*= *params
[param_level_out
];
2360 outs
[0][offset
] = outL
;
2361 outs
[1][offset
] = outR
;
2363 float values
[] = {inL
, inR
, outL
, outR
,
2364 *params
[param_bypass0
] > 0.5f
? 0 : gate
[0].get_output_level(), *params
[param_bypass0
] > 0.5f
? 1 : gate
[0].get_expander_level(),
2365 *params
[param_bypass1
] > 0.5f
? 0 : gate
[1].get_output_level(), *params
[param_bypass1
] > 0.5f
? 1 : gate
[1].get_expander_level(),
2366 *params
[param_bypass2
] > 0.5f
? 0 : gate
[2].get_output_level(), *params
[param_bypass2
] > 0.5f
? 1 : gate
[2].get_expander_level(),
2367 *params
[param_bypass3
] > 0.5f
? 0 : gate
[3].get_output_level(), *params
[param_bypass3
] > 0.5f
? 1 : gate
[3].get_expander_level() };
2368 meters
.process(values
);
2372 } // cycle trough samples
2374 } // process all strips (no bypass)
2375 meters
.fall(numsamples
);
2376 return outputs_mask
;
2379 const expander_audio_module
*multibandgate_audio_module::get_strip_by_param_index(int index
) const
2381 // let's handle by the corresponding strip
2395 bool multibandgate_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
2399 redraw
= std::max(0, redraw
- 1);
2401 const expander_audio_module
*m
= get_strip_by_param_index(index
);
2403 r
= m
->get_graph(subindex
, data
, points
, context
, mode
);
2405 r
= crossover
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
2407 if ((index
== param_solo0
+ 12 * page
and subindex
== 1)
2408 or (index
== param_bypass
and subindex
== page
)) {
2411 if ((subindex
== 1 and index
!= param_bypass
)
2412 or (index
== param_bypass
)) {
2414 and ((index
!= param_bypass
and *params
[index
- 1])
2415 or (index
== param_bypass
and *params
[param_bypass0
+ 12 * subindex
])))
2416 context
->set_source_rgba(0.15, 0.2, 0.0, 0.15);
2418 context
->set_source_rgba(0.15, 0.2, 0.0, 0.5);
2423 bool multibandgate_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
2425 const expander_audio_module
*m
= get_strip_by_param_index(index
);
2427 return m
->get_dot(subindex
, x
, y
, size
, context
);
2431 bool multibandgate_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
2433 const expander_audio_module
*m
= get_strip_by_param_index(index
);
2435 return m
->get_gridline(subindex
, pos
, vertical
, legend
, context
);
2436 if (phase
) return false;
2437 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
2440 bool multibandgate_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
2443 const expander_audio_module
*m
= get_strip_by_param_index(index
);
2445 r
= m
->get_layers(index
, generation
, layers
);
2447 r
= crossover
.get_layers(index
, generation
, layers
);
2450 layers
|= LG_CACHE_GRAPH
;
2457 /**********************************************************************
2458 * TRANSIENT DESIGNER by Christian Holschuh and Markus Schmidt
2459 **********************************************************************/
2462 transientdesigner_audio_module::transientdesigner_audio_module() {
2472 pbuffer_available
= false;
2474 display_max
= pow(2,-12);
2475 transients
.set_channels(channels
);
2477 transientdesigner_audio_module::~transientdesigner_audio_module()
2481 void transientdesigner_audio_module::activate() {
2485 void transientdesigner_audio_module::deactivate() {
2489 void transientdesigner_audio_module::params_changed() {
2490 if (*params
[param_display
] != display_old
) {
2491 dsp::zero(pbuffer
, (int)(pixels
* 2));
2492 display_old
= *params
[param_display
];
2494 transients
.set_params(*params
[param_attack_time
],
2495 *params
[param_attack_boost
],
2496 *params
[param_release_time
],
2497 *params
[param_release_boost
],
2498 *params
[param_sustain_threshold
],
2499 *params
[param_lookahead
],
2500 *params
[param_mix
]);
2503 uint32_t transientdesigner_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
) {
2504 for(uint32_t i
= offset
; i
< offset
+ numsamples
; i
++) {
2505 float L
= ins
[0][i
];
2506 float R
= ins
[1][i
];
2511 float s
= (fabs(L
) + fabs(R
)) / 2;
2512 if(*params
[param_bypass
] > 0.5) {
2513 outs
[0][i
] = ins
[0][i
];
2514 outs
[1][i
] = ins
[1][i
];
2518 L
*= *params
[param_level_in
];
2519 R
*= *params
[param_level_in
];
2525 // transient designer
2526 float values
[] = {L
, R
};
2527 transients
.process(values
);
2532 L
*= *params
[param_level_out
];
2533 R
*= *params
[param_level_out
];
2542 // fill pixel buffer
2543 if (pbuffer_available
) {
2544 // sanitize the buffer position if enough samples have
2545 // been captured. This is recognized by a negative value
2546 for (int i
= 0; i
< 5; i
++) {
2547 pbuffer
[pbuffer_pos
+ i
] = std::max(pbuffer
[pbuffer_pos
+ i
], 0.f
);
2550 // add samples to the buffer at the actual address
2551 pbuffer
[pbuffer_pos
] = std::max(s
, pbuffer
[pbuffer_pos
]);
2552 pbuffer
[pbuffer_pos
+ 1] = std::max((float)(fabs(L
) + fabs(R
)), (float)pbuffer
[pbuffer_pos
+ 1]);
2553 pbuffer
[pbuffer_pos
+ 2] = transients
.envelope
;
2554 pbuffer
[pbuffer_pos
+ 3] = transients
.attack
;
2555 pbuffer
[pbuffer_pos
+ 4] = transients
.release
;
2557 pbuffer_sample
+= 1;
2559 if (pbuffer_sample
>= (int)(srate
* *params
[param_display
] / 1000.f
/ pixels
)) {
2560 // we captured enough samples for one pixel on this
2561 // address. to keep track of the finalization invert
2562 // its values as a marker to sanitize in the next
2563 // cycle before adding samples again
2564 pbuffer
[pbuffer_pos
] *= -1.f
* *params
[param_level_in
];
2565 pbuffer
[pbuffer_pos
+ 1] /= -2.f
;
2567 // advance the buffer position
2568 pbuffer_pos
= (pbuffer_pos
+ 5) % pbuffer_size
;
2570 // reset sample counter
2576 if ( transients
.envelope
== transients
.release
2577 and transients
.envelope
> *params
[param_display_threshold
]
2578 and attcount
>= srate
/ 100
2579 and pbuffer_available
) {
2580 int diff
= (int)(srate
/ 10 / pixels
);
2582 attack_pos
= (pbuffer_pos
- diff
+ pbuffer_size
) % pbuffer_size
;
2585 float values
[] = {meter_inL
, meter_inR
, meter_outL
, meter_outR
};
2586 meters
.process(values
);
2588 meters
.fall(numsamples
);
2589 return outputs_mask
;
2592 void transientdesigner_audio_module::set_sample_rate(uint32_t sr
)
2595 attcount
= srate
/ 5;
2596 transients
.set_sample_rate(srate
);
2597 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
};
2598 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
};
2599 meters
.init(params
, meter
, clip
, 4, srate
);
2601 bool transientdesigner_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
2605 if (points
!= pixels
) {
2606 // the zoom level changed or it's the first time we want to draw
2609 // buffer size is the amount of pixels for the max display value
2610 // if drawn in the min display zoom level multiplied by 5 for
2611 // keeping the input and the output fabs signals and all graphs
2613 pbuffer_size
= (int)(points
* 5.f
* 100.f
);
2615 pbuffer
= (float*) calloc(pbuffer_size
, sizeof(float));
2617 // sanitize some indexes and addresses
2621 pbuffer_available
= true;
2624 // check if threshold is above minimum - we want to see trigger hold
2625 bool hold
= *params
[param_display_threshold
] > display_max
;
2626 // set the address to start from in both drawing cycles
2627 // to amount of pixels before pbuffer_pos or to attack_pos
2628 if (subindex
== 0) {
2629 int pos
= hold
? attack_pos
: pbuffer_pos
;
2630 pbuffer_draw
= *params
[param_display_threshold
] > display_max
? pos
2631 : (pbuffer_size
+ pos
- pixels
* 5) % pbuffer_size
;
2634 // get outa here if max graph is reached
2635 if (last_drawn
>= 5) {
2640 // get the next graph to draw leaving out inactive
2641 while (last_drawn
< 5 and !*params
[param_input
+ last_drawn
] > 0.5)
2644 // get outa here if max graph is reached
2645 if (last_drawn
>= 5) {
2650 // input is drawn as bars with less opacity
2652 context
->set_source_rgba(0.15, 0.2, 0.0, 0.2);
2653 } else if (last_drawn
== 1) {
2654 // output is a precise line
2655 context
->set_line_width(0.75);
2657 // envelope, attack and release are dotted
2658 set_channel_dash(context
, last_drawn
- 2);
2659 context
->set_line_width(1);
2663 for (int i
= 0; i
<= points
; i
++) {
2664 int pos
= (pbuffer_draw
+ i
* 5) % pbuffer_size
+ last_drawn
;
2666 and ((pos
> pbuffer_pos
and ((pbuffer_pos
> attack_pos
and pos
> attack_pos
)
2667 or (pbuffer_pos
< attack_pos
and pos
< attack_pos
)))
2668 or (pbuffer_pos
> attack_pos
and pos
< attack_pos
))) {
2669 // we are drawing trigger hold stuff outside the hold window
2670 // so we don't want to see old data - zero it out.
2671 data
[i
] = dB_grid(2.51e-10, 128, 0.6);
2674 data
[i
] = dB_grid(fabs(pbuffer
[pos
]) + 2.51e-10, 128, 0.6);
2680 bool transientdesigner_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
2682 if (subindex
>= 16 or phase
)
2684 float gain
= 16.f
/ (1 << subindex
);
2685 pos
= dB_grid(gain
, 128, 0.6);
2686 context
->set_source_rgba(0, 0, 0, subindex
& 1 ? 0.1 : 0.2);
2687 if (!(subindex
& 1) and subindex
) {
2688 std::stringstream ss
;
2689 ss
<< (24 - 6 * subindex
) << " dB";
2695 bool transientdesigner_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
2697 layers
= LG_REALTIME_GRAPH
| (generation
? 0 : LG_CACHE_GRID
);