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_numsamples
= numsamples
-offset
;
781 uint32_t orig_offset
= offset
;
782 compressor
.update_curve();
784 while(offset
< numsamples
) {
785 // cycle through samples
788 float inL
= ins
[0][offset
];
789 float inR
= ins
[1][offset
];
790 float Lin
= ins
[0][offset
];
791 float Rin
= ins
[1][offset
];
794 inR
*= *params
[param_level_in
];
795 inL
*= *params
[param_level_in
];
800 compressor
.process(leftAC
, rightAC
);
806 outL
= outL
* *params
[param_mix
] + Lin
* (*params
[param_mix
] * -1 + 1);
807 outR
= outR
* *params
[param_mix
] + Rin
* (*params
[param_mix
] * -1 + 1);
810 outs
[0][offset
] = outL
;
811 outs
[1][offset
] = outR
;
813 float values
[] = {std::max(inL
, inR
), std::max(outL
, outR
), compressor
.get_comp_level()};
814 meters
.process(values
);
818 } // cycle trough samples
819 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
821 meters
.fall(numsamples
);
824 bool compressor_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
826 return compressor
.get_graph(subindex
, data
, points
, context
, mode
);
829 bool compressor_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
831 return compressor
.get_dot(subindex
, x
, y
, size
, context
);
834 bool compressor_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
836 return compressor
.get_gridline(subindex
, pos
, vertical
, legend
, context
);
839 bool compressor_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
841 return compressor
.get_layers(index
, generation
, layers
);
844 /**********************************************************************
845 * SIDECHAIN COMPRESSOR by Markus Schmidt
846 **********************************************************************/
848 sidechaincompressor_audio_module::sidechaincompressor_audio_module()
860 sc_mode_old1
= WIDEBAND
;
864 void sidechaincompressor_audio_module::activate()
867 // set all filters and strips
868 compressor
.activate();
871 void sidechaincompressor_audio_module::deactivate()
874 compressor
.deactivate();
877 sidechaincompressor_audio_module::cfloat
sidechaincompressor_audio_module::h_z(const cfloat
&z
) const
879 switch ((CalfScModes
)sc_mode
) {
890 return f1L
.h_z(z
) * f2L
.h_z(z
);
895 case DERUMBLER_SPLIT
:
902 float sidechaincompressor_audio_module::freq_gain(int index
, double freq
) const
904 typedef std::complex<double> cfloat
;
905 freq
*= 2.0 * M_PI
/ srate
;
906 cfloat z
= 1.0 / exp(cfloat(0.0, freq
));
908 return std::abs(h_z(z
));
911 void sidechaincompressor_audio_module::params_changed()
913 // set the params of all filters
914 if(*params
[param_f1_freq
] != f1_freq_old
or *params
[param_f1_level
] != f1_level_old
915 or *params
[param_f2_freq
] != f2_freq_old
or *params
[param_f2_level
] != f2_level_old
916 or *params
[param_sc_mode
] != sc_mode
) {
918 switch ((CalfScModes
)*params
[param_sc_mode
]) {
921 f1L
.set_hp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
922 f1R
.copy_coeffs(f1L
);
923 f2L
.set_lp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
924 f2R
.copy_coeffs(f2L
);
929 f1L
.set_peakeq_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
930 f1R
.copy_coeffs(f1L
);
931 f2L
.set_hp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
932 f2R
.copy_coeffs(f2L
);
937 f1L
.set_lp_rbj((float)*params
[param_f2_freq
] * (1 + 0.17), q
, (float)srate
);
938 f1R
.copy_coeffs(f1L
);
939 f2L
.set_hp_rbj((float)*params
[param_f2_freq
] * (1 - 0.17), q
, (float)srate
, *params
[param_f2_level
]);
940 f2R
.copy_coeffs(f2L
);
945 f1L
.set_lp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
946 f1R
.copy_coeffs(f1L
);
947 f2L
.set_peakeq_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
948 f2R
.copy_coeffs(f2L
);
952 case DERUMBLER_SPLIT
:
953 f1L
.set_lp_rbj((float)*params
[param_f1_freq
] * (1 + 0.17), q
, (float)srate
, *params
[param_f1_level
]);
954 f1R
.copy_coeffs(f1L
);
955 f2L
.set_hp_rbj((float)*params
[param_f1_freq
] * (1 - 0.17), q
, (float)srate
);
956 f2R
.copy_coeffs(f2L
);
961 f1L
.set_lowshelf_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
962 f1R
.copy_coeffs(f1L
);
963 f2L
.set_highshelf_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
964 f2R
.copy_coeffs(f2L
);
969 f1L
.set_lowshelf_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
970 f1R
.copy_coeffs(f1L
);
971 f2L
.set_peakeq_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
972 f2R
.copy_coeffs(f2L
);
977 f1L
.set_peakeq_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
978 f1R
.copy_coeffs(f1L
);
979 f2L
.set_highshelf_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
980 f2R
.copy_coeffs(f2L
);
985 f1L
.set_bp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
986 f1R
.copy_coeffs(f1L
);
987 f2L
.set_hp_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
988 f2R
.copy_coeffs(f2L
);
993 f1L
.set_hp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
994 f1R
.copy_coeffs(f1L
);
995 f2L
.set_lp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
996 f2R
.copy_coeffs(f2L
);
1001 f1_freq_old
= *params
[param_f1_freq
];
1002 f1_level_old
= *params
[param_f1_level
];
1003 f2_freq_old
= *params
[param_f2_freq
];
1004 f2_level_old
= *params
[param_f2_level
];
1005 sc_mode
= (CalfScModes
)*params
[param_sc_mode
];
1008 if(params
[param_f1_active
] != NULL
) {
1009 *params
[param_f1_active
] = f1_active
;
1011 if(params
[param_f2_active
] != NULL
) {
1012 *params
[param_f2_active
] = f2_active
;
1014 // and set the compressor module
1015 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
);
1017 if (*params
[param_f1_freq
] != f1_freq_old1
1018 or *params
[param_f2_freq
] != f2_freq_old1
1019 or *params
[param_f1_level
] != f1_level_old1
1020 or *params
[param_f2_level
] != f2_level_old1
1021 or *params
[param_sc_mode
] != sc_mode_old1
)
1023 f1_freq_old1
= *params
[param_f1_freq
];
1024 f2_freq_old1
= *params
[param_f2_freq
];
1025 f1_level_old1
= *params
[param_f1_level
];
1026 f2_level_old1
= *params
[param_f2_level
];
1027 sc_mode_old1
= (CalfScModes
)*params
[param_sc_mode
];
1028 redraw_graph
= true;
1032 void sidechaincompressor_audio_module::set_sample_rate(uint32_t sr
)
1035 compressor
.set_sample_rate(srate
);
1036 int meter
[] = {param_meter_in
, param_meter_out
, -param_compression
};
1037 int clip
[] = {param_clip_in
, param_clip_out
, -1};
1038 meters
.init(params
, meter
, clip
, 3, srate
);
1041 uint32_t sidechaincompressor_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1043 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
1044 numsamples
+= offset
;
1046 // everything bypassed
1047 while(offset
< numsamples
) {
1048 outs
[0][offset
] = ins
[0][offset
];
1049 outs
[1][offset
] = ins
[1][offset
];
1050 float values
[] = {0, 0, 1};
1051 meters
.process(values
);
1056 uint32_t orig_numsamples
= numsamples
-offset
;
1057 uint32_t orig_offset
= offset
;
1058 compressor
.update_curve();
1060 while(offset
< numsamples
) {
1061 // cycle through samples
1064 float inL
= ins
[0][offset
];
1065 float inR
= ins
[1][offset
];
1066 float Lin
= ins
[0][offset
];
1067 float Rin
= ins
[1][offset
];
1069 float in2L
= ins
[2] ? ins
[2][offset
] : 0;
1070 float in2R
= ins
[3] ? ins
[3][offset
] : 0;
1073 inR
*= *params
[param_level_in
];
1074 inL
*= *params
[param_level_in
];
1077 float rightAC
= inR
;
1079 float rightSC
= inR
;
1081 float rightMC
= inR
;
1083 if (*params
[param_sc_route
] > 0.5) {
1086 leftSC
= in2L
* *params
[param_sc_level
];
1087 rightSC
= in2R
* *params
[param_sc_level
];
1092 switch ((CalfScModes
)*params
[param_sc_mode
]) {
1095 compressor
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
1100 case DERUMBLER_WIDE
:
1105 leftSC
= f2L
.process(f1L
.process(leftSC
));
1106 rightSC
= f2R
.process(f1R
.process(rightSC
));
1109 compressor
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
1112 leftSC
= f2L
.process(leftSC
);
1113 rightSC
= f2R
.process(rightSC
);
1116 compressor
.process(leftSC
, rightSC
, &leftSC
, &rightSC
);
1117 leftAC
= f1L
.process(leftAC
);
1118 rightAC
= f1R
.process(rightAC
);
1122 case DERUMBLER_SPLIT
:
1123 leftSC
= f1L
.process(leftSC
);
1124 rightSC
= f1R
.process(rightSC
);
1127 compressor
.process(leftSC
, rightSC
, &leftSC
, &rightSC
);
1128 leftAC
= f2L
.process(leftAC
);
1129 rightAC
= f2R
.process(rightAC
);
1134 leftSC
= f1L
.process(leftSC
);
1135 rightSC
= f1R
.process(rightSC
);
1138 compressor
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
1142 if(*params
[param_sc_listen
] > 0.f
) {
1149 outL
= outL
* *params
[param_mix
] + Lin
* (*params
[param_mix
] * -1 + 1);
1150 outR
= outR
* *params
[param_mix
] + Rin
* (*params
[param_mix
] * -1 + 1);
1154 outs
[0][offset
] = outL
;
1155 outs
[1][offset
] = outR
;
1157 float values
[] = {std::max(inL
, inR
), std::max(outL
, outR
), compressor
.get_comp_level()};
1158 meters
.process(values
);
1162 } // cycle trough samples
1163 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
1169 meters
.fall(numsamples
);
1170 return outputs_mask
;
1172 bool sidechaincompressor_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1174 if (!is_active
or phase
)
1176 if (index
== param_sc_listen
&& !subindex
) {
1177 return ::get_graph(*this, subindex
, data
, points
);
1178 } else if(index
== param_bypass
) {
1179 return compressor
.get_graph(subindex
, data
, points
, context
, mode
);
1184 bool sidechaincompressor_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
1186 if (!is_active
or !phase
)
1188 if (index
== param_bypass
) {
1189 return compressor
.get_dot(subindex
, x
, y
, size
, context
);
1194 bool sidechaincompressor_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
1196 if (!is_active
or phase
)
1198 if (index
== param_bypass
) {
1199 return compressor
.get_gridline(subindex
, pos
, vertical
, legend
, context
);
1201 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
1206 bool sidechaincompressor_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1208 if(index
== param_bypass
)
1209 return compressor
.get_layers(index
, generation
, layers
);
1210 bool redraw
= redraw_graph
|| !generation
;
1211 layers
= 0 | (generation
? 0 : LG_CACHE_GRID
) | (redraw
? LG_CACHE_GRAPH
: 0);
1212 redraw_graph
= false;
1216 /**********************************************************************
1217 * MULTIBAND COMPRESSOR by Markus Schmidt
1218 **********************************************************************/
1220 multibandcompressor_audio_module::multibandcompressor_audio_module()
1228 crossover
.init(2, 4, 44100);
1231 void multibandcompressor_audio_module::activate()
1234 // set all filters and strips
1236 // activate all strips
1237 for (int j
= 0; j
< strips
; j
++) {
1238 strip
[j
].activate();
1243 void multibandcompressor_audio_module::deactivate()
1246 // deactivate all strips
1247 for (int j
= 0; j
< strips
; j
++) {
1248 strip
[j
].deactivate();
1252 void multibandcompressor_audio_module::params_changed()
1254 // determine mute/solo states
1255 solo
[0] = *params
[param_solo0
] > 0.f
? true : false;
1256 solo
[1] = *params
[param_solo1
] > 0.f
? true : false;
1257 solo
[2] = *params
[param_solo2
] > 0.f
? true : false;
1258 solo
[3] = *params
[param_solo3
] > 0.f
? true : false;
1259 no_solo
= (*params
[param_solo0
] > 0.f
||
1260 *params
[param_solo1
] > 0.f
||
1261 *params
[param_solo2
] > 0.f
||
1262 *params
[param_solo3
] > 0.f
) ? false : true;
1265 int m
= *params
[param_mode
];
1267 mode
= *params
[param_mode
];
1270 int p
= (int)*params
[param_notebook
];
1273 redraw
= strips
* 2 + strips
;
1276 int b
= (int)*params
[param_bypass0
] + (int)*params
[param_bypass1
] + (int)*params
[param_bypass2
] + (int)*params
[param_bypass3
];
1278 redraw
= strips
* 2 + strips
;
1282 crossover
.set_mode(mode
+ 1);
1283 crossover
.set_filter(0, *params
[param_freq0
]);
1284 crossover
.set_filter(1, *params
[param_freq1
]);
1285 crossover
.set_filter(2, *params
[param_freq2
]);
1287 // set the params of all strips
1288 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
));
1289 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
));
1290 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
));
1291 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
));
1294 void multibandcompressor_audio_module::set_sample_rate(uint32_t sr
)
1297 // set srate of all strips
1298 for (int j
= 0; j
< strips
; j
++) {
1299 strip
[j
].set_sample_rate(srate
);
1301 // set srate of crossover
1302 crossover
.set_sample_rate(srate
);
1303 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
,
1304 param_output0
, -param_compression0
,
1305 param_output1
, -param_compression1
,
1306 param_output2
, -param_compression2
,
1307 param_output3
, -param_compression3
};
1308 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
, -1, -1, -1, -1, -1, -1, -1, -1};
1309 meters
.init(params
, meter
, clip
, 12, srate
);
1312 uint32_t multibandcompressor_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1314 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
1315 numsamples
+= offset
;
1317 for (int i
= 0; i
< strips
; i
++)
1318 strip
[i
].update_curve();
1320 // everything bypassed
1321 while(offset
< numsamples
) {
1322 outs
[0][offset
] = ins
[0][offset
];
1323 outs
[1][offset
] = ins
[1][offset
];
1324 float values
[] = {0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1};
1325 meters
.process(values
);
1329 // process all strips
1330 uint32_t orig_numsamples
= numsamples
-offset
;
1331 uint32_t orig_offset
= offset
;
1332 while(offset
< numsamples
) {
1333 // cycle through samples
1334 float inL
= ins
[0][offset
];
1335 float inR
= ins
[1][offset
];
1337 inR
*= *params
[param_level_in
];
1338 inL
*= *params
[param_level_in
];
1339 // process crossover
1342 crossover
.process(xin
);
1346 for (int i
= 0; i
< strips
; i
++) {
1347 // cycle trough strips
1348 if (solo
[i
] || no_solo
) {
1350 float left
= crossover
.get_value(0, i
);
1351 float right
= crossover
.get_value(1, i
);
1352 // process gain reduction
1353 strip
[i
].process(left
, right
);
1358 } // process single strip
1361 outL
*= *params
[param_level_out
];
1362 outR
*= *params
[param_level_out
];
1365 outs
[0][offset
] = outL
;
1366 outs
[1][offset
] = outR
;
1368 float values
[] = {inL
, inR
, outL
, outR
,
1369 *params
[param_bypass0
] > 0.5f
? 0 : strip
[0].get_output_level(), *params
[param_bypass0
] > 0.5f
? 1 : strip
[0].get_comp_level(),
1370 *params
[param_bypass1
] > 0.5f
? 0 : strip
[1].get_output_level(), *params
[param_bypass1
] > 0.5f
? 1 : strip
[1].get_comp_level(),
1371 *params
[param_bypass2
] > 0.5f
? 0 : strip
[2].get_output_level(), *params
[param_bypass2
] > 0.5f
? 1 : strip
[2].get_comp_level(),
1372 *params
[param_bypass3
] > 0.5f
? 0 : strip
[3].get_output_level(), *params
[param_bypass3
] > 0.5f
? 1 : strip
[3].get_comp_level() };
1373 meters
.process(values
);
1377 } // cycle trough samples
1378 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
1379 } // process all strips (no bypass)
1380 meters
.fall(numsamples
);
1381 return outputs_mask
;
1384 const gain_reduction_audio_module
*multibandcompressor_audio_module::get_strip_by_param_index(int index
) const
1386 // let's handle by the corresponding strip
1400 bool multibandcompressor_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1405 redraw
= std::max(0, redraw
- 1);
1407 const gain_reduction_audio_module
*m
= get_strip_by_param_index(index
);
1409 r
= m
->get_graph(subindex
, data
, points
, context
, mode
);
1411 r
= crossover
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
1413 if ((index
== param_solo0
+ 11 * page
and subindex
== 1)
1414 or (index
== param_bypass
and subindex
== page
)) {
1417 if ((subindex
== 1 and index
!= param_bypass
)
1418 or (index
== param_bypass
)) {
1420 and ((index
!= param_bypass
and *params
[index
- 1])
1421 or (index
== param_bypass
and *params
[param_bypass0
+ 11 * subindex
])))
1422 context
->set_source_rgba(0.15, 0.2, 0.0, 0.15);
1424 context
->set_source_rgba(0.15, 0.2, 0.0, 0.5);
1429 bool multibandcompressor_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
1431 const gain_reduction_audio_module
*m
= get_strip_by_param_index(index
);
1433 return m
->get_dot(subindex
, x
, y
, size
, context
);
1437 bool multibandcompressor_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
1439 const gain_reduction_audio_module
*m
= get_strip_by_param_index(index
);
1441 return m
->get_gridline(subindex
, pos
, vertical
, legend
, context
);
1442 if (phase
) return false;
1443 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
1446 bool multibandcompressor_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1449 const gain_reduction_audio_module
*m
= get_strip_by_param_index(index
);
1451 r
= m
->get_layers(index
, generation
, layers
);
1453 r
= crossover
.get_layers(index
, generation
, layers
);
1456 layers
|= LG_CACHE_GRAPH
;
1463 /**********************************************************************
1464 * MONO COMPRESSOR by Damien Zammit
1465 **********************************************************************/
1467 monocompressor_audio_module::monocompressor_audio_module()
1473 void monocompressor_audio_module::activate()
1476 // set all filters and strips
1477 monocompressor
.activate();
1480 void monocompressor_audio_module::deactivate()
1483 monocompressor
.deactivate();
1486 void monocompressor_audio_module::params_changed()
1488 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
);
1491 void monocompressor_audio_module::set_sample_rate(uint32_t sr
)
1494 monocompressor
.set_sample_rate(srate
);
1495 int meter
[] = {param_meter_in
, param_meter_out
, -param_compression
};
1496 int clip
[] = {param_clip_in
, param_clip_out
, -1};
1497 meters
.init(params
, meter
, clip
, 3, srate
);
1500 uint32_t monocompressor_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1502 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
1503 numsamples
+= offset
;
1505 // everything bypassed
1506 while(offset
< numsamples
) {
1507 outs
[0][offset
] = ins
[0][offset
];
1508 float values
[] = {0, 0, 1};
1509 meters
.process(values
);
1514 uint32_t orig_numsamples
= numsamples
-offset
;
1515 uint32_t orig_offset
= offset
;
1516 monocompressor
.update_curve();
1518 while(offset
< numsamples
) {
1519 // cycle through samples
1522 float inL
= ins
[0][offset
];
1523 //float inR = ins[1][offset];
1524 float Lin
= ins
[0][offset
];
1525 //float Rin = ins[1][offset];
1528 //inR *= *params[param_level_in];
1529 inL
*= *params
[param_level_in
];
1532 //float rightAC = inR;
1534 monocompressor
.process(leftAC
);
1540 outL
= outL
* *params
[param_mix
] + Lin
* (*params
[param_mix
] * -1 + 1);
1541 //outR = outR * *params[param_mix] + Rin * (*params[param_mix] * -1 + 1);
1544 outs
[0][offset
] = outL
;
1545 //outs[1][offset] = 0.f;
1547 float values
[] = {inL
, outL
, monocompressor
.get_comp_level()};
1548 meters
.process(values
);
1552 } // cycle trough samples
1553 bypass
.crossfade(ins
, outs
, 1, orig_offset
, orig_numsamples
);
1555 meters
.fall(numsamples
);
1556 return outputs_mask
;
1558 bool monocompressor_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1560 return monocompressor
.get_graph(subindex
, data
, points
, context
, mode
);
1563 bool monocompressor_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
1565 return monocompressor
.get_dot(subindex
, x
, y
, size
, context
);
1568 bool monocompressor_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
1570 return monocompressor
.get_gridline(subindex
, pos
, vertical
, legend
, context
);
1573 bool monocompressor_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1575 return monocompressor
.get_layers(index
, generation
, layers
);
1578 /**********************************************************************
1579 * DEESSER by Markus Schmidt
1580 **********************************************************************/
1582 deesser_audio_module::deesser_audio_module()
1588 f1_level_old1
= 0.f
;
1589 f2_level_old1
= 0.f
;
1597 redraw_graph
= true;
1600 void deesser_audio_module::activate()
1603 // set all filters and strips
1604 compressor
.activate();
1609 void deesser_audio_module::deactivate()
1612 compressor
.deactivate();
1615 void deesser_audio_module::params_changed()
1617 // set the params of all filters
1618 if(*params
[param_f1_freq
] != f1_freq_old
or *params
[param_f1_level
] != f1_level_old
1619 or *params
[param_f2_freq
] != f2_freq_old
or *params
[param_f2_level
] != f2_level_old
1620 or *params
[param_f2_q
] != f2_q_old
) {
1623 hpL
.set_hp_rbj((float)*params
[param_f1_freq
] * (1 - 0.17), q
, (float)srate
, *params
[param_f1_level
]);
1624 hpR
.copy_coeffs(hpL
);
1625 lpL
.set_lp_rbj((float)*params
[param_f1_freq
] * (1 + 0.17), q
, (float)srate
);
1626 lpR
.copy_coeffs(lpL
);
1627 pL
.set_peakeq_rbj((float)*params
[param_f2_freq
], *params
[param_f2_q
], *params
[param_f2_level
], (float)srate
);
1629 f1_freq_old
= *params
[param_f1_freq
];
1630 f1_level_old
= *params
[param_f1_level
];
1631 f2_freq_old
= *params
[param_f2_freq
];
1632 f2_level_old
= *params
[param_f2_level
];
1633 f2_q_old
= *params
[param_f2_q
];
1635 // and set the compressor module
1636 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
);
1637 if (*params
[param_f1_freq
] != f1_freq_old1
1638 or *params
[param_f2_freq
] != f2_freq_old1
1639 or *params
[param_f1_level
] != f1_level_old1
1640 or *params
[param_f2_level
] != f2_level_old1
1641 or *params
[param_f2_q
] !=f2_q_old1
)
1643 f1_freq_old1
= *params
[param_f1_freq
];
1644 f2_freq_old1
= *params
[param_f2_freq
];
1645 f1_level_old1
= *params
[param_f1_level
];
1646 f2_level_old1
= *params
[param_f2_level
];
1647 f2_q_old1
= *params
[param_f2_q
];
1648 redraw_graph
= true;
1652 void deesser_audio_module::set_sample_rate(uint32_t sr
)
1655 compressor
.set_sample_rate(srate
);
1656 int meter
[] = {param_detected
, -param_compression
};
1657 int clip
[] = {param_clip_out
, -1};
1658 meters
.init(params
, meter
, clip
, 2, srate
);
1661 uint32_t deesser_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1663 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
1664 numsamples
+= offset
;
1666 // everything bypassed81e8da266
1667 while(offset
< numsamples
) {
1668 outs
[0][offset
] = ins
[0][offset
];
1669 outs
[1][offset
] = ins
[1][offset
];
1670 float values
[] = {0, 1};
1671 meters
.process(values
);
1676 uint32_t orig_numsamples
= numsamples
-offset
;
1677 uint32_t orig_offset
= offset
;
1678 detected_led
-= std::min(detected_led
, numsamples
);
1679 compressor
.update_curve();
1681 while(offset
< numsamples
) {
1682 // cycle through samples
1685 float inL
= ins
[0][offset
];
1686 float inR
= ins
[1][offset
];
1690 float rightAC
= inR
;
1692 float rightSC
= inR
;
1694 float rightRC
= inR
;
1696 float rightMC
= inR
;
1698 leftSC
= pL
.process(hpL
.process(leftSC
));
1699 rightSC
= pR
.process(hpR
.process(rightSC
));
1703 switch ((int)*params
[param_mode
]) {
1706 compressor
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
1711 leftRC
= hpL
.process(leftRC
);
1712 rightRC
= hpR
.process(rightRC
);
1713 compressor
.process(leftRC
, rightRC
, &leftSC
, &rightSC
);
1714 leftAC
= lpL
.process(leftAC
);
1715 rightAC
= lpR
.process(rightAC
);
1721 if(*params
[param_sc_listen
] > 0.f
) {
1730 outs
[0][offset
] = outL
;
1731 outs
[1][offset
] = outR
;
1733 if(std::max(fabs(leftSC
), fabs(rightSC
)) > *params
[param_threshold
]) {
1734 detected_led
= srate
>> 3;
1736 detected
= std::max(fabs(leftMC
), fabs(rightMC
));
1738 float values
[] = {detected
, compressor
.get_comp_level()};
1739 meters
.process(values
);
1743 } // cycle trough samples
1744 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
1753 if(params
[param_detected_led
] != NULL
) {
1754 *params
[param_detected_led
] = detected_led
;
1756 meters
.fall(numsamples
);
1757 return outputs_mask
;
1761 /**********************************************************************
1762 * GATE AUDIO MODULE Damien Zammit
1763 **********************************************************************/
1765 gate_audio_module::gate_audio_module()
1771 void gate_audio_module::activate()
1774 // set all filters and strips
1778 void gate_audio_module::deactivate()
1784 void gate_audio_module::params_changed()
1786 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
]);
1789 void gate_audio_module::set_sample_rate(uint32_t sr
)
1792 gate
.set_sample_rate(srate
);
1793 int meter
[] = {param_meter_in
, param_meter_out
, -param_gating
};
1794 int clip
[] = {param_clip_in
, param_clip_out
, -1};
1795 meters
.init(params
, meter
, clip
, 3, srate
);
1798 uint32_t gate_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1800 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
1801 numsamples
+= offset
;
1803 // everything bypassed
1804 while(offset
< numsamples
) {
1805 outs
[0][offset
] = ins
[0][offset
];
1806 outs
[1][offset
] = ins
[1][offset
];
1807 float values
[] = {0, 0, 1};
1808 meters
.process(values
);
1813 gate
.update_curve();
1814 uint32_t orig_numsamples
= numsamples
-offset
;
1815 uint32_t orig_offset
= offset
;
1816 while(offset
< numsamples
) {
1817 // cycle through samples
1820 float inL
= ins
[0][offset
];
1821 float inR
= ins
[1][offset
];
1823 inR
*= *params
[param_level_in
];
1824 inL
*= *params
[param_level_in
];
1827 float rightAC
= inR
;
1829 gate
.process(leftAC
, rightAC
);
1835 outs
[0][offset
] = outL
;
1836 outs
[1][offset
] = outR
;
1838 float values
[] = {std::max(inL
, inR
), std::max(outL
, outR
), gate
.get_expander_level()};
1839 meters
.process(values
);
1843 } // cycle trough samples
1844 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
1846 meters
.fall(numsamples
);
1847 return outputs_mask
;
1849 bool gate_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1851 return gate
.get_graph(subindex
, data
, points
, context
, mode
);
1854 bool gate_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
1856 return gate
.get_dot(subindex
, x
, y
, size
, context
);
1859 bool gate_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
1861 return gate
.get_gridline(subindex
, pos
, vertical
, legend
, context
);
1864 bool gate_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1866 return gate
.get_layers(index
, generation
, layers
);
1869 /**********************************************************************
1870 * SIDECHAIN GATE by Markus Schmidt
1871 **********************************************************************/
1873 sidechaingate_audio_module::sidechaingate_audio_module()
1877 redraw_graph
= true;
1878 f1_freq_old
= f2_freq_old
= f1_level_old
= f2_level_old
= 0;
1879 f1_freq_old1
= f2_freq_old1
= f1_level_old1
= f2_level_old1
= 0;
1880 sc_mode_old
= sc_mode_old1
= WIDEBAND
; // doesn't matter as long as it's sane
1883 void sidechaingate_audio_module::activate()
1886 // set all filters and strips
1890 void sidechaingate_audio_module::deactivate()
1896 sidechaingate_audio_module::cfloat
sidechaingate_audio_module::h_z(const cfloat
&z
) const
1898 switch ((CalfScModes
)sc_mode
) {
1909 return f1L
.h_z(z
) * f2L
.h_z(z
);
1911 case HIGHGATE_SPLIT
:
1921 float sidechaingate_audio_module::freq_gain(int index
, double freq
) const
1923 typedef std::complex<double> cfloat
;
1924 freq
*= 2.0 * M_PI
/ srate
;
1925 cfloat z
= 1.0 / exp(cfloat(0.0, freq
));
1927 return std::abs(h_z(z
));
1930 void sidechaingate_audio_module::params_changed()
1932 // set the params of all filters
1933 if(*params
[param_f1_freq
] != f1_freq_old
or *params
[param_f1_level
] != f1_level_old
1934 or *params
[param_f2_freq
] != f2_freq_old
or *params
[param_f2_level
] != f2_level_old
1935 or *params
[param_sc_mode
] != sc_mode
) {
1937 switch ((CalfScModes
)*params
[param_sc_mode
]) {
1940 f1L
.set_hp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
1941 f1R
.copy_coeffs(f1L
);
1942 f2L
.set_lp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
1943 f2R
.copy_coeffs(f2L
);
1948 f1L
.set_peakeq_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
1949 f1R
.copy_coeffs(f1L
);
1950 f2L
.set_hp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
1951 f2R
.copy_coeffs(f2L
);
1955 case HIGHGATE_SPLIT
:
1956 f1L
.set_lp_rbj((float)*params
[param_f2_freq
] * (1 + 0.17), q
, (float)srate
);
1957 f1R
.copy_coeffs(f1L
);
1958 f2L
.set_hp_rbj((float)*params
[param_f2_freq
] * (1 - 0.17), q
, (float)srate
, *params
[param_f2_level
]);
1959 f2R
.copy_coeffs(f2L
);
1964 f1L
.set_lp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
1965 f1R
.copy_coeffs(f1L
);
1966 f2L
.set_peakeq_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1967 f2R
.copy_coeffs(f2L
);
1972 f1L
.set_lp_rbj((float)*params
[param_f1_freq
] * (1 + 0.17), q
, (float)srate
, *params
[param_f1_level
]);
1973 f1R
.copy_coeffs(f1L
);
1974 f2L
.set_hp_rbj((float)*params
[param_f1_freq
] * (1 - 0.17), q
, (float)srate
);
1975 f2R
.copy_coeffs(f2L
);
1980 f1L
.set_lowshelf_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
1981 f1R
.copy_coeffs(f1L
);
1982 f2L
.set_highshelf_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1983 f2R
.copy_coeffs(f2L
);
1988 f1L
.set_lowshelf_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
1989 f1R
.copy_coeffs(f1L
);
1990 f2L
.set_peakeq_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1991 f2R
.copy_coeffs(f2L
);
1996 f1L
.set_peakeq_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
1997 f1R
.copy_coeffs(f1L
);
1998 f2L
.set_highshelf_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1999 f2R
.copy_coeffs(f2L
);
2004 f1L
.set_bp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
2005 f1R
.copy_coeffs(f1L
);
2006 f2L
.set_hp_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
2007 f2R
.copy_coeffs(f2L
);
2012 f1L
.set_hp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
2013 f1R
.copy_coeffs(f1L
);
2014 f2L
.set_lp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
2015 f2R
.copy_coeffs(f2L
);
2020 f1_freq_old
= *params
[param_f1_freq
];
2021 f1_level_old
= *params
[param_f1_level
];
2022 f2_freq_old
= *params
[param_f2_freq
];
2023 f2_level_old
= *params
[param_f2_level
];
2024 sc_mode
= (CalfScModes
)*params
[param_sc_mode
];
2027 if(params
[param_f1_active
] != NULL
) {
2028 *params
[param_f1_active
] = f1_active
;
2030 if(params
[param_f2_active
] != NULL
) {
2031 *params
[param_f2_active
] = f2_active
;
2033 // and set the expander module
2034 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
]);
2036 if (*params
[param_f1_freq
] != f1_freq_old1
2037 or *params
[param_f2_freq
] != f2_freq_old1
2038 or *params
[param_f1_level
] != f1_level_old1
2039 or *params
[param_f2_level
] != f2_level_old1
2040 or *params
[param_sc_mode
] != sc_mode_old1
)
2042 f1_freq_old1
= *params
[param_f1_freq
];
2043 f2_freq_old1
= *params
[param_f2_freq
];
2044 f1_level_old1
= *params
[param_f1_level
];
2045 f2_level_old1
= *params
[param_f2_level
];
2046 sc_mode_old1
= (CalfScModes
)*params
[param_sc_mode
];
2047 redraw_graph
= true;
2051 void sidechaingate_audio_module::set_sample_rate(uint32_t sr
)
2054 gate
.set_sample_rate(srate
);
2055 int meter
[] = {param_meter_in
, param_meter_out
, -param_gating
};
2056 int clip
[] = {param_clip_in
, param_clip_out
, -1};
2057 meters
.init(params
, meter
, clip
, 3, srate
);
2060 uint32_t sidechaingate_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
2062 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
2063 numsamples
+= offset
;
2065 // everything bypassed
2066 while(offset
< numsamples
) {
2067 outs
[0][offset
] = ins
[0][offset
];
2068 outs
[1][offset
] = ins
[1][offset
];
2069 float values
[] = {0, 0, 1};
2070 meters
.process(values
);
2075 uint32_t orig_numsamples
= numsamples
-offset
;
2076 uint32_t orig_offset
= offset
;
2077 gate
.update_curve();
2079 while(offset
< numsamples
) {
2080 // cycle through samples
2083 float inL
= ins
[0][offset
];
2084 float inR
= ins
[1][offset
];
2086 float in2L
= ins
[2] ? ins
[2][offset
] : 0;
2087 float in2R
= ins
[3] ? ins
[3][offset
] : 0;
2090 inR
*= *params
[param_level_in
];
2091 inL
*= *params
[param_level_in
];
2094 float rightAC
= inR
;
2096 float rightSC
= inR
;
2098 float rightMC
= inR
;
2100 if (*params
[param_sc_route
] > 0.5) {
2103 leftSC
= in2L
* *params
[param_sc_level
];
2104 rightSC
= in2R
* *params
[param_sc_level
];
2109 switch ((CalfScModes
)*params
[param_sc_mode
]) {
2112 gate
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
2122 leftSC
= f2L
.process(f1L
.process(leftSC
));
2123 rightSC
= f2R
.process(f1R
.process(rightSC
));
2126 gate
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
2128 case HIGHGATE_SPLIT
:
2129 leftSC
= f2L
.process(leftSC
);
2130 rightSC
= f2R
.process(rightSC
);
2133 gate
.process(leftSC
, rightSC
, &leftSC
, &rightSC
);
2134 leftAC
= f1L
.process(leftAC
);
2135 rightAC
= f1R
.process(rightAC
);
2140 leftSC
= f1L
.process(leftSC
);
2141 rightSC
= f1R
.process(rightSC
);
2144 gate
.process(leftSC
, rightSC
, &leftSC
, &rightSC
);
2145 leftAC
= f2L
.process(leftAC
);
2146 rightAC
= f2R
.process(rightAC
);
2151 leftSC
= f1L
.process(leftSC
);
2152 rightSC
= f1R
.process(rightSC
);
2155 gate
.process(leftAC
, rightAC
, &leftSC
, &rightSC
);
2159 if(*params
[param_sc_listen
] > 0.f
) {
2168 outs
[0][offset
] = outL
;
2169 outs
[1][offset
] = outR
;
2171 float values
[] = {std::max(inL
, inR
), std::max(outL
, outR
), gate
.get_expander_level()};
2172 meters
.process(values
);
2176 } // cycle trough samples
2177 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
2184 meters
.fall(numsamples
);
2185 return outputs_mask
;
2187 bool sidechaingate_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
2189 if (!is_active
or phase
)
2191 if (index
== param_sc_listen
&& !subindex
) {
2192 return ::get_graph(*this, subindex
, data
, points
);
2193 } else if(index
== param_bypass
) {
2194 return gate
.get_graph(subindex
, data
, points
, context
, mode
);
2199 bool sidechaingate_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
2201 if (!is_active
or !phase
)
2203 if (index
== param_bypass
) {
2204 return gate
.get_dot(subindex
, x
, y
, size
, context
);
2209 bool sidechaingate_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
2211 if (!is_active
or phase
)
2213 if (index
== param_bypass
) {
2214 return gate
.get_gridline(subindex
, pos
, vertical
, legend
, context
);
2216 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
2220 bool sidechaingate_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
2222 if(index
== param_bypass
)
2223 return gate
.get_layers(index
, generation
, layers
);
2224 bool redraw
= redraw_graph
|| !generation
;
2225 layers
= 0 | (generation
? 0 : LG_CACHE_GRID
) | (redraw
? LG_CACHE_GRAPH
: 0);
2226 redraw_graph
= false;
2231 /**********************************************************************
2232 * MULTIBAND GATE by Markus Schmidt
2233 **********************************************************************/
2235 multibandgate_audio_module::multibandgate_audio_module()
2243 crossover
.init(2, 4, 44100);
2246 void multibandgate_audio_module::activate()
2249 // set all filters and strips
2251 // activate all strips
2252 for (int j
= 0; j
< strips
; j
++) {
2258 void multibandgate_audio_module::deactivate()
2261 // deactivate all strips
2262 for (int j
= 0; j
< strips
; j
++) {
2263 gate
[j
].deactivate();
2267 void multibandgate_audio_module::params_changed()
2269 // determine mute/solo states
2270 solo
[0] = *params
[param_solo0
] > 0.f
? true : false;
2271 solo
[1] = *params
[param_solo1
] > 0.f
? true : false;
2272 solo
[2] = *params
[param_solo2
] > 0.f
? true : false;
2273 solo
[3] = *params
[param_solo3
] > 0.f
? true : false;
2274 no_solo
= (*params
[param_solo0
] > 0.f
||
2275 *params
[param_solo1
] > 0.f
||
2276 *params
[param_solo2
] > 0.f
||
2277 *params
[param_solo3
] > 0.f
) ? false : true;
2279 int m
= *params
[param_mode
];
2281 mode
= *params
[param_mode
];
2284 int p
= (int)*params
[param_notebook
];
2287 redraw
= strips
* 2 + strips
;
2290 int b
= (int)*params
[param_bypass0
] + (int)*params
[param_bypass1
] + (int)*params
[param_bypass2
] + (int)*params
[param_bypass3
];
2292 redraw
= strips
* 2 + strips
;
2296 crossover
.set_mode(mode
+ 1);
2297 crossover
.set_filter(0, *params
[param_freq0
]);
2298 crossover
.set_filter(1, *params
[param_freq1
]);
2299 crossover
.set_filter(2, *params
[param_freq2
]);
2301 // set the params of all strips
2302 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
]);
2303 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
]);
2304 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
]);
2305 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
]);
2308 void multibandgate_audio_module::set_sample_rate(uint32_t sr
)
2311 // set srate of all strips
2312 for (int j
= 0; j
< strips
; j
++) {
2313 gate
[j
].set_sample_rate(srate
);
2315 // set srate of crossover
2316 crossover
.set_sample_rate(srate
);
2317 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
,
2318 param_output0
, -param_gating0
,
2319 param_output1
, -param_gating1
,
2320 param_output2
, -param_gating2
,
2321 param_output3
, -param_gating3
};
2322 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
, -1, -1, -1, -1, -1, -1, -1, -1};
2323 meters
.init(params
, meter
, clip
, 12, srate
);
2326 uint32_t multibandgate_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
2328 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
2329 numsamples
+= offset
;
2330 for (int i
= 0; i
< strips
; i
++)
2331 gate
[i
].update_curve();
2333 // everything bypassed
2334 while(offset
< numsamples
) {
2335 outs
[0][offset
] = ins
[0][offset
];
2336 outs
[1][offset
] = ins
[1][offset
];
2337 float values
[] = {0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1};
2338 meters
.process(values
);
2342 // process all strips
2343 uint32_t orig_numsamples
= numsamples
-offset
;
2344 uint32_t orig_offset
= offset
;
2345 while(offset
< numsamples
) {
2346 // cycle through samples
2347 float inL
= ins
[0][offset
];
2348 float inR
= ins
[1][offset
];
2350 inR
*= *params
[param_level_in
];
2351 inL
*= *params
[param_level_in
];
2352 // process crossover
2355 crossover
.process(xin
);
2359 for (int i
= 0; i
< strips
; i
++) {
2360 // cycle trough strips
2361 if (solo
[i
] || no_solo
) {
2363 float left
= crossover
.get_value(0, i
);
2364 float right
= crossover
.get_value(1, i
);
2365 gate
[i
].process(left
, right
);
2370 } // process single strip
2373 outL
*= *params
[param_level_out
];
2374 outR
*= *params
[param_level_out
];
2377 outs
[0][offset
] = outL
;
2378 outs
[1][offset
] = outR
;
2380 float values
[] = {inL
, inR
, outL
, outR
,
2381 *params
[param_bypass0
] > 0.5f
? 0 : gate
[0].get_output_level(), *params
[param_bypass0
] > 0.5f
? 1 : gate
[0].get_expander_level(),
2382 *params
[param_bypass1
] > 0.5f
? 0 : gate
[1].get_output_level(), *params
[param_bypass1
] > 0.5f
? 1 : gate
[1].get_expander_level(),
2383 *params
[param_bypass2
] > 0.5f
? 0 : gate
[2].get_output_level(), *params
[param_bypass2
] > 0.5f
? 1 : gate
[2].get_expander_level(),
2384 *params
[param_bypass3
] > 0.5f
? 0 : gate
[3].get_output_level(), *params
[param_bypass3
] > 0.5f
? 1 : gate
[3].get_expander_level() };
2385 meters
.process(values
);
2389 } // cycle trough samples
2390 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
2392 } // process all strips (no bypass)
2393 meters
.fall(numsamples
);
2394 return outputs_mask
;
2397 const expander_audio_module
*multibandgate_audio_module::get_strip_by_param_index(int index
) const
2399 // let's handle by the corresponding strip
2413 bool multibandgate_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
2417 redraw
= std::max(0, redraw
- 1);
2419 const expander_audio_module
*m
= get_strip_by_param_index(index
);
2421 r
= m
->get_graph(subindex
, data
, points
, context
, mode
);
2423 r
= crossover
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
2425 if ((index
== param_solo0
+ 12 * page
and subindex
== 1)
2426 or (index
== param_bypass
and subindex
== page
)) {
2429 if ((subindex
== 1 and index
!= param_bypass
)
2430 or (index
== param_bypass
)) {
2432 and ((index
!= param_bypass
and *params
[index
- 1])
2433 or (index
== param_bypass
and *params
[param_bypass0
+ 12 * subindex
])))
2434 context
->set_source_rgba(0.15, 0.2, 0.0, 0.15);
2436 context
->set_source_rgba(0.15, 0.2, 0.0, 0.5);
2441 bool multibandgate_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
2443 const expander_audio_module
*m
= get_strip_by_param_index(index
);
2445 return m
->get_dot(subindex
, x
, y
, size
, context
);
2449 bool multibandgate_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
2451 const expander_audio_module
*m
= get_strip_by_param_index(index
);
2453 return m
->get_gridline(subindex
, pos
, vertical
, legend
, context
);
2454 if (phase
) return false;
2455 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
2458 bool multibandgate_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
2461 const expander_audio_module
*m
= get_strip_by_param_index(index
);
2463 r
= m
->get_layers(index
, generation
, layers
);
2465 r
= crossover
.get_layers(index
, generation
, layers
);
2468 layers
|= LG_CACHE_GRAPH
;
2475 /**********************************************************************
2476 * TRANSIENT DESIGNER by Christian Holschuh and Markus Schmidt
2477 **********************************************************************/
2480 transientdesigner_audio_module::transientdesigner_audio_module() {
2490 pbuffer_available
= false;
2491 display_max
= pow(2,-12);
2492 transients
.set_channels(channels
);
2493 hp_f_old
= hp_m_old
= lp_f_old
= lp_m_old
= 0;
2496 transientdesigner_audio_module::~transientdesigner_audio_module()
2500 void transientdesigner_audio_module::activate() {
2504 void transientdesigner_audio_module::deactivate() {
2508 void transientdesigner_audio_module::params_changed() {
2509 if (*params
[param_display
] != display_old
) {
2510 dsp::zero(pbuffer
, (int)(pixels
* 2));
2511 display_old
= *params
[param_display
];
2513 transients
.set_params(*params
[param_attack_time
],
2514 *params
[param_attack_boost
],
2515 *params
[param_release_time
],
2516 *params
[param_release_boost
],
2517 *params
[param_sustain_threshold
],
2518 *params
[param_lookahead
]);
2519 if (hp_f_old
!= *params
[param_hipass
]) {
2520 hp
[0].set_hp_rbj(*params
[param_hipass
], 0.707, (float)srate
, 1.0);
2521 hp
[1].copy_coeffs(hp
[0]);
2522 hp
[2].copy_coeffs(hp
[0]);
2524 hp_f_old
= *params
[param_hipass
];
2526 if (lp_f_old
!= *params
[param_lopass
]) {
2527 lp
[0].set_lp_rbj(*params
[param_lopass
], 0.707, (float)srate
, 1.0);
2528 lp
[1].copy_coeffs(lp
[0]);
2529 lp
[2].copy_coeffs(lp
[0]);
2531 lp_f_old
= *params
[param_lopass
];
2533 if (hp_m_old
!= *params
[param_hp_mode
]) {
2535 hp_m_old
= *params
[param_hp_mode
];
2537 if (lp_m_old
!= *params
[param_lp_mode
]) {
2539 lp_m_old
= *params
[param_lp_mode
];
2543 uint32_t transientdesigner_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
) {
2544 uint32_t orig_offset
= offset
;
2545 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
2546 for(uint32_t i
= offset
; i
< offset
+ numsamples
; i
++) {
2547 float L
= ins
[0][i
];
2548 float R
= ins
[1][i
];
2553 float s
= (fabs(L
) + fabs(R
)) / 2;
2555 outs
[0][i
] = ins
[0][i
];
2556 outs
[1][i
] = ins
[1][i
];
2560 L
*= *params
[param_level_in
];
2561 R
*= *params
[param_level_in
];
2567 // transient designer
2568 float s
= (L
+ R
) / 2.f
;
2569 for (int k
= 0; k
< *params
[param_hp_mode
]; k
++)
2570 s
= hp
[k
].process(s
);
2571 for (int j
= 0; j
< *params
[param_lp_mode
]; j
++)
2572 s
= lp
[j
].process(s
);
2574 float values
[] = {L
, R
};
2575 transients
.process(values
, s
);
2577 L
= values
[0] * *params
[param_mix
] + L
* (*params
[param_mix
] * -1 + 1);
2578 R
= values
[1] * *params
[param_mix
] + R
* (*params
[param_mix
] * -1 + 1);
2581 L
*= *params
[param_level_out
];
2582 R
*= *params
[param_level_out
];
2585 if (*params
[param_listen
] > 0.5) {
2595 // fill pixel buffer (pbuffer)
2597 // the pixel buffer is an array holding all necessary values for
2598 // the line graph per pixel. its length is 5 times the available
2599 // pixel width of the graph multiplied with the maximum zoom
2600 // to hold input, output, attack, release and envelope data.
2602 // here we write the pixel buffer, get_graph will read its
2603 // contents later in a drawing event.
2605 // pbuffer_pos is the actual position in the array we are writing
2606 // to. It points to the first position of a set of the 5 values.
2608 // Since we have more audio samples than pixels we add a couple
2609 // of samples to one pixel before we step forward with pbuffer_pos.
2611 if (pbuffer_available
) {
2612 // sanitize the buffer position if enough samples have
2613 // been captured. This is recognized by a negative value
2614 for (int i
= 0; i
< 5; i
++) {
2615 pbuffer
[pbuffer_pos
+ i
] = std::max(pbuffer
[pbuffer_pos
+ i
], 0.f
);
2618 // add samples to the buffer at the actual address
2619 pbuffer
[pbuffer_pos
] = std::max(s
, pbuffer
[pbuffer_pos
]);
2620 pbuffer
[pbuffer_pos
+ 1] = std::max((float)(fabs(L
) + fabs(R
)), (float)pbuffer
[pbuffer_pos
+ 1]);
2623 pbuffer
[pbuffer_pos
+ 2] = 0;
2624 pbuffer
[pbuffer_pos
+ 3] = 0;
2625 pbuffer
[pbuffer_pos
+ 4] = 0;
2627 pbuffer
[pbuffer_pos
+ 2] = transients
.envelope
;
2628 pbuffer
[pbuffer_pos
+ 3] = transients
.attack
;
2629 pbuffer
[pbuffer_pos
+ 4] = transients
.release
;
2632 pbuffer_sample
+= 1;
2634 if (pbuffer_sample
>= (int)(srate
* *params
[param_display
] / 1000.f
/ pixels
)) {
2635 // we captured enough samples for one pixel on this
2636 // address. to keep track of the finalization invert
2637 // its values as a marker to sanitize in the next
2638 // cycle before adding samples again
2639 pbuffer
[pbuffer_pos
] *= -1.f
* *params
[param_level_in
];
2640 pbuffer
[pbuffer_pos
+ 1] /= -2.f
;
2642 // advance the buffer position
2643 pbuffer_pos
= (pbuffer_pos
+ 5) % pbuffer_size
;
2645 // reset sample counter
2651 if ( transients
.envelope
== transients
.release
2652 and transients
.envelope
> *params
[param_display_threshold
]
2653 and attcount
>= srate
/ 100
2654 and pbuffer_available
) {
2655 int diff
= (int)(srate
/ 10 / pixels
);
2657 attack_pos
= (pbuffer_pos
- diff
* 5 + pbuffer_size
) % pbuffer_size
;
2660 float mval
[] = {meter_inL
, meter_inR
, meter_outL
, meter_outR
};
2661 meters
.process(mval
);
2664 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
2665 meters
.fall(numsamples
);
2666 return outputs_mask
;
2669 void transientdesigner_audio_module::set_sample_rate(uint32_t sr
)
2672 attcount
= srate
/ 5;
2673 transients
.set_sample_rate(srate
);
2674 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
};
2675 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
};
2676 meters
.init(params
, meter
, clip
, 4, srate
);
2678 bool transientdesigner_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
2680 if (index
== param_hipass
) {
2681 // frequency response
2682 if (subindex
) return false;
2685 for (int i
= 0; i
< points
; i
++) {
2687 freq
= 20.0 * pow (20000.0 / 20.0, i
* 1.0 / points
);
2688 if(*params
[param_hp_mode
])
2689 ret
*= pow(hp
[0].freq_gain(freq
, (float)srate
), *params
[param_hp_mode
]);
2690 if(*params
[param_lp_mode
])
2691 ret
*= pow(lp
[0].freq_gain(freq
, (float)srate
), *params
[param_lp_mode
]);
2692 data
[i
] = dB_grid(ret
);
2698 if (subindex
>= 2 or (*params
[param_bypass
] > 0.5f
and subindex
>= 1))
2702 if (points
!= pixels
) {
2703 // the zoom level changed or it's the first time we want to draw
2706 // buffer size is the amount of pixels for the max display value
2707 // if drawn in the min display zoom level multiplied by 5 for
2708 // keeping the input and the output fabs signals and all graphs
2710 pbuffer_size
= (int)(points
* 5 * 100);
2712 pbuffer
= (float*) calloc(pbuffer_size
, sizeof(float));
2714 // sanitize some indexes and addresses
2718 pbuffer_available
= true;
2721 // check if threshold is above minimum - we want to see trigger hold
2722 bool hold
= *params
[param_display_threshold
] > display_max
;
2723 // set the address to start from in both drawing cycles
2724 // to amount of pixels before pbuffer_pos or to attack_pos
2725 if (subindex
== 0) {
2726 int pos
= hold
? attack_pos
: pbuffer_pos
;
2727 pbuffer_draw
= hold
? pos
: (pbuffer_size
+ pos
- pixels
* 5) % pbuffer_size
;
2732 draw_curve
= subindex
+ *params
[param_view
];
2735 // input is drawn as bars with less opacity
2737 context
->set_source_rgba(0.15, 0.2, 0.0, 0.2);
2739 // output/envelope is a precise line
2740 context
->set_line_width(0.75);
2744 for (int i
= 0; i
<= points
; i
++) {
2745 int pos
= (pbuffer_draw
+ i
* 5) % pbuffer_size
+ draw_curve
;
2747 and ((pos
> pbuffer_pos
and ((pbuffer_pos
> attack_pos
and pos
> attack_pos
)
2748 or (pbuffer_pos
< attack_pos
and pos
< attack_pos
)))
2749 or (pbuffer_pos
> attack_pos
and pos
< attack_pos
))) {
2750 // we are drawing trigger hold stuff outside the hold window
2751 // so we don't want to see old data - zero it out.
2752 data
[i
] = dB_grid(2.51e-10, 128, 0.6);
2755 data
[i
] = dB_grid(fabs(pbuffer
[pos
]) + 2.51e-10, 128, 0.6);
2760 bool transientdesigner_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
2762 if (index
== param_hipass
)
2763 // frequency response
2764 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
2766 if (subindex
>= 16 or phase
)
2768 float gain
= 16.f
/ (1 << subindex
);
2769 pos
= dB_grid(gain
, 128, 0.6);
2770 context
->set_source_rgba(0, 0, 0, subindex
& 1 ? 0.1 : 0.2);
2771 if (!(subindex
& 1) and subindex
) {
2772 std::stringstream ss
;
2773 ss
<< (24 - 6 * subindex
) << " dB";
2779 bool transientdesigner_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
2781 if (index
== param_hipass
) {
2782 layers
= (redraw
|| !generation
? LG_CACHE_GRAPH
: LG_NONE
) | (generation
? LG_NONE
: LG_CACHE_GRID
);
2785 layers
= LG_REALTIME_GRAPH
| (generation
? 0 : LG_CACHE_GRID
);