Update of /cvsroot/pure-data/externals/frankenstein In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21617
Modified Files: harmonizer.c test-harmonizer2.pd voicing_analyzer.c Log Message: number of voices is now settable
Index: harmonizer.c =================================================================== RCS file: /cvsroot/pure-data/externals/frankenstein/harmonizer.c,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** harmonizer.c 21 Jan 2006 02:23:16 -0000 1.9 --- harmonizer.c 21 Jan 2006 11:22:52 -0000 1.10 *************** *** 74,84 **** t_object x_obj; // myself // genotypes ! int population[MAX_POPULATION][VOICES]; ! int current_voices[VOICES]; chord_abs_t current_chord; chord_abs_t target_chord; int target_notes[POSSIBLE_NOTES]; t_outlet *l_out; ! float wideness; int center_note; --- 74,86 ---- t_object x_obj; // myself // genotypes ! //int population[MAX_POPULATION][VOICES]; ! //int current_voices[VOICES]; ! int *population[MAX_POPULATION]; ! int *current_voices; chord_abs_t current_chord; chord_abs_t target_chord; int target_notes[POSSIBLE_NOTES]; t_outlet *l_out; ! int voices; float wideness; int center_note; *************** *** 236,240 **** for (i=0; i<MAX_POPULATION; i++) { ! for (j=0; j<VOICES; j++) { /* --- 238,242 ---- for (i=0; i<MAX_POPULATION; i++) { ! for (j=0; j<x->voices; j++) { /* *************** *** 286,289 **** --- 288,301 ---- }
+ void harmonizer_allocate(t_harmonizer *x) + { + int i; + for (i=0; i<MAX_POPULATION; i++) + { + x->population[i] = malloc(sizeof(int)*x->voices); + } + x->current_voices = malloc(sizeof(int)*x->voices); + + }
void harmonizer_free(t_harmonizer *x) *************** *** 291,294 **** --- 303,313 ---- // freebytes(x->buf_strum1, sizeof(x->buf_strum1)); // freebytes(x->buf_strum2, sizeof(x->buf_strum2)); + + int i; + for (i=0; i<MAX_POPULATION; i++) + { + free(x->population[i]); + } + free(x->current_voices); }
*************** *** 300,310 **** short int chord_notes[4]; short int chord_notes_ok[4]; ! short int transitions[VOICES]; ! short int directions[VOICES]; // intervals between voices // for parallel and hidden 5ths // voices spacing etc.. ! short int intervals[VOICES][VOICES]; ! short int notes[VOICES]; res=50; // starting fitness
--- 319,333 ---- short int chord_notes[4]; short int chord_notes_ok[4]; ! //short int transitions[VOICES]; ! short int *transitions; ! //short int directions[VOICES]; ! short int *directions; // intervals between voices // for parallel and hidden 5ths // voices spacing etc.. ! //short int intervals[VOICES][VOICES]; ! short int **intervals; ! //short int notes[VOICES]; ! short int *notes; res=50; // starting fitness
*************** *** 312,317 **** post("evaluating fitness of %i %i %i %i", candidate[0], candidate[1], candidate[2], candidate[3]);
// shared objects ! for (i=0; i<VOICES; i++) { notes[i]=candidate[i]; --- 335,350 ---- post("evaluating fitness of %i %i %i %i", candidate[0], candidate[1], candidate[2], candidate[3]);
+ // allocate arrays + transitions = malloc(sizeof(short int)*x->voices); + directions = malloc(sizeof(short int)*x->voices); + notes = malloc(sizeof(short int)*x->voices); + intervals = malloc(sizeof(short int *) * x->voices); + for (i=0; i<x->voices; i++) + { + intervals[i] = malloc(sizeof(short int) * x->voices); + } + // shared objects ! for (i=0; i<x->voices; i++) { notes[i]=candidate[i]; *************** *** 325,331 ****
} ! for (i=0; i<VOICES; i++) { ! for (j=i+1; j<VOICES; j++) { intervals[i][j] = (candidate[i]-candidate[j])%12 ; --- 358,364 ----
} ! for (i=0; i<x->voices; i++) { ! for (j=i+1; j<x->voices; j++) { intervals[i][j] = (candidate[i]-candidate[j])%12 ; *************** *** 334,338 **** } } ! SGLIB_ARRAY_SINGLE_QUICK_SORT(short int, notes, VOICES, SGLIB_NUMERIC_COMPARATOR)
// all same direction? --- 367,371 ---- } } ! SGLIB_ARRAY_SINGLE_QUICK_SORT(short int, notes, x->voices, SGLIB_NUMERIC_COMPARATOR)
// all same direction? *************** *** 349,355 **** // how? // hidden 8ths nor 5ths ? ! for (i=0; i<VOICES; i++) { ! for (j=i+1; j<VOICES; j++) { if (intervals[i][j]==7 || intervals[i][j]==0) --- 382,388 ---- // how? // hidden 8ths nor 5ths ? ! for (i=0; i<x->voices; i++) { ! for (j=i+1; j<x->voices; j++) { if (intervals[i][j]==7 || intervals[i][j]==0) *************** *** 371,375 **** // are voices average centered? tmp=0; ! for (i=1; i<VOICES; i++) { tmp+=notes[i]; --- 404,408 ---- // are voices average centered? tmp=0; ! for (i=1; i<x->voices; i++) { tmp+=notes[i]; *************** *** 378,384 **** } // this is the average note ! tmp = tmp/(VOICES-1); if (DEBUG_VERBOSE) ! post("average note is %i after division by (VOICES-1)", tmp); // tmp = abs((LOWER_POSSIBLE_NOTE + NOTES_RANGE)*2/3 - tmp); // how much average is far from 72 tmp = abs(x->center_note - tmp); // how much average is far from desired center note --- 411,417 ---- } // this is the average note ! tmp = tmp/(x->voices-1); if (DEBUG_VERBOSE) ! post("average note is %i after division by (x->voices-1)", tmp); // tmp = abs((LOWER_POSSIBLE_NOTE + NOTES_RANGE)*2/3 - tmp); // how much average is far from 72 tmp = abs(x->center_note - tmp); // how much average is far from desired center note *************** *** 407,411 **** if (DEBUG_VERBOSE) post("res before transitions %i", res); ! for (i=0; i<VOICES; i++) { if (DEBUG_VERBOSE) --- 440,444 ---- if (DEBUG_VERBOSE) post("res before transitions %i", res); ! for (i=0; i<x->voices; i++) { if (DEBUG_VERBOSE) *************** *** 446,450 **** chord_notes_ok[i] = 0; } ! for (i=0; i<VOICES; i++) { tmp = notes[i] % 12; --- 479,483 ---- chord_notes_ok[i] = 0; } ! for (i=0; i<x->voices; i++) { tmp = notes[i] % 12; *************** *** 473,481 **** res -= 2^chord_notes_ok[j]; } ! res += 2*VOICES;
// penalize too many basses tmp = 0; ! for (i=0; i<VOICES; i++) { if (notes[i]<48) --- 506,514 ---- res -= 2^chord_notes_ok[j]; } ! res += 2*x->voices;
// penalize too many basses tmp = 0; ! for (i=0; i<x->voices; i++) { if (notes[i]<48) *************** *** 493,497 **** // now wideness min = notes[0]; ! max = notes[VOICES-1]; distance = max - min; wideness = (float) (((float)distance) / ((float)12)); --- 526,530 ---- // now wideness min = notes[0]; ! max = notes[x->voices-1]; distance = max - min; wideness = (float) (((float)distance) / ((float)12)); *************** *** 502,505 **** --- 535,548 ---- post("fitness is %i", res);
+ // free memory + free(transitions); + free(directions); + free(notes); + for (i=0; i<x->voices; i++) + { + free(intervals[i]); + } + free(intervals); + return res; } *************** *** 511,520 **** // crossover rnd = rand()/((double)RAND_MAX + 1); ! split = rnd * VOICES; for (i=0; i<split; i++) { kid[i]=mammy[i]; } ! for (i=split; i<VOICES; i++) { kid[i]=daddy[i]; --- 554,563 ---- // crossover rnd = rand()/((double)RAND_MAX + 1); ! split = rnd * x->voices; for (i=0; i<split; i++) { kid[i]=mammy[i]; } ! for (i=split; i<x->voices; i++) { kid[i]=daddy[i]; *************** *** 522,526 ****
// mutation ! for (i=0; i<VOICES; i++) { rnd = rand()/((double)RAND_MAX + 1); --- 565,569 ----
// mutation ! for (i=0; i<x->voices; i++) { rnd = rand()/((double)RAND_MAX + 1); *************** *** 546,550 **** int i, generation, mum, dad, winner; double rnd; ! t_atom lista[VOICES]; // inizialize tables of notes build_possible_notes_table(x); --- 589,597 ---- int i, generation, mum, dad, winner; double rnd; ! //t_atom lista[VOICES]; ! t_atom *lista; ! ! lista = malloc(sizeof(t_atom)*x->voices); ! // inizialize tables of notes build_possible_notes_table(x); *************** *** 592,596 **** post("winner fitness = %i", fitness_evaluations[MAX_POPULATION-1].fitness);
! for (i=0;i<VOICES;i++) { SETFLOAT(lista+i, x->population[winner][i]); --- 639,643 ---- post("winner fitness = %i", fitness_evaluations[MAX_POPULATION-1].fitness);
! for (i=0;i<x->voices;i++) { SETFLOAT(lista+i, x->population[winner][i]); *************** *** 600,605 **** outlet_anything(x->l_out, gensym("list") , ! VOICES, lista); }
--- 647,653 ---- outlet_anything(x->l_out, gensym("list") , ! x->voices, lista); + free(lista); }
*************** *** 614,618 **** int i=0; ! if (argc<VOICES) { error("insufficient notes sent!"); --- 662,666 ---- int i=0; ! if (argc<x->voices) { error("insufficient notes sent!"); *************** *** 620,624 **** } // fill input array with actual data sent to inlet ! for (i=0;i<VOICES;i++) { x->current_voices[i] = atom_getint(argv++); --- 668,672 ---- } // fill input array with actual data sent to inlet ! for (i=0;i<x->voices;i++) { x->current_voices[i] = atom_getint(argv++); *************** *** 681,692 **** }
void print_help(t_harmonizer *x) { post(""); post("harmonizer is an external that builds voicing"); ! post("takes chords name and outputs a list of %i midi notes", VOICES); post("available commands:"); post("current symbol: sets the current chord name (which chordwe are in)"); post("target symbol: sets the target chord name (which chord we want to go to)"); post("wideness float: now many octaves wide should the next chord be? must be > than 0"); post("set_center_note int: sets the desired center chord note, min 24 max 100"); --- 729,754 ---- }
+ void set_voices(t_harmonizer *x, t_floatarg f) + { + int newval = (int) f; + if (newval<1) + { + error("number of voices must be > 0 !"); + return; + } + x->voices = newval; + harmonizer_free(x); + harmonizer_allocate(x); + } + void print_help(t_harmonizer *x) { post(""); post("harmonizer is an external that builds voicing"); ! post("takes chords name and outputs a list of midi notes"); post("available commands:"); post("current symbol: sets the current chord name (which chordwe are in)"); post("target symbol: sets the target chord name (which chord we want to go to)"); + post("voices: sets the number of voices"); post("wideness float: now many octaves wide should the next chord be? must be > than 0"); post("set_center_note int: sets the desired center chord note, min 24 max 100"); *************** *** 715,718 **** --- 777,786 ---- x->i_like_parallelism = -1; // by default we don't like them! x->small_intervals = 1; //by default we want small intervals + x->voices = VOICES; + if (argc>0) + { + x->voices = atom_getintarg(0, argc, argv); + } + harmonizer_allocate(x); return (x); } *************** *** 732,735 **** --- 800,805 ---- class_addmethod(harmonizer_class, (t_method)set_i_like_parallelism, gensym("i_like_parallelism"), A_DEFFLOAT, 0); class_addmethod(harmonizer_class, (t_method)set_small_intervals, gensym("small_intervals"), A_DEFFLOAT, 0); + // set number of voices + class_addmethod(harmonizer_class, (t_method)set_voices, gensym("voices"), A_DEFFLOAT, 0);
Index: test-harmonizer2.pd =================================================================== RCS file: /cvsroot/pure-data/externals/frankenstein/test-harmonizer2.pd,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test-harmonizer2.pd 12 Dec 2005 13:17:40 -0000 1.2 --- test-harmonizer2.pd 21 Jan 2006 11:22:52 -0000 1.3 *************** *** 1,575 **** ! #N canvas 194 23 939 711 10; ! #X symbolatom 157 205 18 0 0 2 next_chord - -; ! #N canvas 39 349 535 332 readme 0; ! #X text 59 31 howto populate the graph: play the chord , when the ! output of [chord] is ok bang the "add" message. bang it each time you ! change chord , it will store the transitions; ! #X text 56 120 howto ask for the next chord: play the chord , bang ! the "set" message , this will set the current chord without adding ! it to the graph's memory , now bang the next 1 message. this chord_graph ! will respond with the chord you played most of the times after the [...1131 lines suppressed...] ! #X connect 72 0 62 0; ! #X connect 73 0 62 1; ! #X connect 74 0 76 0; ! #X connect 76 0 70 0; ! #X connect 77 0 65 0; ! #X connect 78 0 0 0; ! #X connect 78 0 4 1; ! #X connect 78 0 21 0; ! #X connect 78 0 45 1; ! #X connect 78 0 15 0; ! #X connect 78 0 50 1; ! #X connect 78 1 49 0; ! #X connect 78 2 53 0; ! #X connect 80 0 83 0; ! #X connect 81 0 80 0; ! #X connect 82 0 26 0; ! #X connect 83 0 14 0; ! #X connect 83 0 79 0; ! #X connect 83 0 82 0; ! #X connect 84 0 82 0;
Index: voicing_analyzer.c =================================================================== RCS file: /cvsroot/pure-data/externals/frankenstein/voicing_analyzer.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** voicing_analyzer.c 16 Jan 2006 00:56:01 -0000 1.2 --- voicing_analyzer.c 21 Jan 2006 11:22:52 -0000 1.3 *************** *** 35,43 **** { t_object x_obj; // myself ! int current_voices[VOICES]; ! int previous_voices[VOICES]; t_outlet *small_intervals_out, *i_like_parallelism_out, *center_note_out, *wideness_out; ! } t_voicing_analyzer;
--- 35,45 ---- { t_object x_obj; // myself ! //int current_voices[VOICES]; ! //int previous_voices[VOICES]; ! int *current_voices; ! int *previous_voices; t_outlet *small_intervals_out, *i_like_parallelism_out, *center_note_out, *wideness_out; ! int voices; } t_voicing_analyzer;
*************** *** 45,52 **** --- 47,67 ---- void voicing_analyzer_free(t_voicing_analyzer *x) { + free(x->current_voices); + free(x->previous_voices); // freebytes(x->buf_strum1, sizeof(x->buf_strum1)); // freebytes(x->buf_strum2, sizeof(x->buf_strum2)); }
+ void voicing_analyzer_allocate(t_voicing_analyzer *x) + { + int i; + x->current_voices = malloc(sizeof(int)*x->voices); + x->previous_voices = malloc(sizeof(int)*x->voices); + for (i=0; i<x->voices; i++) + { + x->current_voices[i] = 60; + x->previous_voices[i] = 60; + } + }
// here i evaluate this voicing *************** *** 57,72 **** short int chord_notes[4]; short int chord_notes_ok[4]; ! short int transitions[VOICES]; ! short int directions[VOICES]; // intervals between voices // for parallel and hidden 5ths // voices spacing etc.. ! short int intervals[VOICES][VOICES]; ! short int notes[VOICES]; res = 0; // starting fitness tmp = 0;
// shared objects ! for (i=0; i<VOICES; i++) { notes[i]=x->current_voices[i]; --- 72,101 ---- short int chord_notes[4]; short int chord_notes_ok[4]; ! //short int transitions[VOICES]; ! short int *transitions; ! //short int directions[VOICES]; ! short int *directions; // intervals between voices // for parallel and hidden 5ths // voices spacing etc.. ! //short int intervals[VOICES][VOICES]; ! short int **intervals; ! //short int notes[VOICES]; ! short int *notes; res = 0; // starting fitness tmp = 0;
+ // allocate arrays + transitions = malloc(sizeof(short int)*x->voices); + directions = malloc(sizeof(short int)*x->voices); + notes = malloc(sizeof(short int)*x->voices); + intervals = malloc(sizeof(short int *) * x->voices); + for (i=0; i<x->voices; i++) + { + intervals[i] = malloc(sizeof(short int) * x->voices); + } + // shared objects ! for (i=0; i<x->voices; i++) { notes[i]=x->current_voices[i]; *************** *** 80,86 ****
} ! for (i=0; i<VOICES; i++) { ! for (j=i+1; j<VOICES; j++) { intervals[i][j] = (x->current_voices[i] - x->current_voices[j])%12 ; --- 109,115 ----
} ! for (i=0; i<x->voices; i++) { ! for (j=i+1; j<x->voices; j++) { intervals[i][j] = (x->current_voices[i] - x->current_voices[j])%12 ; *************** *** 89,93 **** } } ! SGLIB_ARRAY_SINGLE_QUICK_SORT(short int, notes, VOICES, SGLIB_NUMERIC_COMPARATOR)
sameDirection = 0; --- 118,122 ---- } } ! SGLIB_ARRAY_SINGLE_QUICK_SORT(short int, notes, x->voices, SGLIB_NUMERIC_COMPARATOR)
sameDirection = 0; *************** *** 107,113 **** // how? // hidden 8ths nor 5ths ? ! for (i=0; i<VOICES; i++) { ! for (j=i+1; j<VOICES; j++) { if (intervals[i][j]==7 || intervals[i][j]==0) --- 136,142 ---- // how? // hidden 8ths nor 5ths ? ! for (i=0; i<x->voices; i++) { ! for (j=i+1; j<x->voices; j++) { if (intervals[i][j]==7 || intervals[i][j]==0) *************** *** 129,133 **** *i_like_parallelism += sameDirection; if (parallel8_5) ! *i_like_parallelism += (float) ( ((float)parallel8_5) / ((float)(VOICES*(VOICES-1))) );
--- 158,162 ---- *i_like_parallelism += sameDirection; if (parallel8_5) ! *i_like_parallelism += (float) ( ((float)parallel8_5) / ((float)(x->voices*(x->voices - 1))) );
*************** *** 135,139 **** // TODO: use notes[] // are voices average centered? ! for (i=0; i<VOICES; i++) { tmp+=notes[i]; --- 164,168 ---- // TODO: use notes[] // are voices average centered? ! for (i=0; i<x->voices; i++) { tmp+=notes[i]; *************** *** 142,150 **** } // this is the average note ! *center_note = tmp/(VOICES);
// are intervals small? tmp=0; ! for (i=0; i<VOICES; i++) { // if (DEBUG_VERBOSE) --- 171,179 ---- } // this is the average note ! *center_note = tmp/(x->voices);
// are intervals small? tmp=0; ! for (i=0; i<x->voices; i++) { // if (DEBUG_VERBOSE) *************** *** 172,185 **** }
! *small_intervals = (float) (((float) res) / ((float) (5 * VOICES)));
// now wideness min = notes[0]; ! max = notes[VOICES-1]; distance = max - min; *wideness = (float) (((float)distance) / ((float)12));
! }
--- 201,222 ---- }
! *small_intervals = (float) (((float) res) / ((float) (5 * x->voices)));
// now wideness min = notes[0]; ! max = notes[x->voices-1]; distance = max - min; *wideness = (float) (((float)distance) / ((float)12));
! // free memory ! free(transitions); ! free(directions); ! free(notes); ! for (i=0; i<x->voices; i++) ! { ! free(intervals[i]); ! } ! free(intervals); }
*************** *** 194,203 **** void analyze_voicing(t_voicing_analyzer *x) { ! t_atom lista[VOICES]; float small_intervals=0; float i_like_parallelism=0; float wideness=0; int center_note=0; ! analyze_it(x, &wideness, &i_like_parallelism, ¢er_note, &small_intervals); --- 231,240 ---- void analyze_voicing(t_voicing_analyzer *x) { ! t_atom lista[4]; float small_intervals=0; float i_like_parallelism=0; float wideness=0; int center_note=0; ! analyze_it(x, &wideness, &i_like_parallelism, ¢er_note, &small_intervals); *************** *** 215,219 **** int i=0; ! if (argc<VOICES) { error("insufficient notes sent!"); --- 252,256 ---- int i=0; ! if (argc<x->voices) { error("insufficient notes sent!"); *************** *** 221,225 **** } // fill input array with actual data sent to inlet ! for (i=0;i<VOICES;i++) { x->previous_voices[i] = x->current_voices[i]; --- 258,262 ---- } // fill input array with actual data sent to inlet ! for (i=0;i<x->voices;i++) { x->previous_voices[i] = x->current_voices[i]; *************** *** 232,235 **** --- 269,284 ---- }
+ void set_voices(t_voicing_analyzer *x, t_floatarg f) + { + int newval = (int) f; + if (newval<1) + { + error("number of voices must be > 0 !"); + return; + } + x->voices = newval; + voicing_analyzer_free(x); + voicing_analyzer_allocate(x); + }
void print_help(t_voicing_analyzer *x) *************** *** 237,242 **** post(""); post("voicing_analyzer is an external that analyze voicing"); ! post("takes as input %i midi notes", VOICES); post("available commands:"); post("this externalis part of the frank framework"); post("authors: davide morelli, david casals"); --- 286,297 ---- post(""); post("voicing_analyzer is an external that analyze voicing"); ! post("takes as input a list of midi notes"); ! post("and send out 4 values (from left to right):"); ! post("1)the center note of the chord (average value)"); ! post("2)wideness of the chord (how many octaves)"); ! post("3)small intervals were used? (-1=no, 1=yes)"); ! post("4)parallelism was used? (parallel octaves and fifths) (-1=no, 1=yes)"); post("available commands:"); + post("voices: changes the number of expected notes"); post("this externalis part of the frank framework"); post("authors: davide morelli, david casals"); *************** *** 253,262 **** x->small_intervals_out = outlet_new(&x->x_obj, gensym("float")); x->i_like_parallelism_out = outlet_new(&x->x_obj, gensym("float")); ! ! for (i=0;i<VOICES;i++) { ! x->previous_voices[i] = 0; ! x->current_voices[i] = 0; }
return (x); --- 308,317 ---- x->small_intervals_out = outlet_new(&x->x_obj, gensym("float")); x->i_like_parallelism_out = outlet_new(&x->x_obj, gensym("float")); ! x->voices = VOICES; ! if (argc>0) { ! x->voices = atom_getintarg(0, argc, argv); } + voicing_analyzer_allocate(x);
return (x); *************** *** 269,273 **** class_addmethod(voicing_analyzer_class, (t_method)print_help, gensym("help"),0, 0); class_addlist(voicing_analyzer_class, (t_method)set_current_voices); !
} --- 324,330 ---- class_addmethod(voicing_analyzer_class, (t_method)print_help, gensym("help"),0, 0); class_addlist(voicing_analyzer_class, (t_method)set_current_voices); ! // set number of voices ! class_addmethod(voicing_analyzer_class, (t_method)set_voices, gensym("voices"), A_DEFFLOAT, 0); !
}