static void sliceplay_set(t_sliceplay *x) { t_garray *array; int arraysize, logloopsize; if(!(array = (t_garray *)pd_findbyclass(x->arrayname, garray_class))) { if (x->arrayname->s_name) pd_error(x, "sliceplay~: %s: no such array", x->arrayname->s_name); x->arraypointer = 0; } else if (!garray_getfloatwords(array, &arraysize, &x->arraypointer)) { pd_error(x, "%s: bad template for sliceplay~", x->arrayname->s_name); x->arraypointer = 0; } else { logloopsize = ilog2(arraysize-3); // arraysize must be at least loopsize + 1 sample x->loopsize = 1<<logloopsize; // loopsize is rounded to a power of two x->loopmask = x->loopsize - 1; // bitwise-and mask for loopsize garray_usedindsp(array); } }
/* on failure *bufsize is not modified */ t_word *cybuf_get(t_cybuf *c, t_symbol * name, int *bufsize, int indsp, int complain){ //in dsp = used in dsp, if (name && name != &s_){ t_garray *ap = (t_garray *)pd_findbyclass(name, garray_class); if (ap){ int bufsz; t_word *vec; if (garray_getfloatwords(ap, &bufsz, &vec)){ //c->c_len = garray_npoints(ap); if (indsp) garray_usedindsp(ap); if (bufsize) *bufsize = bufsz; return (vec); } else pd_error(c->c_owner, /* always complain */ "bad template of array '%s'", name->s_name); } else{ if(complain){ pd_error(c->c_owner, "no such array '%s'", name->s_name); }; }; } return (0); }
static void tabosc4_tilde_set(t_tabosc4_tilde *x, t_symbol *s) { t_garray *a; int npoints, pointsinarray; x->x_arrayname = s; if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) { if (*s->s_name) pd_error(x, "tabosc4~: %s: no such array", x->x_arrayname->s_name); x->x_vec = 0; } else if (!garray_getfloatwords(a, &pointsinarray, &x->x_vec)) { pd_error(x, "%s: bad template for tabosc4~", x->x_arrayname->s_name); x->x_vec = 0; } else if ((npoints = pointsinarray - 3) != (1 << ilog2(pointsinarray - 3))) { pd_error(x, "%s: number of points (%d) not a power of 2 plus three", x->x_arrayname->s_name, pointsinarray); x->x_vec = 0; garray_usedindsp(a); } else { x->x_fnpoints = npoints; x->x_finvnpoints = 1./npoints; garray_usedindsp(a); } }
static void bark_print(t_bark *x) { t_garray *a; if(!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) pd_error(x, "%s: no such array", x->x_arrayname->s_name); else if(!garray_getfloatwords(a, &x->x_array_points, &x->x_vec)) pd_error(x, "%s: bad template for bark", x->x_arrayname->s_name); else post("total frames: %i", (int)floor((x->x_array_points - x->window)/x->hop)); post("window size: %i", (int)x->window); post("hop: %i", x->hop); post("Bark spacing: %0.2f", x->barkSpacing); post("no. of filters: %i", x->numFilters); post("bin range: %i through %i (inclusive)", x->loBin, x->hiBin); post("low thresh: %0.2f, high thresh: %0.2f", x->loThresh, x->hiThresh); post("minvel: %f", x->minvel); post("mask periods: %i, mask decay: %0.2f", x->maskPeriods, x->maskDecay); post("debounce time: %0.2f", x->debounceTime); post("normalization: %i", x->normalize); post("filter averaging: %i", x->filterAvg); post("power spectrum: %i", x->powerSpectrum); post("loudness weights: %i", x->useWeights); post("spew mode: %i", x->spew); post("debug mode: %i", x->debug); }
int clear(t_trento *x) { t_garray *a; t_symbol *b_name; t_word *b_samples; int b_frames; x->b_valid = 0; b_name = x->b_name; int i; if (!(a = (t_garray *)pd_findbyclass(b_name,garray_class))) { if (b_name->s_name) pd_error(x,"trento: %s: no such array",b_name->s_name); return x->b_valid; } if (!garray_getfloatwords(a, &b_frames, &b_samples)) { pd_error(x, "trento: bad array for %s", b_name->s_name); return x->b_valid; } else { for (i=0;i<b_frames;i++) b_samples[i].w_float = 0.f; x->b_valid = 1; } return x->b_valid; }
int attach_array(t_trento *x) { t_garray *a; t_symbol *b_name; t_word *b_samples; int b_frames; x->b_valid = 0; b_name = x->b_name; if (!(a = (t_garray *)pd_findbyclass(b_name,garray_class))) { if (b_name->s_name) pd_error(x,"trento: %s: no such array",b_name->s_name); return x->b_valid; } if (!garray_getfloatwords(a, &b_frames, &b_samples)) { pd_error(x, "trento: bad array for %s", b_name->s_name); return x->b_valid; } else { x->b_valid = 1; x->b_frames = b_frames; x->b_samples = b_samples; x->buffy = a; } return x->b_valid; }
int init(t_trento *x) { t_garray *a; t_symbol *b_name; t_word *b_samples; int b_frames; x->b_valid = 0; b_name = x->b_name; x->loadcomplete = 1; x->graincomplete = 1; x->sr = sys_getsr(); if(x->sr <= 0) x->sr = 44100; int i; x->seed = time(NULL); srand(x->seed); if (!(a = (t_garray *)pd_findbyclass(b_name,garray_class))) { if (b_name->s_name) pd_error(x,"trento: %s: no such array",b_name->s_name); return x->b_valid; } if (!garray_getfloatwords(a, &b_frames, &b_samples)) { pd_error(x, "trento: bad array for %s", b_name->s_name); return x->b_valid; } else { for (i=0;i<b_frames;i++) b_samples[i].w_float = 0.f; x->b_valid = 1; } return x->b_valid; }
static void tabread4_float(t_tabread4 *x, t_float f) { t_garray *a; int npoints; t_word *vec; if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) pd_error(x, "%s: no such array", x->x_arrayname->s_name); else if (!garray_getfloatwords(a, &npoints, &vec)) pd_error(x, "%s: bad template for tabread4", x->x_arrayname->s_name); else if (npoints < 4) outlet_float(x->x_obj.ob_outlet, 0); else if (f <= 1) outlet_float(x->x_obj.ob_outlet, vec[1].w_float); else if (f >= npoints - 2) outlet_float(x->x_obj.ob_outlet, vec[npoints - 2].w_float); else { int n = f; float a, b, c, d, cminusb, frac; t_word *wp; if (n >= npoints - 2) n = npoints - 3; wp = vec + n; frac = f - n; a = wp[-1].w_float; b = wp[0].w_float; c = wp[1].w_float; d = wp[2].w_float; cminusb = c-b; outlet_float(x->x_obj.ob_outlet, b + frac * ( cminusb - 0.1666667f * (1.-frac) * ( (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)))); } }
// analyze the whole damn array static void specCentroid_bang(t_specCentroid *x) { int window, startSamp, lengthSamp; t_garray *a; if(!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) pd_error(x, "%s: no such array", x->x_arrayname->s_name); else if(!garray_getfloatwords(a, &x->x_arrayPoints, &x->x_vec)) pd_error(x, "%s: bad template for specCentroid", x->x_arrayname->s_name); else { startSamp = 0; lengthSamp = x->x_arrayPoints; if(lengthSamp > x->powersOfTwo[x->powTwoArrSize-1]) { post("WARNING: specCentroid: window truncated because requested size is larger than the current max_window setting. Use the max_window method to allow larger windows. Sizes of more than 131072 may produce unreliable results."); lengthSamp = x->powersOfTwo[x->powTwoArrSize-1]; window = lengthSamp; } specCentroid_analyze(x, startSamp, lengthSamp); } }
static void *specCentroid_new(t_symbol *s) { t_specCentroid *x = (t_specCentroid *)pd_new(specCentroid_class); int i; t_garray *a; x->x_centroid = outlet_new(&x->x_obj, &s_float); if(s) { x->x_arrayname = s; if(!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) ; else if(!garray_getfloatwords(a, &x->x_arrayPoints, &x->x_vec)) pd_error(x, "%s: bad template for specCentroid", x->x_arrayname->s_name); } else error("specCentroid: no array specified."); x->sr = 44100.0; x->window = 1; // should be a bogus size initially to force the proper resizes when a real _analyze request comes through x->windowFuncSize = 1; x->windowFunction = 4; // 4 is hann window x->powerSpectrum = 0; // choose mag (0) or power (1) spec in the specCentroid computation x->maxWindowSize = MAXWINDOWSIZE; // this seems to be the maximum size allowable by mayer_realfft(); x->powersOfTwo = (int *)t_getbytes(sizeof(int)); x->powersOfTwo[0] = 64; // must have at least this large of a window i=1; while(x->powersOfTwo[i-1] < x->maxWindowSize) { x->powersOfTwo = (int *)t_resizebytes(x->powersOfTwo, i*sizeof(int), (i+1)*sizeof(int)); x->powersOfTwo[i] = pow(2, i+6); // +6 because we're starting at 2**6 i++; } x->powTwoArrSize = i; x->signal_R = (t_sample *)t_getbytes(x->window*sizeof(t_sample)); for(i=0; i<x->window; i++) x->signal_R[i] = 0.0; x->blackman = (t_float *)t_getbytes(x->windowFuncSize*sizeof(t_float)); x->cosine = (t_float *)t_getbytes(x->windowFuncSize*sizeof(t_float)); x->hamming = (t_float *)t_getbytes(x->windowFuncSize*sizeof(t_float)); x->hann = (t_float *)t_getbytes(x->windowFuncSize*sizeof(t_float)); // initialize signal windowing functions tIDLib_blackmanWindow(x->blackman, x->windowFuncSize); tIDLib_cosineWindow(x->cosine, x->windowFuncSize); tIDLib_hammingWindow(x->hamming, x->windowFuncSize); tIDLib_hannWindow(x->hann, x->windowFuncSize); return (x); }
void fofsynth_usearray(t_symbol* s,int* points,t_word** vec) { t_garray *a; if (!(a = (t_garray *)pd_findbyclass(s, garray_class))) error("%s: no such array", s->s_name); else if (!garray_getfloatwords(a,points,vec)) error("%s: bad template for fof~", s->s_name); else garray_usedindsp(a); }
void granulesf_setbuf(t_granulesf *x, t_symbol *wavename, t_symbol *windowname) { t_garray *a; int frames; x->hosed = 0; x->wavebuf->b_frames = 0; x->windowbuf->b_frames = 0; x->wavebuf->b_nchans = 1;//unused, should kill x->windowbuf->b_nchans = 1; //unused, should kill x->b_nchans = 1; /* load up sample array */ if (!(a = (t_garray *)pd_findbyclass(wavename, garray_class))) { if (*wavename->s_name) pd_error(x, "granulesf~: %s: no such array", wavename->s_name); x->hosed = 1; } else if (!garray_getfloatwords(a, &frames, &x->wavebuf->b_samples)) { pd_error(x, "%s: bad template for granulesf~", wavename->s_name); x->hosed = 1; } else { x->wavebuf->b_frames = frames; x->b_nchans = 1; // Pd buffers are always mono (so far) garray_usedindsp(a); } /* load up envelope array*/ if (!(a = (t_garray *)pd_findbyclass(windowname, garray_class))) { if (*wavename->s_name) pd_error(x, "granulesf~: %s: no such array", windowname->s_name); x->hosed = 1; } else if (!garray_getfloatwords(a, &frames, &x->windowbuf->b_samples)) { pd_error(x, "%s: bad template for granulesf~", windowname->s_name); x->hosed = 1; } else { x->windowbuf->b_frames = frames; garray_usedindsp(a); } x->maxskip = x->wavebuf->b_frames - 1; }
void annealing_bang(t_annealing *x) { t_garray *a; int npoints; t_word *vec; if (!(a = (t_garray *)pd_findbyclass(x->arrayname, garray_class))) pd_error(x, "%s: no such array", x->arrayname->s_name); else if (!garray_getfloatwords(a, &npoints, &vec)) pd_error(x, "%s: bad template for annealing", x->arrayname->s_name); else { if (x->pIndex == -1) x->pIndex = (int)(arc4random() % npoints); if (x->pIndex < 0) x->pIndex = 0; else if (x->pIndex >= npoints) x->pIndex = npoints - 1; x->parent = vec[x->pIndex].w_float; int cIndex = (int)(arc4random() % npoints); // this uses random index // this uses a random index surrounding the current index // int cIndex = getNewIndex(x->pIndex, npoints); float child = vec[cIndex].w_float; float diff = child - x->parent; if (diff > 0) { x->pIndex = cIndex; x->parent = child; } else { if (x->temp < 0) x->temp = 1; float p = pow(M_E, ((diff * x->scalingFactor / x->temp))); // post("Difference is: %f. P is = %f", diff, p); float r = (rand() % 100) / 100.0; // float r = (arc4random() % 1000) / 1000.0; if (p > r) { // post("The switch to a lower solution happened. R is = %f", r); x->pIndex = cIndex; x->parent = child; } } // keep the best solution in case parent leaves it if (x->parent > x->bestSol) x->bestSol = x->parent; // post("PARENT: %f", x->parent); // post("BEST SOLUTION: %f", x->bestSol); outlet_float(x->parentOut, (npoints ? x->parent : 0)); outlet_float(x->bestOut, x->bestSol); } }
static void specCentroid_set(t_specCentroid *x, t_symbol *s) { t_garray *a; if(!(a = (t_garray *)pd_findbyclass(s, garray_class))) pd_error(x, "%s: no such array", s->s_name); else if(!garray_getfloatwords(a, &x->x_arrayPoints, &x->x_vec)) pd_error(x, "%s: bad template for specCentroid", s->s_name); else x->x_arrayname = s; }
static void pique_list(t_pique *x, t_symbol *s, int argc, t_atom *argv) { int npts = atom_getintarg(0, argc, argv); t_symbol *symreal = atom_getsymbolarg(1, argc, argv); t_symbol *symimag = atom_getsymbolarg(2, argc, argv); int npeak = atom_getintarg(3, argc, argv); int n; t_garray *a; t_word *fpreal, *fpimag; if (npts < 8 || npeak < 1) error("pique: bad npoints or npeak"); if (npeak > x->x_n) npeak = x->x_n; if (!(a = (t_garray *)pd_findbyclass(symreal, garray_class)) || !garray_getfloatwords(a, &n, &fpreal) || n < npts) error("%s: missing or bad array", symreal->s_name); else if (!(a = (t_garray *)pd_findbyclass(symimag, garray_class)) || !garray_getfloatwords(a, &n, &fpimag) || n < npts) error("%s: missing or bad array", symimag->s_name); else { int nfound, i; t_float *fpfreq = x->x_freq; t_float *fpamp = x->x_amp; t_float *fpampre = x->x_ampre; t_float *fpampim = x->x_ampim; pique_doit(npts, fpreal, fpimag, npeak, &nfound, fpfreq, fpamp, fpampre, fpampim, x->x_errthresh); for (i = 0; i < nfound; i++, fpamp++, fpfreq++, fpampre++, fpampim++) { t_atom at[5]; SETFLOAT(at, (t_float)i); SETFLOAT(at+1, *fpfreq); SETFLOAT(at+2, *fpamp); SETFLOAT(at+3, *fpampre); SETFLOAT(at+4, *fpampim); outlet_list(x->x_obj.ob_outlet, &s_list, 5, at); } } }
int load_two(t_trento *x, t_symbol *name1, t_symbol *name2) { t_garray *b1; t_garray *b2; int flag = 0; int frames1; int frames2; t_word *samples1; t_word *samples2; if (!(b1 = (t_garray *)pd_findbyclass(name1,garray_class))) { if (name1->s_name) pd_error(x,"trento: %s: no such array",name1->s_name); return flag; } if (!(b2 = (t_garray *)pd_findbyclass(name2,garray_class))) { if (name2->s_name) pd_error(x,"trento: %s: no such array",name2->s_name); return flag; } if (!garray_getfloatwords(b1, &frames1, &samples1)) { pd_error(x, "trento: bad array for %s", name1->s_name); return flag; } if(!garray_getfloatwords(b2, &frames2, &samples2)) { pd_error(x, "trento: bad array for %s", name2->s_name); return flag; } else { flag = 1; x->inc_frames1 = frames1; x->inc_frames2 = frames2; x->inc_samples1 = samples1; x->inc_samples2 = samples2; x->inc_buff1 = b1; x->inc_buff2 = b2; } return flag; }
static void *specCentroid_new(t_symbol *s) { t_specCentroid *x = (t_specCentroid *)pd_new(specCentroid_class); int i; t_garray *a; x->x_centroid = outlet_new(&x->x_obj, &s_float); if(s) { x->x_arrayname = s; if(!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) ; else if(!garray_getfloatwords(a, &x->x_array_points, &x->x_vec)) pd_error(x, "%s: bad template for specCentroid", x->x_arrayname->s_name); } else error("specCentroid: no array specified."); x->sr = 44100.0; x->window = 1; // should be a bogus size initially to force the proper resizes when a real _analyze request comes through x->window_func_size = 1; x->window_function = 3; x->power_spectrum = 0; x->max_window_size = 131072; // this seems to be the maximum size allowable by mayer_realfft(); x->powers_of_two = (int *)getbytes(sizeof(int)); x->powers_of_two[0] = 64; // must have at least this large of a window i=1; while(x->powers_of_two[i-1] < x->max_window_size) { x->powers_of_two = (int *)t_resizebytes(x->powers_of_two, i*sizeof(int), (i+1)*sizeof(int)); x->powers_of_two[i] = pow(2, i+6); // +6 because we're starting at 2**6 i++; } x->pow_two_arr_size = i; x->signal_R = (t_sample *)getbytes(x->window*sizeof(t_sample)); // initialize signal_R memset(x->signal_R, 0, x->window*sizeof(t_sample)); return (x); }
/* * max_ex_tab -- evaluate this table access * eptr is the name of the table and arg is the index we * have to put the result in optr * return 1 on error and 0 otherwise * * Arguments: * the expr object * table * the argument * the result pointer */ int max_ex_tab(struct expr *expr, fts_symbol_t s, struct ex_ex *arg, struct ex_ex *optr) { #ifdef PD t_garray *garray; int size, indx; t_word *wvec; if (!s || !(garray = (t_garray *)pd_findbyclass(s, garray_class)) || !garray_getfloatwords(garray, &size, &wvec)) { optr->ex_type = ET_FLT; optr->ex_flt = 0; pd_error(expr, "no such table '%s'", s->s_name); return (1); } optr->ex_type = ET_FLT; switch (arg->ex_type) { case ET_INT: indx = arg->ex_int; break; case ET_FLT: /* strange interpolation code deleted here -msp */ indx = arg->ex_flt; break; default: /* do something with strings */ pd_error(expr, "expr: bad argument for table '%s'\n", fts_symbol_name(s)); indx = 0; } if (indx < 0) indx = 0; else if (indx >= size) indx = size - 1; optr->ex_flt = wvec[indx].w_float; #else /* MSP */ /* * table lookup not done for MSP yet */ post("max_ex_tab: not complete for MSP yet!"); optr->ex_type = ET_FLT; optr->ex_flt = 0; #endif return (0); }
static void tabwrite_tilde_set(t_tabwrite_tilde *x, t_symbol *s) { t_garray *a; x->x_arrayname = s; if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) { if (*s->s_name) pd_error(x, "tabwrite~: %s: no such array", x->x_arrayname->s_name); x->x_vec = 0; } else if (!garray_getfloatwords(a, &x->x_nsampsintab, &x->x_vec)) { pd_error(x, "%s: bad template for tabwrite~", x->x_arrayname->s_name); x->x_vec = 0; } else garray_usedindsp(a); }
static void tabread_float(t_tabread *x, t_float f) { t_garray *a; int npoints; t_word *vec; if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) pd_error(x, "%s: no such array", x->x_arrayname->s_name); else if (!garray_getfloatwords(a, &npoints, &vec)) pd_error(x, "%s: bad template for tabread", x->x_arrayname->s_name); else { int n = f; if (n < 0) n = 0; else if (n >= npoints) n = npoints - 1; outlet_float(x->x_obj.ob_outlet, (npoints ? vec[n].w_float : 0)); } }
void mill_tilde_set(t_mill_tilde *x, t_symbol *s) { t_garray *a; x->arrayname = s; if (!(a = (t_garray *)pd_findbyclass(x->arrayname, garray_class))) { if (*s->s_name) pd_error(x, "tabread~: %s: no such array", x->arrayname->s_name); x->x_vec = 0; } else if (!garray_getfloatwords(a, &x->arraysize, &x->x_vec)) { pd_error(x, "%s: bad template for tabread~", x->arrayname->s_name); x->x_vec = 0; } else garray_usedindsp(a); }
void function_setbuf(t_function *x, t_symbol *wavename) { int frames; t_garray *a; x->b_frames = 0; x->b_nchans = 1; if (!(a = (t_garray *)pd_findbyclass(wavename, garray_class))) { if (*wavename->s_name) pd_error(x, "function~: %s: no such array", wavename->s_name); } else if (!garray_getfloatwords(a, &frames, &x->b_samples)) { pd_error(x, "%s: bad template for function~", wavename->s_name); } else { x->b_frames = frames; garray_usedindsp(a); // post("%d frames in buffer", x->b_frames); } }
void moop_tilde_set(t_moop *x, t_symbol *s) { t_garray *a; int points; x->x_arrayname = s; if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) { if (*s->s_name) pd_error(x, "moop~: %s: no such array", x->x_arrayname->s_name); x->x_buf.x_vec = 0; } else if (!garray_getfloatwords(a, &points, &x->x_buf.x_vec)) { pd_error(x, "%s: bad template for moop~", x->x_arrayname->s_name); x->x_buf.x_vec = 0; } else { x->x_buf.x_npoints = points - 4; garray_usedindsp(a); } }
static void tabwrite_float(t_tabwrite *x, t_float f) { int i, vecsize; t_garray *a; t_word *vec; if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) pd_error(x, "%s: no such array", x->x_arrayname->s_name); else if (!garray_getfloatwords(a, &vecsize, &vec)) pd_error(x, "%s: bad template for tabwrite", x->x_arrayname->s_name); else { int n = x->x_ft1; if (n < 0) n = 0; else if (n >= vecsize) n = vecsize-1; vec[n].w_float = f; garray_redraw(a); } }
/* void function_rcos(t_function *x) { int i; long b_frames; t_word *b_samples; t_symbol *wavename = x->wavename; int frames; t_garray *a; x->b_frames = 0; x->b_nchans = 1; // open array if (!(a = (t_garray *)pd_findbyclass(wavename, garray_class))) { if (*wavename->s_name) pd_error(x, "function~: %s: no such array", wavename->s_name); } else if (!garray_getfloatwords(a, &frames, &x->b_samples)) { pd_error(x, "%s: bad template for function~", wavename->s_name); } else { x->b_frames = frames; garray_usedindsp(a); } b_frames = x->b_frames; post("rcos generating %d frames", b_frames); // correct // put samples into array for(i=0;i<b_frames;i++){ x->b_samples[i].w_float = (t_float) (0.5 - 0.5 * cos(TWOPI * (t_float)i/(t_float)b_frames)); } if (!(a = (t_garray *)pd_findbyclass(x->wavename, garray_class))) { if (*x->wavename->s_name) pd_error(x, "function~: %s: no such array", x->wavename->s_name); } else { garray_redraw(a); } // printed samples are correct for(i=0;i<b_frames;i++){ post("%f", x->b_samples[i].w_float); } } */ void function_print(t_function *x) { int frames; t_garray *a; int i; x->b_frames = 0; x->b_nchans = 1; if (!(a = (t_garray *)pd_findbyclass(x->wavename, garray_class))) { if (*x->wavename->s_name) pd_error(x, "function~: %s: no such array", x->wavename->s_name); } else if (!garray_getfloatwords(a, &frames, &x->b_samples)) { pd_error(x, "%s: bad template for function~", x->wavename->s_name); } else { x->b_frames = frames; garray_usedindsp(a); for(i = 0; i < frames; i++){ post("%d: %f",i, x->b_samples[i].w_float); } } }
void bvplay_set(t_bvplay *x, t_symbol *wavename) { t_garray *a; int b_frames; t_word *b_samples; if (!(a = (t_garray *)pd_findbyclass(wavename, garray_class))) { if (*wavename->s_name) pd_error(x, "%s: %s: no such array",OBJECT_NAME,wavename->s_name); x->wavebuf->b_valid = 0; } else if (!garray_getfloatwords(a, &b_frames, &b_samples)) { pd_error(x, "%s: bad array for %s", wavename->s_name,OBJECT_NAME); x->wavebuf->b_valid = 0; } else { x->wavebuf->b_valid = 1; x->wavebuf->b_frames = b_frames; x->wavebuf->b_nchans = 1; x->wavebuf->b_samples = b_samples; garray_usedindsp(a); } }
static void specCentroid_analyze(t_specCentroid *x, t_floatarg start, t_floatarg n) { int i, j, oldWindow, window, windowHalf, startSamp, endSamp, lengthSamp; t_float dividend, divisor, centroid, *windowFuncPtr; t_sample *signal_I; t_garray *a; if(!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) pd_error(x, "%s: no such array", x->x_arrayname->s_name); else if(!garray_getfloatwords(a, &x->x_arrayPoints, &x->x_vec)) pd_error(x, "%s: bad template for specCentroid", x->x_arrayname->s_name); else { startSamp = start; startSamp = (startSamp<0)?0:startSamp; if(n) endSamp = startSamp + n-1; else endSamp = startSamp + x->window-1; if(endSamp > x->x_arrayPoints) endSamp = x->x_arrayPoints-1; lengthSamp = endSamp-startSamp+1; if(endSamp <= startSamp) { error("bad range of samples."); return; } if(lengthSamp > x->powersOfTwo[x->powTwoArrSize-1]) { post("WARNING: specCentroid: window truncated because requested size is larger than the current max_window setting. Use the max_window method to allow larger windows."); lengthSamp = x->powersOfTwo[x->powTwoArrSize-1]; window = lengthSamp; endSamp = startSamp + window - 1; } else { i=0; while(lengthSamp > x->powersOfTwo[i]) i++; window = x->powersOfTwo[i]; } windowHalf = window * 0.5; if(x->window != window) { oldWindow = x->window; x->window = window; x->signal_R = (t_sample *)t_resizebytes(x->signal_R, oldWindow*sizeof(t_sample), x->window*sizeof(t_sample)); } if(x->windowFuncSize != lengthSamp) { x->blackman = (t_float *)t_resizebytes(x->blackman, x->windowFuncSize*sizeof(t_float), lengthSamp*sizeof(t_float)); x->cosine = (t_float *)t_resizebytes(x->cosine, x->windowFuncSize*sizeof(t_float), lengthSamp*sizeof(t_float)); x->hamming = (t_float *)t_resizebytes(x->hamming, x->windowFuncSize*sizeof(t_float), lengthSamp*sizeof(t_float)); x->hann = (t_float *)t_resizebytes(x->hann, x->windowFuncSize*sizeof(t_float), lengthSamp*sizeof(t_float)); x->windowFuncSize = lengthSamp; tIDLib_blackmanWindow(x->blackman, x->windowFuncSize); tIDLib_cosineWindow(x->cosine, x->windowFuncSize); tIDLib_hammingWindow(x->hamming, x->windowFuncSize); tIDLib_hannWindow(x->hann, x->windowFuncSize); } // create local memory signal_I = (t_sample *)t_getbytes((windowHalf+1)*sizeof(t_sample)); // construct analysis window for(i=0, j=startSamp; j<=endSamp; i++, j++) x->signal_R[i] = x->x_vec[j].w_float; // set window function windowFuncPtr = x->hann; //default case to get rid of compile warning switch(x->windowFunction) { case 0: break; case 1: windowFuncPtr = x->blackman; break; case 2: windowFuncPtr = x->cosine; break; case 3: windowFuncPtr = x->hamming; break; case 4: windowFuncPtr = x->hann; break; default: break; }; // if windowFunction == 0, skip the windowing (rectangular) if(x->windowFunction>0) for(i=0; i<lengthSamp; i++, windowFuncPtr++) x->signal_R[i] *= *windowFuncPtr; // then zero pad the end for(; i<window; i++) x->signal_R[i] = 0.0; mayer_realfft(window, x->signal_R); tIDLib_realfftUnpack(window, windowHalf, x->signal_R, signal_I); tIDLib_power(windowHalf+1, x->signal_R, signal_I); // power spectrum sometimes generates lower scores than magnitude. make it optional. if(!x->powerSpectrum) tIDLib_mag(windowHalf+1, x->signal_R); dividend=0; divisor=0; centroid=0; for(i=0; i<=windowHalf; i++) dividend += x->signal_R[i]*(i*(x->sr/window)); // weight by bin freq for(i=0; i<=windowHalf; i++) divisor += x->signal_R[i]; if(divisor==0) divisor = 1; // don't divide by zero centroid = dividend/divisor; outlet_float(x->x_centroid, centroid); // free local memory t_freebytes(signal_I, (windowHalf+1)*sizeof(t_sample)); } }
static void *bark_new(t_symbol *s, t_floatarg w, t_floatarg h, t_floatarg bs) { t_bark *x = (t_bark *)pd_new(bark_class); int i, isPow2; t_garray *a; x->x_timeOut = outlet_new(&x->x_obj, &s_float); x->x_growthOut = outlet_new(&x->x_obj, &s_float); x->x_outputList = outlet_new(&x->x_obj, gensym("list")); if(bs) { x->x_arrayname = s; if(!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) ; else if(!garray_getfloatwords(a, &x->x_array_points, &x->x_vec)) pd_error(x, "%s: bad template for bark", x->x_arrayname->s_name); isPow2 = (int)w && !( ((int)w-1) & (int)w ); if( !isPow2 ) { error("requested window size is not a power of 2. using default value of 2048 instead."); x->window = 2048; } else x->window = w; if(h<0) { error("hop value must be > 0. default value of 128 samples used instead."); x->hop = 128; } else x->hop = h; x->barkSpacing = bs; } else if(h) { x->x_arrayname = s; if(!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) ; else if(!garray_getfloatwords(a, &x->x_array_points, &x->x_vec)) pd_error(x, "%s: bad template for bark", x->x_arrayname->s_name); isPow2 = (int)w && !( ((int)w-1) & (int)w ); if( !isPow2 ) { error("requested window size is not a power of 2. using default value of 2048 instead."); x->window = 2048; } else x->window = w; if(h<0) { error("hop value must be > 0. default value of 128 samples used instead."); x->hop = 128; } else x->hop = h; x->barkSpacing = 0.5; } else if(w) { x->x_arrayname = s; if(!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) ; else if(!garray_getfloatwords(a, &x->x_array_points, &x->x_vec)) pd_error(x, "%s: bad template for bark", x->x_arrayname->s_name); isPow2 = (int)w && !( ((int)w-1) & (int)w ); if( !isPow2 ) { error("requested window size is not a power of 2. using default value of 2048 instead."); x->window = 2048; } else x->window = w; x->hop = 128; x->barkSpacing = 0.5; } else if(s) { x->x_arrayname = s; if(!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) ; else if(!garray_getfloatwords(a, &x->x_array_points, &x->x_vec)) pd_error(x, "%s: bad template for bark", x->x_arrayname->s_name); x->window = 2048; x->hop = 128; x->barkSpacing = 0.5; } else { error("bark: no array specified."); x->window = 2048; x->hop = 128; x->barkSpacing = 0.5; } x->debug = 0; x->sr = 44100.0; x->n = BLOCKSIZE; x->windowFunction = 4; // 4 is hann window x->powerSpectrum = 1; // choose mag (0) or power (1) spec x->normalize = 0; x->filterAvg = 0; x->loThresh = 3; x->hiThresh = 7; x->minvel = 1.0; x->haveHit = 0; x->debounceTime = 20; x->debounceSamp = x->debounceTime*0.001*x->sr; x->debounceActive = -1; x->maskDecay = 0.7; x->maskPeriods = 4; x->numFilters = 0; x->prevTotalGrowth = 0.0; x->useWeights = 0; x->spew = 0; x->signalBuf = (t_sample *)t_getbytes(x->window * sizeof(t_sample)); x->analysisBuf = (t_float *)t_getbytes(x->window * sizeof(t_float)); for(i=0; i<x->window; i++) { x->signalBuf[i] = 0.0; x->analysisBuf[i] = 0.0; } x->blackman = (t_float *)t_getbytes(x->window*sizeof(t_float)); x->cosine = (t_float *)t_getbytes(x->window*sizeof(t_float)); x->hamming = (t_float *)t_getbytes(x->window*sizeof(t_float)); x->hann = (t_float *)t_getbytes(x->window*sizeof(t_float)); // initialize signal windowing functions tIDLib_blackmanWindow(x->blackman, x->window); tIDLib_cosineWindow(x->cosine, x->window); tIDLib_hammingWindow(x->hamming, x->window); tIDLib_hannWindow(x->hann, x->window); // grab memory x->x_filterbank = (t_filter *)t_getbytes(0); x->x_filterFreqs = (t_float *)t_getbytes(0); x->numFilters = tIDLib_getBarkFilterSpacing(&x->x_filterFreqs, x->sizeFilterFreqs, x->barkSpacing, x->sr); x->sizeFilterFreqs = x->numFilters+2; tIDLib_createFilterbank(x->x_filterFreqs, &x->x_filterbank, 0, x->numFilters, x->window, x->sr); x->loBin = 0; x->hiBin = x->numFilters-1; x->mask = (t_float *)t_getbytes(x->numFilters*sizeof(t_float)); x->growth = (t_float *)t_getbytes(x->numFilters*sizeof(t_float)); x->numPeriods = (int *)t_getbytes(x->numFilters*sizeof(int)); x->growthList = (t_atom *)t_getbytes(x->numFilters*sizeof(t_atom)); x->loudWeights = (t_float *)t_getbytes(x->numFilters*sizeof(t_float)); for(i=0; i<x->numFilters; i++) { x->mask[i] = 0.0; x->growth[i] = 0.0; x->numPeriods[i] = 0.0; SETFLOAT(x->growthList+i, 0.0); x->loudWeights[i] = 0.0; } bark_create_loudness_weighting(x); post("bark 0.0.6: window size: %i, hop: %i", (int)x->window, x->hop); return (x); }
static void bark_analyze(t_bark *x, t_floatarg startTime, t_floatarg endTime) { int i, j, window, windowHalf, hop, nFrames, frame, sampRange, startSamp, endSamp; t_float totalGrowth, totalVel, *windowFuncPtr; t_garray *a; if(!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) pd_error(x, "%s: no such array", x->x_arrayname->s_name); else if(!garray_getfloatwords(a, &x->x_array_points, &x->x_vec)) pd_error(x, "%s: bad template for bark", x->x_arrayname->s_name); else { window = x->window; windowHalf = window*0.5; hop = x->hop; if(endTime) { startSamp = floor(startTime*x->sr); endSamp = floor(endTime*x->sr); if(startSamp>=0 && endSamp<x->x_array_points) sampRange = endSamp-startSamp+1; else { error("invalid time range"); return; } } else { sampRange = x->x_array_points; startSamp = 0; endSamp = x->x_array_points-1; } nFrames = floor((sampRange-window)/hop); // init mask to zero for(i=0; i<x->numFilters; i++) x->mask[i] = 0.0; for(frame=0; frame<nFrames; frame++) { // fill buffer with <window> samples for(i=0, j=frame*hop+startSamp; i<window; i++, j++) x->signalBuf[i] = x->x_vec[j].w_float; totalGrowth = 0.0; totalVel = 0.0; // set window function windowFuncPtr = x->hann; //default case to get rid of compile warning switch(x->windowFunction) { case 0: break; case 1: windowFuncPtr = x->blackman; break; case 2: windowFuncPtr = x->cosine; break; case 3: windowFuncPtr = x->hamming; break; case 4: windowFuncPtr = x->hann; break; default: break; }; // if windowFunction == 0, skip the windowing (rectangular) if(x->windowFunction>0) for(i=0; i<window; i++, windowFuncPtr++) x->analysisBuf[i] = x->signalBuf[i] * *windowFuncPtr; else for(i=0; i<window; i++, windowFuncPtr++) x->analysisBuf[i] = x->signalBuf[i]; mayer_realfft(window, x->analysisBuf); // calculate the power spectrum in place. we'll overwrite the first N/2+1 points in x->analysisBuf with the magnitude spectrum, as this is all that's used below in filterbank_multiply() x->analysisBuf[0] = x->analysisBuf[0] * x->analysisBuf[0]; // DC x->analysisBuf[windowHalf] = x->analysisBuf[windowHalf] * x->analysisBuf[windowHalf]; // Nyquist for(i=(window-1), j=1; i>windowHalf; i--, j++) x->analysisBuf[j] = (x->analysisBuf[j]*x->analysisBuf[j]) + (x->analysisBuf[i]*x->analysisBuf[i]); // optional use of power/magnitude spectrum if(!x->powerSpectrum) for(i=0; i<=windowHalf; i++) x->analysisBuf[i] = sqrt(x->analysisBuf[i]); tIDLib_filterbankMultiply(x->analysisBuf, x->normalize, x->filterAvg, x->x_filterbank, x->numFilters); // optional loudness weighting if(x->useWeights) for(i=0; i<x->numFilters; i++) x->analysisBuf[i] *= x->loudWeights[i]; for(i=0; i<x->numFilters; i++) totalVel += x->analysisBuf[i]; // init growth list to zero for(i=0; i<x->numFilters; i++) x->growth[i] = 0.0; for(i=0; i<x->numFilters; i++) { // from p.3 of Puckette/Apel/Zicarelli, 1998 // salt divisor with + 1.0e-15 in case previous power was zero if(x->analysisBuf[i] > x->mask[i]) x->growth[i] = x->analysisBuf[i]/(x->mask[i] + 1.0e-15) - 1.0; if(i>=x->loBin && i<=x->hiBin && x->growth[i]>0) totalGrowth += x->growth[i]; SETFLOAT(x->growthList+i, x->growth[i]); } if(frame*hop+startSamp >= x->debounceActive) x->debounceActive = -1; if(totalVel >= x->minvel && totalGrowth > x->hiThresh && !x->haveHit && x->debounceActive < 0) { if(x->debug) post("peak: %f", totalGrowth); x->haveHit = 1; x->debounceActive = frame*hop+startSamp + x->debounceSamp; } else if(x->haveHit && x->loThresh>0 && totalGrowth < x->loThresh) // if loThresh is an actual value (not -1), then wait until growth drops below that value before reporting attack { if(x->debug) post("drop: %f", totalGrowth); x->haveHit = 0; // don't output data if spew will do it anyway below if(!x->spew) { outlet_list(x->x_outputList, 0, x->numFilters, x->growthList); outlet_float(x->x_growthOut, totalGrowth); } // add half a window of samples as a fudge factor. note that since this NRT and we can look into the future, all attack reports will be roughly a half window EARLY. in RT, everything is a half window LATE because the point of reference is the END of the window. here, it's the BEGINNING of the window. outlet_float(x->x_timeOut, (frame*hop+startSamp + windowHalf)/x->sr); } else if(x->haveHit && x->loThresh<0 && totalGrowth < x->prevTotalGrowth) // if loThresh == -1, report attack as soon as growth shows any decay at all { if(x->debug) post("drop: %f", totalGrowth); x->haveHit = 0; // don't output data if spew will do it anyway below if(!x->spew) { outlet_list(x->x_outputList, 0, x->numFilters, x->growthList); outlet_float(x->x_growthOut, totalGrowth); } // add half a window of samples as a fudge factor. note that since this NRT and we can look into the future, all attack reports will be roughly a half window EARLY. in RT, everything is a half window LATE because the point of reference is the END of the window. here, it's the BEGINNING of the window. outlet_float(x->x_timeOut, (frame*hop+startSamp + windowHalf)/x->sr); } if(x->spew) { outlet_list(x->x_outputList, 0, x->numFilters, x->growthList); outlet_float(x->x_growthOut, totalGrowth); } // update mask for(i=0; i<x->numFilters; i++) { if(x->analysisBuf[i] > x->mask[i]) { x->mask[i] = x->analysisBuf[i]; x->numPeriods[i] = 0; } else if(++x->numPeriods[i] >= x->maskPeriods) x->mask[i] *= x->maskDecay; } x->prevTotalGrowth = totalGrowth; } } post("analyzed %i frames", nFrames); }
static void specCentroid_analyze(t_specCentroid *x, t_floatarg start, t_floatarg n) { int i, j, old_window, window, window_half, start_samp, end_samp, length_samp; float *window_func_ptr; float dividend, divisor, centroid; t_sample *signal_I; t_garray *a; if(!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) pd_error(x, "%s: no such array", x->x_arrayname->s_name); else if(!garray_getfloatwords(a, &x->x_array_points, &x->x_vec)) pd_error(x, "%s: bad template for specCentroid", x->x_arrayname->s_name); else { start_samp = start; if(start_samp < 0) start_samp = 0; if(n) end_samp = start_samp + n-1; else end_samp = start_samp + x->window-1; if(end_samp > x->x_array_points) end_samp = x->x_array_points-1; length_samp = end_samp - start_samp + 1; if(end_samp <= start_samp) { error("bad range of samples."); return; } if(length_samp > x->powers_of_two[x->pow_two_arr_size-1]) { post("WARNING: specCentroid: window truncated because requested size is larger than the current max_window setting. Use the max_window method to allow larger windows. Sizes of more than 131072 may produce unreliable results."); length_samp = x->powers_of_two[x->pow_two_arr_size-1]; window = length_samp; end_samp = start_samp + window - 1; } else { i=0; while(length_samp > x->powers_of_two[i]) i++; window = x->powers_of_two[i]; } window_half = window * 0.5; if(x->window != window) { old_window = x->window; x->window = window; x->signal_R = (t_sample *)t_resizebytes(x->signal_R, old_window*sizeof(t_sample), window*sizeof(t_sample)); } if(x->window_func_size != length_samp) { x->blackman = (float *)t_resizebytes(x->blackman, x->window_func_size*sizeof(float), length_samp*sizeof(float)); x->cosine = (float *)t_resizebytes(x->cosine, x->window_func_size*sizeof(float), length_samp*sizeof(float)); x->hamming = (float *)t_resizebytes(x->hamming, x->window_func_size*sizeof(float), length_samp*sizeof(float)); x->hann = (float *)t_resizebytes(x->hann, x->window_func_size*sizeof(float), length_samp*sizeof(float)); x->window_func_size = length_samp; specCentroid_blackman_window(x->blackman, x->window_func_size); specCentroid_cosine_window(x->cosine, x->window_func_size); specCentroid_hamming_window(x->hamming, x->window_func_size); specCentroid_hann_window(x->hann, x->window_func_size); } // create local memory signal_I = (t_sample *)getbytes(window_half*sizeof(t_sample)); // construct analysis window for(i=0, j=start_samp; j<=end_samp; i++, j++) x->signal_R[i] = x->x_vec[j].w_float; // set window window_func_ptr = x->hann; //default case to get rid of compile warning switch(x->window_function) { case 0: window_func_ptr = x->blackman; break; case 1: window_func_ptr = x->cosine; break; case 2: window_func_ptr = x->hamming; break; case 3: window_func_ptr = x->hann; break; default: break; }; // then multiply against the chosen window for(i=0; i<length_samp; i++, window_func_ptr++) x->signal_R[i] *= *window_func_ptr; // then zero pad the end for(; i<window; i++) x->signal_R[i] = 0.0; mayer_realfft(window, x->signal_R); specCentroid_realfft_unpack(window, window_half, x->signal_R, signal_I); specCentroid_power(window_half, x->signal_R, signal_I); if(!x->power_spectrum) specCentroid_mag(window_half, x->signal_R); dividend=0; divisor=0; centroid=0; for(i=0; i<window_half; i++) dividend += x->signal_R[i]*(i*(x->sr/window)); // weight by bin freq for(i=0; i<window_half; i++) divisor += x->signal_R[i]; if(divisor==0) divisor = 1; // don't divide by zero centroid = dividend/divisor; outlet_float(x->x_centroid, centroid); // free local memory t_freebytes(signal_I, window_half*sizeof(t_sample)); } }