aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavide Morelli <morellid@users.sourceforge.net>2006-01-15 22:54:41 +0000
committerDavide Morelli <morellid@users.sourceforge.net>2006-01-15 22:54:41 +0000
commitd1ceaf286dcdd8b1ab51838d66a9df2b8ca4dce1 (patch)
tree5865c38a199011cd0b50224e0806eca1747fabcd
parenta2c32daace69e8651804d073a9f505adcd4ff16c (diff)
adding voicing_analyzer and fixing typos
svn path=/trunk/externals/frankenstein/; revision=4408
-rwxr-xr-xMakefile2
-rwxr-xr-xchords_memory.c165
-rwxr-xr-xcommon.c150
-rwxr-xr-xcommon.h96
-rwxr-xr-xharmonizer.c8
-rwxr-xr-xthemes_memory.c10
-rwxr-xr-xvoicing_analyzer.c272
-rwxr-xr-xvoicing_analyzer.vcproj133
8 files changed, 660 insertions, 176 deletions
diff --git a/Makefile b/Makefile
index 052a1dc..7bb548b 100755
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ PDPATH="H:\PureData\pd-0.38-3.msw\pd"
current: pd_nt distclean
-pd_nt: chord_melo.dll chords_memory.dll harmonizer.dll GArhythm.dll ritmo1.dll rhythms_memory.dll themes_memory.dll
+pd_nt: chord_melo.dll chords_memory.dll harmonizer.dll voicing_analyzer.dll GArhythm.dll ritmo1.dll rhythms_memory.dll themes_memory.dll
.SUFFIXES: .dll
diff --git a/chords_memory.c b/chords_memory.c
index 7a39cd3..1905eba 100755
--- a/chords_memory.c
+++ b/chords_memory.c
@@ -97,6 +97,7 @@ there are plenty of such algos, we must just copy them down.
#include <ctype.h>
#include "m_pd.h"
+#include "common.h"
#define DEBUG 0 // messaggi di debug
@@ -111,85 +112,6 @@ there are plenty of such algos, we must just copy them down.
static t_class *chords_memory_class;
-// how can a chord be?
-#define TYPES_NUM 17 // keep me updated
-typedef enum {
- kMaj=0,
- kMin=1,
- kDim=2,
- kAug=3,
- kDom7=4,
- kMaj7=5,
- kMin7=6,
- kMinMaj7=7,
- kDim7=8,
- kHalfDim7=9,
- //pland adding 9ths 30.11.05 and beyond
- kDomb9=10,
- kMaj9=11,
- kDom9=12,
- kMin9=13,
- kHalfDim9=14,
- kMinMaj9=15,
- kDimMaj9=16
- } chord_type_t;
-
-// how many tones do we have in our octave?
-#define TONES_NUM 12 // keep me updated
-typedef enum {
- I=0,
- Id=1,
- II=2,
- IId=3,
- III=4,
- IV=5,
- IVd=6,
- V=7,
- Vd=8,
- VI=9,
- VId=10,
- VII=11
- } chord_tone_t;
-
-// how many nodes does this graph have?
-// for now TYPES_NUM*TONES_NUM
-// when we introduce modulation
-// we'll have more
-#define NODES_NUM TYPES_NUM*TONES_NUM
-
-// this defines a chord in a tonality
-typedef struct _chord
-{
- chord_type_t mode;
- chord_tone_t note;
-} chord_t;
-
-// enumeration of absolute notes
-// i'll need this when parsing strings like "C major"
-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
- } abs_note_t;
-
-// enumeration of modes
-// i'll start with minor and major only
-// but we could add phrigian, doric, misolidian ,e tc...
-#define MODES_NUM 2
-typedef enum {
- MAJOR=0,
- MINOR=1 } modes_t;
-
-#define MODULATIONS_NUM MODES_NUM*TONES_NUM
// data type for the steps of a walk
typedef struct _step
@@ -281,91 +203,6 @@ void chords_memory_init(t_chords_memory *x, t_floatarg f)
// ------------- function for string manipulation (from string to chords)
-// tries to find out absolute tones names in this string
-abs_note_t from_string_to_abs_tone(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;
-}
-
-chord_type_t from_string_to_type(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;
- // pland adding chords 30.11.05
- if (strstr(substr, "dominant b9"))
- return kDomb9;
- if (strstr(substr, "major 9th"))
- return kMaj9;
- if (strstr(substr, "dominant 9th"))
- return kDom9;
- if (strstr(substr, "minor 9th"))
- return kMin9;
- if (strstr(substr, "half diminished 9th"))
- return kHalfDim9;
- if (strstr(substr, "minor major 9th"))
- return kMinMaj9;
- if (strstr(substr, "diminished major 9th"))
- return kDimMaj9;
- // TODO: other chords
- // beware when adding new chords
- // put shorter names at end of this function!
- return C;
-}
-
-// find the tonality mode in this string
-modes_t from_string_to_mode(const char *substr)
-{
- if (strstr(substr, "major"))
- return MAJOR;
- if (strstr(substr, "minor"))
- return MINOR;
-
- // TODO: other modes (doric, misolidian , custom, etc..
- return C;
-}
-
// builds a string for this chord
// the string is in maxlib's chord format
void chords_memory_chord2string(t_chords_memory *x, char *string, chord_t chord)
diff --git a/common.c b/common.c
index c136fcf..fdb5a78 100755
--- a/common.c
+++ b/common.c
@@ -11,6 +11,7 @@ David Plans Casal http://www.studios.uea.ac.uk/people/staff/casal
#include <math.h>
#include <stdlib.h>
+#include <string.h>
#include "m_pd.h" // to post errors and debug messages
@@ -802,4 +803,151 @@ void freeNotes(t_note_event *currentEvent)
free(currentEvent);
} while(next);
-} \ No newline at end of file
+}
+
+
+// ------------- function for string manipulation (from string to chords)
+
+// tries to find out absolute tones names in this string
+abs_note_t from_string_to_abs_tone(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;
+}
+
+chord_type_t from_string_to_type(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;
+ // pland adding chords 30.11.05
+ if (strstr(substr, "dominant b9"))
+ return kDomb9;
+ if (strstr(substr, "major 9th"))
+ return kMaj9;
+ if (strstr(substr, "dominant 9th"))
+ return kDom9;
+ if (strstr(substr, "minor 9th"))
+ return kMin9;
+ if (strstr(substr, "half diminished 9th"))
+ return kHalfDim9;
+ if (strstr(substr, "minor major 9th"))
+ return kMinMaj9;
+ if (strstr(substr, "diminished major 9th"))
+ return kDimMaj9;
+ // TODO: other chords
+ // beware when adding new chords
+ // put shorter names at end of this function!
+ return C;
+}
+
+// find the tonality mode in this string
+modes_t from_string_to_mode(const char *substr)
+{
+ if (strstr(substr, "major"))
+ return MAJOR;
+ if (strstr(substr, "minor"))
+ return MINOR;
+
+ // TODO: other modes (doric, misolidian , custom, etc..
+ return C;
+}
+
+// tries to find out absolute tones names in this string
+abs_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;
+}
+
+chord_type_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;
+}
+
diff --git a/common.h b/common.h
index ac74379..f30bda4 100755
--- a/common.h
+++ b/common.h
@@ -129,6 +129,89 @@ struct t_rhythm_memory_representation
// define a return value to express "rhythm not found in this representation"
#define INVALID_RHYTHM 65535
+// chords data structure
+// tells you how many durations there // how can a chord be?
+#define TYPES_NUM 17 // keep me updated
+typedef enum {
+ kMaj=0,
+ kMin=1,
+ kDim=2,
+ kAug=3,
+ kDom7=4,
+ kMaj7=5,
+ kMin7=6,
+ kMinMaj7=7,
+ kDim7=8,
+ kHalfDim7=9,
+ //pland adding 9ths 30.11.05 and beyond
+ kDomb9=10,
+ kMaj9=11,
+ kDom9=12,
+ kMin9=13,
+ kHalfDim9=14,
+ kMinMaj9=15,
+ kDimMaj9=16
+ } chord_type_t;
+
+// how many tones do we have in our octave?
+#define TONES_NUM 12 // keep me updated
+typedef enum {
+ I=0,
+ Id=1,
+ II=2,
+ IId=3,
+ III=4,
+ IV=5,
+ IVd=6,
+ V=7,
+ Vd=8,
+ VI=9,
+ VId=10,
+ VII=11
+ } chord_tone_t;
+
+// how many nodes does this graph have?
+// for now TYPES_NUM*TONES_NUM
+// when we introduce modulation
+// we'll have more
+#define NODES_NUM TYPES_NUM*TONES_NUM
+
+// this defines a chord in a tonality
+typedef struct _chord
+{
+ chord_type_t mode;
+ chord_tone_t note;
+} chord_t;
+
+// enumeration of absolute notes
+// i'll need this when parsing strings like "C major"
+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
+ } abs_note_t;
+
+// enumeration of modes
+// i'll start with minor and major only
+// but we could add phrigian, doric, misolidian ,e tc...
+#define MODES_NUM 2
+typedef enum {
+ MAJOR=0,
+ MINOR=1 } modes_t;
+
+#define MODULATIONS_NUM MODES_NUM*TONES_NUM
+
+
+
// ------------------------------------------------ functions
// ----------- rhythm manipolation functions
@@ -139,7 +222,7 @@ t_duration int2duration(int n);
// converts from duration to integer: used to know this duration
// what corresponds in terms table index
unsigned short int duration2int(t_duration dur);
-// tells you how many durations there are
+
int possible_durations();
// converts from float (0-1) to duration. it performs quantization
@@ -287,3 +370,14 @@ void concatenateNote(t_note_event *currentEvent, unsigned short int voice, float
// used to free the memory allocated by this list
void freeNotes(t_note_event *currentEvent);
+
+
+
+// ------------- function for string manipulation (from string to chords)
+
+// tries to find out absolute tones names in this string
+abs_note_t from_string_to_abs_tone(const char *substr);
+chord_type_t from_string_to_type(const char *substr);
+modes_t from_string_to_mode(const char *substr);
+chord_type_t string2mode(const char *substr);
+abs_note_t string2note(const char *substr);
diff --git a/harmonizer.c b/harmonizer.c
index 18024f1..9a99559 100755
--- a/harmonizer.c
+++ b/harmonizer.c
@@ -62,11 +62,11 @@ static t_class *harmonizer_class;
// this defines a chord in a tonality
-typedef struct _chord
+typedef struct _chord_abs
{
chord_type_t mode;
abs_note_t note;
-} chord_t;
+} chord_abs_t;
typedef struct _harmonizer
@@ -75,8 +75,8 @@ typedef struct _harmonizer
// genotypes
int population[MAX_POPULATION][VOICES];
int current_voices[VOICES];
- chord_t current_chord;
- chord_t target_chord;
+ chord_abs_t current_chord;
+ chord_abs_t target_chord;
int target_notes[POSSIBLE_NOTES];
t_outlet *l_out;
diff --git a/themes_memory.c b/themes_memory.c
index d4d716a..cefdb5e 100755
--- a/themes_memory.c
+++ b/themes_memory.c
@@ -210,13 +210,13 @@ void end_measure(t_themes_memory *x)
if (rhythm_found==0)
{
post("themes_memory: rhythm %i %i was not found ", x->next_main_rhythm_out, x->next_sub_rhythm_out);
- return 0;
+ return;
}
if (wanted_rhythm==0)
{
error("themes_memory: wanted_rhythm should not be null! ");
- return 0;
+ return;
}
// now I setup the events_out list
@@ -385,9 +385,9 @@ void *themes_memory_new(t_symbol *s, int argc, t_atom *argv)
//x->l_out = outlet_new(&x->x_obj, &s_list);
x->bangs_out = outlet_new(&x->x_obj, gensym("bang"));
// this outputs lists of events
- x->list_out = outlet_new(&x->x_obj, "symbol");
+ x->list_out = outlet_new(&x->x_obj, gensym("symbol"));
// this outputs info on the last detected rhythm
- x->info_out = outlet_new(&x->x_obj, "symbol");
+ x->info_out = outlet_new(&x->x_obj, gensym("symbol"));
// inlet for rhythms in the form of lists
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("list"), gensym("rhythm_in"));
@@ -406,7 +406,7 @@ void crash(t_themes_memory *x)
{
int *a;
a = malloc(sizeof(int));
- a[9999999999999999999] = 1;
+ a[99999] = 1;
}
void themes_memory_setup(void)
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 <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 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; i<VOICES; i++)
+ {
+ notes[i]=x->current_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; i<VOICES; i++)
+ {
+ for (j=i+1; j<VOICES; j++)
+ {
+ intervals[i][j] = (x->current_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<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])
+ {
+ parallel8_5 += 1;
+ if (DEBUG_VERBOSE)
+ post("hidden or parallel consonance!");
+ }
+ }
+ }
+ }
+
+ // now i can compute parallelism
+ *i_like_parallelism = (float) -1;
+ *i_like_parallelism += sameDirection;
+ *i_like_parallelism += (float) ( ((float)(VOICES*(VOICES-1))) / ((float)parallel8_5) );
+
+ // is voice spacing uniform ?(except for the bass)
+ // TODO: use notes[]
+ // are voices average centered?
+ for (i=0; i<VOICES; i++)
+ {
+ tmp+=notes[i];
+ if (DEBUG_VERBOSE)
+ post("average note is %i at passage %i", tmp, i);
+ }
+ // this is the average note
+ *center_note = tmp/(VOICES);
+
+ // are intervals small?
+ tmp=0;
+ 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 -= 3;
+ }
+
+ *small_intervals = (float) (((float) res) / ((float) (5 * VOICES)));
+
+ // now wideness
+ min = notes[0];
+ max = notes[VOICES-1];
+ distance = max - min;
+ *wideness = (float) (((float)distance) / ((float)12));
+
+
+
+
+}
+
+typedef struct fitness_list_element_t
+{
+ int index;
+ int fitness;
+} fitness_list_element;
+
+#define FITNESS_LIST_COMPARATOR(e1, e2) (e1.fitness - e2.fitness)
+
+void analyze_voicing(t_voicing_analyzer *x)
+{
+ t_atom lista[VOICES];
+ float small_intervals=0;
+ float i_like_parallelism=0;
+ float wideness=0;
+ int center_note=0;
+
+ analyze_it(x, &wideness, &i_like_parallelism, &center_note, &small_intervals);
+
+ // order is important!
+ outlet_float(x->i_like_parallelism_out, i_like_parallelism);
+ outlet_float(x->small_intervals_out, small_intervals);
+ outlet_float(x->wideness_out, wideness);
+ outlet_float(x->center_note_out, center_note);
+
+}
+
+// called when i send a list (with midi values)
+void set_current_voices(t_voicing_analyzer *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->previous_voices[i] = x->current_voices[i];
+ x->current_voices[i] = atom_getint(argv++);
+ }
+
+ analyze_voicing(x);
+
+
+}
+
+
+void print_help(t_voicing_analyzer *x)
+{
+ post("");
+ post("voicing_analyzer is an external that analyze voicing");
+ post("takes as input %i midi notes", VOICES);
+ post("available commands:");
+ post("this externalis part of the frank framework");
+ post("authors: davide morelli, david casals");
+
+}
+
+void *voicing_analyzer_new(t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+ time_t a;
+ t_voicing_analyzer *x = (t_voicing_analyzer *)pd_new(voicing_analyzer_class);
+ x->center_note_out = outlet_new(&x->x_obj, gensym("float"));
+ x->wideness_out = outlet_new(&x->x_obj, gensym("float"));
+ x->small_intervals_out = outlet_new(&x->x_obj, gensym("float"));
+ x->i_like_parallelism_out = outlet_new(&x->x_obj, gensym("float"));
+
+ for (i=0;i<VOICES;i++)
+ {
+ x->previous_voices[i] = 0;
+ x->current_voices[i] = 0;
+ }
+
+ return (x);
+}
+
+void voicing_analyzer_setup(void)
+{
+ voicing_analyzer_class = class_new(gensym("voicing_analyzer"), (t_newmethod)voicing_analyzer_new,
+ (t_method)voicing_analyzer_free, sizeof(t_voicing_analyzer), CLASS_DEFAULT, A_GIMME, 0);
+ class_addmethod(voicing_analyzer_class, (t_method)print_help, gensym("help"),0, 0);
+ class_addlist(voicing_analyzer_class, (t_method)set_current_voices);
+
+
+}
diff --git a/voicing_analyzer.vcproj b/voicing_analyzer.vcproj
new file mode 100755
index 0000000..c5be061
--- /dev/null
+++ b/voicing_analyzer.vcproj
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.00"
+ Name="voicing_analyzer"
+ ProjectGUID="{DBC75D2A-816A-4C0A-8FE7-2016518D2D19}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="5"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/export:voicing_analyzer_setup /dll"
+ AdditionalDependencies="pd.lib"
+ OutputFile="$(OutDir)/voicing_analyzer.dll"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/frankenstein.pdb"
+ SubSystem="0"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="TRUE"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="TRUE"
+ RuntimeLibrary="4"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/frankenstein.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ </Configuration>
+ </Configurations>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
+ <File
+ RelativePath="common.c">
+ </File>
+ <File
+ RelativePath="voicing_analyzer.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc">
+ <File
+ RelativePath="common.h">
+ </File>
+ <File
+ RelativePath="..\m_pd.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>