From b28ff6d2448ef06f12ddb29976b90189ed489937 Mon Sep 17 00:00:00 2001 From: Davide Morelli Date: Tue, 6 Dec 2005 12:08:28 +0000 Subject: added simpler functions to manage the rhythms memory svn path=/trunk/externals/frankenstein/; revision=4151 --- Makefile | 4 +- chords_memory.c | 12 ++--- common.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ common.h | 80 +++++++++++++++++++++++++++++- 4 files changed, 238 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 5e1a37a..86a00d2 100755 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ # 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 diff --git a/chords_memory.c b/chords_memory.c index e0cc446..2f7db17 100755 --- a/chords_memory.c +++ b/chords_memory.c @@ -125,12 +125,12 @@ typedef enum { kDim7=8, kHalfDim7=9, //pland adding 9ths 30.11.05 and beyond - kDomb9=10 - kMaj9=11 - kDom9=12 - kMin9=13 - kHalfDim9=14 - kMinMaj9=15 + kDomb9=10, + kMaj9=11, + kDom9=12, + kMin9=13, + kHalfDim9=14, + kMinMaj9=15, kDimMaj9=16 } chord_type_t; diff --git a/common.c b/common.c index c1fac96..8cb310d 100755 --- a/common.c +++ b/common.c @@ -538,6 +538,157 @@ void find_rhythm_in_memory(t_rhythm_memory_representation *rep_list, } +// create a new memory for rhythms +void rhythm_memory_create(t_rhythm_memory_representation **this_rep) +{ + create_rhythm_memory_representation(this_rep, 0); +} + +// free the space +void rhythm_memory_free(t_rhythm_memory_representation *rep_list) +{ + t_rhythm_memory_representation *curr, *next; + next = rep_list; + while (next) + { + curr = next; + next = 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 + t_rhythm_event *src_rhythm, // the rhythm to evaluate + // is it a new rhythm? (0 if no, 1 if new main rhythm, 2 if new subrhythm) + unsigned short int *new_rhythm, + // the id of the closest rhythm or the new id assigned + unsigned short int *id, + // the sub-id of the closest sub-rhythm or the new sub-id assigned + unsigned short int *sub_id, + // how much this rhythm is close to the root (1=identical, 0=nothing common) + float *root_closeness, + // how much this rhythm is close to the closest sub-rhythm (1=identical, 0=nothing common) + float *sub_closeness + ) +{ + float root_closeness_found, sub_closeness_found; + unsigned short int id_found, sub_id_found, new_id; + t_rhythm_memory_representation *curr, *newRep, *lastRep; + int found; + + // look for the closest main rhythm and subrhythm + find_rhythm_in_memory(rep_list, + src_rhythm, // the src rhythm + &id_found, // the id of the closest rhythm + &sub_id_found, // the sub-id of the closest sub-rhythm + &root_closeness_found, // how much this rhythm is close to the root (1=identical, 0=nothing common) + &sub_closeness_found // how much this rhythm is close to the closest sub-rhythm (1=identical, 0=nothing common) + ); + + // decide if add to the memory or if return the closest + + if (root_closeness_found>=min_to_be_same_rhythm) + { + // is close enough to be considered a subrhythm + *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 + *sub_id = sub_id_found; + *sub_closeness = sub_closeness_found; + } else + { + // add this rhythm as a new subrhythm + curr = rep_list; + found = 0; + while (curr && !found) + { + if (curr->id == id_found) + { + // i've found the rhythm + found = 1; + } else + { + curr = curr->next; + } + } + + sub_id_found = add_t_rhythm_memory_element(curr, src_rhythm); + sub_closeness_found = 1; + *sub_id = sub_id_found; + *sub_closeness = sub_closeness_found; + *new_rhythm = 2; + } + } else + { + // this is a completely new rhythm! + // find the last id and representation + curr = rep_list; + new_id = 0; + lastRep = 0; + while (curr) + { + new_id = curr->id; + lastRep = curr; + curr = curr->next; + } + // create a new representation with a new id + new_id++; + create_rhythm_memory_representation(&newRep, new_id); + // link the representations + lastRep->next = newRep; + // add the rhythm as subrhythm + sub_id_found = add_t_rhythm_memory_element(newRep, src_rhythm); + sub_closeness_found = 1; + *sub_id = sub_id_found; + *sub_closeness = sub_closeness_found; + *id = new_id; + *root_closeness = 1; + *new_rhythm = 1; + } + +} +// return 0 if failed finding the rhythm, 1 if the rhythm was found +int rhythm_memory_get_rhythm(t_rhythm_memory_representation *rep_list, // the memory + t_rhythm_event *out_rhythm, // a pointer to the returned rhythm + // the id of the main rhythm wanted + unsigned short int id, + // the sub-id of the sub-rhythm wanted + unsigned short int sub_id) +{ + // look for this id and subid in memory and return that subrhythm + t_rhythm_memory_representation *curr; + t_rhythm_memory_element *curr2; + curr = rep_list; + while (curr) + { + if (curr->id == id) + { + // this is the right main rhythm + // now look for the correct subid + curr2 = curr->rhythms; + while (curr2) + { + if (curr2->id == sub_id) + { + // i've found the rhythm! + out_rhythm=curr2->rhythm; + return 1; + } + curr2 = curr2->next; + } + + } + + curr = curr->next; + } + // if i am here then i didn't find the rhythm + return 0; +} + + // ------------------- themes manipulation functions // set the first note of a sequence diff --git a/common.h b/common.h index 2e33d5f..5ae0874 100755 --- a/common.h +++ b/common.h @@ -82,6 +82,10 @@ static unsigned short int possible_denominators[] = {1,2,3,4,6,8,12,16,18,24,32} // the minimum percentage for a beat to be considered part of the main rhythm #define min_to_be_main_rhythm_beat 0.7 +// minimum value to be considered a subrhythm of this rhythm +#define min_to_be_same_rhythm 0.7 +// minimum percentage to be considered this exact rhythm +#define min_to_be_same_subrhythm 0.9 // this defines a space for rhythms, variations, transitions and representations typedef struct t_rhythm_memory_representation t_rhythm_memory_representation; @@ -158,7 +162,7 @@ void create_rhythm_memory_representation(t_rhythm_memory_representation **this_r // add a new rhythm in the list of similar rhythms related to one main rhythm // the sub id is auto-generated and returned -unsigned short int add_similar_rhythm(t_rhythm_memory_representation *this_rep, t_rhythm_event *new_rhythm); +unsigned short int add_t_rhythm_memory_element(t_rhythm_memory_representation *this_rep, t_rhythm_event *new_rhythm); // free the list of representations void free_memory_representations(t_rhythm_memory_representation *this_rep); @@ -183,6 +187,80 @@ void find_rhythm_in_memory(t_rhythm_memory_representation *rep_list, float *sub_closeness // how much this rhythm is close to the closest sub-rhythm (1=identical, 0=nothing common) ); +// the following are the functions that externals should use +/* usage: + + // first of all declare a pointer for the memory + t_rhythm_memory_representation *rhythms_memory; + // then each time you get a rhythm let the memory evaluate it and + // tell you if is a new rhythm or a old one + float root_closeness, sub_closeness; + unsigned short int id, subid, is_it_a_new_rhythm; + rhythm_memory_evaluate(rhythms_memory, rhythm, &is_it_a_new_rhythm, + &id, &subid, &root_closeness, &sub_closeness); + if (is_it_a_new_rhythm==1) + { + // it was a completely new rhythm + // id tells us new id assigned + // and subid tells us the new sub id assigned + } + if (is_it_a_new_rhythm==2) + { + // it was a new sub-rhythm of a known rhythm + // id tells us rht root rhythm id + // and subid tells us the new sub id assigned + } + if (is_it_a_new_rhythm==0) + { + // it was a known rhythm and subrhythm + // id and subid tell us the identificator + } + // i can also use root_closeness and sub_closeness and is_it_a_new_rhythm + // to know how much novelty there was in this rhythm + + // i can ask the memory to give me back a specific rhythm + t_rhythm_event *wanted_rhythm + int rhythm_found = rhythm_memory_get_rhythm(rhythms_memory, + wanted_rhythm, + id, // the id of the main rhythm wanted + sub_id // the sub-id of the sub-rhythm wanted + ); + if (rhythm_found == 0) + { + // that rhythm was not present! + } + + // when i am ready I should free the memory + rhythm_memory_free(rhythms_memory); +*/ + + +// create a new memory for rhythms +void rhythm_memory_create(t_rhythm_memory_representation **this_rep); +// free the space +void rhythm_memory_free(t_rhythm_memory_representation *rep_list); +// evaluate this rhythm and add it to the memory if is new +void rhythm_memory_evaluate(t_rhythm_memory_representation *rep_list, // the memory + t_rhythm_event *src_rhythm, // the rhythm to evaluate + // is it a new rhythm? (0 if no, 1 if new main rhythm, 2 if new subrhythm) + unsigned short int *new_rhythm, + // the id of the closest rhythm or the new id assigned + unsigned short int *id, + // the sub-id of the closest sub-rhythm or the new sub-id assigned + unsigned short int *sub_id, + // how much this rhythm is close to the root (1=identical, 0=nothing common) + float *root_closeness, + // how much this rhythm is close to the closest sub-rhythm (1=identical, 0=nothing common) + float *sub_closeness + ); +// return 0 if failed finding the rhythm, 1 if the rhythm was found +int rhythm_memory_get_rhythm(t_rhythm_memory_representation *rep_list, // the memory + t_rhythm_event *out_rhythm, // a pointer to the returned rhythm + // the id of the main rhythm wanted + unsigned short int id, + // the sub-id of the sub-rhythm wanted + unsigned short int sub_id); + // -------- notes manipulation functions // set the first beat of a sequence -- cgit v1.2.1