/* CatMap 12.10 :: Thadeus Frazier-Reed c.2004 tcfr33@yahoo.com http://music.calarts.edu/~tcfr33 // add a counter % iterations // add list from 1 - 1000 of the number of iterations to use in mod */ #include "ext.h" #include "z_dsp.h" #include #include #include #define TABLE_SIZE 256 #define N_SIZE 16 #define SAMPLE_RATE 44100 typedef struct cat { t_pxobject x_ob; t_filehandle fh; // file input variables float *file; long type; float *sinetable; // sine table float *matrixA; // these matricies will be pointers to be dynamically allocated float *matrixB; // for the math use matrix conventions and translate to linear math int iter; int modulus; int table_size; int n_size; char loop; // loop on or off char play; // play chooses which matrix to change to // matrixA = 0, matrixB = 1 int phase; float t_incr; float out_value; // interpvalue float freq; int *iter_out; // out for iteration }t_cat; void *cat_class; t_int *cat_perform(t_int *w); void cat_dsp(t_cat *x, t_signal **sp); void cat_dsp_free(t_cat *x); void cat_bang(t_cat *x); void cat_loop(t_cat *x, int tog); void cat_read(t_cat *x, t_symbol *s); void cat_doread(t_cat *x, t_symbol *s, short argc, t_atom *argv); void cat_int(t_cat *x, long n); // increment or decrement the iteration void cat_in1(t_cat *x, float n); // frequency to play at void cat_assist(t_cat *x, void *b, long m, long a, char *s); void *cat_new(long arg1); // arg sets n size //------------------------------ // main void main(void) { setup((t_messlist **)&cat_class, (method)cat_new, (method)cat_dsp_free, (short)sizeof(t_cat), 0L, A_DEFLONG, 0); addbang((method)cat_bang); addint((method)cat_int); addftx((method)cat_in1, 1); addmess((method)cat_loop, "loop", A_DEFLONG, 0); addmess((method)cat_read, "read", A_DEFSYM, 0); addmess((method)cat_assist,"assist", A_CANT, 0); addmess((method)cat_dsp, "dsp", A_CANT, 0); dsp_initclass(); } //------------------------------------------------- //new void *cat_new(long arg1) { int i1, i2, i3; int xval, yval; float twoPi = 8.000f * atanf(1.000f); // setup 2pi // array of iterations for n-size = 1-1000 int iter_array[] = {1,3,4,3,10,12,8,6,12,30,5,12,14,24,20,12,18,12,9,30 ,8,15,24,12,50,42,36,24,7,60,15,24,20,18,40,12,38,9,28, 30,20,24,44,15,60,24,16,12,56,150,36,42,54,36,10,24,36, 21,29,60,30,15,24,48,70,60,68,18,24,120,35,12,74,114,100, 9,40,84,39,60,108,60,84,24,90,132,28,30,22,60,56,24,60,48, 90,24,98,168,60,150,25,36,104,42,40,54,36,36,54,30,76,24, 38,36,120,21,84,87,72,60,55,30,20,15,250,24,128,96,44,210, 65,60,72,204,180,18,138,24,23,120,16,105,70,12,70,222,56, 114,74,300,25,18,36,120,30,84,158,39,108,120,24,108,164, 60,20,84,168,24,182,90,36,132,174,84,200,60,116,66,89,60, 45,168,60,24,190,60,90,48,72,90,95,48,194,294,140,168,198, 60,11,150,68,75,56,36,20,312,24,84,45,120,21,54,140,36,220, 36,120,54,148,30,126,228,224,24,300,114,228,36,57,120,40, 42,26,84,80,87,156,72,119,60,120,165,324,30,280,60,126,30, 84,750,125,24,120,384,180,192,258,132,152,210,84,195,88, 60,270,72,44,204,134,180,135,36,56,138,50,24,278,69,60,120, 28,48,284,105,180,210,40,24,306,210,196,222,294,168,290, 114,180,222,168,300,88,75,100,36,30,36,44,120,104,30,155, 84,314,474,120,39,318,108,35,240,36,24,18,108,350,492,108, 60,16,60,55,84,228,168,340,24,338,546,76,90,15,36,392,132, 120,174,116,84,87,600,252,120,118,348,70,66,72,267,179,60, 171,45,220,168,370,60,368,24,60,570,216,60,374,90,500,48,14, 72,189,90,128,285,384,96,40,582,132,294,194,420,72,168,260,198, 390,60,398,33,72,300,100,204,210,75,540,168,190,36,204,60,276, 312,232,24,420,168,92,45,209,120,42,21,48,54,450,420,120,36, 140,660,215,36,434,120,140,54,72,444,219,30,168,126,444,228,110, 672,148,48,224,300,20,114,100,228,280,36,458,57,36,120,23,120, 464,84,60,78,468,84,136,240,316,174,220,156,450,72,108,357,239, 120,266,120,24,165,490,324,488,30,164,840,245,60,126,126,60,60, 280,84,249,750,168,375,504,24,50,120,364,384,127,180,296,384,36, 258,520,132,80,456,348,210,13,84,524,195,200,264,90,60,552,270, 348,72,140,132,180,204,356,402,280,180,45,135,180,72,270,168,548, 138,60,150,63,24,312,834,380,69,62,60,308,120,180,84,188,48,190, 852,216,210,284,180,285,210,380,120,600,48,578,306,388,210,168, 588,270,222,420,294,588,168,45,870,396,228,594,180,360,222,44,168, 299,300,300,264,204,75,110,300,608,72,56,30,112,36,614,132,20,120, 618,312,103,30,72,465,88,84,1250,942,180,474,342,120,315,78,84,318, 640,108,56,105,420,480,320,36,644,24,220,18,648,108,145,1050,120, 492,654,108,130,60,444,48,329,60,110,165,252,84,360,228,168,168, 224,1020,30,24,674,1014,900,546,226,228,392,90,228,15,684,36,690, 1176,228,132,378,120,69,174,120,348,230,84,180,87,52,600,350,252, 342,240,80,354,200,348,59,210,156,66,120,72,70,267,476,537,359,60, 104,171,120,45,350,660,728,168,972,1110,396,60,734,1104,280,24,340, 60,369,570,252,216,248,60,370,1122,84,90,72,1500,375,48,500,42,50, 72,758,189,120,90,190,384,216,285,180,384,406,192,96,120,516,582, 774,132,150,294,152,582,180,420,35,72,252,168,790,780,788,198,88, 390,152,60,210,1194,540,33,114,72,144,600,132,300,370,204,120,210, 268,150,101,540,135,168,540,570,820,36,396,204,168,60,410,276,824, 312,100,696,828,24,138,420,556,336,504,276,840,45,180,627,419,120, 203,42,28,21,910,48,440,108,284,450,456,420,854,120,180,36,858,420, 39,660,40,645,864,72,870,1302,612,120,195,420,476,54,588,72,1000, 444,878,219,588,60,88,168,884,126,580,444,888,228,128,330,540,672, 144,444,890,96,168,672,105,300,54,60,88,114,90,300,908,228,300,840, 35,36,420,1374,60,57,520,36,51,120,44,69,70,120,950,1392,312,168, 464,60,504,78,620,468,90,84,938,408,628,240,235,948,120,348,360, 660,948,156,518,450,636,72,106,108,190,357,140,717,552,240,465,798, 36,120,970,24,88,330,36,1470,485,324,184,1464,700,60,326,492,110,840, 108,735,984,60,990,126,16,126,264,60,99,120,220,840,110,84,998,249, 684,750}; t_cat *x; x = (t_cat *)newobject(cat_class); dsp_setup((t_pxobject *)x, 0); // no signal inputs floatin(x, 1); //outlets x->iter_out = intout(x); outlet_new((t_object *)x, "signal"); if (arg1 == 0) { x->table_size = TABLE_SIZE; x->n_size = N_SIZE; x->modulus = 12; } else { x->n_size = arg1; x->table_size = x->n_size * x->n_size; x->modulus = iter_array[arg1-1]; } x->sinetable = (float*)sysmem_newptr(x->table_size * sizeof(float)); // initialize sinetable // setup sine table for (i1=0; i1table_size; i1++) { x->sinetable[i1] = sinf((i1 * twoPi)/(float)x->table_size); // load with sine wave } //init with zeroes x->matrixA = (float*)sysmem_newptrclear(x->table_size * sizeof(float)); // initialize matricies x->matrixB = (float*)sysmem_newptrclear(x->table_size * sizeof(float)); for (i1=0; i1table_size; i1++) // original matrix { x->matrixA[i1] = x->sinetable[i1]; } x->loop = 0; x->play = 0; // play matrixA x->phase = 0.0; x->t_incr = 1; x->iter = 0; post("save audio file in SoundHack as Raw Data"); post("with 32 bit floating point format"); return(x); } //------------------------------------------------- //bang void cat_bang(t_cat *x) { if (x->loop == 0) { x->phase = 0; } else { } } //------------------------------------------------- //loop void cat_loop(t_cat *x, int tog) { x->loop = tog; } //------------------------------------------------- // read void cat_read(t_cat *x, t_symbol *s)// optional symbol argument to specify name { if (x->fh) // if a file is already open get ready to open a new one { x->fh = 0; sysmem_freeptr(x->matrixA); sysmem_freeptr(x->matrixB); sysmem_freeptr(x->file); } defer(x,(method)cat_doread,s,0,0); // always defer this message } //------------------------------------------------- // doread void cat_doread(t_cat *x, t_symbol *s, short argc, t_atom *argv) { char filename[256]; short path, err; long type = 'DATA'; // some file type you're looking for long outtype; long count; int i; if (!s->s_name[0]) // empty symbol { if (open_dialog(filename, &path, &outtype, &type, 1)) return; // user cancelled } else { strcpy(filename, s->s_name); // important: copy symbol arg to local string if (locatefile_extended(filename, &path, &outtype, &type, 1)) return; // not found } // at this point, a valid name is in filename and // a valid path is in path err = path_opensysfile(filename, path, &x->fh, READ_PERM); if (err) { x->fh = 0; error("error %d opening file", err); return; } // open file for reading err = path_opensysfile(filename, path, &x->fh, READ_PERM); if (err) { // report any errors error("%s: error %d opening file", filename, err); return; } sysfile_geteof(x->fh, &count); post("file is %d bytes long", count); x->matrixA = (float*)sysmem_newptrclear(x->table_size * sizeof(float)); // initialize matricies x->matrixB = (float*)sysmem_newptrclear(x->table_size * sizeof(float)); x->file = (float *)sysmem_newptrclear(count * sizeof(float)); sysfile_read(x->fh, &count, x->file); x->iter = 0; outlet_int(x->iter_out, x->iter); if (count > x->table_size) { for (i=0; itable_size; i++) // original matrix { x->matrixA[i] = x->file[i]; } } else { for (i=0; imatrixA[i] = x->file[i]; } } sysfile_close(x->fh); } //------------------------------------------------- // int void cat_int(t_cat *x, long n) { int i1,i2; int xval,yval; int linval1, linval2; // the new matrix will be created then play changed if (n == 1) // increment { x->iter += 1; x->iter = x->iter % x->modulus; for (i1=0; i1n_size; i1++) { for (i2=0; i2n_size; i2++) { // do matrix transform xval = (i1+i2)%x->n_size; yval = (i1+(2*i2))%x->n_size; // derive linear positions n*xval+yval linval1 = x->n_size*xval+yval; linval2 = x->n_size*i1+i2; if (x->play == 0) x->matrixB[linval2] = x->matrixA[linval1]; if (x->play == 1) x->matrixA[linval2] = x->matrixB[linval1]; } } } if (n == -1) // decrement { x->iter -= 1; x->iter = x->iter % x->modulus; for (i1=0; i1n_size; i1++) { for (i2=0; i2n_size; i2++) { // do matrix transform xval = (i1+i2)%x->n_size; yval = (i1+(2*i2))%x->n_size; // derive linear positions n*xval+yval linval1 = x->n_size*xval+yval; linval2 = x->n_size*i1+i2; if (x->play == 0) x->matrixB[linval1] = x->matrixA[linval2]; if (x->play == 1) x->matrixA[linval1] = x->matrixB[linval2]; } } } if (x->fh != 0) { // check against file for (i1=0; i1table_size; i1++) { switch(x->play) { case 0: if (x->file[i1] != x->matrixB[i1]) // check matrixB beacause that is the next one to be sent out i1 = x->table_size; break; case 1: if (x->file[i1] != x->matrixA[i1]) // check matrixA beacause that is the next one to be sent out i1 = x->table_size; break; } if (i1 == x->table_size - 1) // if we make it through the check say they are equal { x->iter = 0; post(":::::original configuration:::::"); } } } if (x->fh == 0) { // check against sinetable for (i1=0; i1table_size; i1++) { switch(x->play) { case 0: if (x->sinetable[i1] != x->matrixB[i1]) // check matrixB beacause that is the next one to be sent out i1 = x->table_size; break; case 1: if (x->sinetable[i1] != x->matrixA[i1]) // check matrixA beacause that is the next one to be sent out i1 = x->table_size; break; } if (i1 == x->table_size - 1) // if we make it through the check say they are equal { x->iter = 0; post(":::::original configuration:::::"); } } } if (x->play == 0) x->play = 1; else if (x->play == 1) x->play = 0; if (x->iter < 0) { x->iter = x->modulus + (x->iter); } outlet_int(x->iter_out, x->iter); // x->phase = 0.0; } //------------------------------------------------- // in1 void cat_in1(t_cat *x, float n) // get frequency { if(n == 0) x->t_incr = 1; else { x->freq = n; x->t_incr = x->freq; // set table increment x->t_incr = (x->t_incr/SAMPLE_RATE * x->table_size); } } //------------------------------------------------- // perform t_int *cat_perform(t_int *w) { t_float *out = (t_float *)(w[1]); t_cat *x = (t_cat *)(w[2]); int n = (int)(w[3]); while (n--) { switch(x->loop) { case 0: // don't loop if(x->phase < x->table_size) { switch(x->play) { case 0: *out++ = x->matrixA[x->phase]; break; case 1: *out++ = x->matrixB[x->phase]; break; } x->phase += x->t_incr; } else *out++ = 0.0; break; case 1: // loop switch(x->play) { case 0: *out++ = x->matrixA[x->phase]; break; case 1: *out++ = x->matrixB[x->phase]; break; } x->phase += x->t_incr; while (x->phase >= x->table_size) // check increments { x->phase -= x->table_size; // wrap tables } while (x->phase < 0) { x->phase += x->table_size; } break; } } return(w+4); } //------------------------------------------------- //dsp void cat_dsp(t_cat *x, t_signal **sp) { dsp_add(cat_perform, 3, sp[0]->s_vec, x, sp[0]->s_n ); } //------------------------------------------------- //dsp_free void cat_dsp_free(t_cat *x) { sysmem_freeptr(x->sinetable); sysmem_freeptr(x->matrixA); sysmem_freeptr(x->matrixB); sysmem_freeptr(x->file); dsp_free((t_pxobject *) x); } //------------------------------------------------- // assist void cat_assist(t_cat *x, void *b, long m, long a, char *s) { if (m == 1) { switch (a) { case 0: sprintf(s, "bang to play, loop, +1/-1,read"); break; case 1: sprintf(s, "frequency(float)"); break; } } else if (m == 2) { switch (a) { case 0: sprintf(s, "signal"); break; case 1: sprintf(s, "current iteration"); break; } } }