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);
!
}