From b9406125392107f1fb6a548236e6bbdad3721bcf Mon Sep 17 00:00:00 2001 From: Davide Morelli Date: Wed, 7 Dec 2005 00:20:01 +0000 Subject: first version of rhythms_memory svn path=/trunk/externals/frankenstein/; revision=4161 --- Makefile | 6 +- common.c | 57 +++++++++----- rhythms_memory.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++++ rhythms_memory.sln | 21 +++++ rhythms_memory.vcproj | 130 +++++++++++++++++++++++++++++++ test-rhythms_memory.pd | 42 ++++++++++ 6 files changed, 436 insertions(+), 24 deletions(-) create mode 100755 rhythms_memory.c create mode 100755 rhythms_memory.sln create mode 100755 rhythms_memory.vcproj create mode 100755 test-rhythms_memory.pd diff --git a/Makefile b/Makefile index 86a00d2..a7ac89b 100755 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ # 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" +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 test.dll +pd_nt: chord_melo.dll chords_memory.dll harmonizer.dll GArhythm.dll ritmo1.dll rhythms_memory.dll .SUFFIXES: .dll diff --git a/common.c b/common.c index 8cb310d..f48a370 100755 --- a/common.c +++ b/common.c @@ -206,6 +206,8 @@ void create_rhythm_memory_representation(t_rhythm_memory_representation **this_r // the naming variables (*this_rep)->id = id; // the main id (*this_rep)->last_sub_id = 0; // the sub id + (*this_rep)->next = 0; + (*this_rep)->max_weight = 0; } // add a new rhythm in the list of similar thythms related to one main rhythm @@ -288,6 +290,7 @@ unsigned short int add_t_rhythm_memory_element(t_rhythm_memory_representation *t { // a new champion! this_rep->max_weight = this_rep->transitions[i].weight; + post("DEBUG: max_weight=%i", this_rep->max_weight); } last = i; currEvent = currEvent->next; @@ -377,6 +380,7 @@ void compare_rhythm_vs_representation(t_rhythm_memory_representation *this_rep, unsigned short int best_subid, curr_subid; float best_closeness, curr_closeness; int sub_ok, sub_no; + int count_strong; t_rhythm_memory_element *possible_rhythms; // check that the return values have been allocated @@ -410,23 +414,28 @@ void compare_rhythm_vs_representation(t_rhythm_memory_representation *this_rep, // look all the representation's rhythm // looking for strong beats corrispondance + count_strong = 0; for (i=0; i min_to_be_main_rhythm_beat) - { this_weight_int = this_rep->transitions[i].weight; this_weight_float = (float) (((float) this_weight_int) / ((float) this_rep->max_weight)); - // this is a main rhythm beat - if (src_rhythm_array[i]>0) - { - // both playing - strong_ok++; - } else + post("DEBUG: transition %i this_weight_float=%f", i, this_weight_float); + if (this_weight_float > min_to_be_main_rhythm_beat) { - // strong beat miss - strong_no++; - } - } + // this is a main rhythm beat + if (src_rhythm_array[i]>0) + { + // both playing + strong_ok++; + post("DEBUG: beat %i, both playing", i); + } else + { + // strong beat miss + strong_no++; + post("DEBUG: beat %i, src not playing", i); + } + count_strong++; + } } // this is the average weight of this rhythm in this representation @@ -440,12 +449,14 @@ void compare_rhythm_vs_representation(t_rhythm_memory_representation *this_rep, // ratio of corresponding strong beats.. // close to 0 = no corrispondance // close to 1 = corrispondance - if (strong_no==0) + if (count_strong==0) { - strong_ratio = 1; + strong_ratio = 0; } else { - strong_ratio = (float) ( ((float) strong_ok) / ((float)strong_no) ); + strong_ratio = (float) ( ( ((float) strong_ok) / ((float)count_strong) ) - + ( ((float) strong_no) / ((float)count_strong) )) ; + post("DEBUG: strong_ratio=%f", strong_ratio); } // for each rhythm in the list // count the number of identical nodes @@ -527,6 +538,7 @@ void find_rhythm_in_memory(t_rhythm_memory_representation *rep_list, best_sub_closeness = curr_sub_closeness; best_subid = curr_subid; } + this_rep = this_rep->next; } *id = best_id; @@ -547,14 +559,15 @@ void rhythm_memory_create(t_rhythm_memory_representation **this_rep) // free the space void rhythm_memory_free(t_rhythm_memory_representation *rep_list) { - t_rhythm_memory_representation *curr, *next; - next = rep_list; - while (next) + t_rhythm_memory_representation *curr, *nextRep; + nextRep = rep_list; + while (nextRep) { - curr = next; - next = curr->next; + curr = nextRep; + nextRep = curr->next; free_memory_representations(curr); } + } // evaluate this rhythm and add it to the memory if is new void rhythm_memory_evaluate(t_rhythm_memory_representation *rep_list, // the memory @@ -589,13 +602,15 @@ void rhythm_memory_evaluate(t_rhythm_memory_representation *rep_list, // the mem if (root_closeness_found>=min_to_be_same_rhythm) { - // is close enough to be considered a subrhythm + // is close enough to be considered a rhythm + post("DEBUG: rhythm found"); *new_rhythm = 0; *id = id_found; *root_closeness = root_closeness_found; if (sub_closeness_found>=min_to_be_same_subrhythm) { // this is a known subrhythm + post("DEBUG: sub-rhythm found"); *sub_id = sub_id_found; *sub_closeness = sub_closeness_found; } else diff --git a/rhythms_memory.c b/rhythms_memory.c new file mode 100755 index 0000000..48377ca --- /dev/null +++ b/rhythms_memory.c @@ -0,0 +1,204 @@ +/* +just a dummy rhythms_memory patch + +*/ + +#include "m_pd.h" + +#include "common.h" +#include +#include +#include + +static t_class *rhythms_memory_class; + +typedef struct event event; +typedef struct event +{ + unsigned short int voice; + double when; + event *next; +}; + +typedef struct _rhythms_memory +{ + t_object x_obj; // myself + t_outlet *l_out; + t_rhythm_event *curr_seq; + int seq_initialized; + t_rhythm_memory_representation *rhythms_memory; + double measure_start_time; + double measure_length; + event *events; + +} t_rhythms_memory; + +void rhythms_memory_free(t_rhythms_memory *x) +{ + if (x->curr_seq) + freeBeats(x->curr_seq); + if (x->rhythms_memory) + rhythm_memory_free(x->rhythms_memory); +} + +void start_measure(t_rhythms_memory *x) +{ + // I call the pd functions to get a representation + // of this very moment + x->measure_start_time = clock_getlogicaltime(); +} + +void add_event(t_rhythms_memory *x, unsigned short int voice) +{ + event *newEvent, *currEvent, *lastEvent; + double when; + when = clock_gettimesince(x->measure_start_time); + newEvent = (event *) malloc(sizeof(event)); + newEvent->when = when; + newEvent->voice = voice; + newEvent->next = 0; + currEvent = x->events; + if (currEvent) + { + // this is not the first event + while(currEvent) + { + lastEvent = currEvent; + currEvent = currEvent->next; + } + lastEvent->next = newEvent; + } else + { + // this is the first event + x->events = newEvent; + } + post("event added"); +} + +void end_measure(t_rhythms_memory *x) +{ + float fduration; + event *currEvent, *lastEvent; + unsigned short int is_it_a_new_rhythm; + unsigned short int id, subid; + float root_closeness, sub_closeness; + int counter; + t_atom *lista; + // I call the pd functions to get a representation + // of this very moment + x->measure_length = clock_gettimesince(x->measure_start_time); + // now that i know the exact length of the current measure + // i can process the rhythm in the current measure + // and evaluate it + currEvent = x->events; + // this is not the first event + // now I translate events in rhythm + counter = 0; + while(currEvent) + { + fduration = currEvent->when / x->measure_length; + if (x->seq_initialized) + { + concatenateBeat(x->curr_seq, currEvent->voice, fduration, 1); + } else + { + setFirstBeat(&(x->curr_seq), currEvent->voice, fduration, 1); + x->seq_initialized = 1; + } + currEvent = currEvent->next; + counter++; + } + + // delete events after having evaluated them + currEvent = x->events; + // this is not the first event + while(currEvent) + { + lastEvent = currEvent; + currEvent = currEvent->next; + free(lastEvent); + } + x->events = 0; + x->seq_initialized = 0; + + // now I evaluate this rhythm with the memory + rhythm_memory_evaluate(x->rhythms_memory, x->curr_seq, &is_it_a_new_rhythm, + &id, &subid, &root_closeness, &sub_closeness); + // tell out the answer + // allocate space for the list + lista = (t_atom *) malloc(sizeof(t_atom) * 5); + SETFLOAT(lista, (float) is_it_a_new_rhythm); + SETFLOAT(lista+1, (float) id); + SETFLOAT(lista+2, (float) subid); + SETFLOAT(lista+3, (float) root_closeness); + SETFLOAT(lista+4, (float) sub_closeness); + outlet_anything(x->l_out, + gensym("list") , + 5, + lista); + free(lista); + freeBeats(x->curr_seq); + x->seq_initialized = 0; + x->curr_seq = 0; + + // also start the new measure! + start_measure(x); + + +} + +static void rhythms_memory_bang(t_rhythms_memory *x) { + + // generate a random value + float rnd; + t_rhythm_event *events; + t_duration dur; + + rnd = rand()/((double)RAND_MAX + 1); + dur = float2duration(rnd); + + post("random value=%f duration.numerator=%i duration.denominator=%i", rnd, dur.numerator, dur.denominator); + + if (x->seq_initialized) + { + concatenateBeat(x->curr_seq, 0, rnd, 1); + } else + { + setFirstBeat(&(x->curr_seq), 0, rnd, 1); + x->seq_initialized = 1; + } + + // print the sequence + events = x->curr_seq; + while(events) + { + post("event: numerator=%i, denominator=%i", events->duration.numerator, events->duration.denominator); + events=events->next; + } + +} + +void *rhythms_memory_new(t_symbol *s, int argc, t_atom *argv) +{ + int i; + time_t a; + t_rhythms_memory *x = (t_rhythms_memory *)pd_new(rhythms_memory_class); + x->l_out = outlet_new(&x->x_obj, "list"); + + x->seq_initialized = 0; + + rhythm_memory_create(&(x->rhythms_memory)); + start_measure(x); + + return (x); +} + +void rhythms_memory_setup(void) +{ + rhythms_memory_class = class_new(gensym("rhythms_memory"), (t_newmethod)rhythms_memory_new, + (t_method)rhythms_memory_free, sizeof(t_rhythms_memory), CLASS_DEFAULT, A_GIMME, 0); + class_addbang(rhythms_memory_class, (t_method)rhythms_memory_bang); + class_addmethod(rhythms_memory_class, (t_method)end_measure, gensym("measure"), 0); + class_doaddfloat(rhythms_memory_class, (t_method)add_event); + +} diff --git a/rhythms_memory.sln b/rhythms_memory.sln new file mode 100755 index 0000000..cfb67b0 --- /dev/null +++ b/rhythms_memory.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 7.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rhythms_memory", "rhythms_memory.vcproj", "{DBC75D2A-816A-4C0A-8FE7-2016518D2D19}" +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + ConfigName.0 = Debug + ConfigName.1 = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {DBC75D2A-816A-4C0A-8FE7-2016518D2D19}.Debug.ActiveCfg = Debug|Win32 + {DBC75D2A-816A-4C0A-8FE7-2016518D2D19}.Debug.Build.0 = Debug|Win32 + {DBC75D2A-816A-4C0A-8FE7-2016518D2D19}.Release.ActiveCfg = Release|Win32 + {DBC75D2A-816A-4C0A-8FE7-2016518D2D19}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/rhythms_memory.vcproj b/rhythms_memory.vcproj new file mode 100755 index 0000000..a912a72 --- /dev/null +++ b/rhythms_memory.vcproj @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-rhythms_memory.pd b/test-rhythms_memory.pd new file mode 100755 index 0000000..753e8e9 --- /dev/null +++ b/test-rhythms_memory.pd @@ -0,0 +1,42 @@ +#N canvas 0 0 641 458 12; +#X obj 134 262 rhythms_memory; +#X msg 126 212 measure; +#X msg 317 224 0; +#X obj 168 69 metro 500; +#X obj 130 107 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 168 46 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X obj 169 92 int 0; +#X obj 220 93 + 1; +#X obj 169 115 % 4; +#X floatatom 196 152 5 0 0 0 - - -; +#X obj 127 155 sel 0; +#X obj 125 185 bang; +#X obj 317 189 bng 30 250 50 0 empty empty empty 0 -6 0 8 -258699 -1 +-1; +#X obj 133 285 unpack f f f f f; +#X floatatom 131 312 5 0 0 1 is_this_a_new_rhythm - -; +#X floatatom 160 330 5 0 0 1 id - -; +#X floatatom 193 348 5 0 0 1 subid - -; +#X floatatom 225 368 5 0 0 1 root_closeness - -; +#X floatatom 257 391 5 0 0 1 sub_closeness - -; +#X connect 0 0 13 0; +#X connect 1 0 0 0; +#X connect 2 0 0 0; +#X connect 3 0 4 0; +#X connect 3 0 6 0; +#X connect 5 0 3 0; +#X connect 6 0 7 0; +#X connect 6 0 8 0; +#X connect 7 0 6 1; +#X connect 8 0 9 0; +#X connect 8 0 10 0; +#X connect 10 0 11 0; +#X connect 11 0 1 0; +#X connect 12 0 2 0; +#X connect 13 0 14 0; +#X connect 13 1 15 0; +#X connect 13 2 16 0; +#X connect 13 3 17 0; +#X connect 13 4 18 0; -- cgit v1.2.1