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
], hsq
=*params
[AM::param_hs_q
];
133 float lsfreq
= *params
[AM::param_ls_freq
], lslevel
= *params
[AM::param_ls_level
], lsq
=*params
[AM::param_ls_q
];
135 if(lsfreq
!= ls_freq_old
or lslevel
!= ls_level_old
or lsq
!= ls_q_old
) {
136 lsfreq
= glide(ls_freq_old
, lsfreq
, keep_gliding
);
137 lsL
.set_lowshelf_rbj(lsfreq
, lsq
, lslevel
, (float)srate
);
138 lsR
.copy_coeffs(lsL
);
139 ls_level_old
= lslevel
;
140 ls_freq_old
= lsfreq
;
143 if(hsfreq
!= hs_freq_old
or hslevel
!= hs_level_old
or hsq
!= hs_q_old
) {
144 hsfreq
= glide(hs_freq_old
, hsfreq
, keep_gliding
);
145 hsL
.set_highshelf_rbj(hsfreq
, hsq
, hslevel
, (float)srate
);
146 hsR
.copy_coeffs(hsL
);
147 hs_level_old
= hslevel
;
148 hs_freq_old
= hsfreq
;
151 for (int i
= 0; i
< AM::PeakBands
; i
++)
153 int offset
= i
* params_per_band
;
154 float freq
= *params
[AM::param_p1_freq
+ offset
];
155 float level
= *params
[AM::param_p1_level
+ offset
];
156 float q
= *params
[AM::param_p1_q
+ offset
];
157 if(freq
!= p_freq_old
[i
] or level
!= p_level_old
[i
] or q
!= p_q_old
[i
]) {
158 freq
= glide(p_freq_old
[i
], freq
, keep_gliding
);
159 pL
[i
].set_peakeq_rbj(freq
, q
, level
, (float)srate
);
160 pR
[i
].copy_coeffs(pL
[i
]);
161 p_freq_old
[i
] = freq
;
162 p_level_old
[i
] = level
;
166 if (*params
[AM::param_individuals
] != indiv_old
) {
167 indiv_old
= *params
[AM::param_individuals
];
171 // check if any important parameter for redrawing the graph changed
172 for (int i
= 0; i
< graph_param_count
; i
++) {
173 if (*params
[AM::first_graph_param
+ i
] != old_params_for_graph
[i
])
175 old_params_for_graph
[i
] = *params
[AM::first_graph_param
+ i
];
178 _analyzer
.set_params(
180 *params
[AM::param_analyzer_mode
] + (*params
[AM::param_analyzer_mode
] >= 3 ? 5 : 1),
184 if ((bool)*params
[AM::param_analyzer_active
] != analyzer_old
) {
186 analyzer_old
= (bool)*params
[AM::param_analyzer_active
];
190 template<class BaseClass
, bool has_lphp
>
191 inline void equalizerNband_audio_module
<BaseClass
, has_lphp
>::process_hplp(float &left
, float &right
)
195 int active
= *params
[AM::param_lp_active
];
198 if (active
> 3) diff_ms(left
, right
);
202 if (active
== 1 or active
== 2 or active
== 4)
203 left
= lp
[0][0].process(left
);
204 if (active
== 1 or active
== 3 or active
== 5)
205 right
= lp
[0][1].process(right
);
208 if (active
== 1 or active
== 2 or active
== 4)
209 left
= lp
[1][0].process(lp
[0][0].process(left
));
210 if (active
== 1 or active
== 3 or active
== 5)
211 right
= lp
[1][1].process(lp
[0][1].process(right
));
214 if (active
== 1 or active
== 2 or active
== 4)
215 left
= lp
[2][0].process(lp
[1][0].process(lp
[0][0].process(left
)));
216 if (active
== 1 or active
== 3 or active
== 5)
217 right
= lp
[2][1].process(lp
[1][1].process(lp
[0][1].process(right
)));
220 if (active
> 3) undiff_ms(left
, right
);
222 active
= *params
[AM::param_hp_active
];
225 if (active
> 3) diff_ms(left
, right
);
229 if (active
== 1 or active
== 2 or active
== 4)
230 left
= hp
[0][0].process(left
);
231 if (active
== 1 or active
== 3 or active
== 5)
232 right
= hp
[0][1].process(right
);
235 if (active
== 1 or active
== 2 or active
== 4)
236 left
= hp
[1][0].process(hp
[0][0].process(left
));
237 if (active
== 1 or active
== 3 or active
== 5)
238 right
= hp
[1][1].process(hp
[0][1].process(right
));
241 if (active
== 1 or active
== 2 or active
== 4)
242 left
= hp
[2][0].process(hp
[1][0].process(hp
[0][0].process(left
)));
243 if (active
== 1 or active
== 3 or active
== 5)
244 right
= hp
[2][1].process(hp
[1][1].process(hp
[0][1].process(right
)));
247 if (active
> 3) undiff_ms(left
, right
);
251 template<class BaseClass
, bool has_lphp
>
252 uint32_t equalizerNband_audio_module
<BaseClass
, has_lphp
>::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
254 bool bypassed
= bypass
.update(*params
[AM::param_bypass
] > 0.5f
, numsamples
);
257 // ensure that if params have changed, the params_changed method is
258 // called every 8 samples to interpolate filter parameters
259 while(numsamples
> 8 && keep_gliding
)
262 outputs_mask
|= process(offset
, 8, inputs_mask
, outputs_mask
);
269 numsamples
+= offset
;
271 // everything bypassed
272 while(offset
< numsamples
) {
273 outs
[0][offset
] = ins
[0][offset
];
274 outs
[1][offset
] = ins
[1][offset
];
275 float values
[] = {0, 0, 0, 0};
276 meters
.process(values
);
277 _analyzer
.process(0, 0);
282 uint32_t orig_numsamples
= numsamples
-offset
;
283 uint32_t orig_offset
= offset
;
284 while(offset
< numsamples
) {
285 // cycle through samples
288 float inL
= ins
[0][offset
];
289 float inR
= ins
[1][offset
];
291 inR
*= *params
[AM::param_level_in
];
292 inL
*= *params
[AM::param_level_in
];
297 // all filters in chain
298 process_hplp(procL
, procR
);
300 int active
= *params
[AM::param_ls_active
];
301 if (active
> 3) diff_ms(procL
, procR
);
302 if (active
== 1 or active
== 2 or active
== 4)
303 procL
= lsL
.process(procL
);
304 if (active
== 1 or active
== 3 or active
== 5)
305 procR
= lsR
.process(procR
);
306 if (active
> 3) undiff_ms(procL
, procR
);
308 active
= *params
[AM::param_hs_active
];
309 if (active
> 3) diff_ms(procL
, procR
);
310 if (active
== 1 or active
== 2 or active
== 4)
311 procL
= hsL
.process(procL
);
312 if (active
== 1 or active
== 3 or active
== 5)
313 procR
= hsR
.process(procR
);
314 if (active
> 3) undiff_ms(procL
, procR
);
316 for (int i
= 0; i
< AM::PeakBands
; i
++)
318 int offset
= i
* params_per_band
;
319 int active
= *params
[AM::param_p1_active
+ offset
];
320 if (active
> 3) diff_ms(procL
, procR
);
321 if (active
== 1 or active
== 2 or active
== 4)
322 procL
= pL
[i
].process(procL
);
323 if (active
== 1 or active
== 3 or active
== 5)
324 procR
= pR
[i
].process(procR
);
325 if (active
> 3) undiff_ms(procL
, procR
);
328 outL
= procL
* *params
[AM::param_level_out
];
329 outR
= procR
* *params
[AM::param_level_out
];
332 _analyzer
.process((inL
+ inR
) / 2.f
, (outL
+ outR
) / 2.f
);
335 outs
[0][offset
] = outL
;
336 outs
[1][offset
] = outR
;
338 float values
[] = {inL
, inR
, outL
, outR
};
339 meters
.process(values
);
343 } // cycle trough samples
344 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
346 for(int i
= 0; i
< 3; ++i
) {
354 for(int i
= 0; i
< AM::PeakBands
; ++i
) {
359 meters
.fall(numsamples
);
363 static inline float adjusted_lphp_gain(const float *const *params
, int param_active
, int param_mode
, const biquad_d2
&filter
, float freq
, float srate
)
365 if(*params
[param_active
] > 0.f
) {
366 float gain
= filter
.freq_gain(freq
, srate
);
367 switch((int)*params
[param_mode
]) {
373 return gain
* gain
* gain
;
379 template<class BaseClass
, bool has_lphp
>
380 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
382 if (phase
and *params
[AM::param_analyzer_active
]) {
383 bool r
= _analyzer
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
384 if (*params
[AM::param_analyzer_mode
] == 2) {
385 set_channel_color(context
, subindex
? 0 : 1, 0.15);
387 context
->set_source_rgba(0,0,0,0.1);
390 } else if (phase
and !*params
[AM::param_analyzer_active
]) {
391 redraw_graph
= false;
394 int max
= PeakBands
+ 2 + (has_lphp
? 2 : 0);
397 or (subindex
and !*params
[AM::param_individuals
])
398 or (subindex
> max
and *params
[AM::param_individuals
])) {
399 redraw_graph
= false;
403 // first graph is the overall frequency response graph
405 return ::get_graph(*this, subindex
, data
, points
, 128 * *params
[AM::param_zoom
], 0);
407 // get out if max band is reached
408 if (last_peak
>= max
) {
410 redraw_graph
= false;
414 // get the next filter to draw a curve for and leave out inactive
416 while (last_peak
< PeakBands
and !*params
[AM::param_p1_active
+ last_peak
* params_per_band
])
418 if (last_peak
== PeakBands
and !*params
[AM::param_ls_active
])
420 if (last_peak
== PeakBands
+ 1 and !*params
[AM::param_hs_active
])
422 if (has_lphp
and last_peak
== PeakBands
+ 2 and !*params
[AM::param_hp_active
])
424 if (has_lphp
and last_peak
== PeakBands
+ 3 and !*params
[AM::param_lp_active
])
427 // get out if max band is reached
428 if (last_peak
>= max
) { // and !*params[param_analyzer_active]) {
430 redraw_graph
= false;
433 //else if *params[param_analyzer_active]) {
434 //bool goon = _analyzer.get_graph(subindex, phase, data, points, context, mode);
440 // draw the individual curve of the actual filter
441 for (int i
= 0; i
< points
; i
++) {
442 double freq
= 20.0 * pow (20000.0 / 20.0, i
* 1.0 / points
);
443 if (last_peak
< PeakBands
) {
444 data
[i
] = pL
[last_peak
].freq_gain(freq
, (float)srate
);
445 } else if (last_peak
== PeakBands
) {
446 data
[i
] = lsL
.freq_gain(freq
, (float)srate
);
447 } else if (last_peak
== PeakBands
+ 1) {
448 data
[i
] = hsL
.freq_gain(freq
, (float)srate
);
449 } else if (last_peak
== PeakBands
+ 2 and has_lphp
) {
450 data
[i
] = adjusted_lphp_gain(params
, AM::param_hp_active
, AM::param_hp_mode
, hp
[0][0], freq
, (float)srate
);
451 } else if (last_peak
== PeakBands
+ 3 and has_lphp
) {
452 data
[i
] = adjusted_lphp_gain(params
, AM::param_lp_active
, AM::param_lp_mode
, lp
[0][0], freq
, (float)srate
);
454 data
[i
] = dB_grid(data
[i
], 128 * *params
[AM::param_zoom
], 0);
459 context
->set_source_rgba(0,0,0,0.075);
463 template<class BaseClass
, bool has_lphp
>
464 bool equalizerNband_audio_module
<BaseClass
, has_lphp
>::get_layers(int index
, int generation
, unsigned int &layers
) const
466 redraw_graph
= redraw_graph
|| !generation
;
467 layers
= *params
[AM::param_analyzer_active
] ? LG_REALTIME_GRAPH
: 0;
468 layers
|= (generation
? LG_NONE
: LG_CACHE_GRID
) | (redraw_graph
? LG_CACHE_GRAPH
: LG_NONE
);
469 redraw_graph
|= (bool)*params
[AM::param_analyzer_active
];
470 return redraw_graph
or !generation
;
473 template<class BaseClass
, bool has_lphp
>
474 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
476 if (!is_active
or phase
)
478 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
, true, 128 * *params
[AM::param_zoom
], 0);
481 template<class BaseClass
, bool has_lphp
>
482 float equalizerNband_audio_module
<BaseClass
, has_lphp
>::freq_gain(int index
, double freq
) const
487 ret
*= adjusted_lphp_gain(params
, AM::param_hp_active
, AM::param_hp_mode
, hp
[0][0], freq
, (float)srate
);
488 ret
*= adjusted_lphp_gain(params
, AM::param_lp_active
, AM::param_lp_mode
, lp
[0][0], freq
, (float)srate
);
490 ret
*= (*params
[AM::param_ls_active
] > 0.f
) ? lsL
.freq_gain(freq
, (float)srate
) : 1;
491 ret
*= (*params
[AM::param_hs_active
] > 0.f
) ? hsL
.freq_gain(freq
, (float)srate
) : 1;
492 for (int i
= 0; i
< PeakBands
; i
++)
493 ret
*= (*params
[AM::param_p1_active
+ i
* params_per_band
] > 0.f
) ? pL
[i
].freq_gain(freq
, (float)srate
) : 1;
497 template<class BaseClass
, bool has_lphp
>
498 inline string equalizerNband_audio_module
<BaseClass
, has_lphp
>::get_crosshair_label(int x
, int y
, int sx
, int sy
, int dB
, int name
, int note
, int cents
) const
500 return frequency_crosshair_label(x
, y
, sx
, sy
, dB
, name
, note
, cents
, 128 * *params
[AM::param_zoom
], 0);
503 template class equalizerNband_audio_module
<equalizer5band_metadata
, false>;
504 template class equalizerNband_audio_module
<equalizer8band_metadata
, true>;
505 template class equalizerNband_audio_module
<equalizer12band_metadata
, true>;
507 /**********************************************************************
509 **********************************************************************/
511 void equalizer30band_audio_module::set_freq_grid()
513 //Initialize freq indicators
514 unsigned int param_ptr
= 0;
515 for(unsigned j
= 0; j
< fg
.get_number_of_bands(); j
++)
517 *params
[param_freq11
+ param_ptr
] = fg
.get_rounded_freq(j
);
518 *params
[param_freq21
+ param_ptr
] = fg
.get_rounded_freq(j
);
522 is_freq_grid_init
= true;
525 equalizer30band_audio_module::equalizer30band_audio_module() :
526 conv(orfanidis_eq::eq_min_max_gain_db
),
527 swL(10000), swR(10000)
532 is_freq_grid_init
= false;
534 //Construct equalizers
535 using namespace orfanidis_eq
;
539 eq2
* ptr30L
= new eq2(fg
, butterworth
);
540 eq2
* ptr30R
= new eq2(fg
, butterworth
);
541 eq_arrL
.push_back(ptr30L
);
542 eq_arrR
.push_back(ptr30R
);
544 ptr30L
= new eq2(fg
, chebyshev1
);
545 ptr30R
= new eq2(fg
, chebyshev1
);
546 eq_arrL
.push_back(ptr30L
);
547 eq_arrR
.push_back(ptr30R
);
549 ptr30L
= new eq2(fg
, chebyshev2
);
550 ptr30R
= new eq2(fg
, chebyshev2
);
551 eq_arrL
.push_back(ptr30L
);
552 eq_arrR
.push_back(ptr30R
);
554 flt_type
= butterworth
;
558 swL
.set_previous(butterworth
);
559 swL
.set(butterworth
);
561 swR
.set_previous(butterworth
);
562 swR
.set(butterworth
);
565 equalizer30band_audio_module::~equalizer30band_audio_module()
567 for (unsigned int i
= 0; i
< eq_arrL
.size(); i
++)
570 for (unsigned int i
= 0; i
< eq_arrR
.size(); i
++)
574 void equalizer30band_audio_module::activate()
579 if(is_freq_grid_init
== false)
583 void equalizer30band_audio_module::deactivate()
588 void equalizer30band_audio_module::params_changed()
590 using namespace orfanidis_eq
;
592 //Change gain indicators
593 *params
[param_gain_scale10
] = *params
[param_gain10
] * *params
[param_gainscale1
];
594 *params
[param_gain_scale20
] = *params
[param_gain20
] * *params
[param_gainscale2
];
596 for(unsigned int i
= 0; i
< fg
.get_number_of_bands(); i
++)
597 *params
[param_gain_scale11
+ band_params
*i
] = (*params
[param_gain11
+ band_params
*i
])*
598 *params
[param_gainscale1
];
600 for(unsigned int i
= 0; i
< fg
.get_number_of_bands(); i
++)
601 *params
[param_gain_scale21
+ band_params
*i
] = (*params
[param_gain21
+ band_params
*i
])*
602 *params
[param_gainscale2
];
605 for (unsigned int i
= 0; i
< fg
.get_number_of_bands(); i
++)
606 eq_arrL
[*params
[param_filters
]]->change_band_gain_db(i
,*params
[param_gain_scale11
+ band_params
*i
]);
608 for (unsigned int i
= 0; i
< fg
.get_number_of_bands(); i
++)
609 eq_arrR
[*params
[param_filters
]]->change_band_gain_db(i
,*params
[param_gain_scale21
+ band_params
*i
]);
612 flt_type
= (filter_type
)(*params
[param_filters
] + 1);
615 void equalizer30band_audio_module::set_sample_rate(uint32_t sr
)
619 //Change sample rate for eq's
620 for(unsigned int i
= 0; i
< eq_arrL
.size(); i
++)
622 eq_arrL
[i
]->set_sample_rate(srate
);
623 eq_arrL
[i
]->set_sample_rate(srate
);
626 int meter
[] = {param_level_in_vuL
, param_level_in_vuR
, param_level_out_vuL
, param_level_out_vuR
};
627 int clip
[] = {param_level_in_clipL
, param_level_in_clipR
, param_level_out_clipL
, param_level_out_clipR
};
628 meters
.init(params
, meter
, clip
, 4, sr
);
631 uint32_t equalizer30band_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
633 uint32_t orig_numsamples
= numsamples
;
634 uint32_t orig_offset
= offset
;
635 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
636 numsamples
+= offset
;
638 // everything bypassed
639 while(offset
< numsamples
) {
640 outs
[0][offset
] = ins
[0][offset
];
641 outs
[1][offset
] = ins
[1][offset
];
642 float values
[] = {0, 0, 0, 0};
643 meters
.process(values
);
648 while(offset
< numsamples
) {
650 double inL
= ins
[0][offset
] * *params
[param_level_in
];
651 double inR
= ins
[1][offset
] * *params
[param_level_in
];
656 unsigned int eq_index
= swL
.get_state() - 1;
657 eq_arrL
[eq_index
]->sbs_process(&inL
, &outL
);
658 eq_arrR
[eq_index
]->sbs_process(&inR
, &outR
);
660 //If filter type switched
661 if(flt_type_old
!= flt_type
)
665 flt_type_old
= flt_type
;
668 outL
*= swL
.get_ramp();
669 outR
*= swR
.get_ramp();
671 outL
= outL
* conv
.fast_db_2_lin(*params
[param_gain_scale10
]);
672 outR
= outR
* conv
.fast_db_2_lin(*params
[param_gain_scale20
]);
674 outL
= outL
* *params
[param_level_out
];
675 outR
= outR
* *params
[param_level_out
];
677 outs
[0][offset
] = outL
;
678 outs
[1][offset
] = outR
;
681 float values
[] = {(float)inL
, (float)inR
, (float)outL
, (float)outR
};
682 meters
.process(values
);
686 } // cycle trough samples
687 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
690 meters
.fall(orig_numsamples
);
694 /**********************************************************************
695 * FILTERKLAVIER by Hans Baier
696 **********************************************************************/
698 filterclavier_audio_module::filterclavier_audio_module()
699 : filter_module_with_inertia
<biquad_filter_module
, filterclavier_metadata
>(ins
, outs
, params
)
707 void filterclavier_audio_module::params_changed()
709 inertia_filter_module::inertia_cutoff
.set_inertia(
710 note_to_hz(last_note
+ *params
[par_transpose
], *params
[par_detune
]));
712 float min_resonance
= param_props
[par_max_resonance
].min
;
713 inertia_filter_module::inertia_resonance
.set_inertia(
714 (float(last_velocity
) / 127.0)
716 * (*params
[par_max_resonance
] - min_resonance
+ 0.001)
719 adjust_gain_according_to_filter_mode(last_velocity
);
721 inertia_filter_module::calculate_filter();
725 void filterclavier_audio_module::activate()
727 inertia_filter_module::activate();
730 void filterclavier_audio_module::set_sample_rate(uint32_t sr
)
732 inertia_filter_module::set_sample_rate(sr
);
735 void filterclavier_audio_module::deactivate()
737 inertia_filter_module::deactivate();
741 void filterclavier_audio_module::note_on(int channel
, int note
, int vel
)
745 inertia_filter_module::inertia_cutoff
.set_inertia(
746 note_to_hz(note
+ *params
[par_transpose
], *params
[par_detune
]));
748 float min_resonance
= param_props
[par_max_resonance
].min
;
749 inertia_filter_module::inertia_resonance
.set_inertia(
751 // 0.001: if the difference is equal to zero (which happens
752 // when the max_resonance knom is at minimum position
753 // then the filter gain doesnt seem to snap to zero on most note offs
754 * (*params
[par_max_resonance
] - min_resonance
+ 0.001)
757 adjust_gain_according_to_filter_mode(vel
);
759 inertia_filter_module::calculate_filter();
763 void filterclavier_audio_module::note_off(int channel
, int note
, int vel
)
765 if (note
== last_note
) {
766 inertia_filter_module::inertia_resonance
.set_inertia(param_props
[par_max_resonance
].min
);
767 inertia_filter_module::inertia_gain
.set_inertia(min_gain
);
768 inertia_filter_module::calculate_filter();
774 void filterclavier_audio_module::adjust_gain_according_to_filter_mode(int velocity
)
776 int mode
= dsp::fastf2i_drm(*params
[par_mode
]);
778 // for bandpasses: boost gain for velocities > 0
779 if ( (mode_6db_bp
<= mode
) && (mode
<= mode_18db_bp
) ) {
780 // gain for velocity 0: 1.0
781 // gain for velocity 127: 32.0
782 float mode_max_gain
= max_gain
;
783 // max_gain is right for mode_6db_bp
784 if (mode
== mode_12db_bp
)
785 mode_max_gain
/= 6.0;
786 if (mode
== mode_18db_bp
)
787 mode_max_gain
/= 10.5;
789 inertia_filter_module::inertia_gain
.set_now(
790 (float(velocity
) / 127.0) * (mode_max_gain
- min_gain
) + min_gain
);
792 inertia_filter_module::inertia_gain
.set_now(min_gain
);
796 /**********************************************************************
797 * EMPHASIS by Damien Zammit
798 **********************************************************************/
800 emphasis_audio_module::emphasis_audio_module()
809 void emphasis_audio_module::activate()
816 void emphasis_audio_module::deactivate()
821 void emphasis_audio_module::params_changed()
823 if (mode
!= *params
[param_mode
] or type
!= *params
[param_type
] or bypass_
!= *params
[param_bypass
])
825 mode
= *params
[param_mode
];
826 type
= *params
[param_type
];
827 bypass_
= *params
[param_bypass
];
828 riaacurvL
.set(srate
, mode
, type
);
829 riaacurvR
.set(srate
, mode
, type
);
832 uint32_t emphasis_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
834 uint32_t orig_numsamples
= numsamples
;
835 uint32_t orig_offset
= offset
;
836 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
839 // ensure that if params have changed, the params_changed method is
840 // called every 8 samples to interpolate filter parameters
841 while(numsamples
> 8)
844 outputs_mask
|= process(offset
, 8, inputs_mask
, outputs_mask
);
849 numsamples
+= offset
;
851 // everything bypassed
852 while(offset
< numsamples
) {
853 outs
[0][offset
] = ins
[0][offset
];
854 outs
[1][offset
] = ins
[1][offset
];
855 float values
[] = {0, 0, 0, 0};
856 meters
.process(values
);
861 while(offset
< numsamples
) {
862 // cycle through samples
865 float inL
= ins
[0][offset
];
866 float inR
= ins
[1][offset
];
868 inR
*= *params
[param_level_in
];
869 inL
*= *params
[param_level_in
];
874 procL
= riaacurvL
.process(procL
);
875 procR
= riaacurvR
.process(procR
);
877 outL
= procL
* *params
[param_level_out
];
878 outR
= procR
* *params
[param_level_out
];
881 outs
[0][offset
] = outL
;
882 outs
[1][offset
] = outR
;
884 float values
[] = {inL
, inR
, outL
, outR
};
885 meters
.process(values
);
889 } // cycle trough samples
890 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
892 riaacurvL
.sanitize();
893 riaacurvR
.sanitize();
895 meters
.fall(orig_numsamples
);
898 bool emphasis_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
900 if (phase
or subindex
)
903 context
->set_source_rgba(0.15, 0.2, 0.0, 0.3);
904 return ::get_graph(*this, subindex
, data
, points
, 32, 0);
906 bool emphasis_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
910 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
, true, 32, 0);
913 /**********************************************************************
914 * CROSSOVER N BAND by Markus Schmidt
915 **********************************************************************/
917 template<class XoverBaseClass
>
918 xover_audio_module
<XoverBaseClass
>::xover_audio_module()
923 crossover
.init(AM::channels
, AM::bands
, 44100);
925 template<class XoverBaseClass
>
926 xover_audio_module
<XoverBaseClass
>::~xover_audio_module()
930 template<class XoverBaseClass
>
931 void xover_audio_module
<XoverBaseClass
>::activate()
937 template<class XoverBaseClass
>
938 void xover_audio_module
<XoverBaseClass
>::deactivate()
942 template<class XoverBaseClass
>
943 void xover_audio_module
<XoverBaseClass
>::set_sample_rate(uint32_t sr
)
946 // set srate of crossover
947 crossover
.set_sample_rate(srate
);
949 buffer_size
= (int)(srate
/ 10 * AM::channels
* AM::bands
+ AM::channels
* AM::bands
); // buffer size attack rate multiplied by channels and bands
950 buffer
= (float*) calloc(buffer_size
, sizeof(float));
952 int amount
= AM::bands
* AM::channels
+ AM::channels
;
955 for(int b
= 0; b
< AM::bands
; b
++) {
956 for (int c
= 0; c
< AM::channels
; c
++) {
957 meter
[b
* AM::channels
+ c
] = AM::param_meter_01
+ b
* params_per_band
+ c
;
958 clip
[b
* AM::channels
+ c
] = -1;
961 for (int c
= 0; c
< AM::channels
; c
++) {
962 meter
[c
+ AM::bands
* AM::channels
] = AM::param_meter_0
+ c
;
963 clip
[c
+ AM::bands
* AM::channels
] = -1;
965 meters
.init(params
, meter
, clip
, amount
, srate
);
967 template<class XoverBaseClass
>
968 void xover_audio_module
<XoverBaseClass
>::params_changed()
970 int mode
= *params
[AM::param_mode
];
971 crossover
.set_mode(mode
);
972 for (int i
= 0; i
< AM::bands
- 1; i
++) {
973 crossover
.set_filter(i
, *params
[AM::param_freq0
+ i
]);
975 for (int i
= 0; i
< AM::bands
; i
++) {
976 int offset
= i
* params_per_band
;
977 crossover
.set_level(i
, *params
[AM::param_level1
+ offset
]);
978 crossover
.set_active(i
, *params
[AM::param_active1
+ offset
] > 0.5);
983 template<class XoverBaseClass
>
984 uint32_t xover_audio_module
<XoverBaseClass
>::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
986 unsigned int targ
= numsamples
+ offset
;
988 float values
[AM::bands
* AM::channels
+ AM::channels
];
989 while(offset
< targ
) {
990 // cycle through samples
993 for (int c
= 0; c
< AM::channels
; c
++) {
994 in
[c
] = ins
[c
][offset
] * *params
[AM::param_level
];
996 crossover
.process(in
);
998 for (int b
= 0; b
< AM::bands
; b
++) {
1000 int off
= b
* params_per_band
;
1001 // calc position in delay buffer
1002 if (*params
[AM::param_delay1
+ off
]) {
1003 nbuf
= srate
* (fabs(*params
[AM::param_delay1
+ off
]) / 1000.f
) * AM::bands
* AM::channels
;
1004 nbuf
-= nbuf
% (AM::bands
* AM::channels
);
1006 for (int c
= 0; c
< AM::channels
; c
++) {
1007 // define a pointer between 0 and channels * bands
1008 int ptr
= b
* AM::channels
+ c
;
1010 // get output from crossover module if active
1011 xval
= *params
[AM::param_active1
+ off
] > 0.5 ? crossover
.get_value(c
, b
) : 0.f
;
1013 // fill delay buffer
1014 buffer
[pos
+ ptr
] = xval
;
1016 // get value from delay buffer if neccessary
1017 if (*params
[AM::param_delay1
+ off
])
1018 xval
= buffer
[(pos
- (int)nbuf
+ ptr
+ buffer_size
) % buffer_size
];
1020 // set value with phase to output
1021 outs
[ptr
][offset
] = *params
[AM::param_phase1
+ off
] > 0.5 ? xval
* -1 : xval
;
1024 values
[b
* AM::channels
+ c
] = outs
[ptr
][offset
];
1028 for (int c
= 0; c
< AM::channels
; c
++) {
1029 values
[c
+ AM::bands
* AM::channels
] = ins
[c
][offset
];
1031 meters
.process(values
);
1034 // delay buffer pos forward
1035 pos
= (pos
+ AM::channels
* AM::bands
) % buffer_size
;
1037 } // cycle trough samples
1038 meters
.fall(numsamples
);
1039 return outputs_mask
;
1042 template<class XoverBaseClass
>
1043 bool xover_audio_module
<XoverBaseClass
>::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1045 return crossover
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
1047 template<class XoverBaseClass
>
1048 bool xover_audio_module
<XoverBaseClass
>::get_layers(int index
, int generation
, unsigned int &layers
) const
1050 return crossover
.get_layers(index
, generation
, layers
);
1053 template class xover_audio_module
<xover2_metadata
>;
1054 template class xover_audio_module
<xover3_metadata
>;
1055 template class xover_audio_module
<xover4_metadata
>;
1058 /**********************************************************************
1059 * Vocoder by Markus Schmidt and Christian Holschuh
1060 **********************************************************************/
1062 vocoder_audio_module::vocoder_audio_module()
1073 fcoeff
= log10(20.f
);
1075 memset(env_mods
, 0, 32 * 2 * sizeof(double));
1078 void vocoder_audio_module::activate()
1083 void vocoder_audio_module::deactivate()
1088 void vocoder_audio_module::params_changed()
1090 attack
= exp(log(0.01)/( *params
[param_attack
] * srate
* 0.001));
1091 release
= exp(log(0.01)/( *params
[param_release
] * srate
* 0.001));
1093 int b
= *params
[param_bands
];
1094 bands
= (b
+ 2) * 4 + (b
> 1 ? (b
- 2) * 4 : 0);
1095 order
= std::min(8.f
, *params
[param_order
]);
1096 float q
= pow(10, (fmodf(std::min(8.999f
, *params
[param_order
]), 1.f
) * (7.f
/ pow(1.3, order
))) / 20);
1097 if (bands
!= bands_old
or *params
[param_order
] != order_old
) {
1099 order_old
= *params
[param_order
];
1100 for (int i
= 0; i
< bands
; i
++) {
1101 // set all actually used filters
1102 detector
[0][0][i
].set_bp_rbj(pow(10, fcoeff
+ (0.5f
+ (float)i
) * 3.f
/ (float)bands
), q
, (double)srate
);
1103 for (int j
= 0; j
< order
; j
++) {
1105 detector
[0][j
][i
].copy_coeffs(detector
[0][0][i
]);
1106 detector
[1][j
][i
].copy_coeffs(detector
[0][0][i
]);
1107 modulator
[0][j
][i
].copy_coeffs(detector
[0][0][i
]);
1108 modulator
[1][j
][i
].copy_coeffs(detector
[0][0][i
]);
1111 redraw_graph
= true;
1113 _analyzer
.set_params(256, 1, 6, 0, 1, 0, 0, 0, 15, 2, 0, 0);
1114 redraw_graph
= true;
1117 int vocoder_audio_module::get_solo() const {
1118 for (int i
= 0; i
< bands
; i
++)
1119 if (*params
[param_solo0
+ i
* band_params
])
1124 uint32_t vocoder_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
1126 uint32_t orig_numsamples
= numsamples
;
1127 uint32_t orig_offset
= offset
;
1128 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
1129 int solo
= get_solo();
1130 numsamples
+= offset
;
1131 float led
[32] = {0};
1133 // everything bypassed
1134 while(offset
< numsamples
) {
1135 outs
[0][offset
] = ins
[0][offset
];
1136 outs
[1][offset
] = ins
[1][offset
];
1137 float values
[] = {0, 0, 0, 0, 0, 0};
1138 meters
.process(values
);
1143 while(offset
< numsamples
) {
1144 // cycle through samples
1150 // carrier with level
1151 double cL
= ins
[0][offset
] * *params
[param_carrier_in
];
1152 double cR
= ins
[1][offset
] * *params
[param_carrier_in
];
1154 // modulator with level
1155 double mL
= ins
[2][offset
] * *params
[param_mod_in
];
1156 double mR
= ins
[3][offset
] * *params
[param_mod_in
];
1159 double nL
= (float)rand() / (float)RAND_MAX
;
1160 double nR
= (float)rand() / (float)RAND_MAX
;
1162 for (int i
= 0; i
< bands
; i
++) {
1165 double cL_
= cL
+ nL
* *params
[param_noise0
+ i
* band_params
];
1166 double cR_
= cR
+ nR
* *params
[param_noise0
+ i
* band_params
];
1168 if ((solo
and *params
[param_solo0
+ i
* band_params
]) or !solo
) {
1169 for (int j
= 0; j
< order
; j
++) {
1171 if (*params
[param_link
] > 0.5) {
1172 mL_
= detector
[0][j
][i
].process(std::max(mL_
, mR_
));
1175 mL_
= detector
[0][j
][i
].process(mL_
);
1176 mR_
= detector
[1][j
][i
].process(mR_
);
1178 // filter carrier with noise
1179 cL_
= modulator
[0][j
][i
].process(cL_
);
1180 cR_
= modulator
[1][j
][i
].process(cR_
);
1182 // level by envelope with levelling
1183 cL_
*= env_mods
[0][i
] * ((float)order
/ 2 + 4) * 4;
1184 cR_
*= env_mods
[1][i
] * ((float)order
/ 2 + 4) * 4;
1186 // add band volume setting
1187 cL_
*= *params
[param_volume0
+ i
* band_params
];
1188 cR_
*= *params
[param_volume0
+ i
* band_params
];
1190 // add filtered modulator
1191 cL_
+= mL_
* *params
[param_mod0
+ i
* band_params
];
1192 cR_
+= mR_
* *params
[param_mod0
+ i
* band_params
];
1195 cL_
*= (*params
[param_pan0
+ i
* band_params
] > 0
1196 ? -*params
[param_pan0
+ i
* band_params
] + 1 : 1);
1197 cR_
*= (*params
[param_pan0
+ i
* band_params
] < 0
1198 ? *params
[param_pan0
+ i
* band_params
] + 1 : 1);
1200 // add to outputs with proc level
1201 pL
+= cL_
* *params
[param_proc
];
1202 pR
+= cR_
* *params
[param_proc
];
1205 if (*params
[param_detectors
] > 0.5)
1206 if (env_mods
[0][i
] + env_mods
[1][i
] > led
[i
])
1207 led
[i
] = env_mods
[0][i
] + env_mods
[1][i
];
1209 // advance envelopes
1210 env_mods
[0][i
] = (fabs(mL_
) > env_mods
[0][i
] ? attack
: release
) * (env_mods
[0][i
] - fabs(mL_
)) + fabs(mL_
);
1211 env_mods
[1][i
] = (fabs(mR_
) > env_mods
[1][i
] ? attack
: release
) * (env_mods
[1][i
] - fabs(mR_
)) + fabs(mR_
);
1218 outL
+= cL
* *params
[param_carrier
];
1219 outR
+= cR
* *params
[param_carrier
];
1222 outL
+= mL
* *params
[param_mod
];
1223 outR
+= mR
* *params
[param_mod
];
1226 switch ((int)*params
[param_analyzer
]) {
1231 _analyzer
.process((float)cL
, (float)cR
);
1234 _analyzer
.process((float)mL
, (float)mR
);
1237 _analyzer
.process((float)pL
, (float)pR
);
1240 _analyzer
.process((float)outL
, (float)outR
);
1245 outL
*= *params
[param_out
];
1246 outR
*= *params
[param_out
];
1249 outs
[0][offset
] = outL
;
1250 outs
[1][offset
] = outR
;
1253 float values
[] = {(float)cL
, (float)cR
, (float)mL
, (float)mR
, (float)outL
, (float)outR
};
1254 meters
.process(values
);
1258 } // cycle trough samples
1259 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
1261 for (int i
= 0; i
< bands
; i
++) {
1262 for (int j
= 0; j
< order
; j
++) {
1263 detector
[0][j
][i
].sanitize();
1264 detector
[1][j
][i
].sanitize();
1265 modulator
[0][j
][i
].sanitize();
1266 modulator
[1][j
][i
].sanitize();
1272 for (int i
= 0; i
< 32; i
++) {
1274 if (*params
[param_detectors
] > 0.5)
1275 val
= std::max(0.0, 1 + log((led
[i
] / 2) * order
) / log2_
/ 10);
1276 *params
[param_level0
+ i
* band_params
] = val
;
1278 meters
.fall(orig_numsamples
);
1279 return outputs_mask
;
1281 bool vocoder_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1283 if (phase
and *params
[param_analyzer
]) {
1287 bool r
= _analyzer
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
1288 context
->set_source_rgba(0,0,0,0.25);
1294 if (subindex
>= bands
) {
1295 redraw_graph
= false;
1298 int solo
= get_solo();
1299 if (solo
and !*params
[param_solo0
+ subindex
* band_params
])
1300 context
->set_source_rgba(0,0,0,0.15);
1301 context
->set_line_width(0.99);
1303 double fq
= pow(10, fcoeff
+ (0.5f
+ (float)subindex
) * 3.f
/ (float)bands
);
1304 for (int i
= 0; i
< points
; i
++) {
1305 double freq
= 20.0 * pow (20000.0 / 20.0, i
* 1.0 / points
);
1307 for (int j
= 0; j
< order
; j
++)
1308 level
*= detector
[0][0][subindex
].freq_gain(freq
, srate
);
1309 level
*= *params
[param_volume0
+ subindex
* band_params
];
1310 data
[i
] = dB_grid(level
, 256, 0.4);
1311 if (!drawn
and freq
> fq
) {
1314 sprintf(str
, "%d", subindex
+ 1);
1315 draw_cairo_label(context
, str
, i
, context
->size_y
* (1 - (data
[i
] + 1) / 2.f
), 0, 0, 0.5);
1321 bool vocoder_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1323 redraw_graph
= redraw_graph
|| !generation
;
1324 layers
= *params
[param_analyzer
] ? LG_REALTIME_GRAPH
: 0;
1325 layers
|= (generation
? LG_NONE
: LG_CACHE_GRID
) | (redraw_graph
? LG_CACHE_GRAPH
: LG_NONE
);
1326 redraw_graph
|= (bool)*params
[param_analyzer
];
1327 return redraw_graph
or !generation
;