Update of /cvsroot/pure-data/externals/frankenstein In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2493
Added Files: GArhythm.c Makefile README.txt SHOWME.pd bay.orc chord_melo.c chord_melo_test3.pd chords_memory.c harmonizer.c makefile.darwin manager.pd ritmo1.c sglib.h test-chords_graph.pd test-harmonizer.pd test-harmonizer2.pd test.graph Log Message: initial checkin
--- NEW FILE: SHOWME.pd --- #N canvas 63 95 785 518 12; #X obj 513 100 tabwrite src; #X obj 644 87 tabwrite dest; #N canvas 0 0 450 300 graph25 0; #X array src 16 float 1; #A 0 53 52 55 53 52 50 48 47 48 55 57 59 60 55 52 48; #X array dest 16 float 1; #A 0 53 50 52 38 64 46 43 41 48 64 67 67 36 55 53 57; #X coords 0 127 15 0 400 250 1; #X restore 75 32 graph; #X obj 572 38 tgl 15 0 empty empty START 0 -6 0 8 -258699 -1 -1 1 1 ; #X floatatom 550 138 5 0 0 0 - - -; #X floatatom 596 138 5 0 0 0 - - -; #X floatatom 648 137 5 0 0 0 - - -; #X obj 591 279 tgl 15 0 toggleSRC empty src 0 -6 0 8 -262144 -1 -1 0 1; #X obj 627 279 tgl 15 0 toggleOUT empty out 0 -6 0 8 -262144 -1 -1 1 1; #X obj 572 56 chord_melo_test3; #X floatatom 613 213 5 0 0 0 current_melo - -; #X connect 3 0 9 0; #X connect 9 0 4 0; #X connect 9 0 0 0; #X connect 9 1 1 0; #X connect 9 1 5 0; #X connect 9 2 10 0; #X connect 9 3 0 1; #X connect 9 3 1 1; #X connect 9 3 6 0;
--- NEW FILE: manager.pd --- #N canvas 494 138 557 435 12; #X obj 136 186 select 0; #X obj 124 266 random 2; #X obj 137 211 t a a a; #X obj 137 235 bang; #X obj 140 130 inlet; #X obj 133 304 outlet; #X msg 250 143 0; #X connect 0 0 2 0; #X connect 1 0 5 0; #X connect 2 0 3 0; #X connect 3 0 1 0; #X connect 4 0 0 0; #X connect 6 0 0 0;
--- NEW FILE: harmonizer.c --- /* harmonizer: this external build voicing from a chord to another. takes n voices (midi) as input you can set the current chord you can ask for next note of each voice to get to a target chord
usefull to create chorals
voicing is built using traditional GA (not co-evolving GA)
voicing rules are hardcoded and are: - no parallel 8ths nor 5ths - better no hidden 8ths nor 5ths - better if uniform voice spacing (except for the bass) - better if little intervals - no all voices same direction - no voices outside limits - better complete chords
TODO: would be nice to be able so set some rule at runtime or at least set the importance of rules in realtime..
*/ #include <stdlib.h> #include <math.h> #include <time.h> // for string manipulation #include <string.h> #include <ctype.h> #include "m_pd.h"
// to sort arrays #include "sglib.h"
#define MAX_POPULATION 100
#define DEF_PROB_MUTATION 0.03f
#define VOICES 5
#define NOTES_RANGE 80 // this should be multiple of 16 #define LOWER_POSSIBLE_NOTE 24 // lower note possible, it should be a C #define POSSIBLE_NOTES (NOTES_RANGE/12*4) // 4 is the max number of notes in a chord
// testing i noticed that we don't need more than 1 generation.. // this is because we create an initial population that is really good // we may not need to crossover at all! #define GENERATIONS 1
#define DEBUG 0 // messaggi di debug #define DEBUG_VERBOSE 0 // messaggi di debug
static t_class *harmonizer_class;
typedef enum { kMaj=0, kMin=1, kDim=2, kAug=3, kDom7=4, kMaj7=5, kMin7=6, kMinMaj7=7, kDim7=8, kHalfDim7=9 } mode_t;
typedef enum {C=0, Db=1, D=2, Eb=3, E=4, F=5, Gb=6, G=7, Ab=8, A=9, Bb=10, B=11 } note_t;
// this defines a chord in a tonality typedef struct _chord { mode_t mode; note_t note; } chord_t;
typedef struct _harmonizer { t_object x_obj; // myself // genotypes int population[MAX_POPULATION][VOICES]; int current_voices[VOICES]; chord_t current_chord; chord_t target_chord; int target_notes[POSSIBLE_NOTES]; t_outlet *l_out; } t_harmonizer;
// I build a table of possible notes // are the notes (midi)that form target_chord void build_possible_notes_table(t_harmonizer *x) { int i, octave, basenote; int n1, n2, n3, n4; n1=n2=n3=n4=0; // there always is the fundamental if (DEBUG_VERBOSE) post("build_possible_notes_table target_chord.mode=%i target_chord.note=%i", x->target_chord.mode, x->target_chord.note); switch (x->target_chord.mode) { case kMaj: n2=4; n3=7; n4=0;break; case kMin: n2=3; n3=7; n4=0;break; case kDim: n2=3; n3=6; n4=0;break; case kAug: n2=4; n3=8; n4=0;break; case kMaj7: n2=4; n3=7; n4=11;break; case kDom7: n2=4; n3=7; n4=10;break; case kMin7: n2=3; n3=7; n4=10;break; case kHalfDim7: n2=3; n3=6; n4=10;break; case kDim7: n2=3; n3=6; n4=9;break; case kMinMaj7: n2=4; n3=7; n4=11;break; } if (DEBUG_VERBOSE) post("build_possible_notes_table n2=%i n3=%i n4=%i", n2, n3, n4);
basenote=0; switch (x->target_chord.note) { case C: basenote=0;break; case Db: basenote=1;break; case D: basenote=2;break; case Eb: basenote=3;break; case E: basenote=4;break; case F: basenote=5;break; case Gb: basenote=6;break; case G: basenote=7;break; case Ab: basenote=8;break; case A: basenote=9;break; case Bb: basenote=10;break; case B: basenote=11;break; } if (DEBUG_VERBOSE) post("build_possible_notes_table basenote=%i", basenote); i=0; octave=0; while (i<(POSSIBLE_NOTES-3)) { x->target_notes[i++]=octave*12 + LOWER_POSSIBLE_NOTE + basenote + n1; x->target_notes[i++]=octave*12 + LOWER_POSSIBLE_NOTE + basenote + n2; x->target_notes[i++]=octave*12 + LOWER_POSSIBLE_NOTE + basenote + n3; x->target_notes[i++]=octave*12 + LOWER_POSSIBLE_NOTE + basenote + n4; octave++; } if (DEBUG_VERBOSE) { i=0; while (i<(POSSIBLE_NOTES)) { post("x->target_notes[%i]=%i", i, x->target_notes[i++]); } } }
// tries to find out absolute tones names in this string note_t string2note(const char *substr) { if (strstr(substr, "C")) return C; if (strstr(substr, "Db")) return Db; if (strstr(substr, "D")) return D; if (strstr(substr, "Eb")) return Eb; if (strstr(substr, "E")) return E; if (strstr(substr, "F")) return F; if (strstr(substr, "Gb")) return Gb; if (strstr(substr, "G")) return G; if (strstr(substr, "Ab")) return Ab; if (strstr(substr, "A")) return A; if (strstr(substr, "Bb")) return Bb; if (strstr(substr, "B")) return B; return C; }
mode_t string2mode(const char *substr) { if (strstr(substr, "minor/major 7th")) return kMinMaj7; if (strstr(substr, "major 7th")) return kMaj7; if (strstr(substr, "major")) return kMaj; if (strstr(substr, "minor 7th")) return kMin7; if (strstr(substr, "minor")) return kMin; if (strstr(substr, "half diminished 7th")) return kHalfDim7; if (strstr(substr, "diminished 7th")) return kDim7; if (strstr(substr, "diminished")) return kDim; if (strstr(substr, "augmented")) return kAug; if (strstr(substr, "dominant 7th")) return kDom7; // TODO: other chords // beware when adding new chords // put shorter names at end of this function! return C; }
// ----------------- normal external code ...
void harmonizer_init_pop(t_harmonizer *x) { int i, j, tmp, tmp2, k, steps, note, insertpoint; double rnd; for (i=0; i<MAX_POPULATION; i++) { for (j=0; j<VOICES; j++) { /* // totally randome version rnd = rand()/((double)RAND_MAX + 1); tmp = rnd * POSSIBLE_NOTES; x->population[i][j] = x->target_notes[tmp]; */
// not totally random: i start from currend chord's notes // and randomly go up or down insertpoint = 0; while ((insertpoint < POSSIBLE_NOTES) && (x->target_notes[insertpoint] < x->current_voices[j])) insertpoint++; if (insertpoint >= POSSIBLE_NOTES) { // i didn't find my insert point, possible? // i pick a random one rnd = rand()/((double)RAND_MAX + 1); tmp = rnd * POSSIBLE_NOTES; x->population[i][j] = x->target_notes[tmp]; } else { // insert point found rnd = rand()/((double)RAND_MAX + 1); if (rnd < 0.5) { // i go up rnd = rand()/((double)RAND_MAX + 1); steps = rnd * 5; // how many step (good notes) will I ignore? note = insertpoint + steps; if (note >= POSSIBLE_NOTES) note = POSSIBLE_NOTES-1; } else { // i go down rnd = rand()/((double)RAND_MAX + 1); steps = rnd * 5; // how many step (good notes) will I ignore? note = insertpoint - steps; if (note < 0) note = 0; } // finally assign the note x->population[i][j] = x->target_notes[note]; } } } }
void harmonizer_free(t_harmonizer *x) { // freebytes(x->buf_strum1, sizeof(x->buf_strum1)); // freebytes(x->buf_strum2, sizeof(x->buf_strum2)); }
// here i evaluate this voicing int fitness(t_harmonizer *x, int *candidate) { int i, j, tmp, res, last, avgHI, avgLOW; 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
if (DEBUG_VERBOSE) 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]; transitions[i] = candidate[i] - x->current_voices[i]; if (transitions[i]!=0) directions[i] = transitions[i]/abs(transitions[i]); else directions[i] = 0; if (DEBUG_VERBOSE) post("directions[%i]=%i", i, directions[i]);
} for (i=0; i<VOICES; i++) { for (j=i+1; j<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)
// all same direction? if ( directions[0]==directions[1] && directions[1]==directions[2] && directions[2]==directions[3]) { // bad! res -= 10; if (DEBUG_VERBOSE) post("same direction!"); } // parallel 5ths or octaves? (if yes return 0) // 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) { // hidden or parallel 5th,octave or unison // bad! if (directions[i]==directions[j]) { res -= 10; if (DEBUG_VERBOSE) post("hidden or parallel consonance!"); } } } }
// is voice spacing uniform ?(except for the bass) // TODO: use notes[] // are voices average centered? tmp=0; for (i=1; i<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); 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 res += 30; res -= tmp; if (DEBUG_VERBOSE) post("average note is %i far from 2/3 of notes range", tmp);
tmp=0; /* // are voices average centered? for (i=0; i<VOICES; i++) { tmp+=notes[i]; } // this is the average note tmp = tmp/VOICES; tmp = abs(72-tmp); // how much average is far from 72 res += 30; res -= tmp; */
// are intervals small? //res+=50; if (DEBUG_VERBOSE) post("res before transitions %i", res); for (i=0; i<VOICES; i++) { if (DEBUG_VERBOSE) post("transitions[%i] = %i",i, transitions[i]); res-=abs(transitions[i]); // give an incentive for semitones etc.. if (transitions[i]==0) res += 5; if (abs(transitions[i]==1)) res += 5; if (abs(transitions[i]==2)) res += 5; if (abs(transitions[i]==3)) res += 2; if (abs(transitions[i]==4)) res += 2; if (abs(transitions[i]==5)) res += 1; if (abs(transitions[i]==6)) res += 1; if (abs(transitions[i]>11)) res -= 2; if (abs(transitions[i]>15)) res -= 5;
} if (DEBUG_VERBOSE) post("res after transitions %i", res);
// TODO: too many near limits? // TODO: is a complete chord?
// penalize too many basses tmp = 0; for (i=0; i<VOICES; i++) { if (notes[i]<48) tmp++; } switch (tmp) { case 0: res -= 5; break; case 1: res += 10; break; case 2: res -= 10; break; case 3: res -= 20; break; case 4: res -= 30; break; }
if (DEBUG_VERBOSE) post("fitness is %i", res);
return res; }
void new_genotype(t_harmonizer *x, int *mammy, int *daddy, int *kid) { int i, split; double rnd; // 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]; }
// mutation for (i=0; i<VOICES; i++) { rnd = rand()/((double)RAND_MAX + 1); if (rnd < DEF_PROB_MUTATION) { rnd = rand()/((double)RAND_MAX + 1) * POSSIBLE_NOTES; kid[i]=x->target_notes[(int)rnd]; } } }
typedef struct fitness_list_element_t { int index; int fitness; } fitness_list_element;
#define FITNESS_LIST_COMPARATOR(e1, e2) (e1.fitness - e2.fitness)
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]; // inizialize tables of notes build_possible_notes_table(x); // inizialize population harmonizer_init_pop(x); // GA code for (generation=0; generation<GENERATIONS; generation++) { // i compute all the fitness for (i=0; i<MAX_POPULATION; i++) { fitness_evaluations[i].index=i; fitness_evaluations[i].fitness = fitness(x, x->population[i]); } // i sort the array SGLIB_ARRAY_SINGLE_QUICK_SORT(fitness_list_element, fitness_evaluations, MAX_POPULATION, FITNESS_LIST_COMPARATOR)
// i kill half population // and use the survivors to create new genotypes for (i=0; i<(MAX_POPULATION/2); i++) { // create a new genotype // parents chosen randomly rnd = rand()/((double)RAND_MAX + 1); mum = MAX_POPULATION/2 + rnd*MAX_POPULATION/2; rnd = rand()/((double)RAND_MAX + 1); dad = MAX_POPULATION/2 + rnd*MAX_POPULATION/2; new_genotype(x, x->population[mum], x->population[dad], x->population[i]); } // repeat the process } // finally look for the winner // i compute all the fitness for (i=0; i<MAX_POPULATION; i++) { fitness_evaluations[i].index=i; fitness_evaluations[i].fitness = fitness(x, x->population[i]); } // i sort the array SGLIB_ARRAY_SINGLE_QUICK_SORT(fitness_list_element, fitness_evaluations, MAX_POPULATION, FITNESS_LIST_COMPARATOR) winner = fitness_evaluations[MAX_POPULATION-1].index;
if (DEBUG) post("winner fitness = %i", fitness_evaluations[MAX_POPULATION-1].fitness);
for (i=0;i<VOICES;i++) { SETFLOAT(lista+i, x->population[winner][i]); }
// send output array to outlet outlet_anything(x->l_out, gensym("list") , VOICES, lista); }
// if i want another voicing i can send a bang static void harmonizer_bang(t_harmonizer *x) { generate_voicing(x); }
// called when i send a list (with midi values) void set_current_voices(t_harmonizer *x, t_symbol *sl, int argc, t_atom *argv) { int i=0; if (argc<VOICES) { error("insufficient notes sent!"); return; } // fill input array with actual data sent to inlet for (i=0;i<VOICES;i++) { x->current_voices[i] = atom_getint(argv++); }
generate_voicing(x);
} // set current chord void set_current(t_harmonizer *x, t_symbol *s) { x->current_chord.mode = string2mode(s->s_name); x->current_chord.note = string2note(s->s_name); if (DEBUG) post("harmonizer: set_current %s",s->s_name); }
// set target chord void set_target(t_harmonizer *x, t_symbol *s) { x->target_chord.mode = string2mode(s->s_name); x->target_chord.note = string2note(s->s_name); if (DEBUG) post("harmonizer: set_target %s",s->s_name); }
void *harmonizer_new(t_symbol *s, int argc, t_atom *argv) { int i; time_t a; t_harmonizer *x = (t_harmonizer *)pd_new(harmonizer_class); x->l_out = outlet_new(&x->x_obj, &s_list); /* for (i=0; i<BUFFER_LENGHT; i++) { x->last[i] = harmonizer_note2gene(1,0,0,1); } */ srand(time(&a));
return (x); }
void harmonizer_setup(void) { harmonizer_class = class_new(gensym("harmonizer"), (t_newmethod)harmonizer_new, (t_method)harmonizer_free, sizeof(t_harmonizer), CLASS_DEFAULT, A_GIMME, 0); class_addbang(harmonizer_class, (t_method)harmonizer_bang); class_addmethod(harmonizer_class, (t_method)set_current, gensym("current"),A_SYMBOL, 0); class_addmethod(harmonizer_class, (t_method)set_target, gensym("target"),A_SYMBOL, 0); // class_addmethod(harmonizer_class, (t_method)harmonizer_fitness1_set, gensym("fitness1"), A_DEFFLOAT, 0); class_addlist(harmonizer_class, (t_method)set_current_voices);
}
--- NEW FILE: Makefile --- # customize here ! #VC="C:\Programmi\Microsoft Visual Studio .NET\Vc7" VC="C:\Programmi\Microsoft Visual Studio .NET\Vc7" PDPATH="H:\PureData\pd-0.38-3.msw\pd" #PDPATH="C:\Documents and Settings\Davide\Documenti\personali\pd-0.38-3.msw\pd"
current: pd_nt distclean
pd_nt: chord_melo.dll chords_memory.dll harmonizer.dll GArhythm.dll ritmo1.dll
.SUFFIXES: .dll
PDNTCFLAGS = /W3 /WX /O2 /G6 /DNT /DPD /nologo
PDNTINCLUDE = /I. /I$(PDPATH)\tcl\include /I$(PDPATH)\src /I$(VC)\include /Iinclude
PDNTLDIR = $(VC)\Lib PDNTLIB = $(PDNTLDIR)\libc.lib \ $(PDNTLDIR)\oldnames.lib \ $(PDNTLDIR)\kernel32.lib \ $(PDPATH)\bin\pd.lib
.c.dll: cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c link /dll /export:$*_setup $*.obj $(PDNTLIB)
clean: -del link.stamp -del *.obj -del *.lib -del *.exp -del *.dll
distclean: -del *.obj -del *.lib -del *.exp
--- NEW FILE: bay.orc --- ; ================================================================ ; Header ; ================================================================ sr=44100 kr=882 ksmps=50 nchnls=2
; ================================================================ ; Globals ; ================================================================ zakinit 10,10
; Global variable for the reverb unit ga1 init 0
; ================================================================ ; Tables ; ================================================================ ; Waveform for the string-pad iwave ftgen 1, 0, 4096, 10, 1, .5, .33, .25, .0, .1, .1, .1
; Senoid required by chorus isine ftgen 2, 0, 4096, 10, 1
; ================================================================ ; Instruments ; ================================================================
instr 1 ;String pad ; String-pad borrwoed from the piece "Dorian Gray", ; http://akozar.spymac.net/music/ Modified to fit my needs
; ihz = p4 ; idb = p5/127 * 70 ; rescale MIDI velocity to 70db ; ipos = p6 ; iamp = ampdb(idb)
; modified by dmorelli khz invalue "hz1" kpos invalue "pos1" kamp invalue "amp1" kctrl = kamp*70 kctrl = ampdb(kctrl) ; Slow attack and release ; kctrl linseg 0, p3/4, iamp, p3/2, 0 ; Slight chorus effect afund oscil kctrl, khz, 1 ; audio oscillator acel1 oscil kctrl, khz - .1, 1 ; audio oscillator - flat acel2 oscil kctrl, khz + .1, 1 ; audio oscillator - sharp asig = afund + acel1 + acel2
; Cut-off high frequencies depending on midi-velocity ; (larger velocity implies more brighter sound) asig butterlp asig, (p5-60)*40+900
; Panning kppan = kpos*1.570796325 ; half of PI (radians of 90o angle) kpleft = cos(kppan) ; half sign "down" kpright = sin(kppan) ; half sign "up" asig1 = asig*kpleft; asig2 = asig*kpright; ; To the chorus effect, through zak channels 1 and 2 zawm asig1, 1 zawm asig2, 2 endin
instr 2 ;String pad ; String-pad borrwoed from the piece "Dorian Gray", ; http://akozar.spymac.net/music/ Modified to fit my needs
; ihz = p4 ; idb = p5/127 * 70 ; rescale MIDI velocity to 70db ; ipos = p6 ; iamp = ampdb(idb)
; modified by dmorelli khz invalue "hz2" kpos invalue "pos2" kamp invalue "amp2" kctrl = kamp*70 kctrl = ampdb(kctrl) ; Slow attack and release ; kctrl linseg 0, p3/4, iamp, p3/2, 0 ; Slight chorus effect afund oscil kctrl, khz, 1 ; audio oscillator acel1 oscil kctrl, khz - .1, 1 ; audio oscillator - flat acel2 oscil kctrl, khz + .1, 1 ; audio oscillator - sharp asig = afund + acel1 + acel2
; Cut-off high frequencies depending on midi-velocity ; (larger velocity implies more brighter sound) asig butterlp asig, (p5-60)*40+900
; Panning kppan = kpos*1.570796325 ; half of PI (radians of 90o angle) kpleft = cos(kppan) ; half sign "down" kpright = sin(kppan) ; half sign "up" asig1 = asig*kpleft; asig2 = asig*kpright; ; To the chorus effect, through zak channels 1 and 2 zawm asig1, 1 zawm asig2, 2 endin
instr 3 ;String pad ; String-pad borrwoed from the piece "Dorian Gray", ; http://akozar.spymac.net/music/ Modified to fit my needs
; ihz = p4 ; idb = p5/127 * 70 ; rescale MIDI velocity to 70db ; ipos = p6 ; iamp = ampdb(idb)
; modified by dmorelli khz invalue "hz3" kpos invalue "pos3" kamp invalue "amp3" kctrl = kamp*70 kctrl = ampdb(kctrl) ; Slow attack and release ; kctrl linseg 0, p3/4, iamp, p3/2, 0 ; Slight chorus effect afund oscil kctrl, khz, 1 ; audio oscillator acel1 oscil kctrl, khz - .1, 1 ; audio oscillator - flat acel2 oscil kctrl, khz + .1, 1 ; audio oscillator - sharp asig = afund + acel1 + acel2
; Cut-off high frequencies depending on midi-velocity ; (larger velocity implies more brighter sound) asig butterlp asig, (p5-60)*40+900
; Panning kppan = kpos*1.570796325 ; half of PI (radians of 90o angle) kpleft = cos(kppan) ; half sign "down" kpright = sin(kppan) ; half sign "up" asig1 = asig*kpleft; asig2 = asig*kpright; ; To the chorus effect, through zak channels 1 and 2 zawm asig1, 1 zawm asig2, 2 endin instr 4 ;String pad ; String-pad borrwoed from the piece "Dorian Gray", ; http://akozar.spymac.net/music/ Modified to fit my needs
; ihz = p4 ; idb = p5/127 * 70 ; rescale MIDI velocity to 70db ; ipos = p6 ; iamp = ampdb(idb)
; modified by dmorelli khz invalue "hz4" kpos invalue "pos4" kamp invalue "amp4" kctrl = kamp*70 kctrl = ampdb(kctrl) ; Slow attack and release ; kctrl linseg 0, p3/4, iamp, p3/2, 0 ; Slight chorus effect afund oscil kctrl, khz, 1 ; audio oscillator acel1 oscil kctrl, khz - .1, 1 ; audio oscillator - flat acel2 oscil kctrl, khz + .1, 1 ; audio oscillator - sharp asig = afund + acel1 + acel2
; Cut-off high frequencies depending on midi-velocity ; (larger velocity implies more brighter sound) asig butterlp asig, (p5-60)*40+900
; Panning kppan = kpos*1.570796325 ; half of PI (radians of 90o angle) kpleft = cos(kppan) ; half sign "down" kpright = sin(kppan) ; half sign "up" asig1 = asig*kpleft; asig2 = asig*kpright; ; To the chorus effect, through zak channels 1 and 2 zawm asig1, 1 zawm asig2, 2 endin
; strumento senza invalue
instr 9 ;String pad ; String-pad borrwoed from the piece "Dorian Gray", ; http://akozar.spymac.net/music/ Modified to fit my needs
ihz = p4 idb = p5/127 * 70 ; rescale MIDI velocity to 70db ipos = p6 iamp = ampdb(idb)
; modified by dmorelli
;kpos invalue "pos1" ;kamp invalue "amp1" ;kctrl = kamp*70 ;kctrl = ampdb(kctrl) ; Slow attack and release kctrl linseg 0, p3/4, iamp, p3/2, 0 ; Slight chorus effect afund oscil kctrl, ihz, 1 ; audio oscillator acel1 oscil kctrl, ihz - .1, 1 ; audio oscillator - flat acel2 oscil kctrl, ihz + .1, 1 ; audio oscillator - sharp asig = afund + acel1 + acel2
; Cut-off high frequencies depending on midi-velocity ; (larger velocity implies more brighter sound) asig butterlp asig, (p5-60)*40+900
; Panning ippan = ipos*1.570796325 ; half of PI (radians of 90o angle) ipleft = cos(ippan) ; half sign "down" ipright = sin(ippan) ; half sign "up" asig1 = asig*ipleft; asig2 = asig*ipright; ; To the chorus effect, through zak channels 1 and 2 zawm asig1, 1 zawm asig2, 2 endin
; ================================================================ ; EFFECTS ; ================================================================
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; Chorus effect, borrowed from http://www.jlpublishing.com/Csound.htm ; I made some of its parameters accesible trhough score instr 10 ;Chorus ; Read input from zak a1 zar 1 a2 zar 2 idlyml=p4 ;delay in milliseconds k1 oscili idlyml/p5, 1, 2 ar1l vdelay3 a1, idlyml/5+k1, 900 ;delayed sound 1 ar1r vdelay3 a2, idlyml/5+k1, 900 ;delayed sound 1 k2 oscili idlyml/p5, .995, 2 ar2l vdelay3 a1, idlyml/5+k2, 700 ;delayed sound 2 ar2r vdelay3 a2, idlyml/5+k2, 700 ;delayed sound 2 k3 oscili idlyml/p5, 1.05, 2 ar3l vdelay3 a1, idlyml/5+k3, 700 ;delayed sound 3 ar3r vdelay3 a2, idlyml/5+k3, 700 ;delayed sound 3 k4 oscili idlyml/p5, 1, 2 ar4l vdelay3 a1, idlyml/5+k4, 900 ;delayed sound 4 ar4r vdelay3 a2, idlyml/5+k4, 900 ;delayed sound 4 aoutl = (a1+ar1l+ar2l+ar3l+ar4l)*.5 aoutr = (a2+ar1r+ar2r+ar3r+ar4r)*.5
; To the output mixer zawm aoutl, 5 zawm aoutr, 6 ; and also to the reverb unit ga1 = ga1 + (aoutl+aoutr)*.5 endin
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; Reverb ; 8 delay line FDN reverb, with feedback matrix based upon ; physical modeling scattering junction of 8 lossless waveguides ; of equal characteristic impedance. Based on Julius O. Smith III, ; "A New Approach to Digital Reverberation using Closed Waveguide ; Networks," Proceedings of the International Computer Music ; Conference 1985, p. 47-53 (also available as a seperate ; publication from CCRMA), as well as some more recent papers by ; Smith and others. ; ; Coded by Sean Costello, October 1999 instr 25 ;Reverb ; Note: ga1 is the global input to the reverb. afilt1 init 0 afilt2 init 0 afilt3 init 0 afilt4 init 0 afilt5 init 0 afilt6 init 0 afilt7 init 0 afilt8 init 0 idel1 = (2473.000/sr) idel2 = (2767.000/sr) idel3 = (3217.000/sr) idel4 = (3557.000/sr) idel5 = (3907.000/sr) idel6 = (4127.000/sr) idel7 = (2143.000/sr) idel8 = (1933.000/sr)
igain = p4 ; gain of reverb. Adjust empirically ; for desired reverb time. .6 gives ; a good small "live" room sound, .8 ; a small hall, .9 a large hall, ; .99 an enormous stone cavern.
ipitchmod = p5 ; amount of random pitch modulation ; for the delay lines. 1 is the "normal" ; amount, but this may be too high for ; held pitches such as piano tones. ; Adjust to taste.
itone = p6 ; Cutoff frequency of lowpass filters ; in feedback loops of delay lines, ; in Hz. Lower cutoff frequencies results ; in a sound with more high-frequency ; damping.
; k1-k8 are used to add random pitch modulation to the ; delay lines. Helps eliminate metallic overtones ; in the reverb sound. k1 randi .001, 3.1, .06 k2 randi .0011, 3.5, .9 k3 randi .0017, 1.11, .7 k4 randi .0006, 3.973, .3 k5 randi .001, 2.341, .63 k6 randi .0011, 1.897, .7 k7 randi .0017, 0.891, .9 k8 randi .0006, 3.221, .44 ; apj is used to calculate "resultant junction pressure" for ; the scattering junction of 8 lossless waveguides ; of equal characteristic impedance. If you wish to ; add more delay lines, simply add them to the following ; equation, and replace the .25 by 2/N, where N is the ; number of delay lines. apj = .25 * (afilt1 + afilt2 + afilt3 + afilt4 + afilt5 + afilt6 + afilt7 + afilt8)
adum1 delayr 1 adel1 deltapi idel1 + k1 * ipitchmod delayw ga1 + apj - afilt1
adum2 delayr 1 adel2 deltapi idel2 + k2 * ipitchmod delayw ga1 + apj - afilt2
adum3 delayr 1 adel3 deltapi idel3 + k3 * ipitchmod delayw ga1 + apj - afilt3
adum4 delayr 1 adel4 deltapi idel4 + k4 * ipitchmod delayw ga1 + apj - afilt4
adum5 delayr 1 adel5 deltapi idel5 + k5 * ipitchmod delayw ga1 + apj - afilt5
adum6 delayr 1 adel6 deltapi idel6 + k6 * ipitchmod delayw ga1 + apj - afilt6
adum7 delayr 1 adel7 deltapi idel7 + k7 * ipitchmod delayw ga1 + apj - afilt7
adum8 delayr 1 adel8 deltapi idel8 + k8 * ipitchmod delayw ga1 + apj - afilt8
; 1st order lowpass filters in feedback ; loops of delay lines. afilt1 tone adel1 * igain, itone afilt2 tone adel2 * igain, itone afilt3 tone adel3 * igain, itone afilt4 tone adel4 * igain, itone afilt5 tone adel5 * igain, itone afilt6 tone adel6 * igain, itone afilt7 tone adel7 * igain, itone afilt8 tone adel8 * igain, itone
; The outputs of the delay lines are summed ; and sent to the stereo outputs. This could ; easily be modified for a 4 or 8-channel ; sound system. aout1 = (afilt1 + afilt3 + afilt5 + afilt7) aout2 = (afilt2 + afilt4 + afilt6 + afilt8) ;outs aout1, aout2 ; To the output mixer zawm aout1, 5 zawm aout2, 6 ga1 = 0 endin
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; Output mixer ; It applies a bass enhancement, compression and fadeout ; to the whole piece, instr 30 ;Mixer ; Read input from zak a1 zar 5 a2 zar 6 ; Bass enhancement al1 butterlp a1, 100 al2 butterlp a2, 100 a1 = al1*1.5 +a1 a2 = al2*1.5 +a2
; Global amplitude shape ; It applies a gain of p4 to the whole piece, and creates a ; fadeout the last p5 seconds kenv linseg p4, p3-p5, p4, p5, 0 a1=a1*kenv a2=a2*kenv
; Compression a1 dam a1, 5000, 0.5, 1, 0.2, 0.1 a2 dam a2, 5000, 0.5, 1, 0.2, 0.1
outs a1, a2 zacl 0, 10 endin
--- NEW FILE: makefile.darwin --- current: pd_darwin
clean: ; rm -f *.pd_linux *.o *.pd_darwin
# ----------------------- Mac OSX -----------------------
pd_darwin: chord_melo.pd_darwin
.SUFFIXES: .pd_darwin
# where are the PD header files? # leave it blank if it is a system directory (like /usr/local/include), # since gcc 3.2 complains about it PDPATH=/Users/Development/music/puredatacvs/devel_0_39/src #PDPATH=/Users/davidemorelli/Desktop/robaDavide/Pd-0.38-3.app/Contents/Resources/src/
# where is the PD executable? PD=/Applications/PdOLD.app/Contents/Resources/bin/pd #PD=/usr/local/lib/pd/bin/pd #PD=/Users/davidemorelli/Desktop/robaDavide/Pd-0.38-3.app/Contents/Resources/bin/pd #PD=/Users/davidemorelli/Desktop/robaDavide/Pd-0.38-3.app/Contents/Resources/src/
DARWININCLUDE = -I../../src -I$(PDPATH)
DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \ -Wno-unused -Wno-parentheses -Wno-switch
.c.pd_darwin: cc $(DARWINCFLAGS) $(DARWININCLUDE) -o $*.o -c $*.c cc -bundle -bundle_loader $(PD) -flat_namespace -o $*.pd_darwin *.o # cc -bundle -undefined suppress -flat_namespace -o $*.pd_darwin # rm -f $*.o
# $(FANNLIB)
--- NEW FILE: ritmo1.c --- /* ritmo1 try to extract the current pattern */ #include "m_pd.h"
#define BUFFER_LENGHT 16
static t_class *ritmo1_class;
typedef struct _ritmo1 { t_object x_obj; // myself t_symbol *x_arrayname_src; // where i read the current pattern t_symbol *x_arrayname_dest; // where i put the computed pattern t_float *buf1; t_float *buf2; t_float *buf3; } t_ritmo1;
void ritmo1_allocate_buffers(t_ritmo1 *x) { x->buf1 = (t_float *)getbytes(BUFFER_LENGHT * sizeof(t_float)); x->buf2 = (t_float *)getbytes(BUFFER_LENGHT * sizeof(t_float)); x->buf3 = (t_float *)getbytes(BUFFER_LENGHT * sizeof(t_float)); }
void ritmo1_free(t_ritmo1 *x) { freebytes(x->buf1, sizeof(x->buf1)); freebytes(x->buf2, sizeof(x->buf2)); freebytes(x->buf3, sizeof(x->buf3));}
static void ritmo1_bang(t_ritmo1 *x) {
int i, vecsize; t_garray *arysrc; t_garray *arydest; t_float *vecsrc; t_float *vecdest;
if (!(arysrc = (t_garray *)pd_findbyclass(x->x_arrayname_src, garray_class))) { pd_error(x, "%s: no such array", x->x_arrayname_src->s_name); } else if (!garray_getfloatarray(arysrc, &vecsize, &vecsrc)) { pd_error(x, "%s: bad template for tabwrite", x->x_arrayname_src->s_name); } else if (!(arydest = (t_garray *)pd_findbyclass(x->x_arrayname_dest, garray_class))) { pd_error(x, "%s: no such array", x->x_arrayname_dest->s_name); } else if (!garray_getfloatarray(arydest, &vecsize, &vecdest)) { pd_error(x, "%s: bad template for tabwrite", x->x_arrayname_dest->s_name); } else // I got arrays and data { // step 1: compute the pattern // and write it in vecdest for (i=0; i<16; i++) { vecdest[i] = (x->buf1[i] + x->buf2[i] + x->buf3[i] + vecsrc[i])/4; } // redraw the arrays garray_redraw(arysrc); garray_redraw(arydest);
// step 2: cycle buffers x->buf3 = x->buf2; x->buf2 = x->buf1; x->buf1 = x->buf3; // fill the first buffer with src data for (i=0; i<16; i++) { x->buf1[i] = vecsrc[i]; vecsrc[i]=0; } } }
static void ritmo1_src(t_ritmo1 *x, t_symbol *s) { x->x_arrayname_src = s; }
static void ritmo1_dest(t_ritmo1 *x, t_symbol *s) { x->x_arrayname_dest = s; }
static void *ritmo1_new(t_symbol *s, int argc, t_atom *argv) { t_ritmo1 *x = (t_ritmo1 *)pd_new(ritmo1_class); ritmo1_allocate_buffers(x); if (argc>0) { x->x_arrayname_src = atom_getsymbolarg(0, argc, argv); } if (argc>1) { x->x_arrayname_dest = atom_getsymbolarg(1, argc, argv); } return (x); }
void ritmo1_setup(void) { ritmo1_class = class_new(gensym("ritmo1"), (t_newmethod)ritmo1_new, (t_method)ritmo1_free, sizeof(t_ritmo1), CLASS_DEFAULT, A_GIMME, 0); class_addbang(ritmo1_class, (t_method)ritmo1_bang); class_addmethod(ritmo1_class, (t_method)ritmo1_src, gensym("src"),A_SYMBOL, 0); class_addmethod(ritmo1_class, (t_method)ritmo1_dest, gensym("dest"),A_SYMBOL, 0); }
--- NEW FILE: test-chords_graph.pd --- #N canvas 241 61 710 346 12; #X msg 63 130 write test.graph; #X msg 93 158 read test.graph; #X obj 389 33 notein; #X obj 389 68 chord 59; #X msg 293 151 add $1; #X obj 71 255 chords_graph; #X obj 293 123 symbol; #X obj 294 96 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 285 234 next 1; #X obj 366 165 symbol; #X obj 367 138 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 366 193 set $1; #X msg 123 188 init 1; #X symbolatom 71 281 20 0 0 0 - - -; #X symbolatom 429 103 25 0 0 0 - - -; #N canvas 39 349 531 328 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 385 252 pd readme; #X connect 0 0 5 0; #X connect 1 0 5 0; #X connect 2 0 3 0; #X connect 2 1 3 1; #X connect 3 2 6 1; #X connect 3 2 9 1; #X connect 3 2 14 0; #X connect 4 0 5 0; #X connect 5 0 13 0; #X connect 6 0 4 0; #X connect 7 0 6 0; #X connect 8 0 5 0; #X connect 9 0 11 0; #X connect 10 0 9 0; #X connect 11 0 5 0; #X connect 12 0 5 0;
--- NEW FILE: test-harmonizer2.pd --- #N canvas 72 0 919 691 12; #X symbolatom 157 205 18 0 0 2 next_chord - -; #N canvas 39 349 531 328 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 246 369 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 0 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 0 458 308 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 28 404 bang; #X obj 203 420 mtof; #X obj 252 419 mtof; #X obj 337 423 mtof; #X obj 180 601 dac~; #X obj 109 431 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 2610 1; #X floatatom 32 112 5 0 0 0 - - -; #X obj 178 571 csoundapi~ bay.orc; #X msg 488 520 event i 10 0 17000 10 30; #X msg 488 543 event i 30 0 17000 2 30; #X msg 489 496 event i 25 0 17000 0.98 0.8 20000; #X obj 482 458 loadbang; #X msg 196 492 event i 9 0 10 $1 80 0.5; #X obj 295 422 mtof; #X obj 381 424 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 467 377 ; 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 83 169 chords_memory test.graph; #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 connect 2 0 15 0; #X connect 2 0 28 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 39 0; #X connect 15 3 11 1; #X connect 15 3 26 0; #X connect 15 4 12 1; #X connect 15 4 40 0; #X connect 16 0 18 0; #X connect 17 0 21 0; #X connect 18 0 57 0; #X connect 19 0 57 0; #X connect 20 0 57 0; #X connect 21 0 29 0; #X connect 22 0 14 0; #X connect 22 1 7 0; #X connect 23 0 5 0; #X connect 24 0 38 0; #X connect 25 0 38 0; #X connect 26 0 38 0; #X connect 29 0 30 0; #X connect 30 0 57 0; #X connect 31 0 29 1; #X connect 31 0 32 0; #X connect 33 0 27 0; #X connect 33 1 27 1; #X connect 34 0 33 0; #X connect 35 0 33 0; #X connect 36 0 33 0; #X connect 37 0 36 0; #X connect 37 0 34 0; #X connect 37 0 35 0; #X connect 37 0 51 0; #X connect 38 0 33 0; #X connect 39 0 38 0; #X connect 40 0 38 0; #X connect 41 0 42 0; #X connect 42 0 50 0; #X connect 43 0 31 0; #X connect 44 0 45 0; #X connect 44 0 49 0; #X connect 45 0 44 1; #X connect 46 0 47 0; #X connect 49 0 46 0; #X connect 50 0 21 0; #X connect 50 1 44 0; #X connect 52 0 53 0; #X connect 53 0 57 0; #X connect 54 0 52 0; #X connect 55 0 57 0; #X connect 57 0 0 0; #X connect 57 0 5 1; #X connect 57 0 22 0; #X connect 57 0 52 1; #X connect 57 0 16 0; #X connect 57 0 58 1; #X connect 57 1 56 0; #X connect 57 2 61 0; #X connect 58 0 60 0; #X connect 59 0 58 0; #X connect 60 0 57 0; #X connect 62 0 57 0;
--- NEW FILE: test-harmonizer.pd --- #N canvas 328 37 702 643 12; #X symbolatom 179 191 20 0 0 0 - - -; #N canvas 39 349 531 328 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 496 48 pd readme; #X obj 121 316 harmonizer; #X msg 52 273 current $1; #X msg 158 270 target $1; #X obj 52 249 symbol; #X obj 52 229 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 157 248 symbol; #X obj 289 248 int 36; #X obj 355 249 int 60; #X obj 426 247 int 67; #X obj 494 246 int 76; #X obj 566 249 int 84; #X obj 335 276 pack f f f f f; #X obj 358 220 t b b b b b; #X obj 246 356 unpack f f f f f; #X obj 135 105 symbol; #X obj 98 43 bng 15 250 50 0 empty empty change_chord 0 -6 0 8 -262144 -1 -1; #X msg 135 133 set $1; #N canvas 0 0 706 416 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 326 134 pd midi; #N canvas 0 0 454 304 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 243 133 pd fileIO; #X obj 100 81 t b b; #X obj 157 215 t b a; #X obj 28 391 bang; #X symbolatom 256 35 20 0 0 0 - - -; #X obj 256 11 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 203 407 mtof; #X obj 203 431 sig~; #X obj 204 457 osc~ 440; #X obj 280 405 mtof; #X obj 280 429 sig~; #X obj 281 455 osc~ 440; #X obj 338 509 mtof; #X obj 338 533 sig~; #X obj 339 559 osc~ 440; #X obj 375 403 mtof; #X obj 375 427 sig~; #X obj 376 453 osc~ 440; #X obj 425 509 mtof; #X obj 424 532 sig~; #X obj 425 558 osc~ 440; #X obj 186 491 throw~ audio; #X obj 284 482 throw~ audio; #X obj 391 483 throw~ audio; #X obj 337 586 throw~ audio; #X obj 439 588 throw~ audio; #X obj 99 533 catch~ audio; #X obj 99 585 dac~; #X obj 99 558 *~ 0.2; #X obj 109 418 print; #X obj 83 169 chords_graph test.graph; #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 2900 1; #X floatatom 32 112 5 0 0 0 - - -; #X connect 2 0 15 0; #X connect 2 0 49 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 26 0; #X connect 15 1 9 1; #X connect 15 1 29 0; #X connect 15 2 10 1; #X connect 15 2 32 0; #X connect 15 3 11 1; #X connect 15 3 35 0; #X connect 15 4 12 1; #X connect 15 4 38 0; #X connect 16 0 18 0; #X connect 17 0 21 0; #X connect 18 0 50 0; #X connect 19 0 50 0; #X connect 20 0 50 0; #X connect 21 0 51 0; #X connect 21 1 16 0; #X connect 22 0 14 0; #X connect 22 1 7 0; #X connect 23 0 5 0; #X connect 24 0 5 1; #X connect 24 0 16 0; #X connect 24 0 7 0; #X connect 25 0 24 0; #X connect 26 0 27 0; #X connect 27 0 28 0; #X connect 28 0 41 0; #X connect 29 0 30 0; #X connect 30 0 31 0; #X connect 31 0 42 0; #X connect 32 0 33 0; #X connect 33 0 34 0; #X connect 34 0 44 0; #X connect 35 0 36 0; #X connect 36 0 37 0; #X connect 37 0 43 0; #X connect 38 0 39 0; #X connect 39 0 40 0; #X connect 40 0 45 0; #X connect 46 0 48 0; #X connect 48 0 47 0; #X connect 48 0 47 1; #X connect 50 0 0 0; #X connect 50 0 5 1; #X connect 50 0 16 1; #X connect 50 0 22 0; #X connect 51 0 52 0; #X connect 52 0 50 0; #X connect 53 0 51 1; #X connect 53 0 54 0;
--- NEW FILE: chords_memory.c --- /* chords_memory: an external that using graph learns the played style and reproduces chords sequences see http://en.wikipedia.org/wiki/Graph_%28mathematics%29 for an idea of what graphs are (but we'll use weights also)
idea:
------- NODES
each node of the graph is a chord each node has a name like "Imin Imaj ... IImin IImaj .... etc" We'll cover each possible grade and form, each grade can be maj min dim [...1098 lines suppressed...] chords_memory_class = class_new(gensym("chords_memory"), (t_newmethod)chords_memory_new, (t_method)chords_memory_free, sizeof(t_chords_memory), CLASS_DEFAULT, A_GIMME, 0); class_addbang(chords_memory_class, (t_method)chords_memory_bang); // file I/O class_addmethod(chords_memory_class, (t_method)chords_memory_write_to_file, gensym("write"),A_SYMBOL, 0); class_addmethod(chords_memory_class, (t_method)chords_memory_read_from_file, gensym("read"),A_SYMBOL, 0); // ask for the best choice form here class_addmethod(chords_memory_class, (t_method)chords_memory_next, gensym("next"), A_DEFFLOAT, 0); // ask for a path from here to desired destination class_addmethod(chords_memory_class, (t_method)chords_memory_search, gensym("search"), A_GIMME, 0); // add or set chord class_addmethod(chords_memory_class, (t_method)chords_memory_add_chord, gensym("add"),A_SYMBOL, 0); class_addmethod(chords_memory_class, (t_method)chords_memory_set_chord, gensym("set"),A_SYMBOL, 0); // change current tonality class_addmethod(chords_memory_class, (t_method)chords_memory_set_tonality, gensym("tonality"),A_SYMBOL, 0); class_addmethod(chords_memory_class, (t_method)chords_memory_add_modulation, gensym("modulation"),A_SYMBOL, 0); // reinit memory class_addmethod(chords_memory_class, (t_method)chords_memory_init, gensym("init"), A_DEFFLOAT, 0);
}
--- NEW FILE: test.graph --- (This appears to be a binary file; contents omitted.)
--- NEW FILE: sglib.h --- /*
This is SGLIB version 1.0.3
(C) by Marian Vittek, Bratislava, http://www.xref-tech.com/sglib, 2003-5
License Conditions: You can use a verbatim copy (including this copyright notice) of sglib freely in any project, commercial or not. You can also use derivative forms freely under terms of Open Source Software license or under terms of GNU Public License. If you need to use a derivative form in a commercial project, or you need sglib under any other license conditions, contact the author.
*/
#ifndef _SGLIB__h_ #define _SGLIB__h_
[...1908 lines suppressed...]
#define SGLIB___GET_VALUE(x) (x) #define SGLIB___SET_VALUE(x, value) {(x) = (value);} #define SGLIB_ARRAY_ELEMENTS_EXCHANGER(type, a, i, j) {type _sgl_aee_tmp_; _sgl_aee_tmp_=(a)[(i)]; (a)[(i)]=(a)[(j)]; (a)[(j)]= _sgl_aee_tmp_;}
#define SGLIB_NUMERIC_COMPARATOR(x, y) ((int)((x) - (y))) #define SGLIB_REVERSE_NUMERIC_COMPARATOR(x, y) ((int)((y) - (x)))
#ifndef SGLIB_MAX_TREE_DEEP #define SGLIB_MAX_TREE_DEEP 128 #endif
#ifndef SGLIB_HASH_TAB_SHIFT_CONSTANT #define SGLIB_HASH_TAB_SHIFT_CONSTANT 16381 /* should be a prime */ /* #define SGLIB_HASH_TAB_SHIFT_CONSTANT 536870912 for large tables */ #endif
#endif /* _SGLIB__h_ */
--- NEW FILE: chord_melo_test3.pd --- #N canvas 204 24 1015 713 12; #X obj 620 131 metro; #N canvas 1 23 466 316 msecs 0; #X obj 58 19 inlet; #X obj 61 209 outlet; #X obj 57 147 /; #X obj 57 100 bang; #X obj 73 79 t f f; #X obj 57 174 / 4; #X msg 57 122 60000; #X connect 0 0 4 0; #X connect 2 0 5 0; #X connect 3 0 6 0; #X connect 4 0 3 0; #X connect 4 1 2 1; #X connect 5 0 1 0; #X connect 6 0 2 0; #X restore 684 102 pd msecs; #X obj 683 28 loadbang; #X obj 620 108 tgl 15 0 empty empty empty 0 -6 0 8 -258699 -1 -1 0 1; #N canvas 0 22 498 348 graph2 0; #X obj 122 9 inlet; #X obj 362 255 outlet; #X obj 171 33 int; #X obj 204 31 + 1; #X obj 185 57 % 4; #X obj 168 78 sel 0; #X obj 168 105 bng 15 250 50 0 empty empty beat 0 -6 0 8 -262144 -1 -1; #X obj 263 86 sel 0; #X obj 264 108 bng 15 250 50 0 empty empty bar 0 -6 0 8 -262144 -1 -1; #X obj 262 63 % 16; #X obj 69 278 hradio 10 1 0 16 empty empty empty 0 -6 0 8 -262144 -1 -1 0; #X obj 70 64 / 2; #X obj 71 87 int; #X obj 72 111 hradio 10 1 0 2 empty empty 1/8 0 -6 0 8 -262144 -1 -1 0; #X obj 342 78 int; #X obj 73 220 hradio 10 1 0 4 empty empty 1/4 0 -6 0 8 -262144 -1 -1 0; #X obj 341 55 / 4; #X obj 70 167 hradio 10 1 0 4 empty empty 1/16 0 -6 0 8 -262144 -1 -1 0; #X connect 0 0 2 0; #X connect 2 0 3 0; #X connect 3 0 2 1; #X connect 3 0 4 0; #X connect 3 0 9 0; #X connect 4 0 5 0; #X connect 4 0 17 0; #X connect 4 0 11 0; #X connect 5 0 6 0; #X connect 7 0 8 0; #X connect 9 0 7 0; #X connect 9 0 10 0; #X connect 9 0 16 0; #X connect 9 0 1 0; #X connect 11 0 12 0; #X connect 12 0 13 0; #X connect 14 0 15 0; #X connect 16 0 14 0; #X coords 0 1 100 -1 200 140 1; #X restore 379 92 graph; #X floatatom 706 127 5 0 0 0 - - -; #X obj 632 169 delay; #X obj 667 148 / 2; #X text 296 172 this delay is to center the quantization; #X obj 685 78 nbx 5 14 30 1000 0 0 empty empty empty 0 -6 0 10 -258699 -1 -1 120 256; #X text 29 30 test1: detect rhythmic pattern and proposes a counterpoint ; #N canvas 0 22 458 308 valori 0; #X obj 57 40 inlet; #X obj 136 42 inlet; #X obj 229 42 inlet; #X obj 58 215 outlet; #X msg 60 112 fitness1 $1; #X msg 136 74 fitness2 $1; #X msg 231 133 fitness3 $1; #X connect 0 0 4 0; #X connect 1 0 5 0; #X connect 2 0 6 0; #X connect 4 0 3 0; #X connect 5 0 3 0; #X connect 6 0 3 0; #X restore 713 532 pd valori; #X obj 713 378 vsl 15 128 0 1 0 0 empty empty 1st 0 -8 0 8 -262144 -1 -1 12700 1; #X obj 760 380 vsl 15 128 0 1 0 0 empty empty 2nd 0 -8 0 8 -262144 -1 -1 12700 1; #X obj 800 383 vsl 15 128 0 1 0 0 empty empty 3rd 0 -8 0 8 -262144 -1 -1 12700 1; #X floatatom 700 515 5 0 0 0 - - -; #X floatatom 750 513 5 0 0 0 - - -; #X floatatom 800 522 5 0 0 0 - - -; #X obj 719 49 s sampleinit; #X obj 726 294 loadbang; #N canvas 105 213 716 372 initMelody 0; #X obj 79 28 loadbang; #X msg 18 132 ; src_played const 1 ;; #X msg 29 261 ; src_passing const 0 ;; #X msg 260 69 ; src_note 0 0 1 2 2 1 1 0 0 0 2 2 2 0 2 1 0 ;; #X msg 235 143 ; src_passing 0 0 0 0 -2 0 -2 0 -1 0 0 2 4 0 0 0 0 ;; #X msg 247 107 ; src_octave 0 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 ;; #X connect 0 0 3 0; #X connect 0 0 1 0; #X connect 0 0 5 0; #X connect 0 0 4 0; #X restore 57 108 pd initMelody; #X obj 153 586 noteout; #X obj 153 562 makenote; #X msg 238 539 60; #X msg 270 539 100; #X obj 244 517 loadbang; #X msg 684 49 120; #X msg 712 328 1; #X obj 770 119 table src_octave; #X obj 769 96 table src_note; #X obj 770 141 table src_passing; #X obj 770 165 table src_played; #N canvas 14 41 980 629 play_melody 0; #X obj 58 50 t f f f f; #X obj 58 116 tabread dest_note; #X obj 225 79 tabread dest_octave; #X obj 186 153 tabread dest_passing; #X obj 2 290 tabread dest_played; #X obj 1 315 select 1; #X obj 259 -4 inlet; #X obj 659 8 inlet; #X floatatom 710 68 5 0 0 0 - - -; #X text 729 52 base midi note; #X obj 225 103 * 12; #X obj 57 144 select 0 1 2; #X msg 57 186 0; #X msg 103 184 4; #X msg 150 185 7; #X obj 159 266 +; #X obj 170 303 +; #X obj 180 344 + 36; #X text 245 344 default C; #X obj 275 535 outlet; #X floatatom 204 390 5 0 0 0 - - -; #X obj 95 451 int 0; #X obj 2 339 bang; #X obj 435 50 t f f f f; #X obj 372 332 select 1; #X obj 596 120 * 12; #X obj 428 161 select 0 1 2; #X msg 428 203 0; #X msg 474 201 4; #X msg 521 202 7; #X obj 530 283 +; #X obj 541 320 +; #X obj 551 361 + 36; #X text 616 361 default C; #X floatatom 575 407 5 0 0 0 - - -; #X obj 466 468 int 0; #X obj 373 356 bang; #X obj 373 307 tabread dest_played2; #X obj 429 133 tabread dest_note2; #X obj 596 96 tabread dest_octave2; #X obj 557 170 tabread dest_passing2; #X obj 883 242 inlet; #X obj 235 491 spigot; #X msg 221 455 1; #X msg 256 456 0; #X obj 318 492 spigot; #X msg 297 455 1; #X msg 332 456 0; #X obj 258 19 t f f; #X obj 247 430 select 0 1; #X floatatom 373 533 5 0 0 0 - - -; #X floatatom 195 539 5 0 0 0 - - -; #X connect 0 0 4 0; #X connect 0 1 1 0; #X connect 0 2 3 0; #X connect 0 3 2 0; #X connect 1 0 11 0; #X connect 2 0 10 0; #X connect 3 0 15 1; #X connect 4 0 5 0; #X connect 5 0 22 0; #X connect 6 0 48 0; #X connect 7 0 8 0; #X connect 7 0 17 1; #X connect 7 0 32 1; #X connect 10 0 16 1; #X connect 11 0 12 0; #X connect 11 1 13 0; #X connect 11 2 14 0; #X connect 12 0 15 0; #X connect 13 0 15 0; #X connect 14 0 15 0; #X connect 15 0 16 0; #X connect 16 0 17 0; #X connect 17 0 20 0; #X connect 17 0 21 1; #X connect 21 0 42 0; #X connect 22 0 21 0; #X connect 23 0 37 0; #X connect 23 1 38 0; #X connect 23 2 40 0; #X connect 23 3 39 0; #X connect 24 0 36 0; #X connect 25 0 31 1; #X connect 26 0 27 0; #X connect 26 1 28 0; #X connect 26 2 29 0; #X connect 27 0 30 0; #X connect 28 0 30 0; #X connect 29 0 30 0; #X connect 30 0 31 0; #X connect 31 0 32 0; #X connect 32 0 34 0; #X connect 32 0 35 1; #X connect 35 0 45 0; #X connect 36 0 35 0; #X connect 37 0 24 0; #X connect 38 0 26 0; #X connect 39 0 25 0; #X connect 40 0 30 1; #X connect 41 0 49 0; #X connect 42 0 19 0; #X connect 42 0 51 0; #X connect 43 0 42 1; #X connect 44 0 45 1; #X connect 45 0 19 0; #X connect 45 0 50 0; #X connect 46 0 45 1; #X connect 47 0 42 1; #X connect 48 0 0 0; #X connect 48 1 23 0; #X connect 49 0 43 0; #X connect 49 0 44 0; #X connect 49 1 46 0; #X connect 49 1 47 0; #X restore 153 432 pd play_melody; #X floatatom 264 313 5 0 0 0 base_midi_note - -; #N canvas 80 41 790 533 test_src_melody 0; #X obj 64 33 t f f f f; #X obj -17 299 select 1; #X obj 67 3 inlet; #X obj 418 160 inlet; #X floatatom 442 209 5 0 0 0 - - -; #X text 461 193 base midi note; #X obj 268 125 * 12; #X obj 57 144 select 0 1 2; #X msg 57 186 0; #X msg 103 184 4; #X msg 150 185 7; #X obj 159 266 +; #X obj 170 303 +; #X obj 180 344 + 36; #X text 245 344 default C; #X obj 120 482 outlet; #X floatatom 204 390 5 0 0 0 - - -; #X obj 116 450 int 0; #X obj -16 323 bang; #X obj -16 274 tabread src_played; #X obj 58 116 tabread src_note; #X obj 267 102 tabread src_octave; #X obj 186 153 tabread src_passing; #X connect 0 0 19 0; #X connect 0 1 20 0; #X connect 0 2 22 0; #X connect 0 3 21 0; #X connect 1 0 18 0; #X connect 2 0 0 0; #X connect 3 0 4 0; #X connect 3 0 13 1; #X connect 6 0 12 1; #X connect 7 0 8 0; #X connect 7 1 9 0; #X connect 7 2 10 0; #X connect 8 0 11 0; #X connect 9 0 11 0; #X connect 10 0 11 0; #X connect 11 0 12 0; #X connect 12 0 13 0; #X connect 13 0 16 0; #X connect 13 0 17 1; #X connect 17 0 15 0; #X connect 18 0 17 0; #X connect 19 0 1 0; #X connect 20 0 7 0; #X connect 21 0 6 0; #X connect 22 0 11 1; #X restore 26 383 pd test_src_melody; #N canvas 0 22 462 312 chords 0; #X obj 146 45 select 0; #X obj 147 17 inlet; #X obj 150 255 outlet; #X msg 123 193 36; #X msg 177 193 41; #X msg 232 191 36; #X msg 286 191 43; #X obj 142 96 int 0; #X obj 144 69 bang; #X obj 202 99 + 1; #X obj 141 122 % 4; #X obj 137 147 select 0 1 2 3; #X connect 0 0 8 0; #X connect 1 0 0 0; #X connect 3 0 2 0; #X connect 4 0 2 0; #X connect 5 0 2 0; #X connect 6 0 2 0; #X connect 7 0 9 0; #X connect 7 0 10 0; #X connect 8 0 7 0; #X connect 9 0 7 1; #X connect 10 0 11 0; #X connect 11 0 3 0; #X connect 11 1 4 0; #X connect 11 2 5 0; #X connect 11 3 6 0; #X restore 265 290 pd chords; #X obj 102 619 outlet; #X obj 14 619 outlet; #X obj 569 246 outlet; #X obj 379 233 t a a a a; #X obj 607 56 inlet; #X obj 80 181 tgl 15 0 toggleSRC empty src 0 -6 0 8 -262144 -1 -1 0 1; #X obj 78 215 tgl 15 0 toggleOUT empty out 0 -6 0 8 -262144 -1 -1 0 1; #N canvas 0 22 650 510 toggle 0; #X obj 170 119 r toggleSRC; #X obj 136 144 int 0; #X obj 136 168 select 1; #X obj 137 192 bang; #X obj 154 20 inlet; #X obj 197 270 outlet; #X obj 203 231 int 0; #X obj 86 104 bang; #X obj 201 60 t a a; #X connect 0 0 1 1; #X connect 1 0 2 0; #X connect 2 0 3 0; #X connect 3 0 6 0; #X connect 4 0 8 0; #X connect 6 0 5 0; #X connect 7 0 1 0; #X connect 8 0 7 0; #X connect 8 1 6 1; #X restore 33 414 pd toggle; #N canvas 0 22 662 522 toggle 0; #X obj 136 144 int 0; #X obj 136 168 select 1; #X obj 137 192 bang; #X obj 154 20 inlet; #X obj 197 270 outlet; #X obj 203 231 int 0; #X obj 86 104 bang; #X obj 201 60 t a a; #X obj 170 119 r toggleOUT; #X connect 0 0 1 0; #X connect 1 0 2 0; #X connect 2 0 5 0; #X connect 3 0 7 0; #X connect 5 0 4 0; #X connect 6 0 0 0; #X connect 7 0 6 0; #X connect 7 1 5 1; #X connect 8 0 0 1; #X restore 155 495 pd toggle; #N canvas 0 22 778 359 read-tables 0; #X obj 93 110 tabread dest_note; #X floatatom 96 147 5 0 0 0 - - -; #X floatatom 341 44 5 0 0 0 - - -; #X floatatom 244 147 5 0 0 0 - - -; #X floatatom 388 146 5 0 0 0 - - -; #X floatatom 532 143 5 0 0 0 - - -; #X obj 243 91 tabread dest_octave; #X obj 386 109 tabread dest_passing; #X obj 529 89 tabread dest_played; #X obj 514 175 print; #X connect 0 0 1 0; #X connect 2 0 0 0; #X connect 2 0 6 0; #X connect 2 0 7 0; #X connect 2 0 8 0; #X connect 6 0 3 0; #X connect 7 0 4 0; #X connect 8 0 5 0; #X connect 8 0 9 0; #X restore 847 310 pd read-tables; #X msg 866 529 mutation $1; #X msg 883 549 crossover $1; #X obj 865 373 vsl 15 128 0 1 0 0 empty empty empty 0 -8 0 8 -262144 -1 -1 0 1; #X obj 899 371 vsl 15 128 0 1 0 0 empty empty empty 0 -8 0 8 -262144 -1 -1 0 1; #X floatatom 845 507 5 0 0 0 - - -; #X floatatom 900 505 5 0 0 0 - - -; #X msg 791 327 1; #N canvas 0 22 923 490 chord_melo1 0; #X obj 94 49 inlet; #X obj 349 58 inlet; #X obj 123 264 bang; #X obj 140 116 select 0; #X obj 185 256 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 191 187 int 0; #X obj 240 188 + 1; #X floatatom 191 211 5 0 0 0 generation - -; #X obj 191 164 bang; #X msg 23 270 init a; #X obj 22 227 select 1; #X obj 23 248 bang; #X obj 222 344 chord_melo src_note src_octave src_passing src_played dest_note dest_octave dest_passing dest_played; #X obj 415 139 table dest_note; #X obj 416 162 table dest_octave; #X obj 415 184 table dest_passing; #X obj 415 208 table dest_played; #X connect 0 0 3 0; #X connect 1 0 12 0; #X connect 2 0 12 0; #X connect 3 0 2 0; #X connect 3 0 8 0; #X connect 4 0 12 0; #X connect 5 0 6 0; #X connect 5 0 7 0; #X connect 5 0 10 0; #X connect 6 0 5 1; #X connect 8 0 5 0; #X connect 9 0 12 0; #X connect 10 0 11 0; #X connect 11 0 9 0; #X restore 667 589 pd chord_melo1; #N canvas 0 22 923 490 chord_melo2 0; #X obj 94 49 inlet; #X obj 349 58 inlet; #X obj 123 264 bang; #X obj 140 116 select 0; #X obj 185 256 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 191 187 int 0; #X obj 240 188 + 1; #X floatatom 191 211 5 0 0 0 generation - -; #X obj 191 164 bang; #X msg 23 270 init a; #X obj 22 227 select 1; #X obj 23 248 bang; #X obj 415 139 table dest_note2; #X obj 416 162 table dest_octave2; #X obj 415 184 table dest_passing2; #X obj 415 208 table dest_played2; #X obj 222 344 chord_melo src_note src_octave src_passing src_played dest_note2 dest_octave2 dest_passing2 dest_played2; #X connect 0 0 3 0; #X connect 1 0 16 0; #X connect 2 0 16 0; #X connect 3 0 2 0; #X connect 3 0 8 0; #X connect 4 0 16 0; #X connect 5 0 6 0; #X connect 5 0 7 0; #X connect 5 0 10 0; #X connect 6 0 5 1; #X connect 8 0 5 0; #X connect 9 0 16 0; #X connect 10 0 11 0; #X connect 11 0 9 0; #X restore 473 628 pd chord_melo2; #X obj 339 336 manager; #N canvas 0 22 698 589 sum 0; #X obj 116 64 inlet; #X obj 150 338 outlet; #X obj 278 36 inlet; #X obj 265 72 select 0; #X obj 264 124 int 0; #X obj 312 123 + 1; #X obj 266 96 bang; #X obj 86 202 spigot; #X obj 147 203 int; #X obj 104 236 + 0; #X obj 124 99 t f f; #X obj 211 126 bang; #X text 383 222 not working yet; #X text 337 254 it should join the two statements; #X text 326 277 join means make the first interval small; #X text 400 192 TODO; #X obj 204 295 spigot; #X obj 251 201 bang; #X msg 246 223 1; #X obj 257 247 -; #X obj 253 177 t a a; #X obj 254 147 % 2; #X connect 0 0 10 0; #X connect 2 0 3 0; #X connect 3 0 6 0; #X connect 3 0 11 0; #X connect 4 0 5 0; #X connect 4 0 21 0; #X connect 5 0 4 1; #X connect 6 0 4 0; #X connect 7 0 9 0; #X connect 8 0 9 1; #X connect 9 0 1 0; #X connect 10 0 8 1; #X connect 10 0 7 0; #X connect 10 1 16 0; #X connect 11 0 8 0; #X connect 16 0 1 0; #X connect 17 0 18 0; #X connect 18 0 19 0; #X connect 19 0 16 1; #X connect 20 0 17 0; #X connect 20 1 19 1; #X connect 21 0 20 0; #X connect 21 0 7 1; #X restore 224 468 pd sum; #N canvas 0 22 458 308 valori 0; #X obj 57 40 inlet; #X obj 136 42 inlet; #X obj 229 42 inlet; #X obj 58 215 outlet; #X msg 60 112 fitness1 $1; #X msg 136 74 fitness2 $1; #X msg 231 133 fitness3 $1; #X connect 0 0 4 0; #X connect 1 0 5 0; #X connect 2 0 6 0; #X connect 4 0 3 0; #X connect 5 0 3 0; #X connect 6 0 3 0; #X restore 511 539 pd valori; #X obj 511 385 vsl 15 128 0 1 0 0 empty empty 1st 0 -8 0 8 -262144 -1 -1 12700 1; #X obj 558 387 vsl 15 128 0 1 0 0 empty empty 2nd 0 -8 0 8 -262144 -1 -1 12700 1; #X obj 598 390 vsl 15 128 0 1 0 0 empty empty 3rd 0 -8 0 8 -262144 -1 -1 12700 1; #X floatatom 498 522 5 0 0 0 - - -; #X floatatom 548 520 5 0 0 0 - - -; #X floatatom 598 529 5 0 0 0 - - -; #X obj 524 301 loadbang; #X msg 510 335 1; #X msg 589 334 1; #X msg 423 568 mutation $1; #X msg 440 588 crossover $1; #X obj 422 412 vsl 15 128 0 1 0 0 empty empty empty 0 -8 0 8 -262144 -1 -1 0 1; #X obj 456 410 vsl 15 128 0 1 0 0 empty empty empty 0 -8 0 8 -262144 -1 -1 0 1; #X floatatom 402 546 5 0 0 0 - - -; #X floatatom 457 544 5 0 0 0 - - -; #X floatatom 344 439 5 0 0 0 - - -; #X obj 304 614 outlet; #X connect 0 0 6 0; #X connect 1 0 0 1; #X connect 1 0 5 0; #X connect 1 0 7 0; #X connect 2 0 26 0; #X connect 2 0 18 0; #X connect 3 0 0 0; #X connect 4 0 39 0; #X connect 6 0 4 0; #X connect 7 0 6 1; #X connect 9 0 1 0; #X connect 11 0 53 1; #X connect 12 0 11 0; #X connect 12 0 15 0; #X connect 13 0 11 1; #X connect 13 0 16 0; #X connect 14 0 11 2; #X connect 14 0 17 0; #X connect 19 0 27 0; #X connect 19 0 52 0; #X connect 22 0 21 0; #X connect 22 1 21 1; #X connect 23 0 22 1; #X connect 24 0 22 2; #X connect 25 0 24 0; #X connect 25 0 23 0; #X connect 26 0 9 0; #X connect 27 0 12 0; #X connect 27 0 13 0; #X connect 32 0 36 0; #X connect 32 0 44 0; #X connect 33 0 34 1; #X connect 33 0 32 1; #X connect 34 0 37 0; #X connect 34 0 43 0; #X connect 35 0 33 0; #X connect 39 1 32 0; #X connect 39 1 34 0; #X connect 39 2 35 0; #X connect 39 2 53 0; #X connect 39 2 54 0; #X connect 39 3 38 0; #X connect 39 3 55 0; #X connect 39 3 56 1; #X connect 40 0 3 0; #X connect 43 0 22 0; #X connect 44 0 22 0; #X connect 46 0 53 1; #X connect 47 0 53 1; #X connect 48 0 46 0; #X connect 48 0 50 0; #X connect 49 0 47 0; #X connect 49 0 51 0; #X connect 52 0 14 0; #X connect 55 0 32 2; #X connect 55 0 73 0; #X connect 55 0 74 0; #X connect 57 0 54 1; #X connect 58 0 57 0; #X connect 58 0 61 0; #X connect 59 0 57 1; #X connect 59 0 62 0; #X connect 60 0 57 2; #X connect 60 0 63 0; #X connect 64 0 65 0; #X connect 64 0 66 0; #X connect 65 0 58 0; #X connect 65 0 59 0; #X connect 66 0 60 0; #X connect 67 0 54 1; #X connect 68 0 54 1; #X connect 69 0 67 0; #X connect 69 0 71 0; #X connect 70 0 68 0; #X connect 70 0 72 0;
--- NEW FILE: chord_melo.c --- /* BUGS: - I had to comment out arrays re-display because it crashed my pd - sometimes dest_played gets filled with junk
TODO: - now rests can't be used! change chord_melo_seq_max_min */ #include <stdlib.h> #include <math.h> #include <time.h> #include "m_pd.h"
#define BUFFER_LENGHT 16 // lunghezza dei buffers (quanti elementi nel pattern) #define MAX_POPULATION 500 #define CHOIR 20 #define NOTES 128 // how many notes can I use ? MIDI ! #define MAX_OCTAVES 3
#define DEF_PROB_CROSSOVER 0.9f [...1098 lines suppressed...] { chord_melo_class = class_new(gensym("chord_melo"), (t_newmethod)chord_melo_new, (t_method)chord_melo_free, sizeof(t_chord_melo), CLASS_DEFAULT, A_GIMME, 0); class_addbang(chord_melo_class, (t_method)chord_melo_bang); class_addmethod(chord_melo_class, (t_method)chord_melo_src_note, gensym("src_note"),A_SYMBOL, 0); class_addmethod(chord_melo_class, (t_method)chord_melo_src_octave, gensym("src_octave"),A_SYMBOL, 0); class_addmethod(chord_melo_class, (t_method)chord_melo_src_passing, gensym("src_passing"),A_SYMBOL, 0); class_addmethod(chord_melo_class, (t_method)chord_melo_src_played, gensym("src_played"),A_SYMBOL, 0); class_addmethod(chord_melo_class, (t_method)chord_melo_dest_note, gensym("dest_note"),A_SYMBOL, 0); class_addmethod(chord_melo_class, (t_method)chord_melo_dest_octave, gensym("dest_octave"),A_SYMBOL, 0); class_addmethod(chord_melo_class, (t_method)chord_melo_dest_passing, gensym("dest_passing"),A_SYMBOL, 0); class_addmethod(chord_melo_class, (t_method)chord_melo_dest_played, gensym("dest_played"),A_SYMBOL, 0); class_addmethod(chord_melo_class, (t_method)chord_melo_fitness1_set, gensym("fitness1"), A_DEFFLOAT, 0); class_addmethod(chord_melo_class, (t_method)chord_melo_fitness2_set, gensym("fitness2"), A_DEFFLOAT, 0); class_addmethod(chord_melo_class, (t_method)chord_melo_fitness3_set, gensym("fitness3"), A_DEFFLOAT, 0); class_addmethod(chord_melo_class, (t_method)chord_melo_init_pop2, gensym("init"),A_SYMBOL, 0); class_addmethod(chord_melo_class, (t_method)chord_melo_mutation_set, gensym("mutation"), A_DEFFLOAT, 0); class_addmethod(chord_melo_class, (t_method)chord_melo_crossover_set, gensym("crossover"), A_DEFFLOAT, 0);
}
--- NEW FILE: README.txt --- frankenstein set of externals
authors: dmorelli: www.davidemorelli.it pland: www.davidcasal.com with the help of vatic
last update: 14-10-2005
------------------- what is this?
this is an attempt to build an intelligent system for realtime improvisation, a system that follows a human player and proposes rhythm, melody, chords sequences, formal structure. it learns the style in realtime. it uses various AI techniques: GA, searchs, ANN (maybe)
description of files:
chord_melo.c a GA melody generator. it takes a melody as input and evolves it over time. uses co-evolutionary techniques (Todd)
chords_memory.c it is a directional graph which implements a memory of the played chords sequences, you can train it... and once trained you can ask questions like: in C major, from a D minor 7h where did I go most if the times? or in C major, from a D minor 7h build a chord sequence to bring me in D major in 4 steps using the chords sequences I used most
harmonizer.c a GA external that build choir voicing for 5 voices: you pass it the midi value of each voice, starting chord, next chord and it outputs a list with the midi values of each voice. avoids hidden 8ves and 5ths.
folders:
doc/ implementation documents, notes, logs, ideas, etc.. patches/ example patches, help patches, some used in performances, etc.. aima/ python patches not yes used but interesting for agents ruby/ gridflow patches not yet used old/ old not used code test/ testing code, not to be used backup/ previous versions
TODO:
gluer/solderer an external that takes the input of two or more chord_melody, a chord sequence and glues the melody statemets together to build a long complete melody.
form_manager an external that manages the form and structure of the piece: decide which melody statement to use, the chord sequence to ask for, etc..
various objects to detect played notes
diatonic_melody.c same as chord_melody but without chord reference, only scale used (for post-tonal music non based on chords)
chromatic_melo.c same as diatonic_melo but without any reference (for atonal music)
--- NEW FILE: GArhythm.c --- /*
*/ #include <stdlib.h> #include "m_pd.h"
#define BUFFER_LENGHT 16 // lunghezza dei buffers (quanti elementi nel pattern) #define MAX_POPULATION 100 #define CHOIR 20 #define NUM_STRUM 4 // quanti strumenti uso , max 8
#define DEF_PROB_CROSSOVER 0.9f #define DEF_PROB_MUTATION 0.025f #define REINSERT_SRC 1 // quanti reinserisco ad ogni ciclo usando il ritmo src #define REINSERT_LAST 0 // quanti reinserisco ad ogni ciclo usando il ritmo src
#define DEBUG 0 // messaggi di debug
static t_class *GArhythm_class;
typedef struct _GArhythm { t_object x_obj; // myself t_symbol *x_arrayname_src_strum1; // where i read the current pattern t_symbol *x_arrayname_src_strum2; // where i read the current pattern t_symbol *x_arrayname_src_strum3; // where i read the current pattern t_symbol *x_arrayname_src_strum4; // where i read the current pattern t_symbol *x_arrayname_dest_strum1; // where i put the computed pattern t_symbol *x_arrayname_dest_strum2; // where i put the computed pattern t_symbol *x_arrayname_dest_strum3; // where i put the computed pattern t_symbol *x_arrayname_dest_strum4; // where i put the computed pattern //t_float *buf_strum1; // buffer strum1o //t_float *buf_strum2; // buffer alto // tutti gli indici vanno da 0 a 1; float indice_variazione; // quanto cambio dalla battuta precedente float indice_riempimento; // quanto voglio fitto il pattern risultante float indice_aderenza; // quanto simile al ritmo sorgente devo essere // la popolazione array di cromosomi char population[MAX_POPULATION][BUFFER_LENGHT]; float prob_crossover; float prob_mutation; char last[BUFFER_LENGHT];
} t_GArhythm;
void GArhythm_init_pop(t_GArhythm *x) { int i, j, tmp, k; double rnd; for (i=0; i<MAX_POPULATION; i++) { for (j=0; j<BUFFER_LENGHT; j++) { tmp = 0; for (k=0; k<NUM_STRUM; k++) { rnd = rand()/((double)RAND_MAX + 1); if (rnd > 0.5) { tmp = tmp + (1<<k); // da 0 a MAX_POPULATION } } x->population[i][j]=tmp; } if (DEBUG) post("inizializzo population[%i] = %i%i%i%i", i, x->population[i][0], x->population[i][1], x->population[i][2], x->population[i][3] ); } }
void GArhythm_init_buf(t_float *buf) { int i; for (i=0; i<sizeof(buf); i++) { buf[i] = 0; } }
void GArhythm_allocate_buffers(t_GArhythm *x) { // x->buf_strum1 = (t_float *)getbytes(BUFFER_LENGHT * sizeof(t_float)); // x->buf_strum2 = (t_float *)getbytes(BUFFER_LENGHT * sizeof(t_float)); // GArhythm_init_buf(x->buf_strum1); // GArhythm_init_buf(x->buf_strum2); }
void GArhythm_free(t_GArhythm *x) { // freebytes(x->buf_strum1, sizeof(x->buf_strum1)); // freebytes(x->buf_strum2, sizeof(x->buf_strum2)); }
// returns fitness: how similar are man and woman static double GArhythm_evaluate_fitness1(char *woman, char *man) { int res=0; int max = BUFFER_LENGHT*2; int i; for (i=0; i<BUFFER_LENGHT; i++) { if (woman[i] == man[i]) res++; } for (i=0; i<BUFFER_LENGHT; i++) { if ((woman[i]!= 0) && (man[i] != 0)) res++; if ((woman[i]== 0) && (man[i] == 0)) res++; } return res/max; }
// riempimento static double GArhythm_evaluate_fitness2(char *woman, char *man) { int i, j, max; double ris=0; max = BUFFER_LENGHT * NUM_STRUM; for (i=0; i<BUFFER_LENGHT; i++) { for (j=0; j<NUM_STRUM; j++) { if (man[i] & (0x01<<j)) ris++; } } return ris/max;
}
// similarities TODO static double GArhythm_evaluate_fitness3(char *woman, char *man) { int i; short int global1[BUFFER_LENGHT]; short int global2[BUFFER_LENGHT]; for (i=0; i<BUFFER_LENGHT; i++) { if (woman[i] != 0x00) global1[i]=1; else global1[i]=0; if (man[i] != 0x00) global2[i]=1; else global2[i]=0;
} // TODO return 0; }
static void GArhythm_create_child(t_GArhythm *x, char *woman, char *man, char *child) { double rnd; int split, i, j, tmp; // crossover rnd = rand()/((double)RAND_MAX + 1); if (rnd < x->prob_crossover) { split =(int) ( rnd * BUFFER_LENGHT); // da 0 a MAX_POPULATION for (i=0; i< split; i++) { child[i] = woman[i]; } for (i=split; i<BUFFER_LENGHT; i++) { child[i] = man[i]; } // TODO: vertical split (some instr from mammy, some from daddy) }else { for (i=0; i< BUFFER_LENGHT; i++) { child[i] = woman[i]; } } // mutation for (i=0; i< BUFFER_LENGHT; i++) { // per ogni battito for (j=0; j<NUM_STRUM; j++) { // per ogni strumento tmp = child[i] & (0x01<<j); // tmp > 0 se è presente il battito là rnd = rand()/((double)RAND_MAX + 1); if (rnd < x->prob_mutation) { if (DEBUG) post("mutazione al battito %i allo strumento %i", i, j); if (tmp) { child[i] = child[i] & (~(0x01<<j)); // tolgo il bit } else { child[i] = child[i] | (0x01<<j); // aggiungo il bit } } } } if (DEBUG) post("generato figlio %i %i %i %i tra %i %i %i %i e %i %i %i %i, split=%i", child[0], child[1], child[2], child[3], woman[0], woman[1], woman[2], woman[3], man[0], man[1], man[2], man[3], split);
}
static void GArhythm_bang(t_GArhythm *x) {
int i, j, vecsize, ntot, tmp, me; float prob, variatore; t_garray *arysrc_strum1; t_garray *arysrc_strum2; t_garray *arysrc_strum3; t_garray *arysrc_strum4; t_garray *arydest_strum1; t_garray *arydest_strum2; t_garray *arydest_strum3; t_garray *arydest_strum4; t_float *vecsrc_strum1; t_float *vecsrc_strum2; t_float *vecsrc_strum3; t_float *vecsrc_strum4; t_float *vecdest_strum1; t_float *vecdest_strum2; t_float *vecdest_strum3; t_float *vecdest_strum4; double rnd; int winner; double winner_fitness;
char figli[MAX_POPULATION][BUFFER_LENGHT];
// load tables
if (!(arysrc_strum1 = (t_garray *)pd_findbyclass(x->x_arrayname_src_strum1, garray_class))) { pd_error(x, "%s: no such array", x->x_arrayname_src_strum1->s_name); } else if (!garray_getfloatarray(arysrc_strum1, &vecsize, &vecsrc_strum1)) { pd_error(x, "%s: bad template for tabwrite", x->x_arrayname_src_strum1->s_name); } else if (!(arysrc_strum2 = (t_garray *)pd_findbyclass(x->x_arrayname_src_strum2, garray_class))) { pd_error(x, "%s: no such array", x->x_arrayname_src_strum2->s_name); } else if (!garray_getfloatarray(arysrc_strum2, &vecsize, &vecsrc_strum2)) { pd_error(x, "%s: bad template for tabwrite", x->x_arrayname_src_strum2->s_name); } else if (!(arysrc_strum3 = (t_garray *)pd_findbyclass(x->x_arrayname_src_strum3, garray_class))) { pd_error(x, "%s: no such array", x->x_arrayname_src_strum3->s_name); } else if (!garray_getfloatarray(arysrc_strum3, &vecsize, &vecsrc_strum3)) { pd_error(x, "%s: bad template for tabwrite", x->x_arrayname_src_strum3->s_name); } else if (!(arysrc_strum4 = (t_garray *)pd_findbyclass(x->x_arrayname_src_strum4, garray_class))) { pd_error(x, "%s: no such array", x->x_arrayname_src_strum4->s_name); } else if (!garray_getfloatarray(arysrc_strum4, &vecsize, &vecsrc_strum4)) { pd_error(x, "%s: bad template for tabwrite", x->x_arrayname_src_strum4->s_name); } else if (!(arydest_strum1 = (t_garray *)pd_findbyclass(x->x_arrayname_dest_strum1, garray_class))) { pd_error(x, "%s: no such array", x->x_arrayname_dest_strum1->s_name); } else if (!garray_getfloatarray(arydest_strum1, &vecsize, &vecdest_strum1)) { pd_error(x, "%s: bad template for tabwrite", x->x_arrayname_dest_strum1->s_name); } else if (!(arydest_strum2 = (t_garray *)pd_findbyclass(x->x_arrayname_dest_strum2, garray_class))) { pd_error(x, "%s: no such array", x->x_arrayname_dest_strum2->s_name); } else if (!garray_getfloatarray(arydest_strum2, &vecsize, &vecdest_strum2)) { pd_error(x, "%s: bad template for tabwrite", x->x_arrayname_dest_strum2->s_name); } else if (!(arydest_strum3 = (t_garray *)pd_findbyclass(x->x_arrayname_dest_strum3, garray_class))) { pd_error(x, "%s: no such array", x->x_arrayname_dest_strum3->s_name); } else if (!garray_getfloatarray(arydest_strum3, &vecsize, &vecdest_strum3)) { pd_error(x, "%s: bad template for tabwrite", x->x_arrayname_dest_strum3->s_name); } else if (!(arydest_strum4 = (t_garray *)pd_findbyclass(x->x_arrayname_dest_strum4, garray_class))) { pd_error(x, "%s: no such array", x->x_arrayname_dest_strum4->s_name); } else if (!garray_getfloatarray(arydest_strum4, &vecsize, &vecdest_strum4)) { pd_error(x, "%s: bad template for tabwrite", x->x_arrayname_dest_strum4->s_name); } else // I got arrays and data { // vecdest_strum2 e _strum1 contengono i valori in float degli array if (DEBUG) post("--------- starting process"); // uccido a caso REINSERT_SRC elementi e inserisco il ritmo src al loro posto for (i=0; i<REINSERT_SRC; i++) { rnd = rand()/((double)RAND_MAX + 1); me = (int) (rnd * MAX_POPULATION); for (j=0; j<BUFFER_LENGHT; j++) { char c = 0x00; if (vecsrc_strum1[j]) c = c | 0x01; if (vecsrc_strum2[j]) c = c | (0x01 << 1); if (vecsrc_strum3[j]) c = c | (0x01 << 2); if (vecsrc_strum4[j]) c = c | (0x01 << 3); x->population[me][j]=c; } } // uccido a caso REINSERT_LAST elementi e inserisco il last al loro posto for (i=0; i<REINSERT_LAST; i++) { rnd = rand()/((double)RAND_MAX + 1); me = (int) (rnd * MAX_POPULATION); for (j=0; j<BUFFER_LENGHT; j++) { x->population[me][j]=x->last[j]; } }
// metà sono donne, prese a caso for (i=0; i<(MAX_POPULATION/2); i++) { int winner=CHOIR; int winner_value=0; int men[CHOIR]; char figlio[BUFFER_LENGHT]; double fitness1[CHOIR]; double fitness2[CHOIR]; double fitness3[CHOIR]; double fitnessTOT[CHOIR]; rnd = rand()/((double)RAND_MAX + 1); me =(int) ( rnd * MAX_POPULATION); // da 0 a MAX_POPULATION // me è la donna che valuta gli uomini
if (DEBUG) post("woman %i = %i %i %i %i", me, x->population[me][0], x->population[me][1], x->population[me][2], x->population[me][3]);
for (j=0; j<CHOIR; j++) { rnd = rand()/((double)RAND_MAX + 1); tmp =(int) ( rnd * MAX_POPULATION); // da 0 a MAX_POPULATION // tmp è questo uomo men[j] = tmp; fitness1[j]=GArhythm_evaluate_fitness1(x->population[me], x->population[tmp]); fitness2[j]=GArhythm_evaluate_fitness2(x->population[me], x->population[tmp]); fitness3[j]=GArhythm_evaluate_fitness3(x->population[me], x->population[tmp]); fitnessTOT[j]=fitness1[j] * (x->indice_aderenza) + fitness2[j] * (x->indice_riempimento) + (1 - fitness2[j]) * (1-(x->indice_riempimento)) + fitness3[j] * (x->indice_variazione); if (winner_value <= fitnessTOT[j]) { winner = tmp; winner_value = fitnessTOT[j]; } } // winner è il maschio migliore nel coro if (DEBUG) post("ho scelto il maschio %i", winner); // genero un figlio GArhythm_create_child(x, x->population[me], x->population[winner], figlio); for (j=0; j<BUFFER_LENGHT; j++) { figli[i][j] = figlio[j]; } }
// uccido a caso metà popolazione e ci metto i nuovi nati for (i=0; i<(MAX_POPULATION/2); i++) { rnd = rand()/((double)RAND_MAX + 1); me =(int) ( rnd * MAX_POPULATION); // da 0 a MAX_POPULATION // me è chi deve morire
for (j=0; j<BUFFER_LENGHT; j++) { x->population[me][j] = figli[i][j]; } }
// prendo il più adatto rispetto all'ultimo ritmo suonato winner = 0; winner_fitness = 0; for(i=0; i<BUFFER_LENGHT; i++) { double tmp1, tmp2, tmp3, tmpTOT; tmp1 = GArhythm_evaluate_fitness1(x->last, x->population[i]); tmp2 = GArhythm_evaluate_fitness2(x->last, x->population[i]); tmp3 = GArhythm_evaluate_fitness3(x->last, x->population[i]); tmpTOT = tmp1 * (x->indice_aderenza) + tmp2 * (x->indice_riempimento) + (1-tmp2) * (1-(x->indice_riempimento)) + tmp3 * (x->indice_variazione); if (tmpTOT >= winner_fitness) { winner_fitness = tmpTOT; winner = i; } } for (i=0; i<BUFFER_LENGHT; i++) { // copio il vincitor ein x->last x->last[i] = x->population[winner][i]; // scrivo i buffer in uscita vecdest_strum1[i]=((x->population[winner][i] & (0x01<<0)) ? 1 : 0); vecdest_strum2[i]=((x->population[winner][i] & (0x01<<1)) ? 1 : 0); vecdest_strum3[i]=((x->population[winner][i] & (0x01<<2)) ? 1 : 0); vecdest_strum4[i]=((x->population[winner][i] & (0x01<<3)) ? 1 : 0); }
// redraw the arrays //garray_redraw(arysrc); garray_redraw(arydest_strum1); garray_redraw(arydest_strum2); garray_redraw(arydest_strum3); garray_redraw(arydest_strum4);
} } /* static void GArhythm_src(t_GArhythm *x, t_symbol *s) { x->x_arrayname_src = s; } */
static void GArhythm_variazione_set(t_GArhythm *x, t_floatarg f) { x->indice_variazione = f; }
static void GArhythm_aderenza_set(t_GArhythm *x, t_floatarg f) { x->indice_aderenza = f; }
static void GArhythm_riempimento_set(t_GArhythm *x, t_floatarg f) { x->indice_riempimento = f; }
static void GArhythm_crossover_set(t_GArhythm *x, t_floatarg f) { x->prob_crossover = f; }
static void GArhythm_mutation_set(t_GArhythm *x, t_floatarg f) { x->prob_mutation = f; }
static void *GArhythm_new(t_symbol *s, int argc, t_atom *argv) { t_GArhythm *x = (t_GArhythm *)pd_new(GArhythm_class); GArhythm_allocate_buffers(x); GArhythm_init_pop(x); // inizializzo gli indici x->indice_variazione=0; x->indice_riempimento=0; x->indice_aderenza=0; x->prob_crossover = DEF_PROB_CROSSOVER; x->prob_mutation = DEF_PROB_MUTATION;
if (argc>0) { x->x_arrayname_src_strum1 = atom_getsymbolarg(0, argc, argv); } if (argc>1) { x->x_arrayname_src_strum2 = atom_getsymbolarg(1, argc, argv); } if (argc>2) { x->x_arrayname_src_strum3 = atom_getsymbolarg(2, argc, argv); } if (argc>3) { x->x_arrayname_src_strum4 = atom_getsymbolarg(3, argc, argv); } if (argc>4) { x->x_arrayname_dest_strum1 = atom_getsymbolarg(4, argc, argv); } if (argc>5) { x->x_arrayname_dest_strum2 = atom_getsymbolarg(5, argc, argv); } if (argc>6) { x->x_arrayname_dest_strum3 = atom_getsymbolarg(6, argc, argv); } if (argc>7) { x->x_arrayname_dest_strum4 = atom_getsymbolarg(7, argc, argv); }
return (x); }
void GArhythm_setup(void) { GArhythm_class = class_new(gensym("GArhythm"), (t_newmethod)GArhythm_new, (t_method)GArhythm_free, sizeof(t_GArhythm), CLASS_DEFAULT, A_GIMME, 0); class_addbang(GArhythm_class, (t_method)GArhythm_bang); // class_addmethod(GArhythm_class, (t_method)GArhythm_src, gensym("src"),A_SYMBOL, 0); class_addmethod(GArhythm_class, (t_method)GArhythm_variazione_set, gensym("variazione"), A_DEFFLOAT, 0); class_addmethod(GArhythm_class, (t_method)GArhythm_riempimento_set, gensym("riempimento"), A_DEFFLOAT, 0); class_addmethod(GArhythm_class, (t_method)GArhythm_aderenza_set, gensym("aderenza"), A_DEFFLOAT, 0); }