aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavide Morelli <morellid@users.sourceforge.net>2006-01-21 11:22:52 +0000
committerDavide Morelli <morellid@users.sourceforge.net>2006-01-21 11:22:52 +0000
commite39b05789f12947502eba1114c9682cb0305bdd2 (patch)
tree8273bfbcf91021b3b31d1f18330dadf82fff05ae
parent8bda90bf0ab202a9916ecabbc9372000642c3be7 (diff)
number of voices is now settable
svn path=/trunk/externals/frankenstein/; revision=4459
-rwxr-xr-xharmonizer.c132
-rwxr-xr-xtest-harmonizer2.pd1160
-rwxr-xr-xvoicing_analyzer.c117
3 files changed, 773 insertions, 636 deletions
diff --git a/harmonizer.c b/harmonizer.c
index 27afb8f..2912291 100755
--- a/harmonizer.c
+++ b/harmonizer.c
@@ -73,13 +73,15 @@ typedef struct _harmonizer
{
t_object x_obj; // myself
// genotypes
- int population[MAX_POPULATION][VOICES];
- int current_voices[VOICES];
+ //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;
float i_like_parallelism;
@@ -235,7 +237,7 @@ void harmonizer_init_pop(t_harmonizer *x)
double rnd;
for (i=0; i<MAX_POPULATION; i++)
{
- for (j=0; j<VOICES; j++)
+ for (j=0; j<x->voices; j++)
{
/*
// totally randome version
@@ -285,11 +287,28 @@ void harmonizer_init_pop(t_harmonizer *x)
}
}
+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)
{
// 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);
}
// here i evaluate this voicing
@@ -299,20 +318,34 @@ int fitness(t_harmonizer *x, int *candidate)
float wideness, ftmp;
short int chord_notes[4];
short int chord_notes_ok[4];
- short int transitions[VOICES];
- short int directions[VOICES];
+ //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 notes[VOICES];
+ //short int intervals[VOICES][VOICES];
+ short int **intervals;
+ //short int notes[VOICES];
+ short int *notes;
res=50; // starting fitness
if (DEBUG_VERBOSE)
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<VOICES; i++)
+ for (i=0; i<x->voices; i++)
{
notes[i]=candidate[i];
transitions[i] = candidate[i] - x->current_voices[i];
@@ -324,16 +357,16 @@ int fitness(t_harmonizer *x, int *candidate)
post("directions[%i]=%i", i, directions[i]);
}
- for (i=0; i<VOICES; i++)
+ for (i=0; i<x->voices; i++)
{
- for (j=i+1; j<VOICES; j++)
+ for (j=i+1; j<x->voices; j++)
{
intervals[i][j] = (candidate[i]-candidate[j])%12 ;
if (DEBUG_VERBOSE)
post("intervals[%i][%i]=%i", i, j, intervals[i][j]);
}
}
- SGLIB_ARRAY_SINGLE_QUICK_SORT(short int, notes, VOICES, SGLIB_NUMERIC_COMPARATOR)
+ SGLIB_ARRAY_SINGLE_QUICK_SORT(short int, notes, x->voices, SGLIB_NUMERIC_COMPARATOR)
// all same direction?
if ( directions[0]==directions[1] &&
@@ -348,9 +381,9 @@ int fitness(t_harmonizer *x, int *candidate)
// parallel 5ths or octaves? (if yes return 0)
// how?
// hidden 8ths nor 5ths ?
- for (i=0; i<VOICES; i++)
+ for (i=0; i<x->voices; i++)
{
- for (j=i+1; j<VOICES; j++)
+ for (j=i+1; j<x->voices; j++)
{
if (intervals[i][j]==7 || intervals[i][j]==0)
{
@@ -370,16 +403,16 @@ int fitness(t_harmonizer *x, int *candidate)
// TODO: use notes[]
// are voices average centered?
tmp=0;
- for (i=1; i<VOICES; i++)
+ for (i=1; i<x->voices; i++)
{
tmp+=notes[i];
if (DEBUG_VERBOSE)
post("average note is %i at passage %i", tmp, i);
}
// this is the average note
- tmp = tmp/(VOICES-1);
+ tmp = tmp/(x->voices-1);
if (DEBUG_VERBOSE)
- post("average note is %i after division by (VOICES-1)", tmp);
+ 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
res += 30;
@@ -406,7 +439,7 @@ int fitness(t_harmonizer *x, int *candidate)
//res+=50;
if (DEBUG_VERBOSE)
post("res before transitions %i", res);
- for (i=0; i<VOICES; i++)
+ for (i=0; i<x->voices; i++)
{
if (DEBUG_VERBOSE)
post("transitions[%i] = %i",i, transitions[i]);
@@ -445,7 +478,7 @@ int fitness(t_harmonizer *x, int *candidate)
chord_notes[i] = (x->target_notes[i]) % 12;
chord_notes_ok[i] = 0;
}
- for (i=0; i<VOICES; i++)
+ for (i=0; i<x->voices; i++)
{
tmp = notes[i] % 12;
for (j=0; j<4; j++)
@@ -472,11 +505,11 @@ int fitness(t_harmonizer *x, int *candidate)
{
res -= 2^chord_notes_ok[j];
}
- res += 2*VOICES;
+ res += 2*x->voices;
// penalize too many basses
tmp = 0;
- for (i=0; i<VOICES; i++)
+ for (i=0; i<x->voices; i++)
{
if (notes[i]<48)
tmp++;
@@ -492,7 +525,7 @@ int fitness(t_harmonizer *x, int *candidate)
// now wideness
min = notes[0];
- max = notes[VOICES-1];
+ max = notes[x->voices-1];
distance = max - min;
wideness = (float) (((float)distance) / ((float)12));
ftmp = fabs(wideness - x->wideness);
@@ -501,6 +534,16 @@ int fitness(t_harmonizer *x, int *candidate)
if (DEBUG_VERBOSE)
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;
}
@@ -510,18 +553,18 @@ void new_genotype(t_harmonizer *x, int *mammy, int *daddy, int *kid)
double rnd;
// crossover
rnd = rand()/((double)RAND_MAX + 1);
- split = rnd * VOICES;
+ split = rnd * x->voices;
for (i=0; i<split; i++)
{
kid[i]=mammy[i];
}
- for (i=split; i<VOICES; i++)
+ for (i=split; i<x->voices; i++)
{
kid[i]=daddy[i];
}
// mutation
- for (i=0; i<VOICES; i++)
+ for (i=0; i<x->voices; i++)
{
rnd = rand()/((double)RAND_MAX + 1);
if (rnd < DEF_PROB_MUTATION)
@@ -545,7 +588,11 @@ void generate_voicing(t_harmonizer *x)
fitness_list_element fitness_evaluations[MAX_POPULATION];
int i, generation, mum, dad, winner;
double rnd;
- t_atom lista[VOICES];
+ //t_atom lista[VOICES];
+ t_atom *lista;
+
+ lista = malloc(sizeof(t_atom)*x->voices);
+
// inizialize tables of notes
build_possible_notes_table(x);
// inizialize population
@@ -591,7 +638,7 @@ void generate_voicing(t_harmonizer *x)
if (DEBUG)
post("winner fitness = %i", fitness_evaluations[MAX_POPULATION-1].fitness);
- for (i=0;i<VOICES;i++)
+ for (i=0;i<x->voices;i++)
{
SETFLOAT(lista+i, x->population[winner][i]);
}
@@ -599,8 +646,9 @@ void generate_voicing(t_harmonizer *x)
// send output array to outlet
outlet_anything(x->l_out,
gensym("list") ,
- VOICES,
+ x->voices,
lista);
+ free(lista);
}
// if i want another voicing i can send a bang
@@ -613,13 +661,13 @@ void set_current_voices(t_harmonizer *x, t_symbol *sl, int argc, t_atom *argv)
{
int i=0;
- if (argc<VOICES)
+ if (argc<x->voices)
{
error("insufficient notes sent!");
return;
}
// fill input array with actual data sent to inlet
- for (i=0;i<VOICES;i++)
+ for (i=0;i<x->voices;i++)
{
x->current_voices[i] = atom_getint(argv++);
}
@@ -680,14 +728,28 @@ void set_small_intervals(t_harmonizer *x, t_floatarg f)
x->small_intervals = newval;
}
+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 %i midi notes", VOICES);
+ 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");
post("i_like_parallelism float: do I want parallelism? from -1 (I don't want them) to 1 (I like them), 0 means I don't care, default = -1");
@@ -714,6 +776,12 @@ void *harmonizer_new(t_symbol *s, int argc, t_atom *argv)
x->wideness = DEF_WIDENESS;
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);
}
@@ -731,6 +799,8 @@ void harmonizer_setup(void)
class_addmethod(harmonizer_class, (t_method)set_center_note, gensym("center_note"), A_DEFFLOAT, 0);
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);
}
diff --git a/test-harmonizer2.pd b/test-harmonizer2.pd
index a3bf592..099e127 100755
--- a/test-harmonizer2.pd
+++ b/test-harmonizer2.pd
@@ -1,575 +1,585 @@
-#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
-current chord. you can send "next x" where x is from 0 to 1 \, 0 =
-max novelty \, 1= min novelty;
-#X text 56 259 you can save graph state sending the write message;
-#X restore 607 47 pd readme;
-#X obj 121 329 harmonizer;
-#X msg 52 286 current \$1;
-#X msg 158 283 target \$1;
-#X obj 52 262 symbol;
-#X obj 52 242 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
--1;
-#X obj 157 261 symbol;
-#X obj 289 261 int 36;
-#X obj 355 262 int 60;
-#X obj 426 260 int 67;
-#X obj 494 259 int 76;
-#X obj 566 262 int 84;
-#X obj 335 289 pack f f f f f;
-#X obj 358 233 t b b b b b;
-#X obj 264 329 unpack f f f f f;
-#X obj 127 108 symbol;
-#X obj 98 43 bng 15 250 50 0 empty empty change_chord 0 -6 0 8 -262144
--1 -1;
-#X msg 127 132 set \$1;
-#N canvas 0 22 714 424 midi 0;
-#X obj 141 253 outlet;
-#X obj 271 31 notein;
-#X obj 271 66 chord 59;
-#X msg 175 149 add \$1;
-#X obj 175 121 symbol;
-#X obj 176 94 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
--1;
-#X obj 248 163 symbol;
-#X obj 249 136 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
--1;
-#X msg 248 191 set \$1;
-#X symbolatom 311 101 25 0 0 0 - - -;
-#X connect 1 0 2 0;
-#X connect 1 1 2 1;
-#X connect 2 2 4 1;
-#X connect 2 2 6 1;
-#X connect 2 2 9 0;
-#X connect 3 0 0 0;
-#X connect 4 0 3 0;
-#X connect 5 0 4 0;
-#X connect 6 0 8 0;
-#X connect 7 0 6 0;
-#X connect 8 0 0 0;
-#X restore 512 135 pd midi;
-#N canvas 0 22 462 312 fileIO 0;
-#X obj 143 225 outlet;
-#X msg 115 77 write test.graph;
-#X msg 145 105 read test.graph;
-#X msg 175 135 init 1;
-#X connect 1 0 0 0;
-#X connect 2 0 0 0;
-#X connect 3 0 0 0;
-#X restore 429 134 pd fileIO;
-#X obj 100 73 t b b;
-#X obj 157 228 t b a;
-#X obj 63 359 bang;
-#X obj 221 380 mtof;
-#X obj 270 379 mtof;
-#X obj 355 383 mtof;
-#X obj 144 386 print;
-#X obj 74 111 f 1;
-#X msg 59 135 next \$1;
-#X obj 63 70 vsl 15 30 0 1 0 0 empty empty empty 0 -8 0 8 -262144 -1
--1 0 1;
-#X floatatom 32 112 5 0 0 0 - - -;
-#X obj 527 400 loadbang;
-#X obj 313 382 mtof;
-#X obj 399 384 mtof;
-#X obj 462 22 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
-;
-#X obj 462 41 metro 7000;
-#X obj 13 32 r novelty;
-#X obj 599 121 int 0;
-#X obj 646 120 + 1;
-#X obj 600 171 tabread tab-novelty;
-#X obj 600 194 s novelty;
-#X obj 685 119 table tab-novelty;
-#X obj 600 147 % 10;
-#X obj 462 63 t b b;
-#X msg 489 365 \; tab-novelty 0 1 1 0.8 0.7 0.3 0.5 0.9 0.1 0 0.2;
-#X obj 203 97 symbol;
-#X msg 203 125 tonality \$1;
-#X obj 203 73 bng 15 250 50 0 empty empty change 0 -6 0 8 -262144 -1
--1;
-#X obj 19 160 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
--1;
-#X symbolatom 305 204 15 0 0 2 tonality - -;
-#X obj 307 94 symbol;
-#X obj 307 70 bng 15 250 50 0 empty empty change 0 -6 0 8 -262144 -1
--1;
-#X msg 307 122 modulation \$1;
-#X obj 445 189 print sequence;
-#X msg 235 15 search 9 1 5 0.9;
-#X msg 262 407 i9 0 10 \$1 80 0.5;
-#X msg 502 440 i25 0 17000 0.98 0.8 20000;
-#X msg 500 464 i10 0 17000 10 30;
-#X msg 500 487 i30 0 17000 2 30;
-#X obj 172 422 print;
-#X obj 265 445 s csound;
-#N canvas 0 25 807 561 bay 0;
-#X obj 12 83 loadbang;
-#N canvas 0 22 759 336 ascoltaHits 0;
-#X obj 161 223 outlet;
-#X obj 146 33 r 1-hit;
-#X obj 147 54 bang;
-#X msg 147 83 60;
-#X obj 198 57 bang;
-#X obj 197 36 r 2-hit;
-#X msg 198 86 72;
-#X obj 254 57 bang;
-#X msg 254 86 48;
-#X obj 253 36 r 3-hit;
-#X obj 303 60 bang;
-#X msg 303 89 67;
-#X obj 303 39 r 4-hit;
-#X obj 359 60 bang;
-#X obj 422 60 bang;
-#X obj 422 39 r 6-hit;
-#X obj 359 39 r 5-hit;
-#X msg 359 89 76;
-#X msg 422 89 36;
-#X connect 1 0 2 0;
-#X connect 2 0 3 0;
-#X connect 3 0 0 0;
-#X connect 4 0 6 0;
-#X connect 5 0 4 0;
-#X connect 6 0 0 0;
-#X connect 7 0 8 0;
-#X connect 8 0 0 0;
-#X connect 9 0 7 0;
-#X connect 10 0 11 0;
-#X connect 11 0 0 0;
-#X connect 12 0 10 0;
-#X connect 13 0 17 0;
-#X connect 14 0 18 0;
-#X connect 15 0 14 0;
-#X connect 16 0 13 0;
-#X connect 17 0 0 0;
-#X connect 18 0 0 0;
-#X restore 428 102 pd ascoltaHits;
-#X obj 430 164 mtof;
-#N canvas 0 22 462 312 chords 0;
-#X obj 132 43 inlet;
-#X obj 131 240 outlet;
-#X obj 262 31 loadbang;
-#X obj 260 74 metro 20000;
-#X obj 257 115 int 0;
-#X obj 303 117 + 1;
-#X obj 257 136 % 2;
-#X obj 246 162 select 0 1;
-#X obj 131 214 + 0;
-#X msg 243 182 0;
-#X msg 270 184 7;
-#X msg 260 54 1;
-#X connect 0 0 8 0;
-#X connect 2 0 11 0;
-#X connect 3 0 4 0;
-#X connect 4 0 5 0;
-#X connect 4 0 6 0;
-#X connect 5 0 4 1;
-#X connect 6 0 7 0;
-#X connect 7 0 9 0;
-#X connect 7 1 10 0;
-#X connect 8 0 1 0;
-#X connect 9 0 8 1;
-#X connect 10 0 8 1;
-#X connect 11 0 3 0;
-#X restore 430 131 pd chords;
-#N canvas 0 22 940 672 ascolta-valori 0;
-#X obj 135 554 outlet;
-#X obj 28 146 line;
-#X msg 27 123 \$1 100;
-#X msg 27 175 control amp1 \$1;
-#X obj 146 100 line;
-#X msg 145 77 \$1 100;
-#X obj 144 26 + 1;
-#X obj 143 51 / 2;
-#X obj 265 143 line;
-#X msg 264 119 \$1 100;
-#X obj 382 135 line;
-#X msg 381 112 \$1 100;
-#X obj 380 61 + 1;
-#X obj 379 86 / 2;
-#X msg 264 171 control amp2 \$1;
-#X obj 297 304 line;
-#X msg 296 281 \$1 100;
-#X obj 414 288 line;
-#X msg 413 265 \$1 100;
-#X obj 412 214 + 1;
-#X obj 411 239 / 2;
-#X obj 533 331 line;
-#X msg 532 307 \$1 100;
-#X obj 650 323 line;
-#X msg 649 300 \$1 100;
-#X obj 648 249 + 1;
-#X obj 647 274 / 2;
-#X msg 296 324 control amp3 \$1;
-#X msg 531 359 control amp4 \$1;
-#N canvas 0 22 678 338 graph16 0;
-#X array vol 100 float 3;
-#A 0 0.382146 0.444444 0.527258 0.5757 0.610071 0.636731 0.658514 0.676931
-0.692884 0.706956 0.719544 0.730931 0.741327 0.75089 0.759744 0.767987
-0.775698 0.782941 0.78977 0.796229 0.802357 0.808187 0.813745 0.819055
-0.82414 0.829017 0.833703 0.838212 0.842557 0.84675 0.8508 0.854718
-0.858511 0.862187 0.865754 0.869217 0.872583 0.875856 0.879043 0.882146
-0.885171 0.888121 0.891 0.893811 0.896558 0.899243 0.901869 0.904438
-0.906954 0.909417 0.911831 0.914197 0.916517 0.918792 0.921026 0.923218
-0.925371 0.927485 0.929563 0.931605 0.933613 0.935588 0.937531 0.939443
-0.941324 0.943177 0.945001 0.946797 0.948567 0.950311 0.952031 0.953725
-0.955396 0.957044 0.95867 0.960273 0.961856 0.963418 0.964959 0.966481
-0.967984 0.969468 0.970934 0.972382 0.973813 0.975227 0.976624 0.978006
-0.979371 0.980721 0.982056 0.983376 0.984682 0.985974 0.987252 0.988516
-0.989767 0.991005 0.99223 1.0615;
-#X coords 0 1 99 0 200 140 1;
-#X restore 532 24 graph;
-#X obj 26 101 tabread vol;
-#X obj 28 76 * 100;
-#X obj 265 97 tabread vol;
-#X obj 262 75 * 100;
-#X obj 28 48 clip 0 1;
-#X obj 262 40 clip 0 1;
-#X obj 307 264 tabread vol;
-#X obj 307 242 * 100;
-#X obj 308 222 clip 0 1;
-#X obj 534 284 tabread vol;
-#X obj 534 262 * 100;
-#X obj 535 242 clip 0 1;
-#X msg 149 129 control pos1 \$1;
-#X msg 385 164 control pos2 \$1;
-#X msg 417 317 control pos3 \$1;
-#X msg 653 352 control pos4 \$1;
-#X obj 434 493 line;
-#X msg 433 469 \$1 100;
-#X obj 551 485 line;
-#X msg 550 462 \$1 100;
-#X obj 549 411 + 1;
-#X obj 548 436 / 2;
-#X obj 435 446 tabread vol;
-#X obj 435 424 * 100;
-#X obj 436 404 clip 0 1;
-#X msg 432 521 control amp5 \$1;
-#X msg 553 514 control pos5 \$1;
-#X obj 28 13 r 1-velo;
-#X obj 145 6 r 1-x;
-#X obj 264 17 r 2-velo;
-#X obj 296 202 r 3-velo;
-#X obj 412 194 r 3-x;
-#X obj 528 216 r 4-velo;
-#X obj 649 229 r 4-x;
-#X obj 429 378 r 5-velo;
-#X obj 550 391 r 5-x;
-#X obj 382 40 r 2-x;
-#X obj 839 58 + 1;
-#X obj 761 97 log;
-#X obj 803 59 int 1;
-#X obj 759 119 / 4.65;
-#X obj 807 83 t f f;
-#X obj 785 33 metro 10;
-#X obj 785 14 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
-;
-#X obj 763 183 tabwrite vol;
-#X msg 848 32 1;
-#X obj 758 141 + 0.8;
-#X obj 757 160 / 1.8;
-#X connect 1 0 3 0;
-#X connect 2 0 1 0;
-#X connect 3 0 0 0;
-#X connect 4 0 42 0;
-#X connect 5 0 4 0;
-#X connect 6 0 7 0;
-#X connect 7 0 5 0;
-#X connect 8 0 14 0;
-#X connect 9 0 8 0;
-#X connect 10 0 43 0;
-#X connect 11 0 10 0;
-#X connect 12 0 13 0;
-#X connect 13 0 11 0;
-#X connect 14 0 0 0;
-#X connect 15 0 27 0;
-#X connect 16 0 15 0;
-#X connect 17 0 44 0;
-#X connect 18 0 17 0;
-#X connect 19 0 20 0;
-#X connect 20 0 18 0;
-#X connect 21 0 28 0;
-#X connect 22 0 21 0;
-#X connect 23 0 45 0;
-#X connect 24 0 23 0;
-#X connect 25 0 26 0;
-#X connect 26 0 24 0;
-#X connect 27 0 0 0;
-#X connect 28 0 0 0;
-#X connect 30 0 2 0;
-#X connect 31 0 30 0;
-#X connect 32 0 9 0;
-#X connect 33 0 32 0;
-#X connect 34 0 31 0;
-#X connect 35 0 33 0;
-#X connect 36 0 16 0;
-#X connect 37 0 36 0;
-#X connect 38 0 37 0;
-#X connect 39 0 22 0;
-#X connect 40 0 39 0;
-#X connect 41 0 40 0;
-#X connect 42 0 0 0;
-#X connect 43 0 0 0;
-#X connect 44 0 0 0;
-#X connect 45 0 0 0;
-#X connect 46 0 55 0;
-#X connect 47 0 46 0;
-#X connect 48 0 56 0;
-#X connect 49 0 48 0;
-#X connect 50 0 51 0;
-#X connect 51 0 49 0;
-#X connect 52 0 47 0;
-#X connect 53 0 52 0;
-#X connect 54 0 53 0;
-#X connect 55 0 0 0;
-#X connect 56 0 0 0;
-#X connect 57 0 34 0;
-#X connect 58 0 6 0;
-#X connect 59 0 35 0;
-#X connect 60 0 38 0;
-#X connect 61 0 19 0;
-#X connect 62 0 41 0;
-#X connect 63 0 25 0;
-#X connect 64 0 54 0;
-#X connect 65 0 50 0;
-#X connect 66 0 12 0;
-#X connect 67 0 69 1;
-#X connect 68 0 70 0;
-#X connect 69 0 67 0;
-#X connect 69 0 71 0;
-#X connect 70 0 76 0;
-#X connect 71 0 68 0;
-#X connect 71 1 74 1;
-#X connect 72 0 69 0;
-#X connect 73 0 72 0;
-#X connect 75 0 69 0;
-#X connect 76 0 77 0;
-#X connect 77 0 74 0;
-#X restore 592 84 pd ascolta-valori;
-#X obj 567 118 bay --------;
-#X obj 367 279 catch~ mainL;
-#X obj 491 281 catch~ mainR;
-#X obj 376 318 *~ 0.01;
-#X obj 467 319 *~ 0.01;
-#X obj 701 211 vsl 15 128 0 0.8 0 0 empty empty empty 0 -8 0 8 -262144
--1 -1 317 1;
-#X floatatom 700 346 5 0 0 0 - - -;
-#X obj 750 195 loadbang;
-#X msg 750 216 0.02;
-#X obj 265 365 csound~ 2 2;
-#X obj 332 137 r csound;
-#X msg 156 24 i9 0 8 400 90 0.3;
-#X msg 23 159 i30 0 17000 2 30;
-#X msg 23 136 i10 0 17000 10 30;
-#X msg 24 112 i25 0 17000 0.98 0.8 20000;
-#X msg 1 182 bang \; csound bin /usr/local/bin/csound \; csound orc
-bay.orc \; csound sco bay.sco \; csound csound -dm0 \; csound bang
-\; pd dsp 1;
-#X msg 267 58 i9 0 8 450 90 0.3;
-#X msg 293 20 i9 0 8 500 90 0.3;
-#X obj 255 392 /~ 32767;
-#X obj 324 391 /~ 32767;
-#N canvas 77 25 718 506 note---- 0;
-#X obj 95 284 outlet;
-#X obj 95 222 mtof;
-#X obj 202 211 mtof;
-#X obj 309 220 mtof;
-#X obj 412 221 mtof;
-#X obj 120 133 inlet;
-#X obj 195 140 inlet;
-#X obj 310 163 inlet;
-#X obj 414 170 inlet;
-#X obj 533 224 mtof;
-#X obj 535 173 inlet;
-#X obj 204 283 outlet;
-#X obj 303 284 outlet;
-#X obj 408 280 outlet;
-#X obj 539 274 outlet;
-#X connect 1 0 0 0;
-#X connect 2 0 11 0;
-#X connect 3 0 12 0;
-#X connect 4 0 13 0;
-#X connect 5 0 1 0;
-#X connect 6 0 2 0;
-#X connect 7 0 3 0;
-#X connect 8 0 4 0;
-#X connect 9 0 14 0;
-#X connect 10 0 9 0;
-#X restore 567 142 pd note----;
-#X obj 324 411 /~ 1.5;
-#X obj 255 412 /~ 1.5;
-#X obj 235 450 outlet~;
-#X obj 328 446 outlet~;
-#X msg 404 197 i9 0 14 \$1 90 0.3;
-#X obj 408 242 inlet~;
-#X obj 479 243 inlet~;
-#X connect 0 0 20 0;
-#X connect 0 0 17 0;
-#X connect 0 0 18 0;
-#X connect 0 0 19 0;
-#X connect 1 0 3 0;
-#X connect 2 0 30 0;
-#X connect 3 0 2 0;
-#X connect 5 0 25 0;
-#X connect 5 1 25 1;
-#X connect 5 2 25 2;
-#X connect 5 3 25 3;
-#X connect 5 4 25 4;
-#X connect 6 0 8 0;
-#X connect 7 0 9 0;
-#X connect 8 0 14 0;
-#X connect 9 0 14 1;
-#X connect 10 0 9 1;
-#X connect 10 0 8 1;
-#X connect 10 0 11 0;
-#X connect 12 0 13 0;
-#X connect 13 0 10 0;
-#X connect 14 0 23 0;
-#X connect 14 1 24 0;
-#X connect 15 0 14 0;
-#X connect 16 0 14 0;
-#X connect 17 0 14 0;
-#X connect 18 0 14 0;
-#X connect 19 0 14 0;
-#X connect 21 0 14 0;
-#X connect 22 0 14 0;
-#X connect 23 0 27 0;
-#X connect 24 0 26 0;
-#X connect 25 0 30 0;
-#X connect 25 1 30 0;
-#X connect 25 2 30 0;
-#X connect 25 3 30 0;
-#X connect 25 4 30 0;
-#X connect 26 0 29 0;
-#X connect 27 0 28 0;
-#X connect 30 0 14 0;
-#X connect 31 0 8 0;
-#X connect 32 0 9 0;
-#X restore 195 544 pd bay;
-#X obj 242 683 dac~;
-#X obj 194 629 +~;
-#X obj 294 632 +~;
-#X obj 151 527 vsl 15 128 0.01 1 1 0 empty empty empty 0 -8 0 8 -262144
--1 -1 8262 1;
-#X obj 186 599 *~ 0.5;
-#X obj 238 600 *~ 0.5;
-#X obj 87 563 loadbang;
-#X floatatom 149 660 5 0 0 0 - - -;
-#X obj 380 526 vsl 15 128 0.1 3 0 0 empty empty empty 0 -8 0 8 -262144
--1 -1 8321 1;
-#X floatatom 378 659 5 0 0 0 - - -;
-#X obj 217 653 *~ 1;
-#X obj 269 654 *~ 1;
-#X obj 311 574 loadbang;
-#X text 67 620 volume bay;
-#X msg 313 597 2;
-#X msg 104 594 0.2;
-#X obj 83 169 chords_memory test.graph;
-#X connect 2 0 15 0;
-#X connect 2 0 27 0;
-#X connect 3 0 2 0;
-#X connect 4 0 2 0;
-#X connect 5 0 3 0;
-#X connect 6 0 5 0;
-#X connect 7 0 4 0;
-#X connect 8 0 13 0;
-#X connect 9 0 13 1;
-#X connect 10 0 13 2;
-#X connect 11 0 13 3;
-#X connect 12 0 13 4;
-#X connect 13 0 2 0;
-#X connect 14 0 8 0;
-#X connect 14 1 9 0;
-#X connect 14 2 10 0;
-#X connect 14 3 11 0;
-#X connect 14 4 12 0;
-#X connect 15 0 8 1;
-#X connect 15 0 23 0;
-#X connect 15 0 24 0;
-#X connect 15 1 9 1;
-#X connect 15 1 25 0;
-#X connect 15 2 10 1;
-#X connect 15 2 33 0;
-#X connect 15 3 11 1;
-#X connect 15 3 26 0;
-#X connect 15 4 12 1;
-#X connect 15 4 34 0;
-#X connect 16 0 18 0;
-#X connect 17 0 21 0;
-#X connect 18 0 79 0;
-#X connect 19 0 79 0;
-#X connect 20 0 79 0;
-#X connect 21 0 28 0;
-#X connect 22 0 14 0;
-#X connect 22 1 7 0;
-#X connect 23 0 5 0;
-#X connect 24 0 56 0;
-#X connect 25 0 56 0;
-#X connect 26 0 56 0;
-#X connect 28 0 29 0;
-#X connect 29 0 79 0;
-#X connect 30 0 28 1;
-#X connect 30 0 31 0;
-#X connect 32 0 57 0;
-#X connect 32 0 58 0;
-#X connect 32 0 59 0;
-#X connect 32 0 45 0;
-#X connect 33 0 56 0;
-#X connect 34 0 56 0;
-#X connect 35 0 36 0;
-#X connect 36 0 44 0;
-#X connect 37 0 30 0;
-#X connect 38 0 39 0;
-#X connect 38 0 43 0;
-#X connect 39 0 38 1;
-#X connect 40 0 41 0;
-#X connect 43 0 40 0;
-#X connect 44 0 21 0;
-#X connect 44 1 38 0;
-#X connect 46 0 47 0;
-#X connect 47 0 79 0;
-#X connect 48 0 46 0;
-#X connect 49 0 79 0;
-#X connect 51 0 53 0;
-#X connect 52 0 51 0;
-#X connect 53 0 79 0;
-#X connect 55 0 79 0;
-#X connect 56 0 61 0;
-#X connect 56 0 60 0;
-#X connect 57 0 61 0;
-#X connect 58 0 61 0;
-#X connect 59 0 61 0;
-#X connect 62 0 67 0;
-#X connect 62 1 68 0;
-#X connect 64 0 73 0;
-#X connect 65 0 74 0;
-#X connect 66 0 67 1;
-#X connect 66 0 68 1;
-#X connect 66 0 70 0;
-#X connect 67 0 64 0;
-#X connect 68 0 65 0;
-#X connect 69 0 78 0;
-#X connect 71 0 72 0;
-#X connect 71 0 73 1;
-#X connect 71 0 74 1;
-#X connect 73 0 63 0;
-#X connect 74 0 63 1;
-#X connect 75 0 77 0;
-#X connect 77 0 71 0;
-#X connect 78 0 66 0;
-#X connect 79 0 0 0;
-#X connect 79 0 5 1;
-#X connect 79 0 22 0;
-#X connect 79 0 46 1;
-#X connect 79 0 16 0;
-#X connect 79 0 51 1;
-#X connect 79 1 50 0;
-#X connect 79 2 54 0;
+#N canvas 194 23 947 709 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
+current chord. you can send "next x" where x is from 0 to 1 \, 0 =
+max novelty \, 1= min novelty;
+#X text 56 259 you can save graph state sending the write message;
+#X restore 607 47 pd readme;
+#X msg 52 286 current \$1;
+#X msg 158 283 target \$1;
+#X obj 52 262 symbol;
+#X obj 52 242 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 157 261 symbol;
+#X obj 289 261 int 36;
+#X obj 355 262 int 60;
+#X obj 426 260 int 67;
+#X obj 494 259 int 76;
+#X obj 566 262 int 84;
+#X obj 335 289 pack f f f f f;
+#X obj 358 233 t b b b b b;
+#X obj 264 329 unpack f f f f f;
+#X obj 127 108 symbol;
+#X obj 98 43 bng 15 250 50 0 empty empty change_chord 0 -6 0 8 -262144
+-1 -1;
+#X msg 127 132 set \$1;
+#N canvas 0 22 714 424 midi 0;
+#X obj 141 253 outlet;
+#X obj 271 31 notein;
+#X obj 271 66 chord 59;
+#X msg 175 149 add \$1;
+#X obj 175 121 symbol;
+#X obj 176 94 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 248 163 symbol;
+#X obj 249 136 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 248 191 set \$1;
+#X symbolatom 311 101 25 0 0 0 - - -;
+#X connect 1 0 2 0;
+#X connect 1 1 2 1;
+#X connect 2 2 4 1;
+#X connect 2 2 6 1;
+#X connect 2 2 9 0;
+#X connect 3 0 0 0;
+#X connect 4 0 3 0;
+#X connect 5 0 4 0;
+#X connect 6 0 8 0;
+#X connect 7 0 6 0;
+#X connect 8 0 0 0;
+#X restore 512 135 pd midi;
+#N canvas 0 22 462 312 fileIO 0;
+#X obj 143 225 outlet;
+#X msg 115 77 write test.graph;
+#X msg 145 105 read test.graph;
+#X msg 175 135 init 1;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 0;
+#X restore 429 134 pd fileIO;
+#X obj 100 73 t b b;
+#X obj 157 228 t b a;
+#X obj 63 359 bang;
+#X obj 221 380 mtof;
+#X obj 270 379 mtof;
+#X obj 355 383 mtof;
+#X obj 67 504 print;
+#X obj 74 111 f 1;
+#X msg 59 135 next \$1;
+#X obj 63 70 vsl 15 30 0 1 0 0 empty empty empty 0 -8 0 8 -262144 -1
+-1 0 1;
+#X floatatom 32 112 5 0 0 0 - - -;
+#X obj 527 400 loadbang;
+#X obj 313 382 mtof;
+#X obj 399 384 mtof;
+#X obj 462 22 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 462 41 metro 7000;
+#X obj 13 32 r novelty;
+#X obj 599 121 int 0;
+#X obj 646 120 + 1;
+#X obj 600 171 tabread tab-novelty;
+#X obj 600 194 s novelty;
+#X obj 685 119 table tab-novelty;
+#X obj 600 147 % 10;
+#X obj 462 63 t b b;
+#X msg 489 365 \; tab-novelty 0 1 1 0.8 0.7 0.3 0.5 0.9 0.1 0 0.2;
+#X obj 203 97 symbol;
+#X msg 203 125 tonality \$1;
+#X obj 203 73 bng 15 250 50 0 empty empty change 0 -6 0 8 -262144 -1
+-1;
+#X obj 19 160 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X symbolatom 305 204 15 0 0 2 tonality - -;
+#X obj 307 94 symbol;
+#X obj 307 70 bng 15 250 50 0 empty empty change 0 -6 0 8 -262144 -1
+-1;
+#X msg 307 122 modulation \$1;
+#X obj 445 189 print sequence;
+#X msg 235 15 search 9 1 5 0.9;
+#X msg 262 407 i9 0 10 \$1 80 0.5;
+#X msg 502 440 i25 0 17000 0.98 0.8 20000;
+#X msg 500 464 i10 0 17000 10 30;
+#X msg 500 487 i30 0 17000 2 30;
+#X obj 172 422 print;
+#X obj 265 445 s csound;
+#N canvas 0 25 807 561 bay 0;
+#X obj 12 83 loadbang;
+#N canvas 0 22 759 336 ascoltaHits 0;
+#X obj 161 223 outlet;
+#X obj 146 33 r 1-hit;
+#X obj 147 54 bang;
+#X msg 147 83 60;
+#X obj 198 57 bang;
+#X obj 197 36 r 2-hit;
+#X msg 198 86 72;
+#X obj 254 57 bang;
+#X msg 254 86 48;
+#X obj 253 36 r 3-hit;
+#X obj 303 60 bang;
+#X msg 303 89 67;
+#X obj 303 39 r 4-hit;
+#X obj 359 60 bang;
+#X obj 422 60 bang;
+#X obj 422 39 r 6-hit;
+#X obj 359 39 r 5-hit;
+#X msg 359 89 76;
+#X msg 422 89 36;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
+#X connect 3 0 0 0;
+#X connect 4 0 6 0;
+#X connect 5 0 4 0;
+#X connect 6 0 0 0;
+#X connect 7 0 8 0;
+#X connect 8 0 0 0;
+#X connect 9 0 7 0;
+#X connect 10 0 11 0;
+#X connect 11 0 0 0;
+#X connect 12 0 10 0;
+#X connect 13 0 17 0;
+#X connect 14 0 18 0;
+#X connect 15 0 14 0;
+#X connect 16 0 13 0;
+#X connect 17 0 0 0;
+#X connect 18 0 0 0;
+#X restore 428 102 pd ascoltaHits;
+#X obj 430 164 mtof;
+#N canvas 0 22 462 312 chords 0;
+#X obj 132 43 inlet;
+#X obj 131 240 outlet;
+#X obj 262 31 loadbang;
+#X obj 260 74 metro 20000;
+#X obj 257 115 int 0;
+#X obj 303 117 + 1;
+#X obj 257 136 % 2;
+#X obj 246 162 select 0 1;
+#X obj 131 214 + 0;
+#X msg 243 182 0;
+#X msg 270 184 7;
+#X msg 260 54 1;
+#X connect 0 0 8 0;
+#X connect 2 0 11 0;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 4 0 6 0;
+#X connect 5 0 4 1;
+#X connect 6 0 7 0;
+#X connect 7 0 9 0;
+#X connect 7 1 10 0;
+#X connect 8 0 1 0;
+#X connect 9 0 8 1;
+#X connect 10 0 8 1;
+#X connect 11 0 3 0;
+#X restore 430 131 pd chords;
+#N canvas 0 22 940 672 ascolta-valori 0;
+#X obj 135 554 outlet;
+#X obj 28 146 line;
+#X msg 27 123 \$1 100;
+#X msg 27 175 control amp1 \$1;
+#X obj 146 100 line;
+#X msg 145 77 \$1 100;
+#X obj 144 26 + 1;
+#X obj 143 51 / 2;
+#X obj 265 143 line;
+#X msg 264 119 \$1 100;
+#X obj 382 135 line;
+#X msg 381 112 \$1 100;
+#X obj 380 61 + 1;
+#X obj 379 86 / 2;
+#X msg 264 171 control amp2 \$1;
+#X obj 297 304 line;
+#X msg 296 281 \$1 100;
+#X obj 414 288 line;
+#X msg 413 265 \$1 100;
+#X obj 412 214 + 1;
+#X obj 411 239 / 2;
+#X obj 533 331 line;
+#X msg 532 307 \$1 100;
+#X obj 650 323 line;
+#X msg 649 300 \$1 100;
+#X obj 648 249 + 1;
+#X obj 647 274 / 2;
+#X msg 296 324 control amp3 \$1;
+#X msg 531 359 control amp4 \$1;
+#N canvas 0 22 678 338 graph16 0;
+#X array vol 100 float 3;
+#A 0 0.382146 0.444444 0.527258 0.5757 0.610071 0.636731 0.658514 0.676931
+0.692884 0.706956 0.719544 0.730931 0.741327 0.75089 0.759744 0.767987
+0.775698 0.782941 0.78977 0.796229 0.802357 0.808187 0.813745 0.819055
+0.82414 0.829017 0.833703 0.838212 0.842557 0.84675 0.8508 0.854718
+0.858511 0.862187 0.865754 0.869217 0.872583 0.875856 0.879043 0.882146
+0.885171 0.888121 0.891 0.893811 0.896558 0.899243 0.901869 0.904438
+0.906954 0.909417 0.911831 0.914197 0.916517 0.918792 0.921026 0.923218
+0.925371 0.927485 0.929563 0.931605 0.933613 0.935588 0.937531 0.939443
+0.941324 0.943177 0.945001 0.946797 0.948567 0.950311 0.952031 0.953725
+0.955396 0.957044 0.95867 0.960273 0.961856 0.963418 0.964959 0.966481
+0.967984 0.969468 0.970934 0.972382 0.973813 0.975227 0.976624 0.978006
+0.979371 0.980721 0.982056 0.983376 0.984682 0.985974 0.987252 0.988516
+0.989767 0.991005 0.99223 1.0615;
+#X coords 0 1 99 0 200 140 1;
+#X restore 532 24 graph;
+#X obj 26 101 tabread vol;
+#X obj 28 76 * 100;
+#X obj 265 97 tabread vol;
+#X obj 262 75 * 100;
+#X obj 28 48 clip 0 1;
+#X obj 262 40 clip 0 1;
+#X obj 307 264 tabread vol;
+#X obj 307 242 * 100;
+#X obj 308 222 clip 0 1;
+#X obj 534 284 tabread vol;
+#X obj 534 262 * 100;
+#X obj 535 242 clip 0 1;
+#X msg 149 129 control pos1 \$1;
+#X msg 385 164 control pos2 \$1;
+#X msg 417 317 control pos3 \$1;
+#X msg 653 352 control pos4 \$1;
+#X obj 434 493 line;
+#X msg 433 469 \$1 100;
+#X obj 551 485 line;
+#X msg 550 462 \$1 100;
+#X obj 549 411 + 1;
+#X obj 548 436 / 2;
+#X obj 435 446 tabread vol;
+#X obj 435 424 * 100;
+#X obj 436 404 clip 0 1;
+#X msg 432 521 control amp5 \$1;
+#X msg 553 514 control pos5 \$1;
+#X obj 28 13 r 1-velo;
+#X obj 145 6 r 1-x;
+#X obj 264 17 r 2-velo;
+#X obj 296 202 r 3-velo;
+#X obj 412 194 r 3-x;
+#X obj 528 216 r 4-velo;
+#X obj 649 229 r 4-x;
+#X obj 429 378 r 5-velo;
+#X obj 550 391 r 5-x;
+#X obj 382 40 r 2-x;
+#X obj 839 58 + 1;
+#X obj 761 97 log;
+#X obj 803 59 int 1;
+#X obj 759 119 / 4.65;
+#X obj 807 83 t f f;
+#X obj 785 33 metro 10;
+#X obj 785 14 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 763 183 tabwrite vol;
+#X msg 848 32 1;
+#X obj 758 141 + 0.8;
+#X obj 757 160 / 1.8;
+#X connect 1 0 3 0;
+#X connect 2 0 1 0;
+#X connect 3 0 0 0;
+#X connect 4 0 42 0;
+#X connect 5 0 4 0;
+#X connect 6 0 7 0;
+#X connect 7 0 5 0;
+#X connect 8 0 14 0;
+#X connect 9 0 8 0;
+#X connect 10 0 43 0;
+#X connect 11 0 10 0;
+#X connect 12 0 13 0;
+#X connect 13 0 11 0;
+#X connect 14 0 0 0;
+#X connect 15 0 27 0;
+#X connect 16 0 15 0;
+#X connect 17 0 44 0;
+#X connect 18 0 17 0;
+#X connect 19 0 20 0;
+#X connect 20 0 18 0;
+#X connect 21 0 28 0;
+#X connect 22 0 21 0;
+#X connect 23 0 45 0;
+#X connect 24 0 23 0;
+#X connect 25 0 26 0;
+#X connect 26 0 24 0;
+#X connect 27 0 0 0;
+#X connect 28 0 0 0;
+#X connect 30 0 2 0;
+#X connect 31 0 30 0;
+#X connect 32 0 9 0;
+#X connect 33 0 32 0;
+#X connect 34 0 31 0;
+#X connect 35 0 33 0;
+#X connect 36 0 16 0;
+#X connect 37 0 36 0;
+#X connect 38 0 37 0;
+#X connect 39 0 22 0;
+#X connect 40 0 39 0;
+#X connect 41 0 40 0;
+#X connect 42 0 0 0;
+#X connect 43 0 0 0;
+#X connect 44 0 0 0;
+#X connect 45 0 0 0;
+#X connect 46 0 55 0;
+#X connect 47 0 46 0;
+#X connect 48 0 56 0;
+#X connect 49 0 48 0;
+#X connect 50 0 51 0;
+#X connect 51 0 49 0;
+#X connect 52 0 47 0;
+#X connect 53 0 52 0;
+#X connect 54 0 53 0;
+#X connect 55 0 0 0;
+#X connect 56 0 0 0;
+#X connect 57 0 34 0;
+#X connect 58 0 6 0;
+#X connect 59 0 35 0;
+#X connect 60 0 38 0;
+#X connect 61 0 19 0;
+#X connect 62 0 41 0;
+#X connect 63 0 25 0;
+#X connect 64 0 54 0;
+#X connect 65 0 50 0;
+#X connect 66 0 12 0;
+#X connect 67 0 69 1;
+#X connect 68 0 70 0;
+#X connect 69 0 67 0;
+#X connect 69 0 71 0;
+#X connect 70 0 76 0;
+#X connect 71 0 68 0;
+#X connect 71 1 74 1;
+#X connect 72 0 69 0;
+#X connect 73 0 72 0;
+#X connect 75 0 69 0;
+#X connect 76 0 77 0;
+#X connect 77 0 74 0;
+#X restore 592 84 pd ascolta-valori;
+#X obj 567 118 bay --------;
+#X obj 367 279 catch~ mainL;
+#X obj 491 281 catch~ mainR;
+#X obj 376 318 *~ 0.01;
+#X obj 467 319 *~ 0.01;
+#X obj 701 211 vsl 15 128 0 0.8 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 317 1;
+#X floatatom 700 346 5 0 0 0 - - -;
+#X obj 750 195 loadbang;
+#X msg 750 216 0.02;
+#X obj 265 365 csound~ 2 2;
+#X obj 332 137 r csound;
+#X msg 156 24 i9 0 8 400 90 0.3;
+#X msg 23 159 i30 0 17000 2 30;
+#X msg 23 136 i10 0 17000 10 30;
+#X msg 24 112 i25 0 17000 0.98 0.8 20000;
+#X msg 1 182 bang \; csound bin /usr/local/bin/csound \; csound orc
+bay.orc \; csound sco bay.sco \; csound csound -dm0 \; csound bang
+\; pd dsp 1;
+#X msg 267 58 i9 0 8 450 90 0.3;
+#X msg 293 20 i9 0 8 500 90 0.3;
+#X obj 255 392 /~ 32767;
+#X obj 324 391 /~ 32767;
+#N canvas 77 25 718 506 note---- 0;
+#X obj 95 284 outlet;
+#X obj 95 222 mtof;
+#X obj 202 211 mtof;
+#X obj 309 220 mtof;
+#X obj 412 221 mtof;
+#X obj 120 133 inlet;
+#X obj 195 140 inlet;
+#X obj 310 163 inlet;
+#X obj 414 170 inlet;
+#X obj 533 224 mtof;
+#X obj 535 173 inlet;
+#X obj 204 283 outlet;
+#X obj 303 284 outlet;
+#X obj 408 280 outlet;
+#X obj 539 274 outlet;
+#X connect 1 0 0 0;
+#X connect 2 0 11 0;
+#X connect 3 0 12 0;
+#X connect 4 0 13 0;
+#X connect 5 0 1 0;
+#X connect 6 0 2 0;
+#X connect 7 0 3 0;
+#X connect 8 0 4 0;
+#X connect 9 0 14 0;
+#X connect 10 0 9 0;
+#X restore 567 142 pd note----;
+#X obj 324 411 /~ 1.5;
+#X obj 255 412 /~ 1.5;
+#X obj 235 450 outlet~;
+#X obj 328 446 outlet~;
+#X msg 404 197 i9 0 14 \$1 90 0.3;
+#X obj 408 242 inlet~;
+#X obj 479 243 inlet~;
+#X connect 0 0 20 0;
+#X connect 0 0 17 0;
+#X connect 0 0 18 0;
+#X connect 0 0 19 0;
+#X connect 1 0 3 0;
+#X connect 2 0 30 0;
+#X connect 3 0 2 0;
+#X connect 5 0 25 0;
+#X connect 5 1 25 1;
+#X connect 5 2 25 2;
+#X connect 5 3 25 3;
+#X connect 5 4 25 4;
+#X connect 6 0 8 0;
+#X connect 7 0 9 0;
+#X connect 8 0 14 0;
+#X connect 9 0 14 1;
+#X connect 10 0 9 1;
+#X connect 10 0 8 1;
+#X connect 10 0 11 0;
+#X connect 12 0 13 0;
+#X connect 13 0 10 0;
+#X connect 14 0 23 0;
+#X connect 14 1 24 0;
+#X connect 15 0 14 0;
+#X connect 16 0 14 0;
+#X connect 17 0 14 0;
+#X connect 18 0 14 0;
+#X connect 19 0 14 0;
+#X connect 21 0 14 0;
+#X connect 22 0 14 0;
+#X connect 23 0 27 0;
+#X connect 24 0 26 0;
+#X connect 25 0 30 0;
+#X connect 25 1 30 0;
+#X connect 25 2 30 0;
+#X connect 25 3 30 0;
+#X connect 25 4 30 0;
+#X connect 26 0 29 0;
+#X connect 27 0 28 0;
+#X connect 30 0 14 0;
+#X connect 31 0 8 0;
+#X connect 32 0 9 0;
+#X restore 195 544 pd bay;
+#X obj 242 683 dac~;
+#X obj 194 629 +~;
+#X obj 294 632 +~;
+#X obj 151 527 vsl 15 128 0.01 1 1 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 8262 1;
+#X obj 186 599 *~ 0.5;
+#X obj 238 600 *~ 0.5;
+#X obj 87 563 loadbang;
+#X floatatom 149 660 5 0 0 0 - - -;
+#X obj 380 526 vsl 15 128 0.1 3 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 8321 1;
+#X floatatom 378 659 5 0 0 0 - - -;
+#X obj 217 653 *~ 1;
+#X obj 269 654 *~ 1;
+#X obj 311 574 loadbang;
+#X text 67 620 volume bay;
+#X msg 313 597 2;
+#X msg 104 594 0.2;
+#X obj 83 169 chords_memory test.graph;
+#X obj 91 411 print;
+#X msg 23 420 voices \$1;
+#X floatatom 23 399 5 0 0 0 - - -;
+#X obj 88 478 voicing_analyzer 4;
+#X obj 121 330 harmonizer 4;
+#X msg 64 443 help;
+#X connect 2 0 83 0;
+#X connect 3 0 83 0;
+#X connect 4 0 2 0;
+#X connect 5 0 4 0;
+#X connect 6 0 3 0;
+#X connect 7 0 12 0;
+#X connect 8 0 12 1;
+#X connect 9 0 12 2;
+#X connect 10 0 12 3;
+#X connect 11 0 12 4;
+#X connect 12 0 83 0;
+#X connect 13 0 7 0;
+#X connect 13 1 8 0;
+#X connect 13 2 9 0;
+#X connect 13 3 10 0;
+#X connect 13 4 11 0;
+#X connect 14 0 7 1;
+#X connect 14 0 22 0;
+#X connect 14 0 23 0;
+#X connect 14 1 8 1;
+#X connect 14 1 24 0;
+#X connect 14 2 9 1;
+#X connect 14 2 32 0;
+#X connect 14 3 10 1;
+#X connect 14 3 25 0;
+#X connect 14 4 11 1;
+#X connect 14 4 33 0;
+#X connect 15 0 17 0;
+#X connect 16 0 20 0;
+#X connect 17 0 78 0;
+#X connect 18 0 78 0;
+#X connect 19 0 78 0;
+#X connect 20 0 27 0;
+#X connect 21 0 13 0;
+#X connect 21 1 6 0;
+#X connect 22 0 4 0;
+#X connect 23 0 55 0;
+#X connect 24 0 55 0;
+#X connect 25 0 55 0;
+#X connect 27 0 28 0;
+#X connect 28 0 78 0;
+#X connect 29 0 27 1;
+#X connect 29 0 30 0;
+#X connect 31 0 56 0;
+#X connect 31 0 57 0;
+#X connect 31 0 58 0;
+#X connect 31 0 44 0;
+#X connect 32 0 55 0;
+#X connect 33 0 55 0;
+#X connect 34 0 35 0;
+#X connect 35 0 43 0;
+#X connect 36 0 29 0;
+#X connect 37 0 38 0;
+#X connect 37 0 42 0;
+#X connect 38 0 37 1;
+#X connect 39 0 40 0;
+#X connect 42 0 39 0;
+#X connect 43 0 20 0;
+#X connect 43 1 37 0;
+#X connect 45 0 46 0;
+#X connect 46 0 78 0;
+#X connect 47 0 45 0;
+#X connect 48 0 78 0;
+#X connect 50 0 52 0;
+#X connect 51 0 50 0;
+#X connect 52 0 78 0;
+#X connect 54 0 78 0;
+#X connect 55 0 60 0;
+#X connect 55 0 59 0;
+#X connect 56 0 60 0;
+#X connect 57 0 60 0;
+#X connect 58 0 60 0;
+#X connect 61 0 66 0;
+#X connect 61 1 67 0;
+#X connect 63 0 72 0;
+#X connect 64 0 73 0;
+#X connect 65 0 66 1;
+#X connect 65 0 67 1;
+#X connect 65 0 69 0;
+#X connect 66 0 63 0;
+#X connect 67 0 64 0;
+#X connect 68 0 77 0;
+#X connect 70 0 71 0;
+#X connect 70 0 72 1;
+#X connect 70 0 73 1;
+#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;
diff --git a/voicing_analyzer.c b/voicing_analyzer.c
index 703b74f..abd7675 100755
--- a/voicing_analyzer.c
+++ b/voicing_analyzer.c
@@ -34,20 +34,35 @@ static t_class *voicing_analyzer_class;
typedef struct _voicing_analyzer
{
t_object x_obj; // myself
- int current_voices[VOICES];
- int previous_voices[VOICES];
+ //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;
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
void analyze_it(t_voicing_analyzer *x, float *wideness, float *i_like_parallelism, int *center_note, float *small_intervals)
@@ -56,18 +71,32 @@ void analyze_it(t_voicing_analyzer *x, float *wideness, float *i_like_parallelis
int min,max, distance;
short int chord_notes[4];
short int chord_notes_ok[4];
- short int transitions[VOICES];
- short int directions[VOICES];
+ //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 notes[VOICES];
+ //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<VOICES; i++)
+ for (i=0; i<x->voices; i++)
{
notes[i]=x->current_voices[i];
transitions[i] = x->current_voices[i] - x->previous_voices[i];
@@ -79,16 +108,16 @@ void analyze_it(t_voicing_analyzer *x, float *wideness, float *i_like_parallelis
post("directions[%i]=%i", i, directions[i]);
}
- for (i=0; i<VOICES; i++)
+ for (i=0; i<x->voices; i++)
{
- for (j=i+1; j<VOICES; j++)
+ for (j=i+1; j<x->voices; j++)
{
intervals[i][j] = (x->current_voices[i] - x->current_voices[j])%12 ;
if (DEBUG_VERBOSE)
post("intervals[%i][%i]=%i", i, j, intervals[i][j]);
}
}
- SGLIB_ARRAY_SINGLE_QUICK_SORT(short int, notes, VOICES, SGLIB_NUMERIC_COMPARATOR)
+ SGLIB_ARRAY_SINGLE_QUICK_SORT(short int, notes, x->voices, SGLIB_NUMERIC_COMPARATOR)
sameDirection = 0;
parallel8_5 = 0;
@@ -106,9 +135,9 @@ void analyze_it(t_voicing_analyzer *x, float *wideness, float *i_like_parallelis
// parallel 5ths or octaves? (if yes return 0)
// how?
// hidden 8ths nor 5ths ?
- for (i=0; i<VOICES; i++)
+ for (i=0; i<x->voices; i++)
{
- for (j=i+1; j<VOICES; j++)
+ for (j=i+1; j<x->voices; j++)
{
if (intervals[i][j]==7 || intervals[i][j]==0)
{
@@ -128,24 +157,24 @@ void analyze_it(t_voicing_analyzer *x, float *wideness, float *i_like_parallelis
*i_like_parallelism = (float) -1;
*i_like_parallelism += sameDirection;
if (parallel8_5)
- *i_like_parallelism += (float) ( ((float)parallel8_5) / ((float)(VOICES*(VOICES-1))) );
+ *i_like_parallelism += (float) ( ((float)parallel8_5) / ((float)(x->voices*(x->voices - 1))) );
// is voice spacing uniform ?(except for the bass)
// TODO: use notes[]
// are voices average centered?
- for (i=0; i<VOICES; i++)
+ for (i=0; i<x->voices; i++)
{
tmp+=notes[i];
if (DEBUG_VERBOSE)
post("average note is %i at passage %i", tmp, i);
}
// this is the average note
- *center_note = tmp/(VOICES);
+ *center_note = tmp/(x->voices);
// are intervals small?
tmp=0;
- for (i=0; i<VOICES; i++)
+ for (i=0; i<x->voices; i++)
{
// if (DEBUG_VERBOSE)
// post("transitions[%i] = %i",i, transitions[i]);
@@ -171,16 +200,24 @@ void analyze_it(t_voicing_analyzer *x, float *wideness, float *i_like_parallelis
res -= 3;
}
- *small_intervals = (float) (((float) res) / ((float) (5 * VOICES)));
+ *small_intervals = (float) (((float) res) / ((float) (5 * x->voices)));
// now wideness
min = notes[0];
- max = notes[VOICES-1];
+ 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);
}
typedef struct fitness_list_element_t
@@ -193,12 +230,12 @@ typedef struct fitness_list_element_t
void analyze_voicing(t_voicing_analyzer *x)
{
- t_atom lista[VOICES];
+ 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, &center_note, &small_intervals);
// order is important!
@@ -214,13 +251,13 @@ void set_current_voices(t_voicing_analyzer *x, t_symbol *sl, int argc, t_atom *a
{
int i=0;
- if (argc<VOICES)
+ if (argc<x->voices)
{
error("insufficient notes sent!");
return;
}
// fill input array with actual data sent to inlet
- for (i=0;i<VOICES;i++)
+ for (i=0;i<x->voices;i++)
{
x->previous_voices[i] = x->current_voices[i];
x->current_voices[i] = atom_getint(argv++);
@@ -231,13 +268,31 @@ void set_current_voices(t_voicing_analyzer *x, t_symbol *sl, int argc, t_atom *a
}
+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)
{
post("");
post("voicing_analyzer is an external that analyze voicing");
- post("takes as input %i midi notes", VOICES);
+ 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");
@@ -252,12 +307,12 @@ void *voicing_analyzer_new(t_symbol *s, int argc, t_atom *argv)
x->wideness_out = outlet_new(&x->x_obj, gensym("float"));
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->voices = VOICES;
+ if (argc>0)
{
- x->previous_voices[i] = 0;
- x->current_voices[i] = 0;
+ x->voices = atom_getintarg(0, argc, argv);
}
+ voicing_analyzer_allocate(x);
return (x);
}
@@ -268,6 +323,8 @@ void voicing_analyzer_setup(void)
(t_method)voicing_analyzer_free, sizeof(t_voicing_analyzer), CLASS_DEFAULT, A_GIMME, 0);
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);
+
}