int AmpFollower::transient(int *inL, int *inR, int buffSize) { //peak squared method uses output of one level detector as input to another for(int i = 0; i < buffSize; i++) { int amp = abs16(inL[i]); lvlEst1 = peakDetector1.process(amp); lvlEst2 = peakDetector2.process(lvlEst1); //the amplitude is then averaged over a buffer transientAvg += lvlEst2; } //divide transient average by buffer size, this is equal to multiplying by 1/256 which is 128 transientAvg = mult16(transientAvg, 128); //examine slope of averages, if it is greater than the previous slope, a transient has started transientSlope = transientAvg - prevTransientAvg; //if the slope is greater than the previous slope a transient will have started if(transientSlope > prevTransientSlope) { if(transientLock == 0) { transientLock = 1; //set transient lock return 1; } } //when the slope is less than the previous slope we've ended our transient and can start searching for new ones if(transientSlope < prevTransientSlope) transientLock = 0; //update storage of previous values prevTransientAvg = transientAvg; prevTransientSlope = transientSlope; return 0; }
ssize_t ptrFromStr(const char *src, size_t *len, ptr **dst, bool external) { size_t base = 0; const char *p = src; atommem(sizeof(ptr)); **dst = ptr_nil; if (GDK_STRNIL(src)) return 1; while (GDKisspace(*p)) p++; if (external && strncmp(p, "nil", 3) == 0) { p += 3; } else { if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { p += 2; } if (!num16(*p)) { GDKerror("not a number\n"); return -1; } while (num16(*p)) { if (base >= ((size_t) 1 << (8 * sizeof(size_t) - 4))) { GDKerror("overflow\n"); return -1; } base = mult16(base) + base16(*p); p++; } **dst = (ptr) base; } while (GDKisspace(*p)) p++; return (ssize_t) (p - src); }
int AmpFollower::rmsEnvelope(int inL, int inR) { int amp = max(abs16(inL), abs16(inR)); rmsLevel += mult16(rmsb0, (mult16(amp, amp) - rmsLevel)); return sqrt(rmsLevel); //todo: double check this sqrt function and make sure it properly operates on fixed point }