From d1ceaf286dcdd8b1ab51838d66a9df2b8ca4dce1 Mon Sep 17 00:00:00 2001 From: Davide Morelli Date: Sun, 15 Jan 2006 22:54:41 +0000 Subject: adding voicing_analyzer and fixing typos svn path=/trunk/externals/frankenstein/; revision=4408 --- voicing_analyzer.c | 272 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100755 voicing_analyzer.c (limited to 'voicing_analyzer.c') diff --git a/voicing_analyzer.c b/voicing_analyzer.c new file mode 100755 index 0000000..c1ab8e3 --- /dev/null +++ b/voicing_analyzer.c @@ -0,0 +1,272 @@ +/* +voicing_analyzer: + + +*/ +#include +#include +#include +// for string manipulation +#include +#include +#include "m_pd.h" + +// to sort arrays +#include "sglib.h" + + +#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 + +// default values +#define DEF_WIDENESS 3 // 3 octaves +#define DEF_CENTER_NOTE 72 // central C + +#define DEBUG 0 // messaggi di debug +#define DEBUG_VERBOSE 0 // messaggi di debug + +static t_class *voicing_analyzer_class; + + +typedef struct _voicing_analyzer +{ + t_object x_obj; // myself + int current_voices[VOICES]; + int previous_voices[VOICES]; + t_outlet *small_intervals_out, *i_like_parallelism_out, + *center_note_out, *wideness_out; + +} t_voicing_analyzer; + + +void voicing_analyzer_free(t_voicing_analyzer *x) +{ +// freebytes(x->buf_strum1, sizeof(x->buf_strum1)); +// freebytes(x->buf_strum2, sizeof(x->buf_strum2)); +} + + +// here i evaluate this voicing +void analyze_it(t_voicing_analyzer *x, float *wideness, float *i_like_parallelism, int *center_note, float *small_intervals) +{ + int i, j, tmp, res, last, avgHI, avgLOW, sameDirection, parallel8_5; + int min,max, distance; + short int chord_notes[4]; + short int chord_notes_ok[4]; + 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 = 0; // starting fitness + tmp = 0; + + // shared objects + for (i=0; icurrent_voices[i]; + transitions[i] = x->current_voices[i] - x->previous_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; icurrent_voices[i] - x->current_voices[j])%12 ; + if (DEBUG_VERBOSE) + post("intervals[%i][%i]=%i", i, j, intervals[i][j]); + } + } + SGLIB_ARRAY_SINGLE_QUICK_SORT(short int, notes, VOICES, SGLIB_NUMERIC_COMPARATOR) + + sameDirection = 0; + parallel8_5 = 0; + + // all same direction? + if ( directions[0]==directions[1] && + directions[1]==directions[2] && + directions[2]==directions[3]) + { + sameDirection=1; + if (DEBUG_VERBOSE) + post("same direction!"); + } + + // parallel 5ths or octaves? (if yes return 0) + // how? + // hidden 8ths nor 5ths ? + for (i=0; i