1 /* Calf DSP plugin pack
2 * Equalization related plugins
4 * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
23 #include <calf/giface.h>
24 #include <calf/modules_filter.h>
27 using namespace calf_plugins
;
29 #define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name;
31 /**********************************************************************
32 * EQUALIZER N BAND by Markus Schmidt and Krzysztof Foltman
33 **********************************************************************/
35 inline void diff_ms(float &left
, float &right
) {
36 float tmp
= (left
+ right
) / 2;
40 inline void undiff_ms(float &left
, float &right
) {
41 float tmp
= left
+ right
/ 2;
42 right
= left
- right
/ 2;
46 template<class BaseClass
, bool has_lphp
>
47 equalizerNband_audio_module
<BaseClass
, has_lphp
>::equalizerNband_audio_module()
52 hp_freq_old
= lp_freq_old
= 0;
53 hs_freq_old
= ls_freq_old
= 0;
54 hs_level_old
= ls_level_old
= 0;
59 for (int i
= 0; i
< AM::PeakBands
; i
++)
65 for (int i
= 0; i
< graph_param_count
; i
++)
66 old_params_for_graph
[i
] = -1;
70 template<class BaseClass
, bool has_lphp
>
71 void equalizerNband_audio_module
<BaseClass
, has_lphp
>::activate()
78 template<class BaseClass
, bool has_lphp
>
79 void equalizerNband_audio_module
<BaseClass
, has_lphp
>::deactivate()
84 static inline void copy_lphp(biquad_d2 filters
[3][2])
86 for (int i
= 0; i
< 3; i
++)
87 for (int j
= 0; j
< 2; j
++)
89 filters
[i
][j
].copy_coeffs(filters
[0][0]);
92 static inline double glide(double value
, double target
, int &keep_gliding
)
98 return std::min(target
, (value
+ 0.1) * 1.003);
100 return std::max(target
, (value
/ 1.003) - 0.1);
103 template<class BaseClass
, bool has_lphp
>
104 void equalizerNband_audio_module
<BaseClass
, has_lphp
>::params_changed()
107 // set the params of all filters
109 // lp/hp first (if available)
112 hp_mode
= (CalfEqMode
)(int)*params
[AM::param_hp_mode
];
113 lp_mode
= (CalfEqMode
)(int)*params
[AM::param_lp_mode
];
115 float hpfreq
= *params
[AM::param_hp_freq
], lpfreq
= *params
[AM::param_lp_freq
];
117 if(hpfreq
!= hp_freq_old
) {
118 hpfreq
= glide(hp_freq_old
, hpfreq
, keep_gliding
);
119 hp
[0][0].set_hp_rbj(hpfreq
, 0.707, (float)srate
, 1.0);
121 hp_freq_old
= hpfreq
;
123 if(lpfreq
!= lp_freq_old
) {
124 lpfreq
= glide(lp_freq_old
, lpfreq
, keep_gliding
);
125 lp
[0][0].set_lp_rbj(lpfreq
, 0.707, (float)srate
, 1.0);
127 lp_freq_old
= lpfreq
;
132 float hsfreq
= *params
[AM::param_hs_freq
], hslevel
= *params
[AM::param_hs_level
];
133 float lsfreq
= *params
[AM::param_ls_freq
], lslevel
= *params
[AM::param_ls_level
];
135 if(lsfreq
!= ls_freq_old
or lslevel
!= ls_level_old
) {
136 lsfreq
= glide(ls_freq_old
, lsfreq
, keep_gliding
);
137 lsL
.set_lowshelf_rbj(lsfreq
, 0.707, lslevel
, (float)srate
);
138 lsR
.copy_coeffs(lsL
);
139 ls_level_old
= lslevel
;
140 ls_freq_old
= lsfreq
;
142 if(hsfreq
!= hs_freq_old
or hslevel
!= hs_level_old
) {
143 hsfreq
= glide(hs_freq_old
, hsfreq
, keep_gliding
);
144 hsL
.set_highshelf_rbj(hsfreq
, 0.707, hslevel
, (float)srate
);
145 hsR
.copy_coeffs(hsL
);
146 hs_level_old
= hslevel
;
147 hs_freq_old
= hsfreq
;
149 for (int i
= 0; i
< AM::PeakBands
; i
++)
151 int offset
= i
* params_per_band
;
152 float freq
= *params
[AM::param_p1_freq
+ offset
];
153 float level
= *params
[AM::param_p1_level
+ offset
];
154 float q
= *params
[AM::param_p1_q
+ offset
];
155 if(freq
!= p_freq_old
[i
] or level
!= p_level_old
[i
] or q
!= p_q_old
[i
]) {
156 freq
= glide(p_freq_old
[i
], freq
, keep_gliding
);
157 pL
[i
].set_peakeq_rbj(freq
, q
, level
, (float)srate
);
158 pR
[i
].copy_coeffs(pL
[i
]);
159 p_freq_old
[i
] = freq
;
160 p_level_old
[i
] = level
;
164 if (*params
[AM::param_individuals
] != indiv_old
) {
165 indiv_old
= *params
[AM::param_individuals
];
169 // check if any important parameter for redrawing the graph changed
170 for (int i
= 0; i
< graph_param_count
; i
++) {
171 if (*params
[AM::first_graph_param
+ i
] != old_params_for_graph
[i
])
173 old_params_for_graph
[i
] = *params
[AM::first_graph_param
+ i
];
176 _analyzer
.set_params(
178 *params
[AM::param_analyzer_mode
] + (*params
[AM::param_analyzer_mode
] >= 3 ? 5 : 1),
182 if ((bool)*params
[AM::param_analyzer_active
] != analyzer_old
) {
184 analyzer_old
= (bool)*params
[AM::param_analyzer_active
];
188 template<class BaseClass
, bool has_lphp
>
189 inline void equalizerNband_audio_module
<BaseClass
, has_lphp
>::process_hplp(float &left
, float &right
)
193 int active
= *params
[AM::param_lp_active
];
196 if (active
> 3) diff_ms(left
, right
);
200 if (active
== 1 or active
== 2 or active
== 4)
201 left
= lp
[0][0].process(left
);
202 if (active
== 1 or active
== 3 or active
== 5)
203 right
= lp
[0][1].process(right
);
206 if (active
== 1 or active
== 2 or active
== 4)
207 left
= lp
[1][0].process(lp
[0][0].process(left
));
208 if (active
== 1 or active
== 3 or active
== 5)
209 right
= lp
[1][1].process(lp
[0][1].process(right
));
212 if (active
== 1 or active
== 2 or active
== 4)
213 left
= lp
[2][0].process(lp
[1][0].process(lp
[0][0].process(left
)));
214 if (active
== 1 or active
== 3 or active
== 5)
215 right
= lp
[2][1].process(lp
[1][1].process(lp
[0][1].process(right
)));
218 if (active
> 3) undiff_ms(left
, right
);
220 active
= *params
[AM::param_hp_active
];
223 if (active
> 3) diff_ms(left
, right
);
227 if (active
== 1 or active
== 2 or active
== 4)
228 left
= hp
[0][0].process(left
);
229 if (active
== 1 or active
== 3 or active
== 5)
230 right
= hp
[0][1].process(right
);
233 if (active
== 1 or active
== 2 or active
== 4)
234 left
= hp
[1][0].process(hp
[0][0].process(left
));
235 if (active
== 1 or active
== 3 or active
== 5)
236 right
= hp
[1][1].process(hp
[0][1].process(right
));
239 if (active
== 1 or active
== 2 or active
== 4)
240 left
= hp
[2][0].process(hp
[1][0].process(hp
[0][0].process(left
)));
241 if (active
== 1 or active
== 3 or active
== 5)
242 right
= hp
[2][1].process(hp
[1][1].process(hp
[0][1].process(right
)));
245 if (active
> 3) undiff_ms(left
, right
);
249 template<class BaseClass
, bool has_lphp
>
250 uint32_t equalizerNband_audio_module
<BaseClass
, has_lphp
>::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
252 bool bypassed
= bypass
.update(*params
[AM::param_bypass
] > 0.5f
, numsamples
);
253 if (keep_gliding
&& !bypassed
)
255 // ensure that if params have changed, the params_changed method is
256 // called every 8 samples to interpolate filter parameters
257 while(numsamples
> 8 && keep_gliding
)
260 outputs_mask
|= process(offset
, 8, inputs_mask
, outputs_mask
);
267 numsamples
+= offset
;
269 // everything bypassed
270 while(offset
< numsamples
) {
271 outs
[0][offset
] = ins
[0][offset
];
272 outs
[1][offset
] = ins
[1][offset
];
273 float values
[] = {0, 0, 0, 0};
274 meters
.process(values
);
275 _analyzer
.process(0, 0);
280 uint32_t orig_offset
= offset
;
281 while(offset
< numsamples
) {
282 // cycle through samples
285 float inL
= ins
[0][offset
];
286 float inR
= ins
[1][offset
];
288 inR
*= *params
[AM::param_level_in
];
289 inL
*= *params
[AM::param_level_in
];
294 // all filters in chain
295 process_hplp(procL
, procR
);
297 int active
= *params
[AM::param_ls_active
];
298 if (active
> 3) diff_ms(procL
, procR
);
299 if (active
== 1 or active
== 2 or active
== 4)
300 procL
= lsL
.process(procL
);
301 if (active
== 1 or active
== 3 or active
== 5)
302 procR
= lsR
.process(procR
);
303 if (active
> 3) undiff_ms(procL
, procR
);
305 active
= *params
[AM::param_hs_active
];
306 if (active
> 3) diff_ms(procL
, procR
);
307 if (active
== 1 or active
== 2 or active
== 4)
308 procL
= hsL
.process(procL
);
309 if (active
== 1 or active
== 3 or active
== 5)
310 procR
= hsR
.process(procR
);
311 if (active
> 3) undiff_ms(procL
, procR
);
313 for (int i
= 0; i
< AM::PeakBands
; i
++)
315 int offset
= i
* params_per_band
;
316 int active
= *params
[AM::param_p1_active
+ offset
];
317 if (active
> 3) diff_ms(procL
, procR
);
318 if (active
== 1 or active
== 2 or active
== 4)
319 procL
= pL
[i
].process(procL
);
320 if (active
== 1 or active
== 3 or active
== 5)
321 procR
= pR
[i
].process(procR
);
322 if (active
> 3) undiff_ms(procL
, procR
);
325 outL
= procL
* *params
[AM::param_level_out
];
326 outR
= procR
* *params
[AM::param_level_out
];
329 _analyzer
.process((inL
+ inR
) / 2.f
, (outL
+ outR
) / 2.f
);
332 outs
[0][offset
] = outL
;
333 outs
[1][offset
] = outR
;
335 float values
[] = {inL
, inR
, outL
, outR
};
336 meters
.process(values
);
340 } // cycle trough samples
341 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
343 for(int i
= 0; i
< 3; ++i
) {
351 for(int i
= 0; i
< AM::PeakBands
; ++i
) {
356 meters
.fall(numsamples
);
360 static inline float adjusted_lphp_gain(const float *const *params
, int param_active
, int param_mode
, const biquad_d2
&filter
, float freq
, float srate
)
362 if(*params
[param_active
] > 0.f
) {
363 float gain
= filter
.freq_gain(freq
, srate
);
364 switch((int)*params
[param_mode
]) {
370 return gain
* gain
* gain
;
376 template<class BaseClass
, bool has_lphp
>
377 bool equalizerNband_audio_module
<BaseClass
, has_lphp
>::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
379 if (phase
and *params
[AM::param_analyzer_active
]) {
380 bool r
= _analyzer
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
381 if (*params
[AM::param_analyzer_mode
] == 2) {
382 set_channel_color(context
, subindex
? 0 : 1, 0.15);
384 context
->set_source_rgba(0,0,0,0.1);
387 } else if (phase
and !*params
[AM::param_analyzer_active
]) {
388 redraw_graph
= false;
391 int max
= PeakBands
+ 2 + (has_lphp
? 2 : 0);
394 or (subindex
and !*params
[AM::param_individuals
])
395 or (subindex
> max
and *params
[AM::param_individuals
])) {
396 redraw_graph
= false;
400 // first graph is the overall frequency response graph
402 return ::get_graph(*this, subindex
, data
, points
, 128 * *params
[AM::param_zoom
], 0);
404 // get out if max band is reached
405 if (last_peak
>= max
) {
407 redraw_graph
= false;
411 // get the next filter to draw a curve for and leave out inactive
413 while (last_peak
< PeakBands
and !*params
[AM::param_p1_active
+ last_peak
* params_per_band
])
415 if (last_peak
== PeakBands
and !*params
[AM::param_ls_active
])
417 if (last_peak
== PeakBands
+ 1 and !*params
[AM::param_hs_active
])
419 if (has_lphp
and last_peak
== PeakBands
+ 2 and !*params
[AM::param_hp_active
])
421 if (has_lphp
and last_peak
== PeakBands
+ 3 and !*params
[AM::param_lp_active
])
424 // get out if max band is reached
425 if (last_peak
>= max
) { // and !*params[param_analyzer_active]) {
427 redraw_graph
= false;
430 //else if *params[param_analyzer_active]) {
431 //bool goon = _analyzer.get_graph(subindex, phase, data, points, context, mode);
437 // draw the individual curve of the actual filter
438 for (int i
= 0; i
< points
; i
++) {
439 double freq
= 20.0 * pow (20000.0 / 20.0, i
* 1.0 / points
);
440 if (last_peak
< PeakBands
) {
441 data
[i
] = pL
[last_peak
].freq_gain(freq
, (float)srate
);
442 } else if (last_peak
== PeakBands
) {
443 data
[i
] = lsL
.freq_gain(freq
, (float)srate
);
444 } else if (last_peak
== PeakBands
+ 1) {
445 data
[i
] = hsL
.freq_gain(freq
, (float)srate
);
446 } else if (last_peak
== PeakBands
+ 2 and has_lphp
) {
447 data
[i
] = adjusted_lphp_gain(params
, AM::param_hp_active
, AM::param_hp_mode
, hp
[0][0], freq
, (float)srate
);
448 } else if (last_peak
== PeakBands
+ 3 and has_lphp
) {
449 data
[i
] = adjusted_lphp_gain(params
, AM::param_lp_active
, AM::param_lp_mode
, lp
[0][0], freq
, (float)srate
);
451 data
[i
] = dB_grid(data
[i
], 128 * *params
[AM::param_zoom
], 0);
456 context
->set_source_rgba(0,0,0,0.075);
460 template<class BaseClass
, bool has_lphp
>
461 bool equalizerNband_audio_module
<BaseClass
, has_lphp
>::get_layers(int index
, int generation
, unsigned int &layers
) const
463 redraw_graph
= redraw_graph
|| !generation
;
464 layers
= *params
[AM::param_analyzer_active
] ? LG_REALTIME_GRAPH
: 0;
465 layers
|= (generation
? LG_NONE
: LG_CACHE_GRID
) | (redraw_graph
? LG_CACHE_GRAPH
: LG_NONE
);
466 redraw_graph
|= (bool)*params
[AM::param_analyzer_active
];
467 return redraw_graph
or !generation
;
470 template<class BaseClass
, bool has_lphp
>
471 bool equalizerNband_audio_module
<BaseClass
, has_lphp
>::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
473 if (!is_active
or phase
)
475 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
, true, 128 * *params
[AM::param_zoom
], 0);
478 template<class BaseClass
, bool has_lphp
>
479 float equalizerNband_audio_module
<BaseClass
, has_lphp
>::freq_gain(int index
, double freq
) const
484 ret
*= adjusted_lphp_gain(params
, AM::param_hp_active
, AM::param_hp_mode
, hp
[0][0], freq
, (float)srate
);
485 ret
*= adjusted_lphp_gain(params
, AM::param_lp_active
, AM::param_lp_mode
, lp
[0][0], freq
, (float)srate
);
487 ret
*= (*params
[AM::param_ls_active
] > 0.f
) ? lsL
.freq_gain(freq
, (float)srate
) : 1;
488 ret
*= (*params
[AM::param_hs_active
] > 0.f
) ? hsL
.freq_gain(freq
, (float)srate
) : 1;
489 for (int i
= 0; i
< PeakBands
; i
++)
490 ret
*= (*params
[AM::param_p1_active
+ i
* params_per_band
] > 0.f
) ? pL
[i
].freq_gain(freq
, (float)srate
) : 1;
494 template class equalizerNband_audio_module
<equalizer5band_metadata
, false>;
495 template class equalizerNband_audio_module
<equalizer8band_metadata
, true>;
496 template class equalizerNband_audio_module
<equalizer12band_metadata
, true>;
499 /**********************************************************************
500 * FILTERKLAVIER by Hans Baier
501 **********************************************************************/
503 filterclavier_audio_module::filterclavier_audio_module()
504 : filter_module_with_inertia
<biquad_filter_module
, filterclavier_metadata
>(ins
, outs
, params
)
512 void filterclavier_audio_module::params_changed()
514 inertia_filter_module::inertia_cutoff
.set_inertia(
515 note_to_hz(last_note
+ *params
[par_transpose
], *params
[par_detune
]));
517 float min_resonance
= param_props
[par_max_resonance
].min
;
518 inertia_filter_module::inertia_resonance
.set_inertia(
519 (float(last_velocity
) / 127.0)
521 * (*params
[par_max_resonance
] - min_resonance
+ 0.001)
524 adjust_gain_according_to_filter_mode(last_velocity
);
526 inertia_filter_module::calculate_filter();
530 void filterclavier_audio_module::activate()
532 inertia_filter_module::activate();
535 void filterclavier_audio_module::set_sample_rate(uint32_t sr
)
537 inertia_filter_module::set_sample_rate(sr
);
540 void filterclavier_audio_module::deactivate()
542 inertia_filter_module::deactivate();
546 void filterclavier_audio_module::note_on(int channel
, int note
, int vel
)
550 inertia_filter_module::inertia_cutoff
.set_inertia(
551 note_to_hz(note
+ *params
[par_transpose
], *params
[par_detune
]));
553 float min_resonance
= param_props
[par_max_resonance
].min
;
554 inertia_filter_module::inertia_resonance
.set_inertia(
556 // 0.001: if the difference is equal to zero (which happens
557 // when the max_resonance knom is at minimum position
558 // then the filter gain doesnt seem to snap to zero on most note offs
559 * (*params
[par_max_resonance
] - min_resonance
+ 0.001)
562 adjust_gain_according_to_filter_mode(vel
);
564 inertia_filter_module::calculate_filter();
568 void filterclavier_audio_module::note_off(int channel
, int note
, int vel
)
570 if (note
== last_note
) {
571 inertia_filter_module::inertia_resonance
.set_inertia(param_props
[par_max_resonance
].min
);
572 inertia_filter_module::inertia_gain
.set_inertia(min_gain
);
573 inertia_filter_module::calculate_filter();
579 void filterclavier_audio_module::adjust_gain_according_to_filter_mode(int velocity
)
581 int mode
= dsp::fastf2i_drm(*params
[par_mode
]);
583 // for bandpasses: boost gain for velocities > 0
584 if ( (mode_6db_bp
<= mode
) && (mode
<= mode_18db_bp
) ) {
585 // gain for velocity 0: 1.0
586 // gain for velocity 127: 32.0
587 float mode_max_gain
= max_gain
;
588 // max_gain is right for mode_6db_bp
589 if (mode
== mode_12db_bp
)
590 mode_max_gain
/= 6.0;
591 if (mode
== mode_18db_bp
)
592 mode_max_gain
/= 10.5;
594 inertia_filter_module::inertia_gain
.set_now(
595 (float(velocity
) / 127.0) * (mode_max_gain
- min_gain
) + min_gain
);
597 inertia_filter_module::inertia_gain
.set_now(min_gain
);
601 /**********************************************************************
602 * EMPHASIS by Damien Zammit
603 **********************************************************************/
605 emphasis_audio_module::emphasis_audio_module()
614 void emphasis_audio_module::activate()
621 void emphasis_audio_module::deactivate()
626 void emphasis_audio_module::params_changed()
628 if (mode
!= *params
[param_mode
] or type
!= *params
[param_type
] or bypass_
!= *params
[param_bypass
])
630 mode
= *params
[param_mode
];
631 type
= *params
[param_type
];
632 bypass_
= *params
[param_bypass
];
633 riaacurvL
.set(srate
, mode
, type
);
634 riaacurvR
.set(srate
, mode
, type
);
637 uint32_t emphasis_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
639 uint32_t orig_numsamples
= numsamples
;
640 uint32_t orig_offset
= offset
;
641 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
644 // ensure that if params have changed, the params_changed method is
645 // called every 8 samples to interpolate filter parameters
646 while(numsamples
> 8)
649 outputs_mask
|= process(offset
, 8, inputs_mask
, outputs_mask
);
654 numsamples
+= offset
;
656 // everything bypassed
657 while(offset
< numsamples
) {
658 outs
[0][offset
] = ins
[0][offset
];
659 outs
[1][offset
] = ins
[1][offset
];
660 float values
[] = {0, 0, 0, 0};
661 meters
.process(values
);
666 while(offset
< numsamples
) {
667 // cycle through samples
670 float inL
= ins
[0][offset
];
671 float inR
= ins
[1][offset
];
673 inR
*= *params
[param_level_in
];
674 inL
*= *params
[param_level_in
];
679 procL
= riaacurvL
.process(procL
);
680 procR
= riaacurvR
.process(procR
);
682 outL
= procL
* *params
[param_level_out
];
683 outR
= procR
* *params
[param_level_out
];
686 outs
[0][offset
] = outL
;
687 outs
[1][offset
] = outR
;
689 float values
[] = {inL
, inR
, outL
, outR
};
690 meters
.process(values
);
694 } // cycle trough samples
695 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
697 riaacurvL
.sanitize();
698 riaacurvR
.sanitize();
700 meters
.fall(orig_numsamples
);
703 bool emphasis_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
705 if (phase
or subindex
)
708 context
->set_source_rgba(0.15, 0.2, 0.0, 0.3);
709 return ::get_graph(*this, subindex
, data
, points
, 32, 0);
711 bool emphasis_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
715 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
, true, 32, 0);
718 /**********************************************************************
719 * CROSSOVER N BAND by Markus Schmidt
720 **********************************************************************/
722 template<class XoverBaseClass
>
723 xover_audio_module
<XoverBaseClass
>::xover_audio_module()
728 crossover
.init(AM::channels
, AM::bands
, 44100);
730 template<class XoverBaseClass
>
731 xover_audio_module
<XoverBaseClass
>::~xover_audio_module()
735 template<class XoverBaseClass
>
736 void xover_audio_module
<XoverBaseClass
>::activate()
742 template<class XoverBaseClass
>
743 void xover_audio_module
<XoverBaseClass
>::deactivate()
747 template<class XoverBaseClass
>
748 void xover_audio_module
<XoverBaseClass
>::set_sample_rate(uint32_t sr
)
751 // set srate of crossover
752 crossover
.set_sample_rate(srate
);
754 buffer_size
= (int)(srate
/ 10 * AM::channels
* AM::bands
+ AM::channels
* AM::bands
); // buffer size attack rate multiplied by channels and bands
755 buffer
= (float*) calloc(buffer_size
, sizeof(float));
757 int amount
= AM::bands
* AM::channels
+ AM::channels
;
760 for(int b
= 0; b
< AM::bands
; b
++) {
761 for (int c
= 0; c
< AM::channels
; c
++) {
762 meter
[b
* AM::channels
+ c
] = AM::param_meter_01
+ b
* params_per_band
+ c
;
763 clip
[b
* AM::channels
+ c
] = -1;
766 for (int c
= 0; c
< AM::channels
; c
++) {
767 meter
[c
+ AM::bands
* AM::channels
] = AM::param_meter_0
+ c
;
768 clip
[c
+ AM::bands
* AM::channels
] = -1;
770 meters
.init(params
, meter
, clip
, amount
, srate
);
772 template<class XoverBaseClass
>
773 void xover_audio_module
<XoverBaseClass
>::params_changed()
775 int mode
= *params
[AM::param_mode
];
776 crossover
.set_mode(mode
);
777 for (int i
= 0; i
< AM::bands
- 1; i
++) {
778 crossover
.set_filter(i
, *params
[AM::param_freq0
+ i
]);
780 for (int i
= 0; i
< AM::bands
; i
++) {
781 int offset
= i
* params_per_band
;
782 crossover
.set_level(i
, *params
[AM::param_level1
+ offset
]);
783 crossover
.set_active(i
, *params
[AM::param_active1
+ offset
] > 0.5);
788 template<class XoverBaseClass
>
789 uint32_t xover_audio_module
<XoverBaseClass
>::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
791 unsigned int targ
= numsamples
+ offset
;
793 float values
[AM::bands
* AM::channels
+ AM::channels
];
794 while(offset
< targ
) {
795 // cycle through samples
798 for (int c
= 0; c
< AM::channels
; c
++) {
799 in
[c
] = ins
[c
][offset
] * *params
[AM::param_level
];
801 crossover
.process(in
);
803 for (int b
= 0; b
< AM::bands
; b
++) {
805 int off
= b
* params_per_band
;
806 // calc position in delay buffer
807 if (*params
[AM::param_delay1
+ off
]) {
808 nbuf
= srate
* (fabs(*params
[AM::param_delay1
+ off
]) / 1000.f
) * AM::bands
* AM::channels
;
809 nbuf
-= nbuf
% (AM::bands
* AM::channels
);
811 for (int c
= 0; c
< AM::channels
; c
++) {
812 // define a pointer between 0 and channels * bands
813 int ptr
= b
* AM::channels
+ c
;
815 // get output from crossover module if active
816 xval
= *params
[AM::param_active1
+ off
] > 0.5 ? crossover
.get_value(c
, b
) : 0.f
;
819 buffer
[pos
+ ptr
] = xval
;
821 // get value from delay buffer if neccessary
822 if (*params
[AM::param_delay1
+ off
])
823 xval
= buffer
[(pos
- (int)nbuf
+ ptr
+ buffer_size
) % buffer_size
];
825 // set value with phase to output
826 outs
[ptr
][offset
] = *params
[AM::param_phase1
+ off
] > 0.5 ? xval
* -1 : xval
;
829 values
[b
* AM::channels
+ c
] = outs
[ptr
][offset
];
833 for (int c
= 0; c
< AM::channels
; c
++) {
834 values
[c
+ AM::bands
* AM::channels
] = ins
[c
][offset
];
836 meters
.process(values
);
839 // delay buffer pos forward
840 pos
= (pos
+ AM::channels
* AM::bands
) % buffer_size
;
842 } // cycle trough samples
843 meters
.fall(numsamples
);
847 template<class XoverBaseClass
>
848 bool xover_audio_module
<XoverBaseClass
>::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
850 return crossover
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
852 template<class XoverBaseClass
>
853 bool xover_audio_module
<XoverBaseClass
>::get_layers(int index
, int generation
, unsigned int &layers
) const
855 return crossover
.get_layers(index
, generation
, layers
);
858 template class xover_audio_module
<xover2_metadata
>;
859 template class xover_audio_module
<xover3_metadata
>;
860 template class xover_audio_module
<xover4_metadata
>;
863 /**********************************************************************
864 * Vocoder by Markus Schmidt and Christian Holschuh
865 **********************************************************************/
867 vocoder_audio_module::vocoder_audio_module()
878 fcoeff
= log10(20.f
);
880 memset(env_mods
, 0, 32 * 2 * sizeof(double));
883 void vocoder_audio_module::activate()
888 void vocoder_audio_module::deactivate()
893 void vocoder_audio_module::params_changed()
895 attack
= exp(log(0.01)/( *params
[param_attack
] * srate
* 0.001));
896 release
= exp(log(0.01)/( *params
[param_release
] * srate
* 0.001));
898 int b
= *params
[param_bands
];
899 bands
= (b
+ 2) * 4 + (b
> 1 ? (b
- 2) * 4 : 0);
900 order
= std::min(8.f
, *params
[param_order
]);
901 float q
= pow(10, (fmodf(std::min(8.999f
, *params
[param_order
]), 1.f
) * (7.f
/ pow(1.3, order
))) / 20);
902 if (bands
!= bands_old
or *params
[param_order
] != order_old
) {
904 order_old
= *params
[param_order
];
905 for (int i
= 0; i
< bands
; i
++) {
906 // set all actually used filters
907 detector
[0][0][i
].set_bp_rbj(pow(10, fcoeff
+ (0.5f
+ (float)i
) * 3.f
/ (float)bands
), q
, (double)srate
);
908 for (int j
= 0; j
< order
; j
++) {
910 detector
[0][j
][i
].copy_coeffs(detector
[0][0][i
]);
911 detector
[1][j
][i
].copy_coeffs(detector
[0][0][i
]);
912 modulator
[0][j
][i
].copy_coeffs(detector
[0][0][i
]);
913 modulator
[1][j
][i
].copy_coeffs(detector
[0][0][i
]);
918 _analyzer
.set_params(256, 1, 6, 0, 1, 0, 0, 0, 15, 2, 0, 0);
922 int vocoder_audio_module::get_solo() const {
923 for (int i
= 0; i
< bands
; i
++)
924 if (*params
[param_solo0
+ i
* band_params
])
929 uint32_t vocoder_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
931 uint32_t orig_numsamples
= numsamples
;
932 uint32_t orig_offset
= offset
;
933 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
934 int solo
= get_solo();
935 numsamples
+= offset
;
938 // everything bypassed
939 while(offset
< numsamples
) {
940 outs
[0][offset
] = ins
[0][offset
];
941 outs
[1][offset
] = ins
[1][offset
];
942 float values
[] = {0, 0, 0, 0, 0, 0};
943 meters
.process(values
);
948 while(offset
< numsamples
) {
949 // cycle through samples
955 // carrier with level
956 double cL
= ins
[0][offset
] * *params
[param_carrier_in
];
957 double cR
= ins
[1][offset
] * *params
[param_carrier_in
];
959 // modulator with level
960 double mL
= ins
[2][offset
] * *params
[param_mod_in
];
961 double mR
= ins
[3][offset
] * *params
[param_mod_in
];
964 double nL
= (float)rand() / (float)RAND_MAX
;
965 double nR
= (float)rand() / (float)RAND_MAX
;
967 for (int i
= 0; i
< bands
; i
++) {
970 double cL_
= cL
+ nL
* *params
[param_noise0
+ i
* band_params
];
971 double cR_
= cR
+ nR
* *params
[param_noise0
+ i
* band_params
];
973 if ((solo
and *params
[param_solo0
+ i
* band_params
]) or !solo
) {
974 for (int j
= 0; j
< order
; j
++) {
976 if (*params
[param_link
] > 0.5) {
977 mL_
= detector
[0][j
][i
].process(std::max(mL_
, mR_
));
980 mL_
= detector
[0][j
][i
].process(mL_
);
981 mR_
= detector
[1][j
][i
].process(mR_
);
983 // filter carrier with noise
984 cL_
= modulator
[0][j
][i
].process(cL_
);
985 cR_
= modulator
[1][j
][i
].process(cR_
);
987 // level by envelope with levelling
988 cL_
*= env_mods
[0][i
] * 4;
989 cR_
*= env_mods
[1][i
] * 4;
991 // add band volume setting
992 cL_
*= *params
[param_volume0
+ i
* band_params
];
993 cR_
*= *params
[param_volume0
+ i
* band_params
];
995 // add filtered modulator
996 cL_
+= mL_
* *params
[param_mod0
+ i
* band_params
];
997 cR_
+= mR_
* *params
[param_mod0
+ i
* band_params
];
1000 cL_
*= (*params
[param_pan0
+ i
* band_params
] > 0
1001 ? -*params
[param_pan0
+ i
* band_params
] + 1 : 1);
1002 cR_
*= (*params
[param_pan0
+ i
* band_params
] < 0
1003 ? *params
[param_pan0
+ i
* band_params
] + 1 : 1);
1005 // add to outputs with proc level
1006 pL
+= cL_
* *params
[param_proc
];
1007 pR
+= cR_
* *params
[param_proc
];
1010 if (*params
[param_detectors
] > 0.5)
1011 if (env_mods
[0][i
] + env_mods
[1][i
] > led
[i
])
1012 led
[i
] = env_mods
[0][i
] + env_mods
[1][i
];
1014 // advance envelopes
1015 env_mods
[0][i
] = (fabs(mL_
) > env_mods
[0][i
] ? attack
: release
) * (env_mods
[0][i
] - fabs(mL_
)) + fabs(mL_
);
1016 env_mods
[1][i
] = (fabs(mR_
) > env_mods
[1][i
] ? attack
: release
) * (env_mods
[1][i
] - fabs(mR_
)) + fabs(mR_
);
1023 outL
+= cL
* *params
[param_carrier
];
1024 outR
+= cR
* *params
[param_carrier
];
1027 outL
+= mL
* *params
[param_mod
];
1028 outR
+= mR
* *params
[param_mod
];
1031 switch ((int)*params
[param_analyzer
]) {
1036 _analyzer
.process((float)cL
, (float)cR
);
1039 _analyzer
.process((float)mL
, (float)mR
);
1042 _analyzer
.process((float)pL
, (float)pR
);
1045 _analyzer
.process((float)outL
, (float)outR
);
1050 outL
*= *params
[param_out
];
1051 outR
*= *params
[param_out
];
1054 outs
[0][offset
] = outL
;
1055 outs
[1][offset
] = outR
;
1058 float values
[] = {(float)cL
, (float)cR
, (float)mL
, (float)mR
, (float)outL
, (float)outR
};
1059 meters
.process(values
);
1063 } // cycle trough samples
1064 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
1066 for (int i
= 0; i
< bands
; i
++) {
1067 for (int j
= 0; j
< order
; j
++) {
1068 detector
[0][j
][i
].sanitize();
1069 detector
[1][j
][i
].sanitize();
1070 modulator
[0][j
][i
].sanitize();
1071 modulator
[1][j
][i
].sanitize();
1077 for (int i
= 0; i
< 32; i
++) {
1079 if (*params
[param_detectors
] > 0.5)
1080 val
= std::max(0.0, 1 + log((led
[i
] / 2) * order
) / log2_
/ 10);
1081 *params
[param_level0
+ i
* band_params
] = val
;
1083 meters
.fall(orig_numsamples
);
1084 return outputs_mask
;
1086 bool vocoder_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1088 if (phase
and *params
[param_analyzer
]) {
1092 bool r
= _analyzer
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
1093 context
->set_source_rgba(0,0,0,0.25);
1099 if (subindex
>= bands
) {
1100 redraw_graph
= false;
1103 int solo
= get_solo();
1104 if (solo
and !*params
[param_solo0
+ subindex
* band_params
])
1105 context
->set_source_rgba(0,0,0,0.15);
1106 context
->set_line_width(0.99);
1108 double fq
= pow(10, fcoeff
+ (0.5f
+ (float)subindex
) * 3.f
/ (float)bands
);
1109 for (int i
= 0; i
< points
; i
++) {
1110 double freq
= 20.0 * pow (20000.0 / 20.0, i
* 1.0 / points
);
1112 for (int j
= 0; j
< order
; j
++)
1113 level
*= detector
[0][0][subindex
].freq_gain(freq
, srate
);
1114 level
*= *params
[param_volume0
+ subindex
* band_params
];
1115 data
[i
] = dB_grid(level
, 256, 0.4);
1116 if (!drawn
and freq
> fq
) {
1119 sprintf(str
, "%d", subindex
+ 1);
1120 draw_cairo_label(context
, str
, i
, context
->size_y
* (1 - (data
[i
] + 1) / 2.f
), 0, 0, 0.5);
1126 bool vocoder_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1128 redraw_graph
= redraw_graph
|| !generation
;
1129 layers
= *params
[param_analyzer
] ? LG_REALTIME_GRAPH
: 0;
1130 layers
|= (generation
? LG_NONE
: LG_CACHE_GRID
) | (redraw_graph
? LG_CACHE_GRAPH
: LG_NONE
);
1131 redraw_graph
|= (bool)*params
[param_analyzer
];
1132 return redraw_graph
or !generation
;