pDtct

fast pitch detector
Author: Remco van der Most
License: BSD
Github: sss/conv/pDtct.axo

Inlets

frac32buffer in

frac32 damp

Outlets

frac32 outputs the detected pitch

frac32buffer outputs a highpassed version of the input, removing everything below the detected pitch

Parameters

frac32.u.map pitch detections that are above treshold value will be ommited. I guess around 1 a 2 is best approximation.

int32 sets the size of available zero-crossing times that set the reference pitch for allowed pitch values. 7 has the most significance, but costs more cpu

frac32.s.map dampens the incoming audio. When high, allows the pitchfollower to also try to follow higher frequencies (/harmonics) if these are present in the signal. Set this to -12 for best root approximation.

Declaration
int32_t prv;
uint32_t Prv;
uint32_t cur;
int32_t pitch;
uint32_t writepos;
int32_t array[128];
uint32_t Array[128];
int64_t TM;
int32_t TS;
bool zc;
uint32_t size;
uint32_t LM;
int cnt;
int32_t tmp;
int32_t lp1;
int32_t lp2;
int32_t hp;
int32_t HP1;
int32_t HP2;
uint32_t Time;
int i;

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

int32_t FTOM(int32_t freq) {
  int32_t ptch;
  int32_t mid;
  MTOFEXTENDED(0, mid);
  LOG(mid);
  mid = out;

  int32_t to;
  LOG(freq);
  to = out;
  return ptch = (to - mid >> 1) * 3;
};
Init
pitch = 0;
Control Rate
size = 1 << param_size;
LM = size - 1;
tmp = 0;
for (i = 0; i < 127; i++) {
  // tmp+=array[i]-tmp>>8;
}
int32_t damp;
MTOF(param_damp + inlet_damp, damp)

for (i = 0; i < size; i++) {
  int32_t diff = tmp - array[i];
  diff = diff > 0 ? diff : -diff;
  if (diff < (param_tresh)) {
    int k = (i + writepos) & LM;
    cur = Array[k];
    TM = Array[k] - Prv;
    TS = TM < 0 ? (1 << 32) + TM : TM;
    Prv = Array[k];
  }
}

pitch = FTOM((((int64_t)(268570720)) / TS << 4));
outlet_pitch = pitch;
int32_t frq;
MTOF(outlet_pitch, frq)
Audio Rate
lp1 = ___SMMLA(inlet_in - lp1 << 1, damp, lp1);
lp2 = ___SMMLA(lp1 - lp2 << 1, damp, lp2);
hp += (lp2 - hp) >> 9;
int32_t lh = lp2 - hp;
if ((lh >= 0) && (prv < 0)) {
  int32_t chg = lh - prv;
  tmp += chg - tmp >> 4;
  array[writepos] = chg;
  Array[writepos] = Time;
  writepos = (writepos + 1) & LM;
}
Time += 1;
prv = lh;
HP1 = ___SMMLA(inlet_in - HP1 << 1, frq << 2, HP1);
int32_t HT = (inlet_in - HP1);
HP2 = ___SMMLA(HT - HP2 << 1, frq << 2, HP2);
HT -= HP2;
outlet_out = HT;

Privacy

© 2024 Zrna Research