From b418fb91e7bb45d7b5f1eb8b19703441ae94eb13 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 9 Feb 2006 16:18:39 +0000 Subject: got everything building and working, including building single-object/single-file objects with a shared dylib. Now got to get it integrated into the build system svn path=/trunk/externals/fftease/; revision=4574 --- cavoc27~.c | 675 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 675 insertions(+) create mode 100644 cavoc27~.c (limited to 'cavoc27~.c') diff --git a/cavoc27~.c b/cavoc27~.c new file mode 100644 index 0000000..8fbca59 --- /dev/null +++ b/cavoc27~.c @@ -0,0 +1,675 @@ +#include "MSPd.h" + +#include "fftease.h" + +#if MSP +void *cavoc27_class; +#endif + +#if PD +static t_class *cavoc27_class; +#endif + +#define OBJECT_NAME "cavoc27~" + +/* NOTE THIS IS A MORE COMPLEX CA WITH 3 DIFFERENT STATES */ + +typedef struct _cavoc27 +{ +#if MSP + t_pxobject x_obj; +#endif +#if PD + t_object x_obj; + float x_f; +#endif + int R; + int N; + int N2; + int Nw; + int Nw2; + int D; + int i; + int inCount; + float *Wanal; + float *Wsyn; + float *input; + float *Hwin; + float *buffer; + float *channel; + float *ichannel; //for interpolation + float *tmpchannel; // for spectrum capture + float *output; + float frame_duration; + int max_bin; + + // for CAVOC2 + + float fundamental; + float *last_frame; + short left; + short right; + short center; + short *rule; + float density; + float start_breakpoint; + int hold_frames; + int frames_left; + int set_count; + short interpolate_flag; + short capture_flag; + short capture_lock; + // FFT + // for convert + + float *c_lastphase_in; + float *c_lastphase_out; + float c_fundamental; + float c_factor_in; + float c_factor_out; + float mult; + float *trigland; + int *bitshuffle; + // + void *list_outlet; + t_atom *list_data; + short mute; + int winfac;//window factor + int overlap;//overlap factor + int vs;//vector size + float hold_time;//hold time in seconds +} t_cavoc27; + +void *cavoc27_new(t_symbol *s, int argc, t_atom *argv); +t_int *offset_perform(t_int *w); +t_int *cavoc27_perform(t_int *w); +void cavoc27_dsp(t_cavoc27 *x, t_signal **sp, short *count); +void cavoc27_assist(t_cavoc27 *x, void *b, long m, long a, char *s); +void cavoc27_free( t_cavoc27 *x); +int cavoc27_apply_rule( short left, short right, short center, short *rule); +float cavoc27_randf(float min, float max); +void cavoc27_rule (t_cavoc27 *x, t_symbol *msg, short argc, t_atom *argv); +void cavoc27_density (t_cavoc27 *x, t_floatarg density); +void cavoc27_hold_time (t_cavoc27 *x, t_floatarg hold_time); +void cavoc27_interpolate (t_cavoc27 *x, t_floatarg interpolate); +void cavoc27_capture_spectrum (t_cavoc27 *x, t_floatarg flag ); +void cavoc27_capture_lock (t_cavoc27 *x, t_floatarg toggle ); +void cavoc27_retune (t_cavoc27 *x, t_floatarg min, t_floatarg max); +void cavoc27_mute (t_cavoc27 *x, t_floatarg toggle); +void cavoc27_init(t_cavoc27 *x,short initialized); +void cavoc27_rand_set_spectrum(t_cavoc27 *x); +void cavoc27_rand_set_rule(t_cavoc27 *x); +void cavoc27_fftinfo(t_cavoc27 *x); +void cavoc27_overlap(t_cavoc27 *x, t_floatarg f); +void cavoc27_winfac(t_cavoc27 *x, t_floatarg f); + +#if MSP +void main(void) +{ + setup((t_messlist **)&cavoc27_class, (method)cavoc27_new, (method)cavoc27_free, + (short)sizeof(t_cavoc27), 0, A_GIMME, 0); + addmess((method)cavoc27_dsp, "dsp", A_CANT, 0); + addmess((method)cavoc27_assist,"assist",A_CANT,0); + addmess((method)cavoc27_rule,"rule",A_GIMME,0); + addmess((method)cavoc27_density,"density",A_FLOAT,0); + addmess((method)cavoc27_hold_time,"hold_time",A_FLOAT,0); + addmess((method)cavoc27_interpolate,"interpolate",A_FLOAT,0); + addmess((method)cavoc27_overlap,"overlap",A_FLOAT,0); + addmess((method)cavoc27_winfac,"winfac",A_FLOAT,0); + addmess((method)cavoc27_fftinfo,"fftinfo",0); + addmess((method)cavoc27_retune,"retune",A_FLOAT,A_FLOAT,0); + addmess((method)cavoc27_capture_spectrum,"capture_spectrum",A_FLOAT,0); + addmess((method)cavoc27_mute,"mute",A_FLOAT,0); + dsp_initclass(); + post("%s %s",OBJECT_NAME,FFTEASE_ANNOUNCEMENT); +} +#endif +#if PD +/* Pd Initialization */ +void cavoc27_tilde_setup(void) +{ + cavoc27_class = class_new(gensym("cavoc27~"), (t_newmethod)cavoc27_new, + (t_method)cavoc27_free ,sizeof(t_cavoc27), 0,A_GIMME,0); + CLASS_MAINSIGNALIN(cavoc27_class, t_cavoc27, x_f); + class_addmethod(cavoc27_class, (t_method)cavoc27_dsp, gensym("dsp"), 0); + class_addmethod(cavoc27_class, (t_method)cavoc27_mute, gensym("mute"), A_FLOAT,0); + class_addmethod(cavoc27_class, (t_method)cavoc27_rule, gensym("rule"), A_GIMME,0); + class_addmethod(cavoc27_class, (t_method)cavoc27_density, gensym("density"), A_DEFFLOAT,0); + class_addmethod(cavoc27_class, (t_method)cavoc27_hold_time, gensym("hold_time"), A_DEFFLOAT,0); + class_addmethod(cavoc27_class, (t_method)cavoc27_interpolate, gensym("interpolate"), A_DEFFLOAT, 0); + class_addmethod(cavoc27_class, (t_method)cavoc27_capture_spectrum, gensym("capture_spectrum"), A_FLOAT, 0); + class_addmethod(cavoc27_class, (t_method)cavoc27_retune, gensym("retune"), A_DEFFLOAT,A_DEFFLOAT,0); + class_addmethod(cavoc27_class, (t_method)cavoc27_overlap, gensym("overlap"), A_FLOAT, 0); + class_addmethod(cavoc27_class, (t_method)cavoc27_winfac, gensym("winfac"), A_FLOAT, 0); + class_addmethod(cavoc27_class, (t_method)cavoc27_fftinfo, gensym("fftinfo"), 0); + post("%s %s",OBJECT_NAME,FFTEASE_ANNOUNCEMENT); +} +#endif + +void cavoc27_rand_set_rule(t_cavoc27 *x) +{ +int i; +float rval; + for( i = 0; i < 27; i++ ){ + rval = cavoc27_randf(0.0,1.0); + if( rval < .333 ) + x->rule[i] = 0; + else if(rval < .666 ) + x->rule[i] = 1; + else x->rule[i] = 2; + } +} + +void cavoc27_retune(t_cavoc27 *x, t_floatarg min, t_floatarg max) +{ + int i; + + if( max <= 0 || min <= 0 || min > max ){ + error("bad values for min and max multipliers"); + return; + } + if( min < .1 ) + min = 0.1; + if( max > 2.0 ) + max = 2.0; + for( i = 0; i < x->N2 + 1; i++ ){ + x->channel[ i * 2 + 1 ] = x->c_fundamental * (float) (i / 2) * cavoc27_randf(min, max); + } + +} + +void cavoc27_density(t_cavoc27 *x, t_floatarg density) +{ + int i; + if( density < 0.0001 ){ + density = .0001; + } else if( density > .9999 ){ + density = 1.0; + } + x->density = density; + x->start_breakpoint = 1.0 - x->density; + for( i = 0; i < x->N2 + 1; i++ ){ + if( cavoc27_randf(0.0, 1.0) > x->start_breakpoint ){ + if( cavoc27_randf(0.0,1.0) > 0.5 ){ + x->channel[ i * 2 ] = 1; + } + else { + x->channel[ i * 2 ] = 2; + } + ++(x->set_count); + } else { + x->channel[ i * 2 ] = 0; + } + } + for( i = 0; i < x->N+2; i++ ){ + x->last_frame[i] = x->channel[i]; + } +} + +void cavoc27_mute (t_cavoc27 *x, t_floatarg toggle) +{ + x->mute = (short)toggle; +} + +void cavoc27_hold_time(t_cavoc27 *x, t_floatarg hold_time) +{ + + if(hold_time <= 0){ + post("illegal hold time %f",hold_time); + return; + } + x->hold_time = hold_time; + if(! x->frame_duration){ + error("%s: zero frame duration",OBJECT_NAME); + x->frame_duration = .15; + } + x->hold_frames = (int) ( (hold_time/1000.0) / x->frame_duration); + if( x->hold_frames < 1 ) + x->hold_frames = 1; + // x->frames_left = x->hold_frames; + +} + +void cavoc27_interpolate(t_cavoc27 *x, t_floatarg flag) +{ + x->interpolate_flag = (short) flag; +} + +void cavoc27_capture_spectrum(t_cavoc27 *x, t_floatarg flag ) +{ +// now identical to capture_lock + x->capture_lock = (short)flag; +} + +void cavoc27_capture_lock(t_cavoc27 *x, t_floatarg flag ) +{ + x->capture_lock = (short)flag; +} + +void cavoc27_rule (t_cavoc27 *x, t_symbol *msg, short argc, t_atom *argv) +{ + int i; + short *rule = x->rule; + if( argc != 27 ){ + error("the rule must be size 18"); + return; + } + + for( i = 0; i < 27; i++ ){ + rule[i] = (short) atom_getfloatarg( i, argc, argv); + } +} + +void cavoc27_free( t_cavoc27 *x ){ +#if MSP + dsp_free( (t_pxobject *) x); +#endif + free(x->trigland); + free(x->bitshuffle); + free(x->Wanal); + free(x->Wsyn); + free(x->input); + free(x->Hwin); + free(x->buffer); + free(x->channel); + free(x->ichannel); + free(x->tmpchannel); + free(x->last_frame); + free(x->output); + free(x->c_lastphase_out); + free(x->rule); +} + +void cavoc27_assist (t_cavoc27 *x, void *b, long msg, long arg, char *dst) +{ + if (msg==1) { + switch (arg) { + case 0: + sprintf(dst,"unused(signal)"); + break; + } + } else if (msg==2) { + switch (arg) { + case 0: + sprintf(dst,"output(signal)"); break; + } + } +} + +void *cavoc27_new(t_symbol *s, int argc, t_atom *argv) +{ +#if MSP + t_cavoc27 *x = (t_cavoc27 *)newobject(cavoc27_class); + dsp_setup((t_pxobject *)x,1); + outlet_new((t_pxobject *)x, "signal"); +#endif +#if PD + int i; + t_cavoc27 *x = (t_cavoc27 *)pd_new(cavoc27_class); + outlet_new(&x->x_obj, gensym("signal")); +#endif + + x->overlap = 0; + x->winfac=0; + x->hold_time=0; + x->density = 0; + + x->density = atom_getfloatarg(0,argc,argv); + x->hold_time = atom_getfloatarg(1,argc,argv) * .001;// convert to seconds + x->overlap = atom_getfloatarg(2,argc,argv); + x->winfac = atom_getfloatarg(3,argc,argv); + + if(x->density <= 0) + x->density = .0001; + if(x->density >= 1) + x->density = .9999; + x->start_breakpoint = 1.0 - x->density; + if(!x->hold_time) + x->hold_time = 0.15; + + x->vs = sys_getblksize(); + x->R = sys_getsr(); + + cavoc27_init(x,0); + return (x); +} + +void cavoc27_overlap(t_cavoc27 *x, t_floatarg f) +{ +int i = (int) f; + if(!power_of_two(i)){ + post("%f is not a power of two",f); + return; + } + x->overlap = i; + cavoc27_init(x,1); +} + +void cavoc27_winfac(t_cavoc27 *x, t_floatarg f) +{ +int i = (int)f; + + if(!power_of_two(i)){ + error("%f is not a power of two",f); + return; + } + x->winfac = i; + cavoc27_init(x,2); +} + +void cavoc27_fftinfo(t_cavoc27 *x) +{ + if( ! x->overlap ){ + post("zero overlap!"); + return; + } + post("%s: FFT size %d, hopsize %d, windowsize %d", OBJECT_NAME, x->N, x->N/x->overlap, x->Nw); +} + + +void cavoc27_init(t_cavoc27 *x,short initialized) +{ +int i; + + if(!power_of_two(x->overlap)) + x->overlap = 4; + if(!power_of_two(x->winfac)) + x->winfac = 1; +//post("init with o %d and wf %d",x->overlap,x->winfac); + x->D = x->vs; + x->N = x->D * x->overlap; + x->Nw = x->N * x->winfac; + limit_fftsize(&x->N,&x->Nw,OBJECT_NAME); + + + x->N2 = (x->N)>>1; + x->Nw2 = (x->Nw)>>1; + x->inCount = -(x->Nw); + x->mult = 1. / (float) x->N; + x->c_fundamental = (float) x->R/( (x->N2)<<1 ); + x->c_factor_out = TWOPI * (float) x->D / (float) x->R; + x->c_factor_in = (float) x->R/((float)x->D * TWOPI); + x->frame_duration = (float)x->D/(float) x->R; + x->hold_frames = (int) (x->hold_time/x->frame_duration); + x->frames_left = x->hold_frames; +// x->frames_left = 0; + x->set_count = 0; + + if(!initialized){ + srand(time(0)); + x->interpolate_flag = 0; + x->capture_lock = 0; + + x->mute = 0; + x->Wanal = (float *) calloc(MAX_Nw, sizeof(float)); + x->Wsyn = (float *) calloc(MAX_Nw, sizeof(float)); + x->input = (float *) calloc(MAX_Nw, sizeof(float)); + x->Hwin = (float *) calloc(MAX_Nw, sizeof(float)); + x->buffer = (float *) calloc(MAX_N, sizeof(float)); + x->channel = (float *) calloc(MAX_N+2, sizeof(float)); + x->ichannel = (float *) calloc(MAX_N+2, sizeof(float)); + x->tmpchannel = (float *) calloc(MAX_N+2, sizeof(float)); + x->rule = (short *) calloc(27, sizeof(short)); + x->last_frame = (float *) calloc(MAX_N+2, sizeof(float)); + x->output = (float *) calloc(MAX_Nw, sizeof(float)); + x->bitshuffle = (int *) calloc(MAX_N * 2, sizeof(int)); + x->trigland = (float *) calloc(MAX_N * 2, sizeof(float)); + x->c_lastphase_in = (float *) calloc(MAX_N2+1, sizeof(float)); + x->c_lastphase_out = (float *) calloc(MAX_N2+1, sizeof(float)); + + + } + memset((char *)x->input,0,x->Nw * sizeof(float)); + memset((char *)x->output,0,x->Nw * sizeof(float)); + memset((char *)x->buffer,0,x->N * sizeof(float)); + memset((char *)x->c_lastphase_in,0,(x->N2+1) * sizeof(float)); + memset((char *)x->c_lastphase_out,0,(x->N2+1) * sizeof(float)); + + + cavoc27_rand_set_rule(x); + init_rdft( x->N, x->bitshuffle, x->trigland); + makehanning( x->Hwin, x->Wanal, x->Wsyn, x->Nw, x->N, x->D, 0); + cavoc27_rand_set_spectrum(x); + for( i = 0; i < x->N+2; i++ ){ + x->last_frame[i] = x->channel[i]; + } +} + +void cavoc27_rand_set_spectrum(t_cavoc27 *x) +{ +int i; +float rval; + + //set spectrum + for( i = 0; i < x->N2 + 1; i++ ){ + if( cavoc27_randf(0.0, 1.0) > x->start_breakpoint){ + rval = cavoc27_randf(0.0, 1.0); + if( rval < 0.5 ){ + x->channel[ i * 2 ] = 1; + } + else { + x->channel[ i * 2 ] = 2; + } + ++(x->set_count); + } else { + x->channel[ i * 2 ] = 0; + } + x->channel[ i * 2 + 1 ] = x->c_fundamental * (float) (i / 2) * cavoc27_randf(.9,1.1); + } +} + +t_int *cavoc27_perform(t_int *w) +{ + int i,j; + float m1,m2; + //////////// + t_cavoc27 *x = (t_cavoc27 *) (w[1]); + + float *in = (t_float *)(w[2]); + float *out = (t_float *)(w[3]); + t_int n = w[4]; + + int frames_left = x->frames_left; + float *input = x->input; + float *buffer = x->buffer; + int inCount = x->inCount; + int R = x->R; + int N = x->N; + int N2 = x->N2; + int D = x->D; + int Nw = x->Nw; + float *Wanal = x->Wanal; + float *Wsyn = x->Wsyn; + float *output = x->output; + float *channel = x->channel; + float *tmpchannel = x->tmpchannel; + float *ichannel = x->ichannel; + float mult = x->mult ; + int *bitshuffle = x->bitshuffle; + float *trigland = x->trigland ; + int hold_frames = x->hold_frames; + short *rule = x->rule; + short left = x->left; + short right = x->right; + short center = x->center; + float *last_frame = x->last_frame; + float *c_lastphase_out = x->c_lastphase_out; + float *c_lastphase_in = x->c_lastphase_in; + float c_fundamental = x->c_fundamental; + float c_factor_out = x->c_factor_out; + float c_factor_in = x->c_factor_in; + short interpolate_flag = x->interpolate_flag; + + + if( x->mute ){ + while( n-- ){ + *out++ = 0.0; + } + return (w+5); + } + + x->inCount += D; + + if( x->capture_flag || x->capture_lock ) { + + + for ( j = 0 ; j < (Nw - D) ; j++ ){ + input[j] = input[j+D]; + } + for ( j = (Nw-D), i = 0 ; j < Nw; j++, i++ ) { + input[j] = *in++; + } + + fold( input, Wanal, Nw, buffer, N, x->inCount ); + rdft( N, 1, buffer, bitshuffle, trigland ); + convert( buffer, tmpchannel, N2, c_lastphase_in, c_fundamental, c_factor_in ); + + // ONLY COPY PHASES + for( i = 1; i < N+2; i += 2 ){ + channel[i] = tmpchannel[i]; + // last_frame[i] = channel[i] = tmpchannel[i]; + } + + if( x->capture_flag ){ + --(x->capture_flag); + } + // on final frame - swap in channel (just phases though ) + + + } + if( --frames_left <= 0){ + /* save composite frame for next time (only amps) */ +/* for( i = 0; i < N+1; i++ ){ + last_frame[i] = channel[i]; + }*/ + + for( i = 0; i < N+1; i += 2 ){ + last_frame[i] = channel[i]; + } + + frames_left = hold_frames; + for( i = 2; i < N; i+=2 ){ + left = last_frame[ i - 2 ]; + center = last_frame[i] ; + right = last_frame[i+2]; + channel[i] = cavoc27_apply_rule(left, right, center, rule ); + } + /* boundary cases */ + center = last_frame[0]; + right = last_frame[2]; + left = last_frame[N]; + channel[0] = cavoc27_apply_rule(left, right, center, rule ); + + center = last_frame[N]; + right = last_frame[0]; + left = last_frame[N - 2]; + channel[N] = cavoc27_apply_rule(left, right, center, rule ); + } + if( interpolate_flag ){ + m1 = (float) frames_left / (float) hold_frames ; + m2 = 1.0 - m1; + for( i = 0; i inCount = inCount; + x->frames_left = frames_left; + return (w+5); +} + +int cavoc27_apply_rule( short left, short right, short center, short *rule){ + + if( left == 0 && center == 0 && right == 0 ) + return rule[0]; + if( left == 1 && center == 0 && right == 1 ) + return rule[1]; + if( left == 1 && center == 0 && right == 0 ) + return rule[2]; + if( left == 0 && center == 0 && right == 1 ) + return rule[3]; + if( left == 2 && center == 0 && right == 2 ) + return rule[4]; + if( left == 2 && center == 0 && right == 0 ) + return rule[5]; + if( left == 0 && center == 0 && right == 2 ) + return rule[6]; + if( left == 2 && center == 0 && right == 1 ) + return rule[7]; + if( left == 1 && center == 0 && right == 2 ) + return rule[8]; + + if( left == 0 && center == 1 && right == 0 ) + return rule[9]; + if( left == 1 && center == 1 && right == 1 ) + return rule[10]; + if( left == 1 && center == 1 && right == 0 ) + return rule[11]; + if( left == 0 && center == 1 && right == 1 ) + return rule[12]; + if( left == 2 && center == 1 && right == 2 ) + return rule[13]; + if( left == 2 && center == 1 && right == 0 ) + return rule[14]; + if( left == 0 && center == 1 && right == 2 ) + return rule[15]; + if( left == 2 && center == 1 && right == 1 ) + return rule[16]; + if( left == 1 && center == 1 && right == 2 ) + return rule[17]; + + if( left == 0 && center == 2 && right == 0 ) + return rule[18]; + if( left == 1 && center == 2 && right == 1 ) + return rule[19]; + if( left == 1 && center == 2 && right == 0 ) + return rule[20]; + if( left == 0 && center == 2 && right == 1 ) + return rule[21]; + if( left == 2 && center == 2 && right == 2 ) + return rule[22]; + if( left == 2 && center == 2 && right == 0 ) + return rule[23]; + if( left == 0 && center == 2 && right == 2 ) + return rule[24]; + if( left == 2 && center == 2 && right == 1 ) + return rule[25]; + if( left == 1 && center == 2 && right == 2 ) + return rule[26]; + return 0; //should never happen +} + +float cavoc27_randf(float min, float max) +{ + float randv, retval; + + randv = (float) (rand() % 32768) / 32768.0 ; + return (retval = min + (max-min) * randv) ; +} +void cavoc27_dsp(t_cavoc27 *x, t_signal **sp, short *count) +{ + if(x->vs != sp[0]->s_n || x->R != sp[0]->s_sr) { + x->vs = sp[0]->s_n; + x->R = sp[0]->s_sr; + cavoc27_init(x,1); + } + dsp_add(cavoc27_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); +} + -- cgit v1.2.1