539
/// Lookahead Limiter by Christian Holschuh and Markus Schmidt
541
lookahead_limiter::lookahead_limiter() {
546
overall_buffer_size = 0;
559
auto_release = false;
570
void lookahead_limiter::activate()
577
void lookahead_limiter::set_multi(bool set) { use_multi = set; }
579
void lookahead_limiter::deactivate()
584
float lookahead_limiter::get_attenuation()
591
void lookahead_limiter::set_sample_rate(uint32_t sr)
595
overall_buffer_size = (int)(srate * (100.f / 1000.f) * channels) + channels; // buffer size attack rate multiplied by 2 channels
596
buffer = (float*) calloc(overall_buffer_size, sizeof(float));
597
memset(buffer, 0, overall_buffer_size * sizeof(float)); // reset buffer to zero
600
nextpos = (int*) calloc(overall_buffer_size, sizeof(int));
601
nextdelta = (float*) calloc(overall_buffer_size, sizeof(float));
602
memset(nextpos, -1, overall_buffer_size * sizeof(int));
605
void lookahead_limiter::set_params(float l, float a, float r, float w, bool ar, float arc, bool d)
609
release = r / 1000.f;
616
void lookahead_limiter::reset() {
617
int bs = (int)(srate * attack * channels);
618
buffer_size = bs - bs % channels; // buffer size attack rate
629
void lookahead_limiter::reset_asc() {
636
void lookahead_limiter::process(float &left, float &right, float * multi_buffer)
638
// PROTIP: harming paying customers enough to make them develop a competing
639
// product may be considered an example of a less than sound business practice.
641
// fill lookahead buffer
643
// if we're sanitizing (zeroing) the buffer on attack time change,
644
// don't write the samples to the buffer
646
buffer[pos + 1] = 0.f;
649
buffer[pos + 1] = right;
652
// are we using multiband? get the multiband coefficient or use 1.f
653
float multi_coeff = (use_multi) ? multi_buffer[pos] : 1.f;
655
// input peak - impact higher in left or right channel?
656
peak = fabs(left) > fabs(right) ? fabs(left) : fabs(right);
658
// calc the real limit including weight and multi coeff
659
float _limit = limit * multi_coeff * weight;
661
// add an eventually appearing peak to the asc fake buffer if asc active
662
if(auto_release and peak > _limit) {
667
if(peak > _limit or multi_coeff < 1.0) {
668
float _multi_coeff = 1.f;
671
// calc the attenuation needed to reduce incoming peak
672
float _att = std::min(_limit / peak, 1.f);
675
// calc a release delta from this attenuation
676
float _rdelta = (1.0 - _att) / (srate * release);
677
if(auto_release and asc_c > 0) {
678
// check if releasing to average level of peaks is steeper than
680
float _delta = std::max((limit * weight) / (asc_coeff * asc) * (float)asc_c - _att, 0.000001f) / (srate * release);
681
if(_delta < _rdelta) {
687
// calc the delta for walking to incoming peak attenuation
688
float _delta = (_limit / peak - att) / buffer_size * channels;
691
// is the delta more important than the actual one?
692
// if so, we can forget about all stored deltas (because they can't
693
// be more important - we already checked that earlier) and use this
694
// delta now. and we have to create a release delta in nextpos buffer
697
nextdelta[0] = _rdelta;
702
// we have a peak on input its delta is less important than the
703
// actual delta. But what about the stored deltas we're following?
706
for(i = nextiter; i < nextiter + nextlen; i++) {
707
// walk through our nextpos buffer
708
int j = i % buffer_size;
709
// calculate a delta for the next stored peak
710
// are we using multiband? then get the multi_coeff for the
712
_multi_coeff = (use_multi) ? multi_buffer[nextpos[j]] : 1.f;
713
// is the left or the right channel on this position more
715
_peak = fabs(buffer[nextpos[j]]) > fabs(buffer[nextpos[j] + 1]) ? fabs(buffer[nextpos[j]]) : fabs(buffer[nextpos[j] + 1]);
716
// calc a delta to use to reach our incoming peak from the
718
_delta = (_limit / peak - (limit * _multi_coeff * weight) / _peak) / (((buffer_size - nextpos[j] + pos) % buffer_size) / channels);
719
if(_delta < nextdelta[j]) {
720
// if the buffered delta is more important than the delta
721
// used to reach our peak from the stored position, store
722
// the new delta at that position and stop the loop
723
nextdelta[j] = _delta;
729
// there was something more important in the next-buffer.
730
// throw away any position and delta after the important
731
// position and add a new release delta
732
nextlen = i - nextiter + 1;
733
nextpos[(nextiter + nextlen) % buffer_size] = pos;
734
nextdelta[(nextiter + nextlen) % buffer_size] = _rdelta;
735
// set the next following position value to -1 (cleaning up the
737
nextpos[(nextiter + nextlen + 1) % buffer_size] = -1;
738
// and raise the length of our nextpos buffer for keeping the
745
// switch left and right pointers in buffer to output position
746
left = buffer[(pos + channels) % buffer_size];
747
right = buffer[(pos + channels + 1) % buffer_size];
749
// if a peak leaves the buffer, remove it from asc fake buffer
750
// but only if we're not sanitizing asc buffer
751
float _peak = fabs(left) > fabs(right) ? fabs(left) : fabs(right);
752
float _multi_coeff = (use_multi) ? multi_buffer[(pos + channels) % buffer_size] : 1.f;
753
if(pos == asc_pos and !asc_changed) {
756
if(auto_release and asc_pos == -1 and _peak > (limit * weight * _multi_coeff)) {
761
// change the attenuation level
764
// ...and calculate outpout from it
768
if((pos + channels) % buffer_size == nextpos[nextiter]) {
769
// if we reach a buffered position, change the actual delta and erase
770
// this (the first) element from nextpos and nextdelta buffer
771
delta = nextdelta[nextiter];
772
nextlen = (nextlen - 1) % buffer_size;
773
nextpos[nextiter] = -1;
774
nextiter = (nextiter + 1) % buffer_size;
778
// release time seems over, reset attenuation and delta
783
// main limiting party is over, let's cleanup the puke
786
// we're sanitizing? then send 0.f as output
791
// security personnel pawing your values
793
// if this happens we're doomed!!
794
// may happen on manually lowering attack
795
att = 0.0000000000001;
796
delta = (1.0f - att) / (srate * release);
799
if(att != 1.f and 1 - att < 0.0000000000001) {
804
if(delta != 0.f and fabs(delta) < 0.00000000000001) {
809
// post treatment (denormal, limit)
813
// store max attenuation for meter output
814
att_max = (att < att_max) ? att : att_max;
816
// step forward in our sample ring buffer
817
pos = (pos + channels) % buffer_size;
819
// sanitizing is always done after a full cycle through the lookahead buffer
820
if(_sanitize and pos == 0) _sanitize = false;
825
bool lookahead_limiter::get_asc() {
826
if(!asc_active) return false;