maxsoftLimiter

Hard, but max-softened, limiter. Don't forget to also add a "delay/write_sdram" module (5.33ms, shortest time) and connect it to the same source as you send to the audio input of the limiter. The release knob works a bit differently from "normal" operation. It's hard to hear, but the higher the release knob, the more it sustains the sound and it seems to be a bit clearer at low settings (around 1)
Author: Remco van der Most
License: BSD
Github: sss/dyn/maxsoftLimiter.axo

Inlets

frac32buffer in

Outlets

frac32buffer out

Parameters

frac32.u.map tresh

frac32.u.map ratio

frac32.u.map release

frac32.u.map gain

Attributes

objref delayname

Declaration
int32_t array1[16];
int32_t array2[128];
int i;
int32_t max;
int count;
int32_t val1;
int32_t val2;
int32_t val3;
int32_t val4;
int32_t val5;

int32_t frac_log(int32_t a) {
  Float_t f;
  f.f = a;
  int32_t r1 = ((f.parts.exponent & 0x7F) - 18) << 24;
  int32_t r3 = logt[f.parts.mantissa >> 15] << 10;
  return r1 + r3;
}

int32_t frac_exp(int32_t a) {
  int8_t s = (a >> 24) + 4;
  uint8_t ei = a >> 16;
  if (s >= 0)
    return expt[ei] << s;
  else
    return expt[ei] >> (-s);
}
Control Rate
int32_t mox = 0;
array2[127] = val5;
for (i = 0; i < 127; i++) {
  array2[i] = array2[i + 1];
}
for (i = 0; i < 128; i++) {
  mox = (array2[i] / (1 + ___SMMUL((127 - i) << 6, param_release << 5))) > mox
            ? array2[i]
            : mox;
}

if (mox > val1) {
  val1 = val1 + ((mox - val1));
} else {
  val1 = val1 + ((mox - val1) >> 8);
}

uint32_t delay = attr_delayname.writepos -
                 (__USAT(60 << 21 - 1, 27) >> (27 - attr_delayname.LENGTHPOW)) -
                 BUFSIZE;
Audio Rate
max = inlet_in > 0 ? inlet_in : -inlet_in;
count += 1;
count = count - (count / 16) * 16;
array1[count] = inlet_in > 0 ? inlet_in : -inlet_in;
if (count == 0) {
  for (i = 0; i < 16; i++) {
    max = array1[i] > max ? array1[i] : max;
  }
}

val5 = val5 + ((max - val5) >> 4);

if (val1 > val2) {
  val2 = val2 + ((val1 - val2) >> 9);
} else {
  val2 = val2 + ((val1 - val2) >> 9);
}

val3 = val3 + ((param_tresh - val3) >> 9);
val4 = val4 + ((param_ratio - val4) >> 9);

int32_t inlog = frac_log(val2);
int32_t treshlog = frac_log(val3);
int32_t over = inlog - treshlog;
int32_t gain;
if (over < 0) {
  gain = 0x80000;
} else {
  gain = frac_exp(-___SMMUL(over, val4) << 5);
}
// outlet_out =gain<<8;
outlet_out = ___SMMUL(
    (gain << 10) + (param_gain << 3),
    (attr_delayname.array[(delay++) & attr_delayname.LENGTHMASK] << 14) << 2);

Privacy

© 2024 Zrna Research