compander

Dynamic range compressor/limiter/expander.
Author: Remco van der Most
License: BSD
Github: sss/dyn/compander.axo

Inlets

frac32 release

frac32buffer in

Outlets

frac32buffer out

Parameters

frac32.s.map.lfopitch sets release time

frac32.u.map adds gain to the incoming signal, before compressing

frac32.u.map sets the limiter/compressor treshold and goal for expander

frac32.u.map sets the ratio amount of the gain reduction/addition

frac32.u.map sets the amount of expansion towards the treshold when below

frac32.u.map makes the expander exponential, causing a quicker rise and more distortion at low release settings

Declaration
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);
}
int32_t accum;
int i;
int32_t prev;
int32_t step;
int32_t lp;
int32_t follow;
Init
accum = 0;
Control Rate
int32_t rel;
MTOF(-param_release - inlet_release, rel)
/*
for(i=0;i<BUFSIZE;i++){
        int32_t in=inlet_in[i];
        in=__SSAT(in+__SSAT(__SSAT(___SMMUL(in,param_gainIn)<<5,24)<<4,29),29);
        in=in>0?in:-in;
        accum=in>accum?in:(accum+(___SMMUL(in-accum,rel)>>4));

}

int32_t inlog = frac_log(accum);
int32_t treshlog = frac_log(param_tresh);
int32_t over = inlog-treshlog;

int32_t gain;
if (over<0){
        over=over<-(3<<25)?-(3<<25):over;
        int32_t
tmp=frac_exp(over+(___SMMUL(___SMMUL(over>>1,___SMMUL(over,over))-(over>>1),param_slope)<<5))<<8;
        tmp=(___SMMUL(tmp,-0x80000+frac_exp(-___SMMUL(over,param_ratio)<<5))<<5);
        gain = 0x80000+(___SMMUL(tmp,param_expand)<<5);
} else {
        gain = frac_exp(-___SMMUL(over,param_ratio)<<5);
}
gain = (gain<<8);

step = (gain - prev)>>4;
   int32_t D = prev;
   prev = gain;
for(i=0;i<BUFSIZE;i++){
        lp=D<lp?D:(lp+(___SMMUL(D-lp,rel)>>4));
        int32_t in=inlet_in[i];
        in=__SSAT(in+__SSAT(__SSAT(___SMMUL(in,param_gainIn)<<5,24)<<4,28),28);
        outlet_out[i] =  __SSAT(___SMMUL(in,lp)<<5,28);
        D += step;
}
*/
Audio Rate
int32_t in = inlet_in;
in = __SSAT(in + __SSAT(__SSAT(___SMMUL(in, param_gainIn) << 5, 24) << 4, 29),
            29);
in = in > 0 ? in : -in;
accum = in > accum ? in : (accum + (___SMMUL(in - accum, rel) >> 2));

int32_t inlog = frac_log(accum);
int32_t treshlog = frac_log(param_tresh);
int32_t over = inlog - treshlog;

int32_t gain;
if (over < 0) {
  over = (over >> 3) * 7;
  int32_t tmp =
      frac_exp(over + (___SMMUL(___SMMUL(over >> 1, ___SMMUL(over, over)) -
                                    (over >> 1),
                                param_slope)
                       << 5))
      << 8;
  tmp = (___SMMUL(tmp, -0x80000 + frac_exp(-___SMMUL(over, param_ratio) << 5))
         << 5);
  gain = 0x80000 + (___SMMUL(tmp, param_expand) << 5);
} else {
  gain = frac_exp(-___SMMUL(over, param_ratio) << 5);
}
gain = (gain << 8);

int32_t D = __USAT(gain, 31);

lp = D < lp ? D : (lp + (___SMMUL(D - lp, rel) >> 4));
in = inlet_in;
in = __SSAT(in + __SSAT(__SSAT(___SMMUL(in, param_gainIn) << 5, 24) << 4, 28),
            28);
outlet_out = __SSAT(___SMMUL(in, lp) << 5, 28);
D += step;

Privacy

© 2024 Zrna Research