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_numsamples
= numsamples
-offset
;
281 uint32_t orig_offset
= offset
;
282 while(offset
< numsamples
) {
283 // cycle through samples
286 float inL
= ins
[0][offset
];
287 float inR
= ins
[1][offset
];
289 inR
*= *params
[AM::param_level_in
];
290 inL
*= *params
[AM::param_level_in
];
295 // all filters in chain
296 process_hplp(procL
, procR
);
298 int active
= *params
[AM::param_ls_active
];
299 if (active
> 3) diff_ms(procL
, procR
);
300 if (active
== 1 or active
== 2 or active
== 4)
301 procL
= lsL
.process(procL
);
302 if (active
== 1 or active
== 3 or active
== 5)
303 procR
= lsR
.process(procR
);
304 if (active
> 3) undiff_ms(procL
, procR
);
306 active
= *params
[AM::param_hs_active
];
307 if (active
> 3) diff_ms(procL
, procR
);
308 if (active
== 1 or active
== 2 or active
== 4)
309 procL
= hsL
.process(procL
);
310 if (active
== 1 or active
== 3 or active
== 5)
311 procR
= hsR
.process(procR
);
312 if (active
> 3) undiff_ms(procL
, procR
);
314 for (int i
= 0; i
< AM::PeakBands
; i
++)
316 int offset
= i
* params_per_band
;
317 int active
= *params
[AM::param_p1_active
+ offset
];
318 if (active
> 3) diff_ms(procL
, procR
);
319 if (active
== 1 or active
== 2 or active
== 4)
320 procL
= pL
[i
].process(procL
);
321 if (active
== 1 or active
== 3 or active
== 5)
322 procR
= pR
[i
].process(procR
);
323 if (active
> 3) undiff_ms(procL
, procR
);
326 outL
= procL
* *params
[AM::param_level_out
];
327 outR
= procR
* *params
[AM::param_level_out
];
330 _analyzer
.process((inL
+ inR
) / 2.f
, (outL
+ outR
) / 2.f
);
333 outs
[0][offset
] = outL
;
334 outs
[1][offset
] = outR
;
336 float values
[] = {inL
, inR
, outL
, outR
};
337 meters
.process(values
);
341 } // cycle trough samples
342 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
344 for(int i
= 0; i
< 3; ++i
) {
352 for(int i
= 0; i
< AM::PeakBands
; ++i
) {
357 meters
.fall(numsamples
);
361 static inline float adjusted_lphp_gain(const float *const *params
, int param_active
, int param_mode
, const biquad_d2
&filter
, float freq
, float srate
)
363 if(*params
[param_active
] > 0.f
) {
364 float gain
= filter
.freq_gain(freq
, srate
);
365 switch((int)*params
[param_mode
]) {
371 return gain
* gain
* gain
;
377 template<class BaseClass
, bool has_lphp
>
378 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
380 if (phase
and *params
[AM::param_analyzer_active
]) {
381 bool r
= _analyzer
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
382 if (*params
[AM::param_analyzer_mode
] == 2) {
383 set_channel_color(context
, subindex
? 0 : 1, 0.15);
385 context
->set_source_rgba(0,0,0,0.1);
388 } else if (phase
and !*params
[AM::param_analyzer_active
]) {
389 redraw_graph
= false;
392 int max
= PeakBands
+ 2 + (has_lphp
? 2 : 0);
395 or (subindex
and !*params
[AM::param_individuals
])
396 or (subindex
> max
and *params
[AM::param_individuals
])) {
397 redraw_graph
= false;
401 // first graph is the overall frequency response graph
403 return ::get_graph(*this, subindex
, data
, points
, 128 * *params
[AM::param_zoom
], 0);
405 // get out if max band is reached
406 if (last_peak
>= max
) {
408 redraw_graph
= false;
412 // get the next filter to draw a curve for and leave out inactive
414 while (last_peak
< PeakBands
and !*params
[AM::param_p1_active
+ last_peak
* params_per_band
])
416 if (last_peak
== PeakBands
and !*params
[AM::param_ls_active
])
418 if (last_peak
== PeakBands
+ 1 and !*params
[AM::param_hs_active
])
420 if (has_lphp
and last_peak
== PeakBands
+ 2 and !*params
[AM::param_hp_active
])
422 if (has_lphp
and last_peak
== PeakBands
+ 3 and !*params
[AM::param_lp_active
])
425 // get out if max band is reached
426 if (last_peak
>= max
) { // and !*params[param_analyzer_active]) {
428 redraw_graph
= false;
431 //else if *params[param_analyzer_active]) {
432 //bool goon = _analyzer.get_graph(subindex, phase, data, points, context, mode);
438 // draw the individual curve of the actual filter
439 for (int i
= 0; i
< points
; i
++) {
440 double freq
= 20.0 * pow (20000.0 / 20.0, i
* 1.0 / points
);
441 if (last_peak
< PeakBands
) {
442 data
[i
] = pL
[last_peak
].freq_gain(freq
, (float)srate
);
443 } else if (last_peak
== PeakBands
) {
444 data
[i
] = lsL
.freq_gain(freq
, (float)srate
);
445 } else if (last_peak
== PeakBands
+ 1) {
446 data
[i
] = hsL
.freq_gain(freq
, (float)srate
);
447 } else if (last_peak
== PeakBands
+ 2 and has_lphp
) {
448 data
[i
] = adjusted_lphp_gain(params
, AM::param_hp_active
, AM::param_hp_mode
, hp
[0][0], freq
, (float)srate
);
449 } else if (last_peak
== PeakBands
+ 3 and has_lphp
) {
450 data
[i
] = adjusted_lphp_gain(params
, AM::param_lp_active
, AM::param_lp_mode
, lp
[0][0], freq
, (float)srate
);
452 data
[i
] = dB_grid(data
[i
], 128 * *params
[AM::param_zoom
], 0);
457 context
->set_source_rgba(0,0,0,0.075);
461 template<class BaseClass
, bool has_lphp
>
462 bool equalizerNband_audio_module
<BaseClass
, has_lphp
>::get_layers(int index
, int generation
, unsigned int &layers
) const
464 redraw_graph
= redraw_graph
|| !generation
;
465 layers
= *params
[AM::param_analyzer_active
] ? LG_REALTIME_GRAPH
: 0;
466 layers
|= (generation
? LG_NONE
: LG_CACHE_GRID
) | (redraw_graph
? LG_CACHE_GRAPH
: LG_NONE
);
467 redraw_graph
|= (bool)*params
[AM::param_analyzer_active
];
468 return redraw_graph
or !generation
;
471 template<class BaseClass
, bool has_lphp
>
472 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
474 if (!is_active
or phase
)
476 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
, true, 128 * *params
[AM::param_zoom
], 0);
479 template<class BaseClass
, bool has_lphp
>
480 float equalizerNband_audio_module
<BaseClass
, has_lphp
>::freq_gain(int index
, double freq
) const
485 ret
*= adjusted_lphp_gain(params
, AM::param_hp_active
, AM::param_hp_mode
, hp
[0][0], freq
, (float)srate
);
486 ret
*= adjusted_lphp_gain(params
, AM::param_lp_active
, AM::param_lp_mode
, lp
[0][0], freq
, (float)srate
);
488 ret
*= (*params
[AM::param_ls_active
] > 0.f
) ? lsL
.freq_gain(freq
, (float)srate
) : 1;
489 ret
*= (*params
[AM::param_hs_active
] > 0.f
) ? hsL
.freq_gain(freq
, (float)srate
) : 1;
490 for (int i
= 0; i
< PeakBands
; i
++)
491 ret
*= (*params
[AM::param_p1_active
+ i
* params_per_band
] > 0.f
) ? pL
[i
].freq_gain(freq
, (float)srate
) : 1;
495 template class equalizerNband_audio_module
<equalizer5band_metadata
, false>;
496 template class equalizerNband_audio_module
<equalizer8band_metadata
, true>;
497 template class equalizerNband_audio_module
<equalizer12band_metadata
, true>;
499 /**********************************************************************
501 **********************************************************************/
503 void equalizer30band_audio_module::set_freq_grid()
505 //Initialize freq indicators
506 unsigned int param_ptr
= 0;
507 for(unsigned j
= 0; j
< fg
.get_number_of_bands(); j
++)
509 *params
[param_freq11
+ param_ptr
] = fg
.get_rounded_freq(j
);
510 *params
[param_freq21
+ param_ptr
] = fg
.get_rounded_freq(j
);
514 is_freq_grid_init
= true;
517 equalizer30band_audio_module::equalizer30band_audio_module() :
518 conv(orfanidis_eq::eq_min_max_gain_db
),
519 swL(10000), swR(10000)
524 is_freq_grid_init
= false;
526 //Construct equalizers
527 using namespace orfanidis_eq
;
531 eq2
* ptr30L
= new eq2(fg
, butterworth
);
532 eq2
* ptr30R
= new eq2(fg
, butterworth
);
533 eq_arrL
.push_back(ptr30L
);
534 eq_arrR
.push_back(ptr30R
);
536 ptr30L
= new eq2(fg
, chebyshev1
);
537 ptr30R
= new eq2(fg
, chebyshev1
);
538 eq_arrL
.push_back(ptr30L
);
539 eq_arrR
.push_back(ptr30R
);
541 ptr30L
= new eq2(fg
, chebyshev2
);
542 ptr30R
= new eq2(fg
, chebyshev2
);
543 eq_arrL
.push_back(ptr30L
);
544 eq_arrR
.push_back(ptr30R
);
546 flt_type
= butterworth
;
550 swL
.set_previous(butterworth
);
551 swL
.set(butterworth
);
553 swR
.set_previous(butterworth
);
554 swR
.set(butterworth
);
557 equalizer30band_audio_module::~equalizer30band_audio_module()
559 for (unsigned int i
= 0; i
< eq_arrL
.size(); i
++)
562 for (unsigned int i
= 0; i
< eq_arrR
.size(); i
++)
566 void equalizer30band_audio_module::activate()
571 if(is_freq_grid_init
== false)
575 void equalizer30band_audio_module::deactivate()
580 void equalizer30band_audio_module::params_changed()
582 using namespace orfanidis_eq
;
584 //Change gain indicators
585 *params
[param_gain_scale10
] = *params
[param_gain10
] * *params
[param_gainscale1
];
586 *params
[param_gain_scale20
] = *params
[param_gain20
] * *params
[param_gainscale2
];
588 for(unsigned int i
= 0; i
< fg
.get_number_of_bands(); i
++)
589 *params
[param_gain_scale11
+ band_params
*i
] = (*params
[param_gain11
+ band_params
*i
])*
590 *params
[param_gainscale1
];
592 for(unsigned int i
= 0; i
< fg
.get_number_of_bands(); i
++)
593 *params
[param_gain_scale21
+ band_params
*i
] = (*params
[param_gain21
+ band_params
*i
])*
594 *params
[param_gainscale2
];
597 for (unsigned int i
= 0; i
< fg
.get_number_of_bands(); i
++)
598 eq_arrL
[*params
[param_filters
]]->change_band_gain_db(i
,*params
[param_gain_scale11
+ band_params
*i
]);
600 for (unsigned int i
= 0; i
< fg
.get_number_of_bands(); i
++)
601 eq_arrR
[*params
[param_filters
]]->change_band_gain_db(i
,*params
[param_gain_scale21
+ band_params
*i
]);
604 flt_type
= (filter_type
)(*params
[param_filters
] + 1);
607 void equalizer30band_audio_module::set_sample_rate(uint32_t sr
)
611 //Change sample rate for eq's
612 for(unsigned int i
= 0; i
< eq_arrL
.size(); i
++)
614 eq_arrL
[i
]->set_sample_rate(srate
);
615 eq_arrL
[i
]->set_sample_rate(srate
);
618 int meter
[] = {param_level_in_vuL
, param_level_in_vuR
, param_level_out_vuL
, param_level_out_vuR
};
619 int clip
[] = {param_level_in_clipL
, param_level_in_clipR
, param_level_out_clipL
, param_level_out_clipR
};
620 meters
.init(params
, meter
, clip
, 4, sr
);
623 uint32_t equalizer30band_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
625 uint32_t orig_numsamples
= numsamples
;
626 uint32_t orig_offset
= offset
;
627 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
628 numsamples
+= offset
;
630 // everything bypassed
631 while(offset
< numsamples
) {
632 outs
[0][offset
] = ins
[0][offset
];
633 outs
[1][offset
] = ins
[1][offset
];
634 float values
[] = {0, 0, 0, 0};
635 meters
.process(values
);
640 while(offset
< numsamples
) {
642 double inL
= ins
[0][offset
] * *params
[param_level_in
];
643 double inR
= ins
[1][offset
] * *params
[param_level_in
];
648 unsigned int eq_index
= swL
.get_state() - 1;
649 eq_arrL
[eq_index
]->sbs_process(&inL
, &outL
);
650 eq_arrR
[eq_index
]->sbs_process(&inR
, &outR
);
652 //If filter type switched
653 if(flt_type_old
!= flt_type
)
657 flt_type_old
= flt_type
;
660 outL
*= swL
.get_ramp();
661 outR
*= swR
.get_ramp();
663 outL
= outL
* conv
.fast_db_2_lin(*params
[param_gain_scale10
]);
664 outR
= outR
* conv
.fast_db_2_lin(*params
[param_gain_scale20
]);
666 outL
= outL
* *params
[param_level_out
];
667 outR
= outR
* *params
[param_level_out
];
669 outs
[0][offset
] = outL
;
670 outs
[1][offset
] = outR
;
673 float values
[] = {(float)inL
, (float)inR
, (float)outL
, (float)outR
};
674 meters
.process(values
);
678 } // cycle trough samples
679 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
682 meters
.fall(orig_numsamples
);
686 /**********************************************************************
687 * FILTERKLAVIER by Hans Baier
688 **********************************************************************/
690 filterclavier_audio_module::filterclavier_audio_module()
691 : filter_module_with_inertia
<biquad_filter_module
, filterclavier_metadata
>(ins
, outs
, params
)
699 void filterclavier_audio_module::params_changed()
701 inertia_filter_module::inertia_cutoff
.set_inertia(
702 note_to_hz(last_note
+ *params
[par_transpose
], *params
[par_detune
]));
704 float min_resonance
= param_props
[par_max_resonance
].min
;
705 inertia_filter_module::inertia_resonance
.set_inertia(
706 (float(last_velocity
) / 127.0)
708 * (*params
[par_max_resonance
] - min_resonance
+ 0.001)
711 adjust_gain_according_to_filter_mode(last_velocity
);
713 inertia_filter_module::calculate_filter();
717 void filterclavier_audio_module::activate()
719 inertia_filter_module::activate();
722 void filterclavier_audio_module::set_sample_rate(uint32_t sr
)
724 inertia_filter_module::set_sample_rate(sr
);
727 void filterclavier_audio_module::deactivate()
729 inertia_filter_module::deactivate();
733 void filterclavier_audio_module::note_on(int channel
, int note
, int vel
)
737 inertia_filter_module::inertia_cutoff
.set_inertia(
738 note_to_hz(note
+ *params
[par_transpose
], *params
[par_detune
]));
740 float min_resonance
= param_props
[par_max_resonance
].min
;
741 inertia_filter_module::inertia_resonance
.set_inertia(
743 // 0.001: if the difference is equal to zero (which happens
744 // when the max_resonance knom is at minimum position
745 // then the filter gain doesnt seem to snap to zero on most note offs
746 * (*params
[par_max_resonance
] - min_resonance
+ 0.001)
749 adjust_gain_according_to_filter_mode(vel
);
751 inertia_filter_module::calculate_filter();
755 void filterclavier_audio_module::note_off(int channel
, int note
, int vel
)
757 if (note
== last_note
) {
758 inertia_filter_module::inertia_resonance
.set_inertia(param_props
[par_max_resonance
].min
);
759 inertia_filter_module::inertia_gain
.set_inertia(min_gain
);
760 inertia_filter_module::calculate_filter();
766 void filterclavier_audio_module::adjust_gain_according_to_filter_mode(int velocity
)
768 int mode
= dsp::fastf2i_drm(*params
[par_mode
]);
770 // for bandpasses: boost gain for velocities > 0
771 if ( (mode_6db_bp
<= mode
) && (mode
<= mode_18db_bp
) ) {
772 // gain for velocity 0: 1.0
773 // gain for velocity 127: 32.0
774 float mode_max_gain
= max_gain
;
775 // max_gain is right for mode_6db_bp
776 if (mode
== mode_12db_bp
)
777 mode_max_gain
/= 6.0;
778 if (mode
== mode_18db_bp
)
779 mode_max_gain
/= 10.5;
781 inertia_filter_module::inertia_gain
.set_now(
782 (float(velocity
) / 127.0) * (mode_max_gain
- min_gain
) + min_gain
);
784 inertia_filter_module::inertia_gain
.set_now(min_gain
);
788 /**********************************************************************
789 * EMPHASIS by Damien Zammit
790 **********************************************************************/
792 emphasis_audio_module::emphasis_audio_module()
801 void emphasis_audio_module::activate()
808 void emphasis_audio_module::deactivate()
813 void emphasis_audio_module::params_changed()
815 if (mode
!= *params
[param_mode
] or type
!= *params
[param_type
] or bypass_
!= *params
[param_bypass
])
817 mode
= *params
[param_mode
];
818 type
= *params
[param_type
];
819 bypass_
= *params
[param_bypass
];
820 riaacurvL
.set(srate
, mode
, type
);
821 riaacurvR
.set(srate
, mode
, type
);
824 uint32_t emphasis_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
826 uint32_t orig_numsamples
= numsamples
;
827 uint32_t orig_offset
= offset
;
828 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
831 // ensure that if params have changed, the params_changed method is
832 // called every 8 samples to interpolate filter parameters
833 while(numsamples
> 8)
836 outputs_mask
|= process(offset
, 8, inputs_mask
, outputs_mask
);
841 numsamples
+= offset
;
843 // everything bypassed
844 while(offset
< numsamples
) {
845 outs
[0][offset
] = ins
[0][offset
];
846 outs
[1][offset
] = ins
[1][offset
];
847 float values
[] = {0, 0, 0, 0};
848 meters
.process(values
);
853 while(offset
< numsamples
) {
854 // cycle through samples
857 float inL
= ins
[0][offset
];
858 float inR
= ins
[1][offset
];
860 inR
*= *params
[param_level_in
];
861 inL
*= *params
[param_level_in
];
866 procL
= riaacurvL
.process(procL
);
867 procR
= riaacurvR
.process(procR
);
869 outL
= procL
* *params
[param_level_out
];
870 outR
= procR
* *params
[param_level_out
];
873 outs
[0][offset
] = outL
;
874 outs
[1][offset
] = outR
;
876 float values
[] = {inL
, inR
, outL
, outR
};
877 meters
.process(values
);
881 } // cycle trough samples
882 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
884 riaacurvL
.sanitize();
885 riaacurvR
.sanitize();
887 meters
.fall(orig_numsamples
);
890 bool emphasis_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
892 if (phase
or subindex
)
895 context
->set_source_rgba(0.15, 0.2, 0.0, 0.3);
896 return ::get_graph(*this, subindex
, data
, points
, 32, 0);
898 bool emphasis_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
902 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
, true, 32, 0);
905 /**********************************************************************
906 * CROSSOVER N BAND by Markus Schmidt
907 **********************************************************************/
909 template<class XoverBaseClass
>
910 xover_audio_module
<XoverBaseClass
>::xover_audio_module()
915 crossover
.init(AM::channels
, AM::bands
, 44100);
917 template<class XoverBaseClass
>
918 xover_audio_module
<XoverBaseClass
>::~xover_audio_module()
922 template<class XoverBaseClass
>
923 void xover_audio_module
<XoverBaseClass
>::activate()
929 template<class XoverBaseClass
>
930 void xover_audio_module
<XoverBaseClass
>::deactivate()
934 template<class XoverBaseClass
>
935 void xover_audio_module
<XoverBaseClass
>::set_sample_rate(uint32_t sr
)
938 // set srate of crossover
939 crossover
.set_sample_rate(srate
);
941 buffer_size
= (int)(srate
/ 10 * AM::channels
* AM::bands
+ AM::channels
* AM::bands
); // buffer size attack rate multiplied by channels and bands
942 buffer
= (float*) calloc(buffer_size
, sizeof(float));
944 int amount
= AM::bands
* AM::channels
+ AM::channels
;
947 for(int b
= 0; b
< AM::bands
; b
++) {
948 for (int c
= 0; c
< AM::channels
; c
++) {
949 meter
[b
* AM::channels
+ c
] = AM::param_meter_01
+ b
* params_per_band
+ c
;
950 clip
[b
* AM::channels
+ c
] = -1;
953 for (int c
= 0; c
< AM::channels
; c
++) {
954 meter
[c
+ AM::bands
* AM::channels
] = AM::param_meter_0
+ c
;
955 clip
[c
+ AM::bands
* AM::channels
] = -1;
957 meters
.init(params
, meter
, clip
, amount
, srate
);
959 template<class XoverBaseClass
>
960 void xover_audio_module
<XoverBaseClass
>::params_changed()
962 int mode
= *params
[AM::param_mode
];
963 crossover
.set_mode(mode
);
964 for (int i
= 0; i
< AM::bands
- 1; i
++) {
965 crossover
.set_filter(i
, *params
[AM::param_freq0
+ i
]);
967 for (int i
= 0; i
< AM::bands
; i
++) {
968 int offset
= i
* params_per_band
;
969 crossover
.set_level(i
, *params
[AM::param_level1
+ offset
]);
970 crossover
.set_active(i
, *params
[AM::param_active1
+ offset
] > 0.5);
975 template<class XoverBaseClass
>
976 uint32_t xover_audio_module
<XoverBaseClass
>::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
978 unsigned int targ
= numsamples
+ offset
;
980 float values
[AM::bands
* AM::channels
+ AM::channels
];
981 while(offset
< targ
) {
982 // cycle through samples
985 for (int c
= 0; c
< AM::channels
; c
++) {
986 in
[c
] = ins
[c
][offset
] * *params
[AM::param_level
];
988 crossover
.process(in
);
990 for (int b
= 0; b
< AM::bands
; b
++) {
992 int off
= b
* params_per_band
;
993 // calc position in delay buffer
994 if (*params
[AM::param_delay1
+ off
]) {
995 nbuf
= srate
* (fabs(*params
[AM::param_delay1
+ off
]) / 1000.f
) * AM::bands
* AM::channels
;
996 nbuf
-= nbuf
% (AM::bands
* AM::channels
);
998 for (int c
= 0; c
< AM::channels
; c
++) {
999 // define a pointer between 0 and channels * bands
1000 int ptr
= b
* AM::channels
+ c
;
1002 // get output from crossover module if active
1003 xval
= *params
[AM::param_active1
+ off
] > 0.5 ? crossover
.get_value(c
, b
) : 0.f
;
1005 // fill delay buffer
1006 buffer
[pos
+ ptr
] = xval
;
1008 // get value from delay buffer if neccessary
1009 if (*params
[AM::param_delay1
+ off
])
1010 xval
= buffer
[(pos
- (int)nbuf
+ ptr
+ buffer_size
) % buffer_size
];
1012 // set value with phase to output
1013 outs
[ptr
][offset
] = *params
[AM::param_phase1
+ off
] > 0.5 ? xval
* -1 : xval
;
1016 values
[b
* AM::channels
+ c
] = outs
[ptr
][offset
];
1020 for (int c
= 0; c
< AM::channels
; c
++) {
1021 values
[c
+ AM::bands
* AM::channels
] = ins
[c
][offset
];
1023 meters
.process(values
);
1026 // delay buffer pos forward
1027 pos
= (pos
+ AM::channels
* AM::bands
) % buffer_size
;
1029 } // cycle trough samples
1030 meters
.fall(numsamples
);
1031 return outputs_mask
;
1034 template<class XoverBaseClass
>
1035 bool xover_audio_module
<XoverBaseClass
>::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1037 return crossover
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
1039 template<class XoverBaseClass
>
1040 bool xover_audio_module
<XoverBaseClass
>::get_layers(int index
, int generation
, unsigned int &layers
) const
1042 return crossover
.get_layers(index
, generation
, layers
);
1045 template class xover_audio_module
<xover2_metadata
>;
1046 template class xover_audio_module
<xover3_metadata
>;
1047 template class xover_audio_module
<xover4_metadata
>;
1050 /**********************************************************************
1051 * Vocoder by Markus Schmidt and Christian Holschuh
1052 **********************************************************************/
1054 vocoder_audio_module::vocoder_audio_module()
1065 fcoeff
= log10(20.f
);
1067 memset(env_mods
, 0, 32 * 2 * sizeof(double));
1070 void vocoder_audio_module::activate()
1075 void vocoder_audio_module::deactivate()
1080 void vocoder_audio_module::params_changed()
1082 attack
= exp(log(0.01)/( *params
[param_attack
] * srate
* 0.001));
1083 release
= exp(log(0.01)/( *params
[param_release
] * srate
* 0.001));
1085 int b
= *params
[param_bands
];
1086 bands
= (b
+ 2) * 4 + (b
> 1 ? (b
- 2) * 4 : 0);
1087 order
= std::min(8.f
, *params
[param_order
]);
1088 float q
= pow(10, (fmodf(std::min(8.999f
, *params
[param_order
]), 1.f
) * (7.f
/ pow(1.3, order
))) / 20);
1089 if (bands
!= bands_old
or *params
[param_order
] != order_old
) {
1091 order_old
= *params
[param_order
];
1092 for (int i
= 0; i
< bands
; i
++) {
1093 // set all actually used filters
1094 detector
[0][0][i
].set_bp_rbj(pow(10, fcoeff
+ (0.5f
+ (float)i
) * 3.f
/ (float)bands
), q
, (double)srate
);
1095 for (int j
= 0; j
< order
; j
++) {
1097 detector
[0][j
][i
].copy_coeffs(detector
[0][0][i
]);
1098 detector
[1][j
][i
].copy_coeffs(detector
[0][0][i
]);
1099 modulator
[0][j
][i
].copy_coeffs(detector
[0][0][i
]);
1100 modulator
[1][j
][i
].copy_coeffs(detector
[0][0][i
]);
1103 redraw_graph
= true;
1105 _analyzer
.set_params(256, 1, 6, 0, 1, 0, 0, 0, 15, 2, 0, 0);
1106 redraw_graph
= true;
1109 int vocoder_audio_module::get_solo() const {
1110 for (int i
= 0; i
< bands
; i
++)
1111 if (*params
[param_solo0
+ i
* band_params
])
1116 uint32_t vocoder_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1118 uint32_t orig_numsamples
= numsamples
;
1119 uint32_t orig_offset
= offset
;
1120 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
1121 int solo
= get_solo();
1122 numsamples
+= offset
;
1123 float led
[32] = {0};
1125 // everything bypassed
1126 while(offset
< numsamples
) {
1127 outs
[0][offset
] = ins
[0][offset
];
1128 outs
[1][offset
] = ins
[1][offset
];
1129 float values
[] = {0, 0, 0, 0, 0, 0};
1130 meters
.process(values
);
1135 while(offset
< numsamples
) {
1136 // cycle through samples
1142 // carrier with level
1143 double cL
= ins
[0][offset
] * *params
[param_carrier_in
];
1144 double cR
= ins
[1][offset
] * *params
[param_carrier_in
];
1146 // modulator with level
1147 double mL
= ins
[2][offset
] * *params
[param_mod_in
];
1148 double mR
= ins
[3][offset
] * *params
[param_mod_in
];
1151 double nL
= (float)rand() / (float)RAND_MAX
;
1152 double nR
= (float)rand() / (float)RAND_MAX
;
1154 for (int i
= 0; i
< bands
; i
++) {
1157 double cL_
= cL
+ nL
* *params
[param_noise0
+ i
* band_params
];
1158 double cR_
= cR
+ nR
* *params
[param_noise0
+ i
* band_params
];
1160 if ((solo
and *params
[param_solo0
+ i
* band_params
]) or !solo
) {
1161 for (int j
= 0; j
< order
; j
++) {
1163 if (*params
[param_link
] > 0.5) {
1164 mL_
= detector
[0][j
][i
].process(std::max(mL_
, mR_
));
1167 mL_
= detector
[0][j
][i
].process(mL_
);
1168 mR_
= detector
[1][j
][i
].process(mR_
);
1170 // filter carrier with noise
1171 cL_
= modulator
[0][j
][i
].process(cL_
);
1172 cR_
= modulator
[1][j
][i
].process(cR_
);
1174 // level by envelope with levelling
1175 cL_
*= env_mods
[0][i
] * ((float)order
/ 2 + 4) * 4;
1176 cR_
*= env_mods
[1][i
] * ((float)order
/ 2 + 4) * 4;
1178 // add band volume setting
1179 cL_
*= *params
[param_volume0
+ i
* band_params
];
1180 cR_
*= *params
[param_volume0
+ i
* band_params
];
1182 // add filtered modulator
1183 cL_
+= mL_
* *params
[param_mod0
+ i
* band_params
];
1184 cR_
+= mR_
* *params
[param_mod0
+ i
* band_params
];
1187 cL_
*= (*params
[param_pan0
+ i
* band_params
] > 0
1188 ? -*params
[param_pan0
+ i
* band_params
] + 1 : 1);
1189 cR_
*= (*params
[param_pan0
+ i
* band_params
] < 0
1190 ? *params
[param_pan0
+ i
* band_params
] + 1 : 1);
1192 // add to outputs with proc level
1193 pL
+= cL_
* *params
[param_proc
];
1194 pR
+= cR_
* *params
[param_proc
];
1197 if (*params
[param_detectors
] > 0.5)
1198 if (env_mods
[0][i
] + env_mods
[1][i
] > led
[i
])
1199 led
[i
] = env_mods
[0][i
] + env_mods
[1][i
];
1201 // advance envelopes
1202 env_mods
[0][i
] = (fabs(mL_
) > env_mods
[0][i
] ? attack
: release
) * (env_mods
[0][i
] - fabs(mL_
)) + fabs(mL_
);
1203 env_mods
[1][i
] = (fabs(mR_
) > env_mods
[1][i
] ? attack
: release
) * (env_mods
[1][i
] - fabs(mR_
)) + fabs(mR_
);
1210 outL
+= cL
* *params
[param_carrier
];
1211 outR
+= cR
* *params
[param_carrier
];
1214 outL
+= mL
* *params
[param_mod
];
1215 outR
+= mR
* *params
[param_mod
];
1218 switch ((int)*params
[param_analyzer
]) {
1223 _analyzer
.process((float)cL
, (float)cR
);
1226 _analyzer
.process((float)mL
, (float)mR
);
1229 _analyzer
.process((float)pL
, (float)pR
);
1232 _analyzer
.process((float)outL
, (float)outR
);
1237 outL
*= *params
[param_out
];
1238 outR
*= *params
[param_out
];
1241 outs
[0][offset
] = outL
;
1242 outs
[1][offset
] = outR
;
1245 float values
[] = {(float)cL
, (float)cR
, (float)mL
, (float)mR
, (float)outL
, (float)outR
};
1246 meters
.process(values
);
1250 } // cycle trough samples
1251 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
1253 for (int i
= 0; i
< bands
; i
++) {
1254 for (int j
= 0; j
< order
; j
++) {
1255 detector
[0][j
][i
].sanitize();
1256 detector
[1][j
][i
].sanitize();
1257 modulator
[0][j
][i
].sanitize();
1258 modulator
[1][j
][i
].sanitize();
1264 for (int i
= 0; i
< 32; i
++) {
1266 if (*params
[param_detectors
] > 0.5)
1267 val
= std::max(0.0, 1 + log((led
[i
] / 2) * order
) / log2_
/ 10);
1268 *params
[param_level0
+ i
* band_params
] = val
;
1270 meters
.fall(orig_numsamples
);
1271 return outputs_mask
;
1273 bool vocoder_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1275 if (phase
and *params
[param_analyzer
]) {
1279 bool r
= _analyzer
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
1280 context
->set_source_rgba(0,0,0,0.25);
1286 if (subindex
>= bands
) {
1287 redraw_graph
= false;
1290 int solo
= get_solo();
1291 if (solo
and !*params
[param_solo0
+ subindex
* band_params
])
1292 context
->set_source_rgba(0,0,0,0.15);
1293 context
->set_line_width(0.99);
1295 double fq
= pow(10, fcoeff
+ (0.5f
+ (float)subindex
) * 3.f
/ (float)bands
);
1296 for (int i
= 0; i
< points
; i
++) {
1297 double freq
= 20.0 * pow (20000.0 / 20.0, i
* 1.0 / points
);
1299 for (int j
= 0; j
< order
; j
++)
1300 level
*= detector
[0][0][subindex
].freq_gain(freq
, srate
);
1301 level
*= *params
[param_volume0
+ subindex
* band_params
];
1302 data
[i
] = dB_grid(level
, 256, 0.4);
1303 if (!drawn
and freq
> fq
) {
1306 sprintf(str
, "%d", subindex
+ 1);
1307 draw_cairo_label(context
, str
, i
, context
->size_y
* (1 - (data
[i
] + 1) / 2.f
), 0, 0, 0.5);
1313 bool vocoder_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1315 redraw_graph
= redraw_graph
|| !generation
;
1316 layers
= *params
[param_analyzer
] ? LG_REALTIME_GRAPH
: 0;
1317 layers
|= (generation
? LG_NONE
: LG_CACHE_GRID
) | (redraw_graph
? LG_CACHE_GRAPH
: LG_NONE
);
1318 redraw_graph
|= (bool)*params
[param_analyzer
];
1319 return redraw_graph
or !generation
;