Cleanup
[calf.git] / src / modules_limit.cpp
blob6b7dcb627b13a95bf4264e3e744fd053279cada4
1 /* Calf DSP plugin pack
2 * Limiter 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
21 #include <limits.h>
22 #include <memory.h>
23 #include <calf/giface.h>
24 #include <calf/audio_fx.h>
25 #include <calf/modules_limit.h>
27 using namespace dsp;
28 using namespace calf_plugins;
30 #define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name;
32 /**********************************************************************
33 * LIMITER by Christian Holschuh and Markus Schmidt
34 **********************************************************************/
36 limiter_audio_module::limiter_audio_module()
38 is_active = false;
39 srate = 0;
40 asc_led = 0.f;
41 attack_old = -1.f;
42 limit_old = -1.f;
43 oversampling_old = -1;
44 asc_old = true;
47 void limiter_audio_module::activate()
49 is_active = true;
50 // set all filters and strips
51 params_changed();
52 limiter.activate();
55 void limiter_audio_module::deactivate()
57 is_active = false;
58 limiter.deactivate();
60 void limiter_audio_module::set_srates()
62 resampler[0].set_params(srate, *params[param_oversampling], 2);
63 resampler[1].set_params(srate, *params[param_oversampling], 2);
64 limiter.set_sample_rate(srate * *params[param_oversampling]);
66 void limiter_audio_module::params_changed()
68 limiter.set_params(*params[param_limit], *params[param_attack], *params[param_release], 1.f, *params[param_asc], pow(0.5, (*params[param_asc_coeff] - 0.5) * 2 * -1), true);
69 if( *params[param_attack] != attack_old) {
70 attack_old = *params[param_attack];
71 limiter.reset();
73 if(*params[param_limit] != limit_old or *params[param_asc] != asc_old) {
74 asc_old = *params[param_asc];
75 limit_old = *params[param_limit];
76 limiter.reset_asc();
78 if (oversampling_old != *params[param_oversampling]) {
79 oversampling_old = *params[param_oversampling];
80 set_srates();
84 void limiter_audio_module::set_sample_rate(uint32_t sr)
86 srate = sr;
87 int meter[] = {param_meter_inL, param_meter_inR, param_meter_outL, param_meter_outR, -param_att};
88 int clip[] = {param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR, -1};
89 meters.init(params, meter, clip, 5, srate);
90 set_srates();
93 uint32_t limiter_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
95 bool bypassed = bypass.update(*params[param_bypass] > 0.5f, numsamples);
96 uint32_t orig_numsamples = numsamples;
97 uint32_t orig_offset = offset;
98 numsamples += offset;
99 if(bypassed) {
100 // everything bypassed
101 while(offset < numsamples) {
102 outs[0][offset] = ins[0][offset];
103 outs[1][offset] = ins[1][offset];
104 float values[] = {0, 0, 0, 0, 1};
105 meters.process(values);
106 ++offset;
108 asc_led = 0.f;
109 } else {
110 asc_led -= std::min(asc_led, numsamples);
112 while(offset < numsamples) {
113 // cycle through samples
114 float inL = ins[0][offset];
115 float inR = ins[1][offset];
116 // in level
117 inR *= *params[param_level_in];
118 inL *= *params[param_level_in];
119 // out vars
120 float outL = inL;
121 float outR = inR;
123 // upsampling
124 double *samplesL = resampler[0].upsample((double)outL);
125 double *samplesR = resampler[1].upsample((double)outR);
127 float tmpL;
128 float tmpR;
130 // process gain reduction
131 float fickdich[0];
132 for (int i = 0; i < *params[param_oversampling]; i ++) {
133 tmpL = samplesL[i];
134 tmpR = samplesR[i];
135 limiter.process(tmpL, tmpR, fickdich);
136 samplesL[i] = tmpL;
137 samplesR[i] = tmpR;
138 if(limiter.get_asc())
139 asc_led = srate >> 3;
142 // downsampling
143 outL = resampler[0].downsample(samplesL);
144 outR = resampler[1].downsample(samplesR);
146 // should never be used. but hackers are paranoid by default.
147 // so we make shure NOTHING is above limit
148 outL = std::min(std::max(outL, -*params[param_limit]), *params[param_limit]);
149 outR = std::min(std::max(outR, -*params[param_limit]), *params[param_limit]);
151 // autolevel
152 outL /= *params[param_limit];
153 outR /= *params[param_limit];
155 // out level
156 outL *= *params[param_level_out];
157 outR *= *params[param_level_out];
159 // send to output
160 outs[0][offset] = outL;
161 outs[1][offset] = outR;
163 float values[] = {inL, inR, outL, outR, bypassed ? (float)1.0 : (float)limiter.get_attenuation()};
164 meters.process (values);
166 // next sample
167 ++offset;
168 } // cycle trough samples
169 bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples);
170 } // process (no bypass)
171 meters.fall(numsamples);
172 if (params[param_asc_led] != NULL) *params[param_asc_led] = asc_led;
173 return outputs_mask;
176 /**********************************************************************
177 * MULTIBAND LIMITER by Markus Schmidt and Christian Holschuh
178 **********************************************************************/
180 multibandlimiter_audio_module::multibandlimiter_audio_module()
182 srate = 0;
183 _mode = 0;
184 over = 1;
185 buffer_size = 0;
186 overall_buffer_size = 0;
187 channels = 2;
188 asc_led = 0.f;
189 attack_old = -1.f;
190 oversampling_old = -1.f;
191 limit_old = -1.f;
192 asc_old = true;
193 _sanitize = false;
194 is_active = false;
195 cnt = 0;
197 for(int i = 0; i < strips; i ++) {
198 weight_old[i] = -1.f;
201 crossover.init(channels, strips, 44100);
203 multibandlimiter_audio_module::~multibandlimiter_audio_module()
205 free(buffer);
207 void multibandlimiter_audio_module::activate()
209 is_active = true;
210 // set all filters and strips
211 params_changed();
212 // activate all strips
213 for (int j = 0; j < strips; j ++) {
214 strip[j].activate();
215 strip[j].set_multi(true);
216 strip[j].id = j;
218 broadband.activate();
219 pos = 0;
222 void multibandlimiter_audio_module::deactivate()
224 is_active = false;
225 // deactivate all strips
226 for (int j = 0; j < strips; j ++) {
227 strip[j].deactivate();
229 broadband.deactivate();
232 void multibandlimiter_audio_module::params_changed()
234 // determine mute/solo states
235 solo[0] = *params[param_solo0] > 0.f ? true : false;
236 solo[1] = *params[param_solo1] > 0.f ? true : false;
237 solo[2] = *params[param_solo2] > 0.f ? true : false;
238 solo[3] = *params[param_solo3] > 0.f ? true : false;
239 no_solo = (*params[param_solo0] > 0.f ||
240 *params[param_solo1] > 0.f ||
241 *params[param_solo2] > 0.f ||
242 *params[param_solo3] > 0.f) ? false : true;
244 int m = *params[param_mode];
245 if (m != _mode) {
246 _mode = *params[param_mode];
249 crossover.set_mode(_mode + 1);
250 crossover.set_filter(0, *params[param_freq0]);
251 crossover.set_filter(1, *params[param_freq1]);
252 crossover.set_filter(2, *params[param_freq2]);
254 // set the params of all strips
255 float rel;
256 for (int i = 0; i < strips; i++) {
257 rel = *params[param_release] * pow(0.25, *params[param_release0 + i] * -1);
258 rel = (*params[param_minrel] > 0.5) ? std::max(2500 * (1.f / (i ? *params[param_freq0 + i - 1] : 30)), rel) : rel;
259 weight[i] = pow(0.25, *params[param_weight0 + i] * -1);
260 strip[i].set_params(*params[param_limit], *params[param_attack], rel, weight[i], *params[param_asc], pow(0.5, (*params[param_asc_coeff] - 0.5) * 2 * -1), false);
261 *params[param_effrelease0 + i] = rel;
264 // set broadband limiter
265 broadband.set_params(*params[param_limit], *params[param_attack], rel, 1.f, *params[param_asc], pow(0.5, (*params[param_asc_coeff] - 0.5) * 2 * -1));
267 if (over != *params[param_oversampling]) {
268 over = *params[param_oversampling];
269 set_srates();
272 // rebuild multiband buffer
273 if( *params[param_attack] != attack_old or *params[param_oversampling] != oversampling_old) {
274 int bs = (int)(srate * (*params[param_attack] / 1000.f) * channels * over);
275 buffer_size = bs - bs % channels; // buffer size attack rate
276 attack_old = *params[param_attack];
277 oversampling_old = *params[param_oversampling];
278 _sanitize = true;
279 pos = 0;
280 for (int j = 0; j < strips; j ++) {
281 strip[j].reset();
283 broadband.reset();
285 if(*params[param_limit] != limit_old or *params[param_asc] != asc_old or *params[param_weight0] != weight_old[0] or *params[param_weight1] != weight_old[1] or *params[param_weight2] != weight_old[2] or *params[param_weight3] != weight_old[3] ) {
286 asc_old = *params[param_asc];
287 limit_old = *params[param_limit];
288 for (int j = 0; j < strips; j ++) {
289 weight_old[j] = *params[param_weight0 + j];
290 strip[j].reset_asc();
292 broadband.reset_asc();
296 void multibandlimiter_audio_module::set_sample_rate(uint32_t sr)
298 srate = sr;
299 set_srates();
300 int meter[] = {param_meter_inL, param_meter_inR, param_meter_outL, param_meter_outR, -param_att0, -param_att1, -param_att2, -param_att3};
301 int clip[] = {param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR, -1, -1, -1, -1};
302 meters.init(params, meter, clip, 8, srate);
305 void multibandlimiter_audio_module::set_srates()
307 broadband.set_sample_rate(srate * over);
308 crossover.set_sample_rate(srate);
309 for (int j = 0; j < strips; j ++) {
310 strip[j].set_sample_rate(srate * over);
311 resampler[j][0].set_params(srate, over, 2);
312 resampler[j][1].set_params(srate, over, 2);
314 // rebuild buffer
315 overall_buffer_size = (int)(srate * (100.f / 1000.f) * channels * over) + channels; // buffer size max attack rate
316 buffer = (float*) calloc(overall_buffer_size, sizeof(float));
317 pos = 0;
320 #define BYPASSED_COMPRESSION(index) \
321 if(params[param_att##index] != NULL) \
322 *params[param_att##index] = 1.0; \
324 #define ACTIVE_COMPRESSION(index) \
325 if(params[param_att##index] != NULL) \
326 *params[param_att##index] = strip[index].get_attenuation(); \
329 uint32_t multibandlimiter_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
331 bool bypassed = bypass.update(*params[param_bypass] > 0.5f, numsamples);
332 uint32_t orig_numsamples = numsamples;
333 uint32_t orig_offset = offset;
334 numsamples += offset;
335 float batt = 0.f;
336 if(bypassed) {
337 // everything bypassed
338 while(offset < numsamples) {
339 outs[0][offset] = ins[0][offset];
340 outs[1][offset] = ins[1][offset];
341 float values[] = {0, 0, 0, 0, 1, 1, 1, 1};
342 meters.process(values);
343 ++offset;
345 asc_led = 0.f;
346 } else {
347 // process all strips
348 asc_led -= std::min(asc_led, numsamples);
349 while(offset < numsamples) {
350 float inL = 0.f; // input
351 float inR = 0.f;
352 float outL = 0.f; // final output
353 float outR = 0.f;
354 float tmpL = 0.f; // used for temporary purposes
355 float tmpR = 0.f;
356 double overL[strips * 16];
357 double overR[strips * 16];
358 double resL[16];
359 double resR[16];
361 bool asc_active = false;
363 // cycle through samples
364 if(!_sanitize) {
365 inL = ins[0][offset];
366 inR = ins[1][offset];
368 // in level
369 inR *= *params[param_level_in];
370 inL *= *params[param_level_in];
372 //if(!(cnt%50)) printf("i: %.5f\n", inL);
374 // process crossover
375 float xin[] = {inL, inR};
376 crossover.process(xin);
378 // cycle over strips
379 for (int i = 0; i < strips; i++) {
380 // upsample
381 double *samplesL = resampler[i][0].upsample((double)crossover.get_value(0, i));
382 double *samplesR = resampler[i][1].upsample((double)crossover.get_value(1, i));
383 // copy to cache
384 memcpy(&overL[i * 16], samplesL, sizeof(double) * over);
385 memcpy(&overR[i * 16], samplesR, sizeof(double) * over);
386 //if(!(cnt%200)) printf("u0: %.5f\n", overL[i*16]);
389 // cycle over upsampled samples
390 for (int o = 0; o < over; o++) {
391 tmpL = 0.f;
392 tmpR = 0.f;
393 resL[o] = 0;
394 resR[o] = 0;
396 // cycle over strips for multiband coefficient
398 // -------------------------------------------
399 // The Multiband Coefficient
401 // The Multiband Coefficient tries to make sure, that after
402 // summing up the 4 limited strips, the signal does not raise
403 // above the limit. It works as a correction factor. Because
404 // we use this concept, we can introduce a weighting to each
405 // strip.
406 // a1, a2, a3, ... : signals in strips
407 // then a1 + a2 + a3 + ... might raise above the limit, because
408 // the strips will be limited and the filters, which produced
409 // the signals from source signals, are not complete precisely.
410 // Morethough, external signals might be added in here in future
411 // versions.
413 // So introduce correction factor:
414 // Sum( a_i * weight_i) = limit / multi_coeff
416 // The multi_coeff now can be used in each strip i, to calculate
417 // the real limit for strip i according to the signals in the
418 // other strips and the weighting of the own strip i.
419 // strip_limit_i = limit * multicoeff * weight_i
421 // -------------------------------------------
424 for (int i = 0; i < strips; i++) {
425 // sum up for multiband coefficient
426 int p = i * 16 + o;
427 tmpL += ((fabs(overL[p]) > *params[param_limit]) ? *params[param_limit] * (fabs(overL[p]) / overL[p]) : overL[p]) * weight[i];
428 tmpR += ((fabs(overR[p]) > *params[param_limit]) ? *params[param_limit] * (fabs(overR[p]) / overR[p]) : overR[p]) * weight[i];
431 // write multiband coefficient to buffer
432 buffer[pos] = std::min(*params[param_limit] / std::max(fabs(tmpL), fabs(tmpR)), 1.0);
434 // step forward in multiband buffer
435 pos = (pos + channels) % buffer_size;
436 if(pos == 0) _sanitize = false;
438 // limit and add up strips
439 for (int i = 0; i < strips; i++) {
440 int p = i * 16 + o;
441 //if(!(cnt%200) and !o) printf("u1: %.5f\n", overL[p]);
442 // limit
443 tmpL = (float)overL[p];
444 tmpR = (float)overR[p];
445 //if(!(cnt%200)) printf("1: %.5f\n", tmpL);
446 strip[i].process(tmpL, tmpR, buffer);
447 //if(!(cnt%200)) printf("2: %.5f\n\n", tmpL);
448 if (solo[i] || no_solo) {
449 // add
450 resL[o] += (double)tmpL;
451 resR[o] += (double)tmpR;
452 // flash the asc led?
453 asc_active = asc_active || strip[i].get_asc();
457 // process broadband limiter
458 float fickdich[0];
459 tmpL = resL[o];
460 tmpR = resR[o];
461 broadband.process(tmpL, tmpR, fickdich);
462 resL[o] = (double)tmpL;
463 resR[o] = (double)tmpR;
464 asc_active = asc_active || broadband.get_asc();
467 // downsampling
468 outL = (float)resampler[0][0].downsample(resL);
469 outR = (float)resampler[0][1].downsample(resR);
471 //if(!(cnt%50)) printf("o: %.5f %.5f\n\n", outL, resL[0]);
473 // should never be used. but hackers are paranoid by default.
474 // so we make shure NOTHING is above limit
475 outL = std::min(std::max(outL, -*params[param_limit]), *params[param_limit]);
476 outR = std::min(std::max(outR, -*params[param_limit]), *params[param_limit]);
478 // light led
479 if(asc_active) {
480 asc_led = srate >> 3;
483 // autolevel
484 outL /= *params[param_limit];
485 outR /= *params[param_limit];
487 // out level
488 outL *= *params[param_level_out];
489 outR *= *params[param_level_out];
491 // send to output
492 outs[0][offset] = outL;
493 outs[1][offset] = outR;
495 // next sample
496 ++offset;
498 batt = broadband.get_attenuation();
500 float values[] = {inL, inR, outL, outR,
501 bypassed ? (float)1.0 : (float)strip[0].get_attenuation() * batt,
502 bypassed ? (float)1.0 : (float)strip[1].get_attenuation() * batt,
503 bypassed ? (float)1.0 : (float)strip[2].get_attenuation() * batt,
504 bypassed ? (float)1.0 : (float)strip[3].get_attenuation() * batt};
505 meters.process(values);
509 //for (int i = 0; i < strips; i++) {
510 //left = crossover.get_value(0, i);
511 //right = crossover.get_value(1, i);
513 //// remember filtered values for limiting
514 //// (we need multiband_coeff before we can call the limiter bands)
515 //_tmpL[i] = left;
516 //_tmpR[i] = right;
518 //// sum up for multiband coefficient
519 //sum_left += ((fabs(left) > *params[param_limit]) ? *params[param_limit] * (fabs(left) / left) : left) * weight[i];
520 //sum_right += ((fabs(right) > *params[param_limit]) ? *params[param_limit] * (fabs(right) / right) : right) * weight[i];
521 //} // process single strip with filter
523 //// write multiband coefficient to buffer
524 //buffer[pos] = std::min(*params[param_limit] / std::max(fabs(sum_left), fabs(sum_right)), 1.0);
526 //for (int i = 0; i < strips; i++) {
527 //// process gain reduction
528 //strip[i].process(_tmpL[i], _tmpR[i], buffer);
529 //// sum up output of limiters
530 //if (solo[i] || no_solo) {
531 //outL += _tmpL[i];
532 //outR += _tmpR[i];
534 //asc_active = asc_active || strip[i].get_asc();
535 //} // process single strip again for limiter
536 //float fickdich[0];
537 //broadband.process(outL, outR, fickdich);
538 //asc_active = asc_active || broadband.get_asc();
540 //// should never be used. but hackers are paranoid by default.
541 //// so we make shure NOTHING is above limit
542 //outL = std::max(outL, -*params[param_limit]);
543 //outL = std::min(outL, *params[param_limit]);
544 //outR = std::max(outR, -*params[param_limit]);
545 //outR = std::min(outR, *params[param_limit]);
547 //if(asc_active) {
548 //asc_led = srate >> 3;
550 cnt++;
551 } // cycle trough samples
552 bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples);
553 } // process (no bypass)
554 if (params[param_asc_led] != NULL) *params[param_asc_led] = asc_led;
555 meters.fall(numsamples);
556 return outputs_mask;
559 bool multibandlimiter_audio_module::get_graph(int index, int subindex, int phase, float *data, int points, cairo_iface *context, int *mode) const
561 return crossover.get_graph(subindex, phase, data, points, context, mode);
563 bool multibandlimiter_audio_module::get_layers(int index, int generation, unsigned int &layers) const
565 return crossover.get_layers(index, generation, layers);
568 /**********************************************************************
569 * SIDECHAIN LIMITER by Markus Schmidt and Christian Holschuh
570 **********************************************************************/
572 sidechainlimiter_audio_module::sidechainlimiter_audio_module()
574 srate = 0;
575 _mode = 0;
576 over = 1;
577 buffer_size = 0;
578 overall_buffer_size = 0;
579 channels = 2;
580 asc_led = 0.f;
581 attack_old = -1.f;
582 oversampling_old = -1.f;
583 limit_old = -1.f;
584 asc_old = true;
585 _sanitize = false;
586 is_active = false;
587 cnt = 0;
589 for(int i = 0; i < strips; i ++) {
590 weight_old[i] = -1.f;
593 crossover.init(channels, strips - 1, 44100);
595 sidechainlimiter_audio_module::~sidechainlimiter_audio_module()
597 free(buffer);
599 void sidechainlimiter_audio_module::activate()
601 is_active = true;
602 // set all filters and strips
603 params_changed();
604 // activate all strips
605 for (int j = 0; j < strips; j ++) {
606 strip[j].activate();
607 strip[j].set_multi(true);
608 strip[j].id = j;
610 broadband.activate();
611 pos = 0;
614 void sidechainlimiter_audio_module::deactivate()
616 is_active = false;
617 // deactivate all strips
618 for (int j = 0; j < strips; j ++) {
619 strip[j].deactivate();
621 broadband.deactivate();
624 void sidechainlimiter_audio_module::params_changed()
626 // determine mute/solo states
627 solo[0] = *params[param_solo0] > 0.f ? true : false;
628 solo[1] = *params[param_solo1] > 0.f ? true : false;
629 solo[2] = *params[param_solo2] > 0.f ? true : false;
630 solo[3] = *params[param_solo3] > 0.f ? true : false;
631 solo[4] = *params[param_solo_sc] > 0.f ? true : false;
632 no_solo = (*params[param_solo0] > 0.f ||
633 *params[param_solo1] > 0.f ||
634 *params[param_solo2] > 0.f ||
635 *params[param_solo3] > 0.f ||
636 *params[param_solo_sc] > 0.f) ? false : true;
638 int m = *params[param_mode];
639 if (m != _mode) {
640 _mode = *params[param_mode];
643 crossover.set_mode(_mode + 1);
644 crossover.set_filter(0, *params[param_freq0]);
645 crossover.set_filter(1, *params[param_freq1]);
646 crossover.set_filter(2, *params[param_freq2]);
648 // set the params of all strips
649 float rel;
650 for (int i = 0; i < strips; i++) {
651 rel = *params[param_release] * pow(0.25, *params[param_release0 + i] * -1);
652 if (i < strips - 1)
653 rel = (*params[param_minrel] > 0.5) ? std::max(2500 * (1.f / (i ? *params[param_freq0 + i - 1] : 30)), rel) : rel;
654 weight[i] = pow(0.25, *params[param_weight0 + i] * -1);
655 strip[i].set_params(*params[param_limit], *params[param_attack], rel, weight[i], *params[param_asc], pow(0.5, (*params[param_asc_coeff] - 0.5) * 2 * -1), false);
656 *params[param_effrelease0 + i] = rel;
659 // set broadband limiter
660 broadband.set_params(*params[param_limit], *params[param_attack], rel, 1.f, *params[param_asc], pow(0.5, (*params[param_asc_coeff] - 0.5) * 2 * -1));
662 if (over != *params[param_oversampling]) {
663 over = *params[param_oversampling];
664 set_srates();
667 // rebuild multiband buffer
668 if( *params[param_attack] != attack_old or *params[param_oversampling] != oversampling_old) {
669 int bs = (int)(srate * (*params[param_attack] / 1000.f) * channels * over);
670 buffer_size = bs - bs % channels; // buffer size attack rate
671 attack_old = *params[param_attack];
672 oversampling_old = *params[param_oversampling];
673 _sanitize = true;
674 pos = 0;
675 for (int j = 0; j < strips; j ++) {
676 strip[j].reset();
678 broadband.reset();
680 if(*params[param_limit] != limit_old or *params[param_asc] != asc_old or *params[param_weight0] != weight_old[0] or *params[param_weight1] != weight_old[1] or *params[param_weight2] != weight_old[2] or *params[param_weight3] != weight_old[3] ) {
681 asc_old = *params[param_asc];
682 limit_old = *params[param_limit];
683 for (int j = 0; j < strips; j ++) {
684 weight_old[j] = *params[param_weight0 + j];
685 strip[j].reset_asc();
687 broadband.reset_asc();
691 void sidechainlimiter_audio_module::set_sample_rate(uint32_t sr)
693 srate = sr;
694 set_srates();
695 int meter[] = {param_meter_inL, param_meter_inR, param_meter_scL, param_meter_scR, param_meter_outL, param_meter_outR, -param_att0, -param_att1, -param_att2, -param_att3, -param_att_sc};
696 int clip[] = {param_clip_inL, param_clip_inR, -1, -1, param_clip_outL, param_clip_outR, -1, -1, -1, -1, -1};
697 meters.init(params, meter, clip, 8, srate);
700 void sidechainlimiter_audio_module::set_srates()
702 broadband.set_sample_rate(srate * over);
703 crossover.set_sample_rate(srate);
704 for (int j = 0; j < strips; j ++) {
705 strip[j].set_sample_rate(srate * over);
706 resampler[j][0].set_params(srate, over, 2);
707 resampler[j][1].set_params(srate, over, 2);
709 // rebuild buffer
710 overall_buffer_size = (int)(srate * (100.f / 1000.f) * channels * over) + channels; // buffer size max attack rate
711 buffer = (float*) calloc(overall_buffer_size, sizeof(float));
712 pos = 0;
715 #define BYPASSED_COMPRESSION(index) \
716 if(params[param_att##index] != NULL) \
717 *params[param_att##index] = 1.0; \
719 #define ACTIVE_COMPRESSION(index) \
720 if(params[param_att##index] != NULL) \
721 *params[param_att##index] = strip[index].get_attenuation(); \
724 uint32_t sidechainlimiter_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
726 bool bypassed = bypass.update(*params[param_bypass] > 0.5f, numsamples);
727 uint32_t orig_numsamples = numsamples;
728 uint32_t orig_offset = offset;
729 numsamples += offset;
730 float batt = 0.f;
731 if(bypassed) {
732 // everything bypassed
733 while(offset < numsamples) {
734 outs[0][offset] = ins[0][offset];
735 outs[1][offset] = ins[1][offset];
736 float values[] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};
737 meters.process(values);
738 ++offset;
740 asc_led = 0.f;
741 } else {
742 // process all strips
743 asc_led -= std::min(asc_led, numsamples);
744 while(offset < numsamples) {
745 float inL = 0.f; // input
746 float inR = 0.f;
747 float scL = 0.f;
748 float scR = 0.f;
749 float outL = 0.f; // final output
750 float outR = 0.f;
751 float tmpL = 0.f; // used for temporary purposes
752 float tmpR = 0.f;
753 double overL[strips * 16];
754 double overR[strips * 16];
755 double resL[16];
756 double resR[16];
758 bool asc_active = false;
760 // cycle through samples
761 if(!_sanitize) {
762 inL = ins[0][offset];
763 inR = ins[1][offset];
764 scL = ins[2][offset];
765 scR = ins[3][offset];
768 // in level
769 inR *= *params[param_level_in];
770 inL *= *params[param_level_in];
772 scR *= *params[param_level_sc];
773 scL *= *params[param_level_sc];
775 //if(!(cnt%50)) printf("i: %.5f\n", inL);
777 // process crossover
778 float xin[] = {inL, inR};
779 crossover.process(xin);
781 // cycle over strips
782 for (int i = 0; i < strips; i++) {
783 double *samplesR, *samplesL;
784 // upsample
785 if (i < strips - 1) {
786 samplesL = resampler[i][0].upsample((double)crossover.get_value(0, i));
787 samplesR = resampler[i][1].upsample((double)crossover.get_value(1, i));
788 } else {
789 samplesL = resampler[i][0].upsample((double)scL);
790 samplesR = resampler[i][1].upsample((double)scR);
792 // copy to cache
793 memcpy(&overL[i * 16], samplesL, sizeof(double) * over);
794 memcpy(&overR[i * 16], samplesR, sizeof(double) * over);
795 //if(!(cnt%200)) printf("u0: %.5f\n", overL[i*16]);
798 // cycle over upsampled samples
799 for (int o = 0; o < over; o++) {
800 tmpL = 0.f;
801 tmpR = 0.f;
802 resL[o] = 0;
803 resR[o] = 0;
805 // cycle over strips for multiband coefficient
806 for (int i = 0; i < strips; i++) {
807 // sum up for multiband coefficient
808 int p = i * 16 + o;
809 tmpL += ((fabs(overL[p]) > *params[param_limit]) ? *params[param_limit] * (fabs(overL[p]) / overL[p]) : overL[p]) * weight[i];
810 tmpR += ((fabs(overR[p]) > *params[param_limit]) ? *params[param_limit] * (fabs(overR[p]) / overR[p]) : overR[p]) * weight[i];
813 // write multiband coefficient to buffer
814 buffer[pos] = std::min(*params[param_limit] / std::max(fabs(tmpL), fabs(tmpR)), 1.0);
816 // step forward in multiband buffer
817 pos = (pos + channels) % buffer_size;
818 if(pos == 0) _sanitize = false;
820 // limit and add up strips
821 for (int i = 0; i < strips; i++) {
822 int p = i * 16 + o;
823 //if(!(cnt%200) and !o) printf("u1: %.5f\n", overL[p]);
824 // limit
825 tmpL = (float)overL[p];
826 tmpR = (float)overR[p];
827 //if(!(cnt%200)) printf("1: %.5f\n", tmpL);
828 strip[i].process(tmpL, tmpR, buffer);
829 //if(!(cnt%200)) printf("2: %.5f\n\n", tmpL);
830 if (solo[i] || no_solo) {
831 // add
832 resL[o] += (double)tmpL;
833 resR[o] += (double)tmpR;
834 // flash the asc led?
835 asc_active = asc_active || strip[i].get_asc();
839 // process broadband limiter
840 float fickdich[0];
841 tmpL = resL[o];
842 tmpR = resR[o];
843 broadband.process(tmpL, tmpR, fickdich);
844 resL[o] = (double)tmpL;
845 resR[o] = (double)tmpR;
846 asc_active = asc_active || broadband.get_asc();
849 // downsampling
850 outL = (float)resampler[0][0].downsample(resL);
851 outR = (float)resampler[0][1].downsample(resR);
853 //if(!(cnt%50)) printf("o: %.5f %.5f\n\n", outL, resL[0]);
855 // should never be used. but hackers are paranoid by default.
856 // so we make shure NOTHING is above limit
857 outL = std::min(std::max(outL, -*params[param_limit]), *params[param_limit]);
858 outR = std::min(std::max(outR, -*params[param_limit]), *params[param_limit]);
860 // light led
861 if(asc_active) {
862 asc_led = srate >> 3;
865 // autolevel
866 outL /= *params[param_limit];
867 outR /= *params[param_limit];
869 // out level
870 outL *= *params[param_level_out];
871 outR *= *params[param_level_out];
873 // send to output
874 outs[0][offset] = outL;
875 outs[1][offset] = outR;
877 // next sample
878 ++offset;
880 batt = broadband.get_attenuation();
882 float values[] = {inL, inR, scL, scR, outL, outR,
883 bypassed ? (float)1.0 : (float)strip[0].get_attenuation() * batt,
884 bypassed ? (float)1.0 : (float)strip[1].get_attenuation() * batt,
885 bypassed ? (float)1.0 : (float)strip[2].get_attenuation() * batt,
886 bypassed ? (float)1.0 : (float)strip[3].get_attenuation() * batt,
887 bypassed ? (float)1.0 : (float)strip[4].get_attenuation() * batt};
888 meters.process(values);
890 cnt++;
891 } // cycle trough samples
892 bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples);
893 } // process (no bypass)
894 if (params[param_asc_led] != NULL) *params[param_asc_led] = asc_led;
895 meters.fall(numsamples);
896 return outputs_mask;
899 bool sidechainlimiter_audio_module::get_graph(int index, int subindex, int phase, float *data, int points, cairo_iface *context, int *mode) const
901 return crossover.get_graph(subindex, phase, data, points, context, mode);
903 bool sidechainlimiter_audio_module::get_layers(int index, int generation, unsigned int &layers) const
905 return crossover.get_layers(index, generation, layers);