2 * Example audio modules - DSP code
4 * Copyright (C) 2001-2008 Krzysztof Foltman
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
26 #include <jack/jack.h>
28 #include <calf/giface.h>
29 #include <calf/modules.h>
30 #include <calf/modules_dev.h>
33 using namespace calf_plugins
;
35 /// convert amplitude value to normalized grid-ish value (0dB = 0.5, 30dB = 1.0, -30 dB = 0.0, -60dB = -0.5, -90dB = -1.0)
36 static inline float dB_grid(float amp
)
38 return log(amp
) * (1.0 / log(256.0)) + 0.4;
42 static bool get_graph(Fx
&fx
, int subindex
, float *data
, int points
)
44 for (int i
= 0; i
< points
; i
++)
46 typedef std::complex<double> cfloat
;
47 double freq
= 20.0 * pow (20000.0 / 20.0, i
* 1.0 / points
);
48 data
[i
] = dB_grid(fx
.freq_gain(subindex
, freq
, fx
.srate
));
53 /// convert normalized grid-ish value back to amplitude value
54 static inline float dB_grid_inv(float pos
)
56 return pow(256.0, pos
- 0.4);
59 static void set_channel_color(cairo_iface
*context
, int channel
)
62 context
->set_source_rgba(0.35, 0.4, 0.2, 1);
64 context
->set_source_rgba(0.35, 0.4, 0.2, 0.5);
65 context
->set_line_width(1.5);
68 static bool get_freq_gridline(int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
, bool use_frequencies
= true)
77 if (subindex
== 9) legend
= "100 Hz";
78 if (subindex
== 18) legend
= "1 kHz";
79 if (subindex
== 27) legend
= "10 kHz";
82 freq
= 10 * (subindex
+ 1);
83 else if (subindex
< 18)
84 freq
= 100 * (subindex
- 9 + 1);
85 else if (subindex
< 27)
86 freq
= 1000 * (subindex
- 18 + 1);
88 freq
= 10000 * (subindex
- 27 + 1);
89 pos
= log(freq
/ 20.0) / log(1000);
91 context
->set_source_rgba(0, 0, 0, 0.2);
93 context
->set_source_rgba(0, 0, 0, 0.1);
100 float gain
= 16.0 / (1 << subindex
);
105 context
->set_source_rgba(0, 0, 0, subindex
& 1 ? 0.1 : 0.2);
108 std::stringstream ss
;
109 ss
<< (24 - 6 * subindex
) << " dB";
116 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
118 bool frequency_response_line_graph::get_gridline(int index
, int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
)
120 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
123 int frequency_response_line_graph::get_changed_offsets(int index
, int generation
, int &subindex_graph
, int &subindex_dot
, int &subindex_gridline
)
127 subindex_gridline
= generation
? INT_MAX
: 0;
131 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
133 void flanger_audio_module::activate() {
136 last_r_phase
= *params
[par_stereo
] * (1.f
/ 360.f
);
137 left
.reset_phase(0.f
);
138 right
.reset_phase(last_r_phase
);
142 void flanger_audio_module::set_sample_rate(uint32_t sr
) {
148 void flanger_audio_module::deactivate() {
152 bool flanger_audio_module::get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
)
156 if (index
== par_delay
&& subindex
< 2)
158 set_channel_color(context
, subindex
);
159 return ::get_graph(*this, subindex
, data
, points
);
164 float flanger_audio_module::freq_gain(int subindex
, float freq
, float srate
)
166 return (subindex
? right
: left
).freq_gain(freq
, srate
);
169 ///////////////////////////////////////////////////////////////////////////////////////////////
171 void phaser_audio_module::set_sample_rate(uint32_t sr
)
178 void phaser_audio_module::activate()
183 last_r_phase
= *params
[par_stereo
] * (1.f
/ 360.f
);
184 left
.reset_phase(0.f
);
185 right
.reset_phase(last_r_phase
);
188 void phaser_audio_module::deactivate()
193 bool phaser_audio_module::get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
)
199 set_channel_color(context
, subindex
);
200 return ::get_graph(*this, subindex
, data
, points
);
205 float phaser_audio_module::freq_gain(int subindex
, float freq
, float srate
)
207 return (subindex
? right
: left
).freq_gain(freq
, srate
);
210 bool phaser_audio_module::get_gridline(int index
, int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
)
212 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
215 ///////////////////////////////////////////////////////////////////////////////////////////////
217 void reverb_audio_module::activate()
222 void reverb_audio_module::deactivate()
226 void reverb_audio_module::set_sample_rate(uint32_t sr
)
230 amount
.set_sample_rate(sr
);
233 ///////////////////////////////////////////////////////////////////////////////////////////////
235 bool filter_audio_module::get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
)
239 if (index
== par_cutoff
&& !subindex
) {
240 context
->set_line_width(1.5);
241 return ::get_graph(*this, subindex
, data
, points
);
246 int filter_audio_module::get_changed_offsets(int index
, int generation
, int &subindex_graph
, int &subindex_dot
, int &subindex_gridline
)
248 if (fabs(inertia_cutoff
.get_last() - old_cutoff
) + 100 * fabs(inertia_resonance
.get_last() - old_resonance
) + fabs(*params
[par_mode
] - old_mode
) > 0.1f
)
250 old_cutoff
= inertia_cutoff
.get_last();
251 old_resonance
= inertia_resonance
.get_last();
252 old_mode
= *params
[par_mode
];
255 subindex_dot
= INT_MAX
;
256 subindex_gridline
= INT_MAX
;
260 subindex_dot
= subindex_gridline
= generation
? INT_MAX
: 0;
262 if (generation
== last_calculated_generation
)
263 subindex_graph
= INT_MAX
;
264 return last_generation
;
268 ///////////////////////////////////////////////////////////////////////////////////////////////
270 bool filterclavier_audio_module::get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
)
272 if (!is_active
|| index
!= par_mode
) {
276 context
->set_line_width(1.5);
277 return ::get_graph(*this, subindex
, data
, points
);
282 ///////////////////////////////////////////////////////////////////////////////////////////////
284 rotary_speaker_audio_module::rotary_speaker_audio_module()
286 mwhl_value
= hold_value
= 0.f
;
287 phase_h
= phase_l
= 0.f
;
293 void rotary_speaker_audio_module::set_sample_rate(uint32_t sr
)
299 void rotary_speaker_audio_module::setup()
301 crossover1l
.set_lp_rbj(800.f
, 0.7, (float)srate
);
302 crossover1r
.set_lp_rbj(800.f
, 0.7, (float)srate
);
303 crossover2l
.set_hp_rbj(800.f
, 0.7, (float)srate
);
304 crossover2r
.set_hp_rbj(800.f
, 0.7, (float)srate
);
307 void rotary_speaker_audio_module::activate()
309 phase_h
= phase_l
= 0.f
;
310 maspeed_h
= maspeed_l
= 0.f
;
314 void rotary_speaker_audio_module::deactivate()
318 void rotary_speaker_audio_module::control_change(int ctl
, int val
)
320 if (vibrato_mode
== 3 && ctl
== 64)
322 hold_value
= val
/ 127.f
;
326 if (vibrato_mode
== 4 && ctl
== 1)
328 mwhl_value
= val
/ 127.f
;
334 ///////////////////////////////////////////////////////////////////////////////////////////////
336 void multichorus_audio_module::activate()
342 void multichorus_audio_module::deactivate()
347 void multichorus_audio_module::set_sample_rate(uint32_t sr
) {
353 bool multichorus_audio_module::get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
)
357 int nvoices
= (int)*params
[par_voices
];
358 if (index
== par_delay
&& subindex
< 3)
361 set_channel_color(context
, subindex
);
363 context
->set_source_rgba(0.35, 0.4, 0.2);
364 context
->set_line_width(1.0);
366 return ::get_graph(*this, subindex
, data
, points
);
368 if (index
== par_rate
&& subindex
< nvoices
) {
369 sine_multi_lfo
<float, 8> &lfo
= left
.lfo
;
370 for (int i
= 0; i
< points
; i
++) {
371 float phase
= i
* 2 * M_PI
/ points
;
372 // original -65536 to 65535 value
373 float orig
= subindex
* lfo
.voice_offset
+ ((lfo
.voice_depth
>> (30-13)) * 65536.0 * (0.95 * sin(phase
) + 1)/ 8192.0) - 65536;
375 data
[i
] = orig
/ 65536.0;
382 bool multichorus_audio_module::get_dot(int index
, int subindex
, float &x
, float &y
, int &size
, cairo_iface
*context
)
384 int voice
= subindex
>> 1;
385 int nvoices
= (int)*params
[par_voices
];
386 if ((index
!= par_rate
&& index
!= par_depth
) || voice
>= nvoices
)
389 float unit
= (1 - *params
[par_overlap
]);
390 float scw
= 1 + unit
* (nvoices
- 1);
391 set_channel_color(context
, subindex
);
392 sine_multi_lfo
<float, 8> &lfo
= (subindex
& 1 ? right
: left
).lfo
;
393 if (index
== par_rate
)
395 x
= (double)(lfo
.phase
+ lfo
.vphase
* voice
) / 4096.0;
396 y
= 0.95 * sin(x
* 2 * M_PI
);
397 y
= (voice
* unit
+ (y
+ 1) / 2) / scw
* 2 - 1;
401 double ph
= (double)(lfo
.phase
+ lfo
.vphase
* voice
) / 4096.0;
402 x
= 0.5 + 0.5 * sin(ph
* 2 * M_PI
);
403 y
= subindex
& 1 ? -0.75 : 0.75;
404 x
= (voice
* unit
+ x
) / scw
;
409 bool multichorus_audio_module::get_gridline(int index
, int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
)
411 if (index
== par_rate
&& !subindex
)
417 if (index
== par_delay
)
418 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
422 float multichorus_audio_module::freq_gain(int subindex
, float freq
, float srate
)
425 return *params
[par_amount
] * left
.post
.freq_gain(freq
, srate
);
426 return (subindex
? right
: left
).freq_gain(freq
, srate
);
429 ///////////////////////////////////////////////////////////////////////////////////////////////
431 compressor_audio_module::compressor_audio_module()
438 void compressor_audio_module::activate()
446 void compressor_audio_module::deactivate()
451 void compressor_audio_module::set_sample_rate(uint32_t sr
)
458 bool compressor_audio_module::get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
)
462 if (subindex
> 1) // 1
464 for (int i
= 0; i
< points
; i
++)
466 float input
= dB_grid_inv(-1.0 + i
* 2.0 / (points
- 1));
467 float output
= output_level(input
);
469 data
[i
] = dB_grid(input
);
471 data
[i
] = dB_grid(output
);
473 if (subindex
== (*params
[param_bypass
] > 0.5f
? 1 : 0))
474 context
->set_source_rgba(0.35, 0.4, 0.2, 0.3);
476 context
->set_source_rgba(0.35, 0.4, 0.2, 1);
477 context
->set_line_width(2);
482 bool compressor_audio_module::get_dot(int index
, int subindex
, float &x
, float &y
, int &size
, cairo_iface
*context
)
488 bool rms
= *params
[param_detection
] == 0;
489 float det
= rms
? sqrt(detected
) : detected
;
490 x
= 0.5 + 0.5 * dB_grid(det
);
491 y
= dB_grid(*params
[param_bypass
] > 0.5f
? det
: output_level(det
));
492 return *params
[param_bypass
] > 0.5f
? false : true;
497 bool compressor_audio_module::get_gridline(int index
, int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
)
500 vertical
= (subindex
& 1) != 0;
501 bool result
= get_freq_gridline(subindex
>> 1, pos
, tmp
, legend
, context
, false);
502 if (result
&& vertical
) {
503 if ((subindex
& 4) && !legend
.empty()) {
507 size_t pos
= legend
.find(" dB");
508 if (pos
!= std::string::npos
)
511 pos
= 0.5 + 0.5 * pos
;
516 // In case of doubt: this function is written by Thor. I just moved it to this file, damaging
517 // the output of "git annotate" in the process.
518 uint32_t compressor_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
520 bool bypass
= *params
[param_bypass
] > 0.5f
;
523 numsamples
+= offset
;
524 while(offset
< numsamples
) {
525 outs
[0][offset
] = ins
[0][offset
];
526 outs
[1][offset
] = ins
[1][offset
];
530 if(params
[param_compression
] != NULL
) {
531 *params
[param_compression
] = 1.f
;
534 if(params
[param_clip
] != NULL
) {
535 *params
[param_clip
] = 0.f
;
538 if(params
[param_peak
] != NULL
) {
539 *params
[param_peak
] = 0.f
;
545 bool rms
= *params
[param_detection
] == 0;
546 bool average
= *params
[param_stereo_link
] == 0;
547 int aweighting
= fastf2i_drm(*params
[param_aweighting
]);
548 float linThreshold
= *params
[param_threshold
];
549 ratio
= *params
[param_ratio
];
550 float attack
= *params
[param_attack
];
551 float attack_coeff
= std::min(1.f
, 1.f
/ (attack
* srate
/ 4000.f
));
552 float release
= *params
[param_release
];
553 float release_coeff
= std::min(1.f
, 1.f
/ (release
* srate
/ 4000.f
));
554 makeup
= *params
[param_makeup
];
555 knee
= *params
[param_knee
];
557 float linKneeSqrt
= sqrt(knee
);
558 linKneeStart
= linThreshold
/ linKneeSqrt
;
559 adjKneeStart
= linKneeStart
*linKneeStart
;
560 float linKneeStop
= linThreshold
* linKneeSqrt
;
562 threshold
= log(linThreshold
);
563 kneeStart
= log(linKneeStart
);
564 kneeStop
= log(linKneeStop
);
565 compressedKneeStop
= (kneeStop
- threshold
) / ratio
+ threshold
;
569 bpL
.set_highshelf_rbj(5000, 0.707, 10 << (aweighting
- 2), srate
);
570 bpR
.copy_coeffs(bpL
);
575 numsamples
+= offset
;
577 float compression
= 1.f
;
579 clip
-= std::min(clip
, numsamples
);
581 while(offset
< numsamples
) {
582 float left
= ins
[0][offset
] * *params
[param_input
];
583 float right
= ins
[1][offset
] * *params
[param_input
];
585 if(aweighting
== 1) {
586 left
= awL
.process(left
);
587 right
= awR
.process(right
);
589 else if(aweighting
>= 2) {
590 left
= bpL
.process(left
);
591 right
= bpR
.process(right
);
594 float absample
= average
? (fabs(left
) + fabs(right
)) * 0.5f
: std::max(fabs(left
), fabs(right
));
595 if(rms
) absample
*= absample
;
597 linSlope
+= (absample
- linSlope
) * (absample
> linSlope
? attack_coeff
: release_coeff
);
602 gain
= output_gain(linSlope
, rms
);
608 float outL
= ins
[0][offset
] * gain
* *params
[param_input
];
609 float outR
= ins
[1][offset
] * gain
* *params
[param_input
];
611 outs
[0][offset
] = outL
;
612 outs
[1][offset
] = outR
;
616 float maxLR
= std::max(fabs(outL
), fabs(outR
));
620 if(peak
> 1.f
) clip
= srate
>> 3; /* blink clip LED for 125 ms */
625 if(params
[param_compression
] != NULL
) {
626 *params
[param_compression
] = compression
;
629 if(params
[param_clip
] != NULL
) {
630 *params
[param_clip
] = clip
;
633 if(params
[param_peak
] != NULL
) {
634 *params
[param_peak
] = peak
;
641 /// Multibandcompressor by Markus Schmidt
643 /// This module splits the signal in four different bands
644 /// and sends them through multiple filters (implemented by
645 /// Krzysztof). They are processed by a compressing routine
646 /// (implemented by Thor) afterwards and summed up to the
647 /// final output again.
648 ///////////////////////////////////////////////////////////////////////////////////////////////
650 multibandcompressor_audio_module::multibandcompressor_audio_module()
665 void multibandcompressor_audio_module::activate()
668 // set all filters and strips
670 // activate all strips
671 for (int j
= 0; j
< strips
; j
++) {
677 void multibandcompressor_audio_module::deactivate()
680 // deactivate all strips
681 for (int j
= 0; j
< strips
; j
++) {
682 strip
[j
].deactivate();
686 void multibandcompressor_audio_module::params_changed()
688 // set the params of all filters
689 if(*params
[param_freq0
] != freq_old
[0] or *params
[param_sep0
] != sep_old
[0] or *params
[param_q0
] != q_old
[0]) {
690 lpL0
.set_lp_rbj((float)(*params
[param_freq0
] * (1 - *params
[param_sep0
])), *params
[param_q0
], (float)srate
);
691 lpR0
.copy_coeffs(lpL0
);
692 hpL0
.set_hp_rbj((float)(*params
[param_freq0
] * (1 + *params
[param_sep0
])), *params
[param_q0
], (float)srate
);
693 hpR0
.copy_coeffs(hpL0
);
694 freq_old
[0] = *params
[param_freq0
];
695 sep_old
[0] = *params
[param_sep2
];
696 q_old
[0] = *params
[param_q2
];
698 if(*params
[param_freq1
] != freq_old
[1] or *params
[param_sep1
] != sep_old
[1] or *params
[param_q1
] != q_old
[1]) {
699 lpL1
.set_lp_rbj((float)(*params
[param_freq1
] * (1 - *params
[param_sep1
])), *params
[param_q1
], (float)srate
);
700 lpR1
.copy_coeffs(lpL1
);
701 hpL1
.set_hp_rbj((float)(*params
[param_freq1
] * (1 + *params
[param_sep1
])), *params
[param_q1
], (float)srate
);
702 hpR1
.copy_coeffs(hpL1
);
703 freq_old
[1] = *params
[param_freq1
];
704 sep_old
[1] = *params
[param_sep2
];
705 q_old
[1] = *params
[param_q2
];
707 if(*params
[param_freq2
] != freq_old
[2] or *params
[param_sep2
] != sep_old
[2] or *params
[param_q2
] != q_old
[2]) {
708 lpL2
.set_lp_rbj((float)(*params
[param_freq2
] * (1 - *params
[param_sep2
])), *params
[param_q2
], (float)srate
);
709 lpR2
.copy_coeffs(lpL2
);
710 hpL2
.set_hp_rbj((float)(*params
[param_freq2
] * (1 + *params
[param_sep2
])), *params
[param_q2
], (float)srate
);
711 hpR2
.copy_coeffs(hpL2
);
712 freq_old
[2] = *params
[param_freq2
];
713 sep_old
[2] = *params
[param_sep2
];
714 q_old
[2] = *params
[param_q2
];
716 // set the params of all strips
717 for (int j
= 0; j
< strips
; j
++) {
720 strip
[j
].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
], *params
[param_mute0
]);
723 strip
[j
].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
], *params
[param_mute1
]);
726 strip
[j
].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
], *params
[param_mute2
]);
729 strip
[j
].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
], *params
[param_mute3
]);
735 void multibandcompressor_audio_module::set_sample_rate(uint32_t sr
)
738 // set srate of all strips
739 for (int j
= 0; j
< strips
; j
++) {
740 strip
[j
].set_sample_rate(srate
);
744 uint32_t multibandcompressor_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
746 bool bypass
= *params
[param_bypass
] > 0.5f
;
747 numsamples
+= offset
;
749 // everything bypassed
750 while(offset
< numsamples
) {
751 outs
[0][offset
] = ins
[0][offset
];
752 outs
[1][offset
] = ins
[1][offset
];
765 // process all strips
767 // determine mute state of strips
768 mute
[0] = *params
[param_mute0
] > 0.f
? true : false;
769 mute
[1] = *params
[param_mute1
] > 0.f
? true : false;
770 mute
[2] = *params
[param_mute2
] > 0.f
? true : false;
771 mute
[3] = *params
[param_mute3
] > 0.f
? true : false;
773 // let meters fall a bit
774 clip_inL
-= std::min(clip_inL
, numsamples
);
775 clip_inR
-= std::min(clip_inR
, numsamples
);
776 clip_outL
-= std::min(clip_outL
, numsamples
);
777 clip_outR
-= std::min(clip_outR
, numsamples
);
782 while(offset
< numsamples
) {
783 // cycle through samples
784 float inL
= ins
[0][offset
];
785 float inR
= ins
[1][offset
];
787 inR
*= *params
[param_level_in
];
788 inL
*= *params
[param_level_in
];
792 for (int i
= 0; i
< strips
; i
++) {
793 // cycle trough strips
798 // send trough filters
801 left
= lpL0
.process(left
);
802 right
= lpR0
.process(right
);
807 left
= lpL1
.process(left
);
808 right
= lpR1
.process(right
);
809 left
= hpL0
.process(left
);
810 right
= hpR0
.process(right
);
817 left
= lpL2
.process(left
);
818 right
= lpR2
.process(right
);
819 left
= hpL1
.process(left
);
820 right
= hpR1
.process(right
);
827 left
= hpL2
.process(left
);
828 right
= hpR2
.process(right
);
833 // process gain reduction
834 strip
[i
].process(left
, right
);
844 } // process single strip
846 // even out filters gain reduction
847 // 3dB - levelled manually (based on default sep and q settings)
852 outL
*= *params
[param_level_out
];
853 outR
*= *params
[param_level_out
];
856 outs
[0][offset
] = outL
;
857 outs
[1][offset
] = outR
;
861 clip_inL
= srate
>> 3;
864 clip_inR
= srate
>> 3;
867 clip_outL
= srate
>> 3;
870 clip_outR
= srate
>> 3;
872 // set up in / out meters
873 if(inL
> meter_inL
) {
876 if(inR
> meter_inR
) {
879 if(outL
> meter_outL
) {
882 if(outR
> meter_outR
) {
887 } // cycle trough samples
889 } // process all strips (no bypass)
892 if(params
[param_clip_inL
] != NULL
) {
893 *params
[param_clip_inL
] = clip_inL
;
895 if(params
[param_clip_inR
] != NULL
) {
896 *params
[param_clip_inR
] = clip_inR
;
898 if(params
[param_clip_outL
] != NULL
) {
899 *params
[param_clip_outL
] = clip_outL
;
901 if(params
[param_clip_outR
] != NULL
) {
902 *params
[param_clip_outR
] = clip_outR
;
905 if(params
[param_meter_inL
] != NULL
) {
906 *params
[param_meter_inL
] = meter_inL
;
908 if(params
[param_meter_inR
] != NULL
) {
909 *params
[param_meter_inR
] = meter_inR
;
911 if(params
[param_meter_outL
] != NULL
) {
912 *params
[param_meter_outL
] = meter_outL
;
914 if(params
[param_meter_outR
] != NULL
) {
915 *params
[param_meter_outR
] = meter_outR
;
919 if(params
[param_compression0
] != NULL
) {
920 *params
[param_compression0
] = 1.0f
;
922 if(params
[param_compression1
] != NULL
) {
923 *params
[param_compression1
] = 1.0f
;
925 if(params
[param_compression2
] != NULL
) {
926 *params
[param_compression2
] = 1.0f
;
928 if(params
[param_compression3
] != NULL
) {
929 *params
[param_compression3
] = 1.0f
;
932 if(params
[param_output0
] != NULL
) {
933 *params
[param_output0
] = 0.0f
;
935 if(params
[param_output1
] != NULL
) {
936 *params
[param_output1
] = 0.0f
;
938 if(params
[param_output2
] != NULL
) {
939 *params
[param_output2
] = 0.0f
;
941 if(params
[param_output3
] != NULL
) {
942 *params
[param_output3
] = 0.0f
;
945 if(params
[param_compression0
] != NULL
) {
946 *params
[param_compression0
] = strip
[0].get_comp_level();
948 if(params
[param_compression1
] != NULL
) {
949 *params
[param_compression1
] = strip
[1].get_comp_level();
951 if(params
[param_compression2
] != NULL
) {
952 *params
[param_compression2
] = strip
[2].get_comp_level();
954 if(params
[param_compression3
] != NULL
) {
955 *params
[param_compression3
] = strip
[3].get_comp_level();
958 if(params
[param_output0
] != NULL
) {
959 *params
[param_output0
] = strip
[0].get_output_level();
961 if(params
[param_output1
] != NULL
) {
962 *params
[param_output1
] = strip
[1].get_output_level();
964 if(params
[param_output2
] != NULL
) {
965 *params
[param_output2
] = strip
[2].get_output_level();
967 if(params
[param_output3
] != NULL
) {
968 *params
[param_output3
] = strip
[3].get_output_level();
971 // whatever has to be returned x)
974 bool multibandcompressor_audio_module::get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
)
976 // let's handle by the corresponding strip
978 case param_compression0
:
979 return strip
[0].get_graph(subindex
, data
, points
, context
);
981 case param_compression1
:
982 return strip
[1].get_graph(subindex
, data
, points
, context
);
984 case param_compression2
:
985 return strip
[2].get_graph(subindex
, data
, points
, context
);
987 case param_compression3
:
988 return strip
[3].get_graph(subindex
, data
, points
, context
);
994 bool multibandcompressor_audio_module::get_dot(int index
, int subindex
, float &x
, float &y
, int &size
, cairo_iface
*context
)
996 // let's handle by the corresponding strip
998 case param_compression0
:
999 return strip
[0].get_dot(subindex
, x
, y
, size
, context
);
1001 case param_compression1
:
1002 return strip
[1].get_dot(subindex
, x
, y
, size
, context
);
1004 case param_compression2
:
1005 return strip
[2].get_dot(subindex
, x
, y
, size
, context
);
1007 case param_compression3
:
1008 return strip
[3].get_dot(subindex
, x
, y
, size
, context
);
1014 bool multibandcompressor_audio_module::get_gridline(int index
, int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
)
1016 // let's handle by the corresponding strip
1018 case param_compression0
:
1019 return strip
[0].get_gridline(subindex
, pos
, vertical
, legend
, context
);
1021 case param_compression1
:
1022 return strip
[1].get_gridline(subindex
, pos
, vertical
, legend
, context
);
1024 case param_compression2
:
1025 return strip
[2].get_gridline(subindex
, pos
, vertical
, legend
, context
);
1027 case param_compression3
:
1028 return strip
[3].get_gridline(subindex
, pos
, vertical
, legend
, context
);
1034 int multibandcompressor_audio_module::get_changed_offsets(int index
, int generation
, int &subindex_graph
, int &subindex_dot
, int &subindex_gridline
)
1036 // let's handle by the corresponding strip
1038 case param_compression0
:
1039 return strip
[0].get_changed_offsets(generation
, subindex_graph
, subindex_dot
, subindex_gridline
);
1041 case param_compression1
:
1042 return strip
[1].get_changed_offsets(generation
, subindex_graph
, subindex_dot
, subindex_gridline
);
1044 case param_compression2
:
1045 return strip
[2].get_changed_offsets(generation
, subindex_graph
, subindex_dot
, subindex_gridline
);
1047 case param_compression3
:
1048 return strip
[3].get_changed_offsets(generation
, subindex_graph
, subindex_dot
, subindex_gridline
);
1054 /// Sidecain Compressor by Markus Schmidt
1056 /// This module splits the signal in a sidechain- and a process signal.
1057 /// The sidechain is processed through Krzystofs filters and compresses
1058 /// the process signal via Thor's compression routine afterwards.
1059 ///////////////////////////////////////////////////////////////////////////////////////////////
1061 sidechaincompressor_audio_module::sidechaincompressor_audio_module()
1065 last_generation
= 0;
1068 void sidechaincompressor_audio_module::activate()
1071 // set all filters and strips
1072 compressor
.activate();
1079 void sidechaincompressor_audio_module::deactivate()
1082 compressor
.deactivate();
1085 void sidechaincompressor_audio_module::params_changed()
1087 // set the params of all filters
1088 if(*params
[param_f1_freq
] != f1_freq_old
or *params
[param_f1_level
] != f1_level_old
1089 or *params
[param_f2_freq
] != f2_freq_old
or *params
[param_f2_level
] != f2_level_old
1090 or *params
[param_sc_mode
] != sc_mode
) {
1092 switch ((int)*params
[param_sc_mode
]) {
1095 f1L
.set_hp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
1096 f1R
.copy_coeffs(f1L
);
1097 f2L
.set_lp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
1098 f2R
.copy_coeffs(f2L
);
1103 f1L
.set_peakeq_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
1104 f1R
.copy_coeffs(f1L
);
1105 f2L
.set_hp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
1106 f2R
.copy_coeffs(f2L
);
1111 f1L
.set_lp_rbj((float)*params
[param_f2_freq
] * (1 + 0.17), q
, (float)srate
);
1112 f1R
.copy_coeffs(f1L
);
1113 f2L
.set_hp_rbj((float)*params
[param_f2_freq
] * (1 - 0.17), q
, (float)srate
, *params
[param_f2_level
]);
1114 f2R
.copy_coeffs(f2L
);
1118 case DERUMBLER_WIDE
:
1119 f1L
.set_lp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
1120 f1R
.copy_coeffs(f1L
);
1121 f2L
.set_peakeq_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1122 f2R
.copy_coeffs(f2L
);
1126 case DERUMBLER_SPLIT
:
1127 f1L
.set_lp_rbj((float)*params
[param_f1_freq
] * (1 + 0.17), q
, (float)srate
, *params
[param_f1_level
]);
1128 f1R
.copy_coeffs(f1L
);
1129 f2L
.set_hp_rbj((float)*params
[param_f1_freq
] * (1 - 0.17), q
, (float)srate
);
1130 f2R
.copy_coeffs(f2L
);
1135 f1L
.set_lowshelf_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
1136 f1R
.copy_coeffs(f1L
);
1137 f2L
.set_highshelf_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1138 f2R
.copy_coeffs(f2L
);
1143 f1L
.set_lowshelf_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
1144 f1R
.copy_coeffs(f1L
);
1145 f2L
.set_peakeq_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1146 f2R
.copy_coeffs(f2L
);
1151 f1L
.set_peakeq_rbj((float)*params
[param_f1_freq
], q
, *params
[param_f1_level
], (float)srate
);
1152 f1R
.copy_coeffs(f1L
);
1153 f2L
.set_highshelf_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1154 f2R
.copy_coeffs(f2L
);
1159 f1L
.set_bp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
1160 f1R
.copy_coeffs(f1L
);
1161 f2L
.set_hp_rbj((float)*params
[param_f2_freq
], q
, *params
[param_f2_level
], (float)srate
);
1162 f2R
.copy_coeffs(f2L
);
1167 f1L
.set_hp_rbj((float)*params
[param_f1_freq
], q
, (float)srate
, *params
[param_f1_level
]);
1168 f1R
.copy_coeffs(f1L
);
1169 f2L
.set_lp_rbj((float)*params
[param_f2_freq
], q
, (float)srate
, *params
[param_f2_level
]);
1170 f2R
.copy_coeffs(f2L
);
1175 f1_freq_old
= *params
[param_f1_freq
];
1176 f1_level_old
= *params
[param_f1_level
];
1177 f2_freq_old
= *params
[param_f2_freq
];
1178 f2_level_old
= *params
[param_f2_level
];
1179 sc_mode
= (CalfScModes
)*params
[param_sc_mode
];
1182 if(params
[param_f1_active
] != NULL
) {
1183 *params
[param_f1_active
] = f1_active
;
1185 if(params
[param_f2_active
] != NULL
) {
1186 *params
[param_f2_active
] = f2_active
;
1188 // and set the compressor module
1189 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
);
1192 void sidechaincompressor_audio_module::set_sample_rate(uint32_t sr
)
1195 compressor
.set_sample_rate(srate
);
1198 uint32_t sidechaincompressor_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1200 bool bypass
= *params
[param_bypass
] > 0.5f
;
1201 numsamples
+= offset
;
1203 // everything bypassed
1204 while(offset
< numsamples
) {
1205 outs
[0][offset
] = ins
[0][offset
];
1206 outs
[1][offset
] = ins
[1][offset
];
1217 clip_in
-= std::min(clip_in
, numsamples
);
1218 clip_out
-= std::min(clip_out
, numsamples
);
1220 while(offset
< numsamples
) {
1221 // cycle through samples
1224 float inL
= ins
[0][offset
];
1225 float inR
= ins
[1][offset
];
1227 inR
*= *params
[param_level_in
];
1228 inL
*= *params
[param_level_in
];
1232 float rightAC
= inR
;
1234 float rightSC
= inR
;
1236 float rightMC
= inR
;
1238 switch ((int)*params
[param_sc_mode
]) {
1241 compressor
.process(leftAC
, rightAC
, leftSC
, rightSC
);
1244 case DERUMBLER_WIDE
:
1249 leftSC
= f2L
.process(f1L
.process(leftSC
));
1250 rightSC
= f2R
.process(f1R
.process(rightSC
));
1253 compressor
.process(leftAC
, rightAC
, leftSC
, rightSC
);
1256 leftSC
= f2L
.process(leftSC
);
1257 rightSC
= f2R
.process(rightSC
);
1260 compressor
.process(leftSC
, rightSC
, leftSC
, rightSC
);
1261 leftAC
= f1L
.process(leftAC
);
1262 rightAC
= f1R
.process(rightAC
);
1266 case DERUMBLER_SPLIT
:
1267 leftSC
= f1L
.process(leftSC
);
1268 rightSC
= f1R
.process(rightSC
);
1271 compressor
.process(leftSC
, rightSC
, leftSC
, rightSC
);
1272 leftAC
= f2L
.process(leftAC
);
1273 rightAC
= f2R
.process(rightAC
);
1278 leftSC
= f1L
.process(leftSC
);
1279 rightSC
= f1R
.process(rightSC
);
1282 compressor
.process(leftAC
, rightAC
, leftSC
, rightSC
);
1286 if(*params
[param_sc_listen
] > 0.f
) {
1295 outs
[0][offset
] = outL
;
1296 outs
[1][offset
] = outR
;
1299 if(std::max(fabs(inL
), fabs(inR
)) > 1.f
) {
1300 clip_in
= srate
>> 3;
1302 if(std::max(fabs(outL
), fabs(outR
)) > 1.f
) {
1303 clip_out
= srate
>> 3;
1305 // rise up out meter
1306 meter_in
= std::max(fabs(inL
), fabs(inR
));;
1307 meter_out
= std::max(fabs(outL
), fabs(outR
));;
1311 } // cycle trough samples
1319 if(params
[param_clip_in
] != NULL
) {
1320 *params
[param_clip_in
] = clip_in
;
1322 if(params
[param_clip_out
] != NULL
) {
1323 *params
[param_clip_out
] = clip_out
;
1325 if(params
[param_meter_in
] != NULL
) {
1326 *params
[param_meter_in
] = meter_in
;
1328 if(params
[param_meter_out
] != NULL
) {
1329 *params
[param_meter_out
] = meter_out
;
1333 if(params
[param_compression
] != NULL
) {
1334 *params
[param_compression
] = 1.0f
;
1337 if(params
[param_compression
] != NULL
) {
1338 *params
[param_compression
] = compressor
.get_comp_level();
1341 // whatever has to be returned x)
1342 return outputs_mask
;
1344 bool sidechaincompressor_audio_module::get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
)
1348 if (index
== param_f1_freq
&& !subindex
) {
1349 context
->set_line_width(1.5);
1350 return ::get_graph(*this, subindex
, data
, points
);
1351 } else if(index
== param_compression
) {
1352 return compressor
.get_graph(subindex
, data
, points
, context
);
1357 bool sidechaincompressor_audio_module::get_dot(int index
, int subindex
, float &x
, float &y
, int &size
, cairo_iface
*context
)
1361 if (index
== param_compression
) {
1362 return compressor
.get_dot(subindex
, x
, y
, size
, context
);
1367 bool sidechaincompressor_audio_module::get_gridline(int index
, int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
)
1371 if (index
== param_compression
) {
1372 return compressor
.get_gridline(subindex
, pos
, vertical
, legend
, context
);
1374 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
1379 int sidechaincompressor_audio_module::get_changed_offsets(int index
, int generation
, int &subindex_graph
, int &subindex_dot
, int &subindex_gridline
)
1383 if(index
== param_compression
) {
1384 return compressor
.get_changed_offsets(generation
, subindex_graph
, subindex_dot
, subindex_gridline
);
1386 // (fabs(inertia_cutoff.get_last() - old_cutoff) + 100 * fabs(inertia_resonance.get_last() - old_resonance) + fabs(*params[par_mode] - old_mode) > 0.1f)
1387 if (*params
[param_f1_freq
] != f1_freq_old1
1388 or *params
[param_f2_freq
] != f2_freq_old1
1389 or *params
[param_f1_level
] != f1_level_old1
1390 or *params
[param_f2_level
] != f2_level_old1
1391 or *params
[param_sc_mode
] !=sc_mode_old1
)
1393 f1_freq_old1
= *params
[param_f1_freq
];
1394 f2_freq_old1
= *params
[param_f2_freq
];
1395 f1_level_old1
= *params
[param_f1_level
];
1396 f2_level_old1
= *params
[param_f2_level
];
1397 sc_mode_old1
= (CalfScModes
)*params
[param_sc_mode
];
1400 subindex_dot
= INT_MAX
;
1401 subindex_gridline
= INT_MAX
;
1405 subindex_dot
= subindex_gridline
= generation
? INT_MAX
: 0;
1407 if (generation
== last_calculated_generation
)
1408 subindex_graph
= INT_MAX
;
1409 return last_generation
;
1414 /// Deesser by Markus Schmidt
1416 /// This module splits the signal in a sidechain- and a process signal.
1417 /// The sidechain is processed through Krzystofs filters and compresses
1418 /// the process signal via Thor's compression routine afterwards.
1419 ///////////////////////////////////////////////////////////////////////////////////////////////
1421 deesser_audio_module::deesser_audio_module()
1425 last_generation
= 0;
1428 void deesser_audio_module::activate()
1431 // set all filters and strips
1432 compressor
.activate();
1438 void deesser_audio_module::deactivate()
1441 compressor
.deactivate();
1444 void deesser_audio_module::params_changed()
1446 // set the params of all filters
1447 if(*params
[param_f1_freq
] != f1_freq_old
or *params
[param_f1_level
] != f1_level_old
1448 or *params
[param_f2_freq
] != f2_freq_old
or *params
[param_f2_level
] != f2_level_old
1449 or *params
[param_f2_q
] != f2_q_old
) {
1452 hpL
.set_hp_rbj((float)*params
[param_f1_freq
] * (1 - 0.17), q
, (float)srate
, *params
[param_f1_level
]);
1453 hpR
.copy_coeffs(hpL
);
1454 lpL
.set_lp_rbj((float)*params
[param_f1_freq
] * (1 + 0.17), q
, (float)srate
);
1455 lpR
.copy_coeffs(lpL
);
1456 pL
.set_peakeq_rbj((float)*params
[param_f2_freq
], *params
[param_f2_q
], *params
[param_f2_level
], (float)srate
);
1458 f1_freq_old
= *params
[param_f1_freq
];
1459 f1_level_old
= *params
[param_f1_level
];
1460 f2_freq_old
= *params
[param_f2_freq
];
1461 f2_level_old
= *params
[param_f2_level
];
1462 f2_q_old
= *params
[param_f2_q
];
1464 // and set the compressor module
1465 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
);
1468 void deesser_audio_module::set_sample_rate(uint32_t sr
)
1471 compressor
.set_sample_rate(srate
);
1474 uint32_t deesser_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1476 bool bypass
= *params
[param_bypass
] > 0.5f
;
1477 numsamples
+= offset
;
1479 // everything bypassed
1480 while(offset
< numsamples
) {
1481 outs
[0][offset
] = ins
[0][offset
];
1482 outs
[1][offset
] = ins
[1][offset
];
1492 detected_led
-= std::min(detected_led
, numsamples
);
1493 clip_led
-= std::min(clip_led
, numsamples
);
1495 while(offset
< numsamples
) {
1496 // cycle through samples
1499 float inL
= ins
[0][offset
];
1500 float inR
= ins
[1][offset
];
1504 float rightAC
= inR
;
1506 float rightSC
= inR
;
1508 float rightRC
= inR
;
1510 float rightMC
= inR
;
1512 leftSC
= pL
.process(hpL
.process(leftSC
));
1513 rightSC
= pR
.process(hpR
.process(rightSC
));
1517 switch ((int)*params
[param_mode
]) {
1520 compressor
.process(leftAC
, rightAC
, leftSC
, rightSC
);
1525 leftRC
= hpL
.process(leftRC
);
1526 rightRC
= hpR
.process(rightRC
);
1527 compressor
.process(leftRC
, rightRC
, leftSC
, rightSC
);
1528 leftAC
= lpL
.process(leftAC
);
1529 rightAC
= lpR
.process(rightAC
);
1535 if(*params
[param_sc_listen
] > 0.f
) {
1544 outs
[0][offset
] = outL
;
1545 outs
[1][offset
] = outR
;
1547 if(std::max(fabs(leftSC
), fabs(rightSC
)) > 0.1) {
1548 detected_led
= srate
>> 3;
1550 if(std::max(fabs(leftAC
), fabs(rightAC
)) > 1.f
) {
1551 clip_led
= srate
>> 3;
1556 clip_out
= std::max(fabs(outL
), fabs(outR
));
1558 detected
= std::max(fabs(leftMC
), fabs(rightMC
));
1562 } // cycle trough samples
1571 if(params
[param_detected_led
] != NULL
) {
1572 *params
[param_detected_led
] = detected_led
;
1574 if(params
[param_clip_out
] != NULL
) {
1575 *params
[param_clip_out
] = clip_out
;
1577 if(params
[param_detected
] != NULL
) {
1578 *params
[param_detected
] = detected
;
1582 if(params
[param_compression
] != NULL
) {
1583 *params
[param_compression
] = 1.0f
;
1586 if(params
[param_compression
] != NULL
) {
1587 *params
[param_compression
] = compressor
.get_comp_level();
1590 // whatever has to be returned x)
1591 return outputs_mask
;
1593 bool deesser_audio_module::get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
)
1597 if (index
== param_f1_freq
&& !subindex
) {
1598 context
->set_line_width(1.5);
1599 return ::get_graph(*this, subindex
, data
, points
);
1604 bool deesser_audio_module::get_gridline(int index
, int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
)
1606 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
1611 int deesser_audio_module::get_changed_offsets(int index
, int generation
, int &subindex_graph
, int &subindex_dot
, int &subindex_gridline
)
1616 // (fabs(inertia_cutoff.get_last() - old_cutoff) + 100 * fabs(inertia_resonance.get_last() - old_resonance) + fabs(*params[par_mode] - old_mode) > 0.1f)
1617 if (*params
[param_f1_freq
] != f1_freq_old1
1618 or *params
[param_f2_freq
] != f2_freq_old1
1619 or *params
[param_f1_level
] != f1_level_old1
1620 or *params
[param_f2_level
] != f2_level_old1
1621 or *params
[param_f2_q
] !=f2_q_old1
)
1623 f1_freq_old1
= *params
[param_f1_freq
];
1624 f2_freq_old1
= *params
[param_f2_freq
];
1625 f1_level_old1
= *params
[param_f1_level
];
1626 f2_level_old1
= *params
[param_f2_level
];
1627 f2_q_old1
= *params
[param_f2_q
];
1630 subindex_dot
= INT_MAX
;
1631 subindex_gridline
= INT_MAX
;
1635 subindex_dot
= subindex_gridline
= generation
? INT_MAX
: 0;
1637 if (generation
== last_calculated_generation
)
1638 subindex_graph
= INT_MAX
;
1639 return last_generation
;
1644 /// Gain reduction module by Thor
1645 /// All functions of this module are originally written
1646 /// by Thor, while some features have been stripped (mainly stereo linking
1647 /// and frequency correction as implemented in Sidechain Compressor above)
1648 /// To save some CPU.
1649 ////////////////////////////////////////////////////////////////////////////////
1650 gain_reduction_audio_module::gain_reduction_audio_module()
1653 last_generation
= 0;
1656 void gain_reduction_audio_module::activate()
1670 void gain_reduction_audio_module::deactivate()
1675 void gain_reduction_audio_module::process(float &left
, float &right
, float det_left
, float det_right
)
1685 // this routine is mainly copied from thor's compressor module
1686 // greatest sounding compressor I've heard!
1687 bool rms
= detection
== 0;
1688 bool average
= stereo_link
== 0;
1689 float linThreshold
= threshold
;
1690 float attack_coeff
= std::min(1.f
, 1.f
/ (attack
* srate
/ 4000.f
));
1691 float release_coeff
= std::min(1.f
, 1.f
/ (release
* srate
/ 4000.f
));
1692 float linKneeSqrt
= sqrt(knee
);
1693 linKneeStart
= linThreshold
/ linKneeSqrt
;
1694 adjKneeStart
= linKneeStart
*linKneeStart
;
1695 float linKneeStop
= linThreshold
* linKneeSqrt
;
1696 thres
= log(linThreshold
);
1697 kneeStart
= log(linKneeStart
);
1698 kneeStop
= log(linKneeStop
);
1699 compressedKneeStop
= (kneeStop
- thres
) / ratio
+ thres
;
1701 float absample
= average
? (fabs(det_left
) + fabs(det_right
)) * 0.5f
: std::max(fabs(det_left
), fabs(det_right
));
1702 if(rms
) absample
*= absample
;
1704 linSlope
+= (absample
- linSlope
) * (absample
> linSlope
? attack_coeff
: release_coeff
);
1706 if(linSlope
> 0.f
) {
1707 gain
= output_gain(linSlope
, rms
);
1710 left
*= gain
* makeup
;
1711 right
*= gain
* makeup
;
1712 meter_out
= std::max(fabs(left
), fabs(right
));;
1714 detected
= rms
? sqrt(linSlope
) : linSlope
;
1718 float gain_reduction_audio_module::output_level(float slope
) {
1719 return slope
* output_gain(slope
, false) * makeup
;
1722 float gain_reduction_audio_module::output_gain(float linSlope
, bool rms
) {
1723 //this calculation is also thor's work
1724 if(linSlope
> (rms
? adjKneeStart
: linKneeStart
)) {
1725 float slope
= log(linSlope
);
1726 if(rms
) slope
*= 0.5f
;
1730 if(IS_FAKE_INFINITY(ratio
)) {
1734 gain
= (slope
- thres
) / ratio
+ thres
;
1735 delta
= 1.f
/ ratio
;
1738 if(knee
> 1.f
&& slope
< kneeStop
) {
1739 gain
= hermite_interpolation(slope
, kneeStart
, kneeStop
, kneeStart
, compressedKneeStop
, 1.f
, delta
);
1742 return exp(gain
- slope
);
1748 void gain_reduction_audio_module::set_sample_rate(uint32_t sr
)
1752 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
)
1770 float gain_reduction_audio_module::get_output_level() {
1771 // returns output level (max(left, right))
1774 float gain_reduction_audio_module::get_comp_level() {
1775 // returns amount of compression
1779 bool gain_reduction_audio_module::get_graph(int subindex
, float *data
, int points
, cairo_iface
*context
)
1783 if (subindex
> 1) // 1
1785 for (int i
= 0; i
< points
; i
++)
1787 float input
= dB_grid_inv(-1.0 + i
* 2.0 / (points
- 1));
1789 data
[i
] = dB_grid(input
);
1791 float output
= output_level(input
);
1792 data
[i
] = dB_grid(output
);
1795 if (subindex
== (bypass
> 0.5f
? 1 : 0) or mute
> 0.1f
)
1796 context
->set_source_rgba(0.35, 0.4, 0.2, 0.3);
1798 context
->set_source_rgba(0.35, 0.4, 0.2, 1);
1799 context
->set_line_width(1.5);
1804 bool gain_reduction_audio_module::get_dot(int subindex
, float &x
, float &y
, int &size
, cairo_iface
*context
)
1810 if(bypass
> 0.5f
or mute
> 0.f
) {
1813 bool rms
= detection
== 0;
1814 float det
= rms
? sqrt(detected
) : detected
;
1815 x
= 0.5 + 0.5 * dB_grid(det
);
1816 y
= dB_grid(bypass
> 0.5f
or mute
> 0.f
? det
: output_level(det
));
1823 bool gain_reduction_audio_module::get_gridline(int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
)
1826 vertical
= (subindex
& 1) != 0;
1827 bool result
= get_freq_gridline(subindex
>> 1, pos
, tmp
, legend
, context
, false);
1828 if (result
&& vertical
) {
1829 if ((subindex
& 4) && !legend
.empty()) {
1833 size_t pos
= legend
.find(" dB");
1834 if (pos
!= std::string::npos
)
1837 pos
= 0.5 + 0.5 * pos
;
1842 int gain_reduction_audio_module::get_changed_offsets(int generation
, int &subindex_graph
, int &subindex_dot
, int &subindex_gridline
)
1846 subindex_gridline
= generation
? INT_MAX
: 0;
1848 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
)
1850 old_threshold
= threshold
;
1853 old_makeup
= makeup
;
1854 old_detection
= detection
;
1855 old_bypass
= bypass
;
1860 if (generation
== last_generation
)
1862 return last_generation
;
1865 /// Equalizer 12 Band by Markus Schmidt
1867 /// This module is based on Krzysztof's filters. It provides a couple
1868 /// of different chained filters.
1869 ///////////////////////////////////////////////////////////////////////////////////////////////
1871 equalizer12band_audio_module::equalizer12band_audio_module()
1875 last_generation
= 0;
1886 void equalizer12band_audio_module::activate()
1892 void equalizer12band_audio_module::deactivate()
1897 void equalizer12band_audio_module::params_changed()
1899 // set the params of all filters
1900 if(*params
[param_hp_freq
] != hp_freq_old
) {
1901 hpL
[0].set_hp_rbj(*params
[param_hp_freq
], 0.707, (float)srate
, 1.0);
1902 hpL
[1].copy_coeffs(hpL
[0]);
1903 hpL
[2].copy_coeffs(hpL
[0]);
1904 hpR
[0].copy_coeffs(hpL
[0]);
1905 hpR
[1].copy_coeffs(hpL
[0]);
1906 hpR
[2].copy_coeffs(hpL
[0]);
1907 hp_freq_old
= *params
[param_hp_freq
];
1909 if(*params
[param_lp_freq
] != lp_freq_old
) {
1910 lpL
[0].set_lp_rbj(*params
[param_lp_freq
], 0.707, (float)srate
, 1.0);
1911 lpL
[1].copy_coeffs(lpL
[0]);
1912 lpL
[2].copy_coeffs(lpL
[0]);
1913 lpR
[0].copy_coeffs(lpL
[0]);
1914 lpR
[1].copy_coeffs(lpL
[0]);
1915 lpR
[2].copy_coeffs(lpL
[0]);
1916 lp_freq_old
= *params
[param_lp_freq
];
1918 if(*params
[param_ls_freq
] != ls_freq_old
or *params
[param_ls_level
] != ls_level_old
) {
1919 lsL
.set_lowshelf_rbj(*params
[param_ls_freq
], 0.707, *params
[param_ls_level
], (float)srate
);
1920 lsR
.copy_coeffs(lsL
);
1921 ls_level_old
= *params
[param_ls_level
];
1922 ls_freq_old
= *params
[param_ls_freq
];
1924 if(*params
[param_hs_freq
] != hs_freq_old
or *params
[param_hs_level
] != hs_level_old
) {
1925 hsL
.set_highshelf_rbj(*params
[param_hs_freq
], 0.707, *params
[param_hs_level
], (float)srate
);
1926 hsR
.copy_coeffs(hsL
);
1927 hs_level_old
= *params
[param_hs_level
];
1928 hs_freq_old
= *params
[param_hs_freq
];
1930 if(*params
[param_p1_freq
] != p_freq_old
[0] or *params
[param_p1_level
] != p_level_old
[0] or *params
[param_p1_q
] != p_q_old
[0]) {
1931 pL
[0].set_peakeq_rbj((float)*params
[param_p1_freq
], *params
[param_p1_q
], *params
[param_p1_level
], (float)srate
);
1932 pR
[0].copy_coeffs(pL
[0]);
1933 p_freq_old
[0] = *params
[param_p1_freq
];
1934 p_level_old
[0] = *params
[param_p1_level
];
1935 p_q_old
[0] = *params
[param_p1_q
];
1937 if(*params
[param_p2_freq
] != p_freq_old
[1] or *params
[param_p2_level
] != p_level_old
[1] or *params
[param_p2_q
] != p_q_old
[1]) {
1938 pL
[1].set_peakeq_rbj((float)*params
[param_p2_freq
], *params
[param_p2_q
], *params
[param_p2_level
], (float)srate
);
1939 pR
[1].copy_coeffs(pL
[1]);
1940 p_freq_old
[1] = *params
[param_p2_freq
];
1941 p_level_old
[1] = *params
[param_p2_level
];
1942 p_q_old
[1] = *params
[param_p2_q
];
1944 if(*params
[param_p3_freq
] != p_freq_old
[2] or *params
[param_p3_level
] != p_level_old
[2] or *params
[param_p3_q
] != p_q_old
[2]) {
1945 pL
[2].set_peakeq_rbj((float)*params
[param_p3_freq
], *params
[param_p3_q
], *params
[param_p3_level
], (float)srate
);
1946 pR
[2].copy_coeffs(pL
[2]);
1947 p_freq_old
[2] = *params
[param_p3_freq
];
1948 p_level_old
[2] = *params
[param_p3_level
];
1949 p_q_old
[2] = *params
[param_p3_q
];
1951 if(*params
[param_p4_freq
] != p_freq_old
[3] or *params
[param_p4_level
] != p_level_old
[3] or *params
[param_p4_q
] != p_q_old
[3]) {
1952 pL
[3].set_peakeq_rbj((float)*params
[param_p4_freq
], *params
[param_p4_q
], *params
[param_p4_level
], (float)srate
);
1953 pR
[3].copy_coeffs(pL
[3]);
1954 p_freq_old
[3] = *params
[param_p4_freq
];
1955 p_level_old
[3] = *params
[param_p4_level
];
1956 p_q_old
[3] = *params
[param_p4_q
];
1958 if(*params
[param_p5_freq
] != p_freq_old
[4] or *params
[param_p5_level
] != p_level_old
[4] or *params
[param_p5_q
] != p_q_old
[4]) {
1959 pL
[4].set_peakeq_rbj((float)*params
[param_p5_freq
], *params
[param_p5_q
], *params
[param_p5_level
], (float)srate
);
1960 pR
[4].copy_coeffs(pL
[4]);
1961 p_freq_old
[4] = *params
[param_p5_freq
];
1962 p_level_old
[4] = *params
[param_p5_level
];
1963 p_q_old
[4] = *params
[param_p5_q
];
1965 if(*params
[param_p6_freq
] != p_freq_old
[5] or *params
[param_p6_level
] != p_level_old
[5] or *params
[param_p6_q
] != p_q_old
[5]) {
1966 pL
[5].set_peakeq_rbj((float)*params
[param_p6_freq
], *params
[param_p6_q
], *params
[param_p6_level
], (float)srate
);
1967 pR
[5].copy_coeffs(pL
[5]);
1968 p_freq_old
[5] = *params
[param_p6_freq
];
1969 p_level_old
[5] = *params
[param_p6_level
];
1970 p_q_old
[5] = *params
[param_p6_q
];
1972 if(*params
[param_p7_freq
] != p_freq_old
[6] or *params
[param_p7_level
] != p_level_old
[6] or *params
[param_p7_q
] != p_q_old
[6]) {
1973 pL
[6].set_peakeq_rbj((float)*params
[param_p7_freq
], *params
[param_p7_q
], *params
[param_p7_level
], (float)srate
);
1974 pR
[6].copy_coeffs(pL
[6]);
1975 p_freq_old
[6] = *params
[param_p7_freq
];
1976 p_level_old
[6] = *params
[param_p7_level
];
1977 p_q_old
[6] = *params
[param_p7_q
];
1979 if(*params
[param_p8_freq
] != p_freq_old
[7] or *params
[param_p8_level
] != p_level_old
[7] or *params
[param_p8_q
] != p_q_old
[7]) {
1980 pL
[7].set_peakeq_rbj((float)*params
[param_p8_freq
], *params
[param_p8_q
], *params
[param_p8_level
], (float)srate
);
1981 pR
[7].copy_coeffs(pL
[7]);
1982 p_freq_old
[7] = *params
[param_p8_freq
];
1983 p_level_old
[7] = *params
[param_p8_level
];
1984 p_q_old
[7] = *params
[param_p8_q
];
1988 void equalizer12band_audio_module::set_sample_rate(uint32_t sr
)
1993 uint32_t equalizer12band_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1995 bool bypass
= *params
[param_bypass
] > 0.5f
;
1996 numsamples
+= offset
;
1998 // everything bypassed
1999 while(offset
< numsamples
) {
2000 outs
[0][offset
] = ins
[0][offset
];
2001 outs
[1][offset
] = ins
[1][offset
];
2015 clip_inL
-= std::min(clip_inL
, numsamples
);
2016 clip_inR
-= std::min(clip_inR
, numsamples
);
2017 clip_outL
-= std::min(clip_outL
, numsamples
);
2018 clip_outR
-= std::min(clip_outR
, numsamples
);
2025 while(offset
< numsamples
) {
2026 // cycle through samples
2029 float inL
= ins
[0][offset
];
2030 float inR
= ins
[1][offset
];
2032 inR
*= *params
[param_level_in
];
2033 inL
*= *params
[param_level_in
];
2038 // all filters in chain
2039 if(*params
[param_hp_active
] > 0.f
) {
2040 switch((int)*params
[param_hp_mode
]) {
2042 procL
= hpL
[0].process(procL
);
2043 procR
= hpR
[0].process(procR
);
2046 procL
= hpL
[1].process(hpL
[0].process(procL
));
2047 procR
= hpR
[1].process(hpR
[0].process(procR
));
2050 procL
= hpL
[2].process(hpL
[1].process(hpL
[0].process(procL
)));
2051 procR
= hpR
[2].process(hpR
[1].process(hpR
[0].process(procR
)));
2055 if(*params
[param_lp_active
] > 0.f
) {
2056 switch((int)*params
[param_lp_mode
]) {
2058 procL
= lpL
[0].process(procL
);
2059 procR
= lpR
[0].process(procR
);
2062 procL
= lpL
[1].process(lpL
[0].process(procL
));
2063 procR
= lpR
[1].process(lpR
[0].process(procR
));
2066 procL
= lpL
[2].process(lpL
[1].process(lpL
[0].process(procL
)));
2067 procR
= lpR
[2].process(lpR
[1].process(lpR
[0].process(procR
)));
2071 if(*params
[param_ls_active
] > 0.f
) {
2072 procL
= lsL
.process(procL
);
2073 procR
= lsR
.process(procR
);
2075 if(*params
[param_hs_active
] > 0.f
) {
2076 procL
= hsL
.process(procL
);
2077 procR
= hsR
.process(procR
);
2079 if(*params
[param_p1_active
] > 0.f
) {
2080 procL
= pL
[0].process(procL
);
2081 procR
= pR
[0].process(procR
);
2083 if(*params
[param_p2_active
] > 0.f
) {
2084 procL
= pL
[1].process(procL
);
2085 procR
= pR
[1].process(procR
);
2087 if(*params
[param_p3_active
] > 0.f
) {
2088 procL
= pL
[2].process(procL
);
2089 procR
= pR
[2].process(procR
);
2091 if(*params
[param_p4_active
] > 0.f
) {
2092 procL
= pL
[3].process(procL
);
2093 procR
= pR
[3].process(procR
);
2095 if(*params
[param_p5_active
] > 0.f
) {
2096 procL
= pL
[4].process(procL
);
2097 procR
= pR
[4].process(procR
);
2099 if(*params
[param_p6_active
] > 0.f
) {
2100 procL
= pL
[5].process(procL
);
2101 procR
= pR
[5].process(procR
);
2103 if(*params
[param_p7_active
] > 0.f
) {
2104 procL
= pL
[6].process(procL
);
2105 procR
= pR
[6].process(procR
);
2107 if(*params
[param_p8_active
] > 0.f
) {
2108 procL
= pL
[7].process(procL
);
2109 procR
= pR
[7].process(procR
);
2112 outL
= procL
* *params
[param_level_out
];
2113 outR
= procR
* *params
[param_level_out
];
2116 outs
[0][offset
] = outL
;
2117 outs
[1][offset
] = outR
;
2121 clip_inL
= srate
>> 3;
2124 clip_inR
= srate
>> 3;
2127 clip_outL
= srate
>> 3;
2130 clip_outR
= srate
>> 3;
2132 // set up in / out meters
2133 if(inL
> meter_inL
) {
2136 if(inR
> meter_inR
) {
2139 if(outL
> meter_outL
) {
2142 if(outR
> meter_outR
) {
2148 } // cycle trough samples
2150 for(int i
= 0; i
< 3; ++i
) {
2158 for(int i
= 0; i
< 8; ++i
) {
2164 if(params
[param_clip_inL
] != NULL
) {
2165 *params
[param_clip_inL
] = clip_inL
;
2167 if(params
[param_clip_inR
] != NULL
) {
2168 *params
[param_clip_inR
] = clip_inR
;
2170 if(params
[param_clip_outL
] != NULL
) {
2171 *params
[param_clip_outL
] = clip_outL
;
2173 if(params
[param_clip_outR
] != NULL
) {
2174 *params
[param_clip_outR
] = clip_outR
;
2177 if(params
[param_meter_inL
] != NULL
) {
2178 *params
[param_meter_inL
] = meter_inL
;
2180 if(params
[param_meter_inR
] != NULL
) {
2181 *params
[param_meter_inR
] = meter_inR
;
2183 if(params
[param_meter_outL
] != NULL
) {
2184 *params
[param_meter_outL
] = meter_outL
;
2186 if(params
[param_meter_outR
] != NULL
) {
2187 *params
[param_meter_outR
] = meter_outR
;
2189 // whatever has to be returned x)
2190 return outputs_mask
;
2192 bool equalizer12band_audio_module::get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
)
2196 if (index
== param_p1_freq
&& !subindex
) {
2197 context
->set_line_width(1.5);
2198 return ::get_graph(*this, subindex
, data
, points
);
2203 bool equalizer12band_audio_module::get_gridline(int index
, int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
)
2208 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
2212 int equalizer12band_audio_module::get_changed_offsets(int index
, int generation
, int &subindex_graph
, int &subindex_dot
, int &subindex_gridline
)
2217 if (*params
[param_hp_freq
] != hp_freq_old1
2218 or *params
[param_hp_mode
] != hp_mode_old1
2219 or *params
[param_lp_freq
] != lp_freq_old1
2220 or *params
[param_lp_mode
] != lp_mode_old1
2222 or *params
[param_ls_freq
] != ls_freq_old1
2223 or *params
[param_ls_level
] != ls_level_old1
2224 or *params
[param_hs_freq
] != hs_freq_old1
2225 or *params
[param_hs_level
] != hs_level_old1
2227 or *params
[param_p1_freq
] != p_freq_old1
[0]
2228 or *params
[param_p1_level
] != p_level_old1
[0]
2229 or *params
[param_p1_q
] != p_q_old1
[0]
2231 or *params
[param_p2_freq
] != p_freq_old1
[1]
2232 or *params
[param_p2_level
] != p_level_old1
[1]
2233 or *params
[param_p2_q
] != p_q_old1
[1]
2235 or *params
[param_p3_freq
] != p_freq_old1
[2]
2236 or *params
[param_p3_level
] != p_level_old1
[2]
2237 or *params
[param_p3_q
] != p_q_old1
[2]
2239 or *params
[param_p4_freq
] != p_freq_old1
[3]
2240 or *params
[param_p4_level
] != p_level_old1
[3]
2241 or *params
[param_p4_q
] != p_q_old1
[3]
2243 or *params
[param_p5_freq
] != p_freq_old1
[4]
2244 or *params
[param_p5_level
] != p_level_old1
[4]
2245 or *params
[param_p5_q
] != p_q_old1
[4]
2247 or *params
[param_p6_freq
] != p_freq_old1
[5]
2248 or *params
[param_p6_level
] != p_level_old1
[5]
2249 or *params
[param_p6_q
] != p_q_old1
[5]
2251 or *params
[param_p7_freq
] != p_freq_old1
[6]
2252 or *params
[param_p7_level
] != p_level_old1
[6]
2253 or *params
[param_p7_q
] != p_q_old1
[6]
2255 or *params
[param_p8_freq
] != p_freq_old1
[7]
2256 or *params
[param_p8_level
] != p_level_old1
[7]
2257 or *params
[param_p8_q
] != p_q_old1
[7])
2260 hp_freq_old1
= *params
[param_hp_freq
];
2261 hp_mode_old1
= *params
[param_hp_mode
];
2262 lp_freq_old1
= *params
[param_lp_freq
];
2263 lp_mode_old1
= *params
[param_lp_mode
];
2265 ls_freq_old1
= *params
[param_ls_freq
];
2266 ls_level_old1
= *params
[param_ls_level
];
2267 hs_freq_old1
= *params
[param_hs_freq
];
2268 hs_level_old1
= *params
[param_hs_level
];
2270 p_freq_old1
[0] = *params
[param_p1_freq
];
2271 p_level_old1
[0] = *params
[param_p1_level
];
2272 p_q_old1
[0] = *params
[param_p1_q
];
2274 p_freq_old1
[1] = *params
[param_p2_freq
];
2275 p_level_old1
[1] = *params
[param_p2_level
];
2276 p_q_old1
[1] = *params
[param_p2_q
];
2278 p_freq_old1
[2] = *params
[param_p3_freq
];
2279 p_level_old1
[2] = *params
[param_p3_level
];
2280 p_q_old1
[2] = *params
[param_p3_q
];
2282 p_freq_old1
[3] = *params
[param_p4_freq
];
2283 p_level_old1
[3] = *params
[param_p4_level
];
2284 p_q_old1
[3] = *params
[param_p4_q
];
2286 p_freq_old1
[4] = *params
[param_p5_freq
];
2287 p_level_old1
[4] = *params
[param_p5_level
];
2288 p_q_old1
[4] = *params
[param_p5_q
];
2290 p_freq_old1
[5] = *params
[param_p6_freq
];
2291 p_level_old1
[5] = *params
[param_p6_level
];
2292 p_q_old1
[5] = *params
[param_p6_q
];
2294 p_freq_old1
[6] = *params
[param_p7_freq
];
2295 p_level_old1
[6] = *params
[param_p7_level
];
2296 p_q_old1
[6] = *params
[param_p7_q
];
2298 p_freq_old1
[7] = *params
[param_p8_freq
];
2299 p_level_old1
[7] = *params
[param_p8_level
];
2300 p_q_old1
[7] = *params
[param_p8_q
];
2304 subindex_dot
= INT_MAX
;
2305 subindex_gridline
= INT_MAX
;
2309 subindex_dot
= subindex_gridline
= generation
? INT_MAX
: 0;
2311 if (generation
== last_calculated_generation
)
2312 subindex_graph
= INT_MAX
;
2313 return last_generation
;
2318 /// Equalizer 8 Band by Markus Schmidt
2320 /// This module is based on Krzysztof's filters. It provides a couple
2321 /// of different chained filters.
2322 ///////////////////////////////////////////////////////////////////////////////////////////////
2324 equalizer8band_audio_module::equalizer8band_audio_module()
2328 last_generation
= 0;
2339 void equalizer8band_audio_module::activate()
2345 void equalizer8band_audio_module::deactivate()
2350 void equalizer8band_audio_module::params_changed()
2352 // set the params of all filters
2353 if(*params
[param_hp_freq
] != hp_freq_old
) {
2354 hpL
[0].set_hp_rbj(*params
[param_hp_freq
], 0.707, (float)srate
, 1.0);
2355 hpL
[1].copy_coeffs(hpL
[0]);
2356 hpL
[2].copy_coeffs(hpL
[0]);
2357 hpR
[0].copy_coeffs(hpL
[0]);
2358 hpR
[1].copy_coeffs(hpL
[0]);
2359 hpR
[2].copy_coeffs(hpL
[0]);
2360 hp_freq_old
= *params
[param_hp_freq
];
2362 if(*params
[param_lp_freq
] != lp_freq_old
) {
2363 lpL
[0].set_lp_rbj(*params
[param_lp_freq
], 0.707, (float)srate
, 1.0);
2364 lpL
[1].copy_coeffs(lpL
[0]);
2365 lpL
[2].copy_coeffs(lpL
[0]);
2366 lpR
[0].copy_coeffs(lpL
[0]);
2367 lpR
[1].copy_coeffs(lpL
[0]);
2368 lpR
[2].copy_coeffs(lpL
[0]);
2369 lp_freq_old
= *params
[param_lp_freq
];
2371 if(*params
[param_ls_freq
] != ls_freq_old
or *params
[param_ls_level
] != ls_level_old
) {
2372 lsL
.set_lowshelf_rbj(*params
[param_ls_freq
], 0.707, *params
[param_ls_level
], (float)srate
);
2373 lsR
.copy_coeffs(lsL
);
2374 ls_level_old
= *params
[param_ls_level
];
2375 ls_freq_old
= *params
[param_ls_freq
];
2377 if(*params
[param_hs_freq
] != hs_freq_old
or *params
[param_hs_level
] != hs_level_old
) {
2378 hsL
.set_highshelf_rbj(*params
[param_hs_freq
], 0.707, *params
[param_hs_level
], (float)srate
);
2379 hsR
.copy_coeffs(hsL
);
2380 hs_level_old
= *params
[param_hs_level
];
2381 hs_freq_old
= *params
[param_hs_freq
];
2383 if(*params
[param_p1_freq
] != p_freq_old
[0] or *params
[param_p1_level
] != p_level_old
[0] or *params
[param_p1_q
] != p_q_old
[0]) {
2384 pL
[0].set_peakeq_rbj((float)*params
[param_p1_freq
], *params
[param_p1_q
], *params
[param_p1_level
], (float)srate
);
2385 pR
[0].copy_coeffs(pL
[0]);
2386 p_freq_old
[0] = *params
[param_p1_freq
];
2387 p_level_old
[0] = *params
[param_p1_level
];
2388 p_q_old
[0] = *params
[param_p1_q
];
2390 if(*params
[param_p2_freq
] != p_freq_old
[1] or *params
[param_p2_level
] != p_level_old
[1] or *params
[param_p2_q
] != p_q_old
[1]) {
2391 pL
[1].set_peakeq_rbj((float)*params
[param_p2_freq
], *params
[param_p2_q
], *params
[param_p2_level
], (float)srate
);
2392 pR
[1].copy_coeffs(pL
[1]);
2393 p_freq_old
[1] = *params
[param_p2_freq
];
2394 p_level_old
[1] = *params
[param_p2_level
];
2395 p_q_old
[1] = *params
[param_p2_q
];
2397 if(*params
[param_p3_freq
] != p_freq_old
[2] or *params
[param_p3_level
] != p_level_old
[2] or *params
[param_p3_q
] != p_q_old
[2]) {
2398 pL
[2].set_peakeq_rbj((float)*params
[param_p3_freq
], *params
[param_p3_q
], *params
[param_p3_level
], (float)srate
);
2399 pR
[2].copy_coeffs(pL
[2]);
2400 p_freq_old
[2] = *params
[param_p3_freq
];
2401 p_level_old
[2] = *params
[param_p3_level
];
2402 p_q_old
[2] = *params
[param_p3_q
];
2404 if(*params
[param_p4_freq
] != p_freq_old
[3] or *params
[param_p4_level
] != p_level_old
[3] or *params
[param_p4_q
] != p_q_old
[3]) {
2405 pL
[3].set_peakeq_rbj((float)*params
[param_p4_freq
], *params
[param_p4_q
], *params
[param_p4_level
], (float)srate
);
2406 pR
[3].copy_coeffs(pL
[3]);
2407 p_freq_old
[3] = *params
[param_p4_freq
];
2408 p_level_old
[3] = *params
[param_p4_level
];
2409 p_q_old
[3] = *params
[param_p4_q
];
2413 void equalizer8band_audio_module::set_sample_rate(uint32_t sr
)
2418 uint32_t equalizer8band_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
2420 bool bypass
= *params
[param_bypass
] > 0.5f
;
2421 numsamples
+= offset
;
2423 // everything bypassed
2424 while(offset
< numsamples
) {
2425 outs
[0][offset
] = ins
[0][offset
];
2426 outs
[1][offset
] = ins
[1][offset
];
2440 clip_inL
-= std::min(clip_inL
, numsamples
);
2441 clip_inR
-= std::min(clip_inR
, numsamples
);
2442 clip_outL
-= std::min(clip_outL
, numsamples
);
2443 clip_outR
-= std::min(clip_outR
, numsamples
);
2450 while(offset
< numsamples
) {
2451 // cycle through samples
2454 float inL
= ins
[0][offset
];
2455 float inR
= ins
[1][offset
];
2457 inR
*= *params
[param_level_in
];
2458 inL
*= *params
[param_level_in
];
2463 // all filters in chain
2464 if(*params
[param_hp_active
] > 0.f
) {
2465 switch((int)*params
[param_hp_mode
]) {
2467 procL
= hpL
[0].process(procL
);
2468 procR
= hpR
[0].process(procR
);
2471 procL
= hpL
[1].process(hpL
[0].process(procL
));
2472 procR
= hpR
[1].process(hpR
[0].process(procR
));
2475 procL
= hpL
[2].process(hpL
[1].process(hpL
[0].process(procL
)));
2476 procR
= hpR
[2].process(hpR
[1].process(hpR
[0].process(procR
)));
2480 if(*params
[param_lp_active
] > 0.f
) {
2481 switch((int)*params
[param_lp_mode
]) {
2483 procL
= lpL
[0].process(procL
);
2484 procR
= lpR
[0].process(procR
);
2487 procL
= lpL
[1].process(lpL
[0].process(procL
));
2488 procR
= lpR
[1].process(lpR
[0].process(procR
));
2491 procL
= lpL
[2].process(lpL
[1].process(lpL
[0].process(procL
)));
2492 procR
= lpR
[2].process(lpR
[1].process(lpR
[0].process(procR
)));
2496 if(*params
[param_ls_active
] > 0.f
) {
2497 procL
= lsL
.process(procL
);
2498 procR
= lsR
.process(procR
);
2500 if(*params
[param_hs_active
] > 0.f
) {
2501 procL
= hsL
.process(procL
);
2502 procR
= hsR
.process(procR
);
2504 if(*params
[param_p1_active
] > 0.f
) {
2505 procL
= pL
[0].process(procL
);
2506 procR
= pR
[0].process(procR
);
2508 if(*params
[param_p2_active
] > 0.f
) {
2509 procL
= pL
[1].process(procL
);
2510 procR
= pR
[1].process(procR
);
2512 if(*params
[param_p3_active
] > 0.f
) {
2513 procL
= pL
[2].process(procL
);
2514 procR
= pR
[2].process(procR
);
2516 if(*params
[param_p4_active
] > 0.f
) {
2517 procL
= pL
[3].process(procL
);
2518 procR
= pR
[3].process(procR
);
2521 outL
= procL
* *params
[param_level_out
];
2522 outR
= procR
* *params
[param_level_out
];
2525 outs
[0][offset
] = outL
;
2526 outs
[1][offset
] = outR
;
2530 clip_inL
= srate
>> 3;
2533 clip_inR
= srate
>> 3;
2536 clip_outL
= srate
>> 3;
2539 clip_outR
= srate
>> 3;
2541 // set up in / out meters
2542 if(inL
> meter_inL
) {
2545 if(inR
> meter_inR
) {
2548 if(outL
> meter_outL
) {
2551 if(outR
> meter_outR
) {
2557 } // cycle trough samples
2559 for(int i
= 0; i
< 3; ++i
) {
2567 for(int i
= 0; i
< 4; ++i
) {
2573 if(params
[param_clip_inL
] != NULL
) {
2574 *params
[param_clip_inL
] = clip_inL
;
2576 if(params
[param_clip_inR
] != NULL
) {
2577 *params
[param_clip_inR
] = clip_inR
;
2579 if(params
[param_clip_outL
] != NULL
) {
2580 *params
[param_clip_outL
] = clip_outL
;
2582 if(params
[param_clip_outR
] != NULL
) {
2583 *params
[param_clip_outR
] = clip_outR
;
2586 if(params
[param_meter_inL
] != NULL
) {
2587 *params
[param_meter_inL
] = meter_inL
;
2589 if(params
[param_meter_inR
] != NULL
) {
2590 *params
[param_meter_inR
] = meter_inR
;
2592 if(params
[param_meter_outL
] != NULL
) {
2593 *params
[param_meter_outL
] = meter_outL
;
2595 if(params
[param_meter_outR
] != NULL
) {
2596 *params
[param_meter_outR
] = meter_outR
;
2598 // whatever has to be returned x)
2599 return outputs_mask
;
2601 bool equalizer8band_audio_module::get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
)
2605 if (index
== param_p1_freq
&& !subindex
) {
2606 context
->set_line_width(1.5);
2607 return ::get_graph(*this, subindex
, data
, points
);
2612 bool equalizer8band_audio_module::get_gridline(int index
, int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
)
2617 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
2621 int equalizer8band_audio_module::get_changed_offsets(int index
, int generation
, int &subindex_graph
, int &subindex_dot
, int &subindex_gridline
)
2626 if (*params
[param_hp_freq
] != hp_freq_old1
2627 or *params
[param_hp_mode
] != hp_mode_old1
2628 or *params
[param_lp_freq
] != lp_freq_old1
2629 or *params
[param_lp_mode
] != lp_mode_old1
2631 or *params
[param_ls_freq
] != ls_freq_old1
2632 or *params
[param_ls_level
] != ls_level_old1
2633 or *params
[param_hs_freq
] != hs_freq_old1
2634 or *params
[param_hs_level
] != hs_level_old1
2636 or *params
[param_p1_freq
] != p_freq_old1
[0]
2637 or *params
[param_p1_level
] != p_level_old1
[0]
2638 or *params
[param_p1_q
] != p_q_old1
[0]
2640 or *params
[param_p2_freq
] != p_freq_old1
[1]
2641 or *params
[param_p2_level
] != p_level_old1
[1]
2642 or *params
[param_p2_q
] != p_q_old1
[1]
2644 or *params
[param_p3_freq
] != p_freq_old1
[2]
2645 or *params
[param_p3_level
] != p_level_old1
[2]
2646 or *params
[param_p3_q
] != p_q_old1
[2]
2648 or *params
[param_p4_freq
] != p_freq_old1
[3]
2649 or *params
[param_p4_level
] != p_level_old1
[3]
2650 or *params
[param_p4_q
] != p_q_old1
[3])
2653 hp_freq_old1
= *params
[param_hp_freq
];
2654 hp_mode_old1
= *params
[param_hp_mode
];
2655 lp_freq_old1
= *params
[param_lp_freq
];
2656 lp_mode_old1
= *params
[param_lp_mode
];
2658 ls_freq_old1
= *params
[param_ls_freq
];
2659 ls_level_old1
= *params
[param_ls_level
];
2660 hs_freq_old1
= *params
[param_hs_freq
];
2661 hs_level_old1
= *params
[param_hs_level
];
2663 p_freq_old1
[0] = *params
[param_p1_freq
];
2664 p_level_old1
[0] = *params
[param_p1_level
];
2665 p_q_old1
[0] = *params
[param_p1_q
];
2667 p_freq_old1
[1] = *params
[param_p2_freq
];
2668 p_level_old1
[1] = *params
[param_p2_level
];
2669 p_q_old1
[1] = *params
[param_p2_q
];
2671 p_freq_old1
[2] = *params
[param_p3_freq
];
2672 p_level_old1
[2] = *params
[param_p3_level
];
2673 p_q_old1
[2] = *params
[param_p3_q
];
2675 p_freq_old1
[3] = *params
[param_p4_freq
];
2676 p_level_old1
[3] = *params
[param_p4_level
];
2677 p_q_old1
[3] = *params
[param_p4_q
];
2681 subindex_dot
= INT_MAX
;
2682 subindex_gridline
= INT_MAX
;
2686 subindex_dot
= subindex_gridline
= generation
? INT_MAX
: 0;
2688 if (generation
== last_calculated_generation
)
2689 subindex_graph
= INT_MAX
;
2690 return last_generation
;
2695 /// Equalizer 5 Band by Markus Schmidt
2697 /// This module is based on Krzysztof's filters. It provides a couple
2698 /// of different chained filters.
2699 ///////////////////////////////////////////////////////////////////////////////////////////////
2701 equalizer5band_audio_module::equalizer5band_audio_module()
2705 last_generation
= 0;
2712 void equalizer5band_audio_module::activate()
2718 void equalizer5band_audio_module::deactivate()
2723 void equalizer5band_audio_module::params_changed()
2725 // set the params of all filters
2726 if(*params
[param_ls_freq
] != ls_freq_old
or *params
[param_ls_level
] != ls_level_old
) {
2727 lsL
.set_lowshelf_rbj(*params
[param_ls_freq
], 0.707, *params
[param_ls_level
], (float)srate
);
2728 lsR
.copy_coeffs(lsL
);
2729 ls_level_old
= *params
[param_ls_level
];
2730 ls_freq_old
= *params
[param_ls_freq
];
2732 if(*params
[param_hs_freq
] != hs_freq_old
or *params
[param_hs_level
] != hs_level_old
) {
2733 hsL
.set_highshelf_rbj(*params
[param_hs_freq
], 0.707, *params
[param_hs_level
], (float)srate
);
2734 hsR
.copy_coeffs(hsL
);
2735 hs_level_old
= *params
[param_hs_level
];
2736 hs_freq_old
= *params
[param_hs_freq
];
2738 if(*params
[param_p1_freq
] != p_freq_old
[0] or *params
[param_p1_level
] != p_level_old
[0] or *params
[param_p1_q
] != p_q_old
[0]) {
2739 pL
[0].set_peakeq_rbj((float)*params
[param_p1_freq
], *params
[param_p1_q
], *params
[param_p1_level
], (float)srate
);
2740 pR
[0].copy_coeffs(pL
[0]);
2741 p_freq_old
[0] = *params
[param_p1_freq
];
2742 p_level_old
[0] = *params
[param_p1_level
];
2743 p_q_old
[0] = *params
[param_p1_q
];
2745 if(*params
[param_p2_freq
] != p_freq_old
[1] or *params
[param_p2_level
] != p_level_old
[1] or *params
[param_p2_q
] != p_q_old
[1]) {
2746 pL
[1].set_peakeq_rbj((float)*params
[param_p2_freq
], *params
[param_p2_q
], *params
[param_p2_level
], (float)srate
);
2747 pR
[1].copy_coeffs(pL
[1]);
2748 p_freq_old
[1] = *params
[param_p2_freq
];
2749 p_level_old
[1] = *params
[param_p2_level
];
2750 p_q_old
[1] = *params
[param_p2_q
];
2752 if(*params
[param_p3_freq
] != p_freq_old
[2] or *params
[param_p3_level
] != p_level_old
[2] or *params
[param_p3_q
] != p_q_old
[2]) {
2753 pL
[2].set_peakeq_rbj((float)*params
[param_p3_freq
], *params
[param_p3_q
], *params
[param_p3_level
], (float)srate
);
2754 pR
[2].copy_coeffs(pL
[2]);
2755 p_freq_old
[2] = *params
[param_p3_freq
];
2756 p_level_old
[2] = *params
[param_p3_level
];
2757 p_q_old
[2] = *params
[param_p3_q
];
2761 void equalizer5band_audio_module::set_sample_rate(uint32_t sr
)
2766 uint32_t equalizer5band_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
2768 bool bypass
= *params
[param_bypass
] > 0.5f
;
2769 numsamples
+= offset
;
2771 // everything bypassed
2772 while(offset
< numsamples
) {
2773 outs
[0][offset
] = ins
[0][offset
];
2774 outs
[1][offset
] = ins
[1][offset
];
2784 clip_in
-= std::min(clip_in
, numsamples
);
2785 clip_out
-= std::min(clip_out
, numsamples
);
2790 while(offset
< numsamples
) {
2791 // cycle through samples
2794 float inL
= ins
[0][offset
];
2795 float inR
= ins
[1][offset
];
2797 inR
*= *params
[param_level_in
];
2798 inL
*= *params
[param_level_in
];
2803 // all filters in chain
2804 if(*params
[param_ls_active
] > 0.f
) {
2805 procL
= lsL
.process(procL
);
2806 procR
= lsR
.process(procR
);
2808 if(*params
[param_hs_active
] > 0.f
) {
2809 procL
= hsL
.process(procL
);
2810 procR
= hsR
.process(procR
);
2812 if(*params
[param_p1_active
] > 0.f
) {
2813 procL
= pL
[0].process(procL
);
2814 procR
= pR
[0].process(procR
);
2816 if(*params
[param_p2_active
] > 0.f
) {
2817 procL
= pL
[1].process(procL
);
2818 procR
= pR
[1].process(procR
);
2820 if(*params
[param_p3_active
] > 0.f
) {
2821 procL
= pL
[2].process(procL
);
2822 procR
= pR
[2].process(procR
);
2825 outL
= procL
* *params
[param_level_out
];
2826 outR
= procR
* *params
[param_level_out
];
2829 outs
[0][offset
] = outL
;
2830 outs
[1][offset
] = outR
;
2833 float maxIn
= std::max(fabs(inL
), fabs(inR
));
2834 float maxOut
= std::max(fabs(outL
), fabs(outR
));
2837 clip_in
= srate
>> 3;
2840 clip_out
= srate
>> 3;
2842 // set up in / out meters
2843 if(maxIn
> meter_in
) {
2846 if(maxOut
> meter_out
) {
2852 } // cycle trough samples
2856 for(int i
= 0; i
< 3; ++i
) {
2862 if(params
[param_clip_in
] != NULL
) {
2863 *params
[param_clip_in
] = clip_in
;
2865 if(params
[param_clip_out
] != NULL
) {
2866 *params
[param_clip_out
] = clip_out
;
2869 if(params
[param_meter_in
] != NULL
) {
2870 *params
[param_meter_in
] = meter_in
;
2872 if(params
[param_meter_out
] != NULL
) {
2873 *params
[param_meter_out
] = meter_out
;
2875 // whatever has to be returned x)
2876 return outputs_mask
;
2878 bool equalizer5band_audio_module::get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
)
2882 if (index
== param_p1_freq
&& !subindex
) {
2883 context
->set_line_width(1.5);
2884 return ::get_graph(*this, subindex
, data
, points
);
2889 bool equalizer5band_audio_module::get_gridline(int index
, int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
)
2894 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
2898 int equalizer5band_audio_module::get_changed_offsets(int index
, int generation
, int &subindex_graph
, int &subindex_dot
, int &subindex_gridline
)
2903 if (*params
[param_ls_freq
] != ls_freq_old1
2904 or *params
[param_ls_level
] != ls_level_old1
2905 or *params
[param_hs_freq
] != hs_freq_old1
2906 or *params
[param_hs_level
] != hs_level_old1
2908 or *params
[param_p1_freq
] != p_freq_old1
[0]
2909 or *params
[param_p1_level
] != p_level_old1
[0]
2910 or *params
[param_p1_q
] != p_q_old1
[0]
2912 or *params
[param_p2_freq
] != p_freq_old1
[1]
2913 or *params
[param_p2_level
] != p_level_old1
[1]
2914 or *params
[param_p2_q
] != p_q_old1
[1]
2916 or *params
[param_p3_freq
] != p_freq_old1
[2]
2917 or *params
[param_p3_level
] != p_level_old1
[2]
2918 or *params
[param_p3_q
] != p_q_old1
[2])
2921 ls_freq_old1
= *params
[param_ls_freq
];
2922 ls_level_old1
= *params
[param_ls_level
];
2923 hs_freq_old1
= *params
[param_hs_freq
];
2924 hs_level_old1
= *params
[param_hs_level
];
2926 p_freq_old1
[0] = *params
[param_p1_freq
];
2927 p_level_old1
[0] = *params
[param_p1_level
];
2928 p_q_old1
[0] = *params
[param_p1_q
];
2930 p_freq_old1
[1] = *params
[param_p2_freq
];
2931 p_level_old1
[1] = *params
[param_p2_level
];
2932 p_q_old1
[1] = *params
[param_p2_q
];
2934 p_freq_old1
[2] = *params
[param_p3_freq
];
2935 p_level_old1
[2] = *params
[param_p3_level
];
2936 p_q_old1
[2] = *params
[param_p3_q
];
2940 subindex_dot
= INT_MAX
;
2941 subindex_gridline
= INT_MAX
;
2945 subindex_dot
= subindex_gridline
= generation
? INT_MAX
: 0;
2947 if (generation
== last_calculated_generation
)
2948 subindex_graph
= INT_MAX
;
2949 return last_generation
;