From eb9ef05774af20edb43118182834c18a4ac70707 Mon Sep 17 00:00:00 2001 From: Davide Morelli Date: Tue, 18 Oct 2005 23:10:53 +0000 Subject: initial checkin svn path=/trunk/externals/frankenstein/; revision=3734 --- GArhythm.c | 539 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 539 insertions(+) create mode 100755 GArhythm.c (limited to 'GArhythm.c') diff --git a/GArhythm.c b/GArhythm.c new file mode 100755 index 0000000..a41b311 --- /dev/null +++ b/GArhythm.c @@ -0,0 +1,539 @@ +/* + +*/ +#include +#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 0.5) + { + tmp = tmp + (1<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; ibuf_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; iprob_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 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<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; ipopulation[me][j]=c; + } + } + // uccido a caso REINSERT_LAST elementi e inserisco il last al loro posto + for (i=0; ipopulation[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; jpopulation[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; jpopulation[me][j] = figli[i][j]; + } + } + + // prendo il più adatto rispetto all'ultimo ritmo suonato + winner = 0; + winner_fitness = 0; + for(i=0; ilast, 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; ilast + 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); +} -- cgit v1.2.1