From 71b83fc040b848c98c5065d95ecbc72b0b4f8943 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 17 Jan 2013 22:54:00 +0000 Subject: merging maxlib v1.5.5 from branches/pd-extended/0.43 svn path=/trunk/externals/maxlib/; revision=16897 --- chord.c | 3644 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 1822 insertions(+), 1822 deletions(-) (limited to 'chord.c') diff --git a/chord.c b/chord.c index a1839d3..ad3f6eb 100644 --- a/chord.c +++ b/chord.c @@ -1,1822 +1,1822 @@ -/* ------------------------- chord ------------------------------------------ */ -/* */ -/* Tries to detect a chord (or any harmonic relations) of incoming notes. */ -/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ -/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ -/* */ -/* This program is free software; you can redistribute it and/or */ -/* modify it under the terms of the GNU General Public License */ -/* as published by the Free Software Foundation; either version 2 */ -/* of the License, or (at your option) any later version. */ -/* */ -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ -/* */ -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* */ -/* Based on PureData by Miller Puckette and others. */ -/* */ -/* ---------------------------------------------------------------------------- */ - -#include "m_pd.h" -#include -#include -#ifndef _WIN32 -#include -#endif - - -#define MAX_POLY 32 /* maximum number of notes played at a time */ - -#define kUnison 0 -#define kMaj 1 -#define kMin 2 -#define kDim 3 -#define kAug 4 -#define kMaj7 5 -#define kDom7 6 -#define kMin7 7 -#define kHalfDim7 8 -#define kDim7 9 -#define kMinMaj7 10 -#define kMaj7s5 11 -#define kMaj7b5 12 -#define kDom7s5 13 -#define kDom7b5 14 -#define kDomb9 15 -#define kMaj9 16 -#define kDom9 17 -#define kMin9 18 -#define kHalfDim9 19 -#define kMinMaj9 20 -#define kDimMaj9 21 -#define kMaj9b5 22 -#define kDom9b5 23 -#define kDom9b13 24 -#define kMin9s11 25 -#define kmM9b11 26 -#define kMaj7b9 27 -#define kMaj7s5b9 28 -#define kDom7b9 29 -#define kMin7b9 30 -#define kMinb9s11 31 -#define kHalfDimb9 32 -#define kDim7b9 33 -#define kMinMajb9 34 -#define kDimMajb9 35 -#define kMaj7s9 36 -#define kDom7s9 37 -#define kMaj7s11 38 -#define kMs9s11 39 -#define kHDimb11 40 -#define kMaj11 41 -#define kDom11 42 -#define kMin11 43 -#define kHalfDim11 44 -#define kDim11 45 -#define kMinMaj11 46 -#define kDimMaj11 47 -#define kMaj11b5 48 -#define kMaj11s5 49 -#define kMaj11b9 50 -#define kMaj11s9 51 -#define kMaj11b13 52 -#define kMaj11s13 53 -#define kM11b5b9 54 -#define kDom11b5 55 -#define kDom11b9 56 -#define kDom11s9 57 -#define kHalfDim11b9 58 -#define kDom7s11 59 -#define kMin7s11 60 -#define kDom13s11 61 -#define kM7b913 62 -#define kMaj7s13 63 -#define kMaj9s13 64 -#define kM7b9s13 65 -#define kDom7b13 66 -#define kChrom 67 -#define kNone 68 - -#define kXX -1 - - -static char *version = "chord v0.2, written by Olaf Matthes "; - -static char* pitch_class[13] = {"C ", "Db ", "D ", "Eb ", "E ", "F ", "Gb ", "G ", "Ab ", "A ", "Bb ", "B ", "no root "}; -static char name_class[7] = {'C', 'D', 'E', 'F', 'G', 'A', 'B'}; - -typedef struct { - int type; - int rootMember; -} t_type_root; - -typedef struct chord -{ - t_object x_ob; - t_outlet *x_outchordval; /* chord as MIDI note number of base note */ - t_outlet *x_outchordclass; /* class of chord's bass note */ - t_outlet *x_outchordname; /* chord name, e.g. "Cmajor7" */ - t_outlet *x_outchordinversion; /* inversion of the chord (root = 0, 1st = 1, 2nd = 2) */ - t_outlet *x_outchordnotes; /* list with note numbers belonging to the chord */ - - t_int x_pitch; - t_int x_pc[12]; /* pitch class array */ - t_int x_abs_pc[12]; /* pitch class array: absolute MIDI note numbers */ - t_int x_velo; - t_int x_alloctable[MAX_POLY]; /* a table used to store all playing notes */ - t_int x_poly; /* number of notes currently playing */ - t_atom x_chordlist[12]; /* list that stores the note numbers for output */ - t_int x_split; /* highes note number to process */ - - t_int x_chord_type; /* chord's type (number between 0 and 68) */ - t_int x_chord_root; /* chord's root (pitch class) */ - t_int x_chord_bass; /* chord's bass note (MIDI note number) */ - t_int x_chord_inversion; /* chord's state of inversion (root, 1st, 2nd) */ - -} t_chord; - -/* functions */ -static void chord_kick_out_member(t_chord *x, t_int number, t_int *members); -static void chord_chord_finder(t_chord *x, t_int num_pcs); -static void chord_draw_chord_type(t_chord *x, t_int num_pcs); - - -static void chord_unison(t_chord *x) -{ - int i; - int member = 0; - for(i = 0; i < 12; i++) - if(x->x_pc[i]) - { - member = i; // find pitch class - break; - } - x->x_chord_type = 0; - x->x_chord_root = member; - chord_draw_chord_type(x, 1); // output onto the screen -} - -static void chord_dyad(t_chord *x) -{ - static t_type_root dyads[11] = - {{ kMaj7, 1 }, { kDom7, 1 }, { kMin, 0 }, { kMaj, 0 }, { kMaj, 1 }, - { kDom7 , 0 }, { kMaj, 0 }, { kMaj, 1 }, { kMin, 1 }, { kDom7, 0 }, { kMaj7, 0 }}; - register t_type_root* t; - - int members[2]; - int i, j = 0; - int interval1; - - for(i = 0; i < 12; i++) - if(x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */ - interval1 = members[1] - members[0]; /* calculate interval between first two members */ - interval1 = interval1 - 1; /* reduce interval1 to start at zero */ - t = &(dyads[interval1]); /* find TypeRoot struct for this interval */ - x->x_chord_type = t->type; - if (interval1 == 5) - x->x_chord_root = (members[0]+8)%12; - else - x->x_chord_root = members[t->rootMember]; - x->x_chord_inversion = t->rootMember; /* get state of inversion */ - chord_draw_chord_type(x, 2); /* output results */ -} - -static void chord_triad(t_chord *x) -{ - static t_type_root triads[10][10] = - {/* interval1 is a half step */ - {{ kMaj7b9, 1 }, { kMaj9, 1 }, { kMinMaj7, 1 }, { kMaj7, 1 }, { kDom7s11,2 }, - { kDomb9 , 0 }, { kMaj7, 1 }, { kMaj7s5, 1 }, { kMin9, 2 }, { kMaj7b9, 0 }}, - /* interval1 is a whole step */ - {{ kMin9, 0 }, { kDom9, 0 }, { kMin7, 1 }, { kDom7, 1 }, { kDom9, 0 }, - { kHalfDim7, 1 }, { kDom7, 1 }, { kDom9, 0 }, { kMaj9, 0 }}, - /* interval1 is a minor third */ - {{ kMaj7s5, 2 }, { kDom7, 2 }, { kDim, 0 }, { kMin, 0 }, { kMaj, 2 }, - { kDim, 2 }, { kMin7, 0 }, { kMinMaj7, 0 }}, - /* interval1 is a major third */ - {{ kMaj7, 2 }, { kHalfDim7, 2 }, { kMaj, 0 }, { kAug, 0 }, { kMin, 2 }, - { kDom7, 0 }, { kMaj7, 0 }}, - /* interval1 is a perfect fourth */ - {{ kDomb9, 1 }, { kDom9, 1 }, { kMin, 1 }, { kMaj, 1 }, { kDom9, 2 }, - { kDom7s11, 1 }}, - /* interval1 is an augmented fourth */ - {{ kDom7s11, 0 }, { kDom7, 2 }, { kDim, 1 }, { kHalfDim7, 0 }, { kDomb9, 2 }}, - /* interval1 is a perfect fifth */ - {{ kMaj7, 2 }, { kMin7, 2 }, { kDom7, 0 }, { kMaj7, 0 }}, - /* interval1 is a minor sixth */ - {{ kMinMaj7, 2 }, { kDom9, 1 }, { kMaj7s5, 0 }}, - /* interval1 is a major sixth */ - {{ kMaj9, 2 }, { kMin9, 1 }}, - /* interval1 is a minor seventh */ - {{ kMaj7b9, 2 }} - }; - register t_type_root* t; - - int members[3]; - int i, j = 0; - int interval1, interval2; - - for(i = 0; i < 12; i++) - if(x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */ - interval1 = members[1] - members[0]; /* calculate interval between first two members */ - interval2 = members[2] - members[0]; /* calculate interval between first and third */ - interval2 = interval2 - interval1 - 1; /* reduce interval2 to start at zero */ - interval1 = interval1 - 1; /* reduce interval1 to start at zero */ - t = &(triads[interval1][interval2]); /* find TypeRoot struct for this interval vector */ - x->x_chord_type = t->type; - x->x_chord_root = members[t->rootMember]; - switch(t->rootMember) { /* get state of inversion */ - case 0: - x->x_chord_inversion = 0; - break; - case 1: - x->x_chord_inversion = 2; - break; - case 2: - x->x_chord_inversion = 1; - } - chord_draw_chord_type(x, 3); /* output onto the screen */ -} - -static void chord_quartad(t_chord *x) -{ - static t_type_root quartads[9][9][9] = - { - {/* interval1 is a half step */ - {/* interval2 is a whole step */ - { kM7b9s13, 2 }, { kMinMajb9,1 }, { kMaj7b9, 1 }, { kMaj7s13, 2 }, { kDimMajb9, 1 }, - { kMaj7b9, 1 }, { kMaj7s13, 2 }, { kM7b913, 1 }, { kM7b9s13, 1 }}, - {/* interval2 is a minor third */ - { kMinMaj9, 1 }, { kMaj9, 1 }, { kHalfDimb9,0 }, { kMin7b9, 0 }, { kMaj9, 1 }, - { kDim7b9, 0 }, { kMin7b9, 0 }, { kMinMajb9, 0 }}, - {/* interval2 is a major third */ - { kMaj7s9, 1 }, { kDom7s11, 3 }, { kDomb9, 0 }, { kMinMaj7, 1 }, { kDom7s9, 3 }, - { kDomb9, 0 }, { kMaj7b9, 0 }}, - {/* interval2 is a perfect fourth */ - { kMaj11, 1 }, { kMaj7b5, 1 }, { kMaj7, 1 }, { kMaj7s5, 1 }, { kMin9, 3 }, - { kMaj7s13, 1 }}, - {/* interval2 is a tritone */ - { kDimMaj9, 3 }, { kDom11, 3 }, { kDim7b9, 0 }, { kHalfDimb9,0 }, { kDimMajb9, 0 }}, - {/* interval2 is a perfect fifth */ - { kMaj11, 3 }, { kDom7s9, 3 }, { kDomb9, 0 }, { kMaj7b9, 0 }}, - {/* interval2 is a minor sixth */ - { kMaj7s9, 3 }, { kMin9, 3 }, { kMaj7s13, 1 }}, - {/* interval2 is a major sixth */ - { kMinMaj9, 3 }, { kM7b913, 0 }}, - {/* interval2 is a minor seventh */ - { kM7b9s13, 0 }} - }, - {/* interval1 is a whole step */ - {/* interval2 is a minor third */ - { kM7b913, 2 }, { kMin7b9, 1 }, { kDomb9, 1 }, { kMin9, 0 }, { kHalfDimb9,1 }, - { kDomb9, 1 }, { kMin9, 0 }, { kMinMaj9, 0 }}, - {/* interval2 is a major third */ - { kMin9, 1 }, { kDom9, 1 }, { kDom9, 0 }, { kDom7s5, 2 }, { kDom9, 1 }, - { kDom9, 0 }, { kMaj9, 0 }}, - {/* interval2 is a perfect fourth */ - { kDom7s9, 1 }, { kDom11, 3 }, { kHalfDim7, 1 }, { kMin7, 1 }, { kDom9, 3 }, - { kHalfDimb9,3 }}, - {/* interval2 is a tritone */ - { kDom11, 1 }, { kDom7b5, 3 }, { kDom7, 1 }, { kDom7s5, 1 }, { kMin7b9, 3 }}, - {/* interval2 is a perfect fifth */ - { kMaj7b5, 3 }, { kDom11, 1 }, { kDom9, 0 }, { kMaj9, 0 }}, - {/* interval2 is a minor sixth */ - { kDom7s11, 1 }, { kDom9, 3 }, { kDim7b9, 3 }}, - {/* interval2 is a major sixth */ - { kMaj9, 3 }, { kMin7b9, 3 }}, - {/* interval2 is a minor seventh */ - { kMinMajb9, 3 }} - }, - {/* interval1 is a minor third */ - {/* interval2 is a major third */ - { kMaj7s13, 3 }, { kDim7b9, 1 }, { kDom7s9, 0 }, { kMaj7s5, 2 }, { kDim7b9, 1 }, - { kDom7s9, 0 }, { kMaj7s9, 0 }}, - {/* interval2 is a perfect fourth */ - { kDomb9, 2 }, { kDom9, 2 }, { kMin7, 2 }, { kDom7, 2 }, { kDom11, 2 }, - { kDom7s11, 2 }}, - {/* interval2 is a tritone */ - { kDim7b9, 2 }, { kDom7, 3 }, { kDim7, 0 }, { kHalfDim7, 0 }, { kDomb9, 3 }}, - {/* interval2 is a perfect fifth */ - { kMaj7, 3 }, { kHalfDim7,3 }, { kMin7, 0 }, { kMinMaj7, 0 }}, - {/* interval2 is a minor sixth */ - { kDomb9, 2 }, { kDom9, 2 }, { kDom7s9, 2 }}, - {/* interval2 is a major sixth */ - { kHalfDimb9,2 }, { kDomb9, 3 }}, - {/* interval2 is a minor seventh */ - { kMaj7b9, 3 }} - }, - {/* interval1 is a major third */ - {/* interval2 is a perfect fourth */ - { kMaj7b9, 2 }, { kMaj9, 2 }, { kMinMaj7, 2 }, { kMaj7, 2 }, { kDom11, 0 }, - { kMaj11, 0 }}, - {/* interval2 is a tritone */ - { kHalfDimb9,2 }, { kDom7s5, 3 }, { kHalfDim7, 2 }, { kDom7b5, 0 }, { kMaj7b5, 0 }}, - {/* interval2 is a perfect fifth */ - { kMaj7s5, 3 }, { kMin7, 3 }, { kDom7, 0 }, { kMaj7, 0 }}, - {/* interval2 is a minor sixth */ - { kMinMaj7, 3 }, { kDom7s5, 0 }, { kMaj7s5, 0 }}, - {/* interval2 is a major sixth */ - { kMin7b9, 2 }, { kMin9, 2 }}, - {/* interval2 is a minor seventh */ - { kMaj7s13, 0 }} - }, - {/* interval1 is a perfect fourth */ - {/* interval2 is a tritone */ - { kDimMajb9, 2 }, { kMin7b9, 1 }, { kDomb9, 1 }, { kMaj7b5, 2 }, { kDimMaj9, 0 }}, - {/* interval2 is a perfect fifth */ - { kMin9, 1 }, { kDom9, 1 }, { kDom11, 0 }, { kDom11, 2 }}, - {/* interval2 is a minor sixth */ - { kDom7s9, 1 }, { kDom9, 3 }, { kDim7b9, 3 }}, - {/* interval2 is a major sixth */ - { kMaj9, 3 }, { kHalfDimb9,3 }}, - {/* interval2 is a minor seventh */ - { kDimMajb9, 3 }} - }, - {/* interval1 is a tritone */ - {/* interval2 is a perfect fifth */ - { kMaj7s13, 3 }, { kHalfDimb9,1 }, { kDom7s11, 0 }, { kMaj11, 2 }}, - {/* interval2 is a minor sixth */ - { kDomb9, 2 }, { kDom9, 2 }, { kDom7s9, 2 }}, - {/* interval2 is a major sixth */ - { kDim7b9, 2 }, { kDomb9, 3 }}, - {/* interval2 is a minor seventh */ - { kMaj7b9, 3 }} - }, - {/* interval1 is a perfect fifth */ - {/* interval2 is a minor sixth */ - { kMaj7b9, 2 }, { kMaj9, 2 }, { kMaj7s9, 2 }}, - {/* interval2 is a major sixth */ - { kMin7b9, 2 }, { kMin9, 2 }}, - {/* interval2 is a minor seventh */ - { kMaj7s13, 0 }} - }, - {/* interval1 is a minor sixth */ - {/* interval2 is a major sixth */ - { kMinMajb9, 2 }, { kMinMaj9, 2 }}, - {/* interval2 is a minor seventh */ - { kM7b913, 3 }} - }, - {/* interval1 is a major sixth */ - {/* interval2 is a minor seventh */ - { kM7b9s13, 2 }} - } - }; - - register t_type_root* t; - - int members[4]; - int interval1, interval2, interval3; - int i, j = 0; - for (i=0; i<12; i++) - if (x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */ - interval1 = members[1] - members[0]; /* calculate interval between first two members */ - interval2 = members[2] - members[0]; /* calculate interval between first and third */ - interval3 = members[3] - members[0]; /* calculate interval between first and third */ - interval3 = interval3 - interval2 - 1; /* reduce interval3 to start at zero */ - interval2 = interval2 - interval1 - 1; /* reduce interval2 to start at zero */ - interval1 = interval1 - 1; /* reduce interval1 to start at zero */ - - /* find TypeRoot struct for this interval set */ - t = &(quartads[interval1][interval2][interval3]); - x->x_chord_type = t->type; - x->x_chord_root = members[t->rootMember]; - switch(t->rootMember) { /* get state of inversion */ - case 0: - x->x_chord_inversion = 0; - break; - case 1: - x->x_chord_inversion = 2; - break; - case 2: - x->x_chord_inversion = 2; - break; - case 3: - x->x_chord_inversion = 1; - } - chord_draw_chord_type(x, 4); /* output results */ -} - -static void chord_fatal_error(char* s1, char* s2) -{ - post("chord: error: %s : %s", s1, s2); -} - -static void chord_quintad(t_chord *x) -{ - static int initialized = 0; - static t_type_root quintads[8][8][8][8]; - register int i, j, k, l; - register t_type_root *t; - t_int members[5]; - int interval1, interval2, interval3, interval4; - int *st; - int maj9[5][4] = {{1,1,2,3}, {0,1,1,2}, {3,0,1,1}, {2,3,0,1}, {1,2,3,0}}; - int dom9[5][4] = {{1,1,2,2}, {1,1,1,2}, {2,1,1,1}, {2,2,1,1}, {1,2,2,1}}; - int min9[5][4] = {{1,0,3,2}, {1,1,0,3}, {2,1,1,0}, {3,2,1,1}, {0,3,2,1}}; - int had9[5][4] = {{1,0,2,3}, {1,1,0,2}, {3,1,1,0}, {2,3,1,1}, {0,2,3,1}}; - int miM9[5][4] = {{1,0,3,3}, {0,1,0,3}, {3,0,1,0}, {3,3,0,1}, {0,3,3,0}}; - int diM9[5][4] = {{1,0,2,4}, {0,1,0,2}, {4,0,1,0}, {2,4,0,1}, {0,2,4,0}}; - int M9b5[5][4] = {{1,1,1,4}, {0,1,1,1}, {4,0,1,1}, {1,4,0,1}, {1,1,4,0}}; - int D9b5[5][4] = {{1,1,1,3}, {1,1,1,1}, {3,1,1,1}, {1,3,1,1}, {1,1,3,1}}; - int mM91[5][4] = {{1,0,0,6}, {0,1,0,0}, {6,0,1,0}, {0,6,0,1}, {0,0,6,0}}; - int M7b9[5][4] = {{0,2,2,3}, {0,0,2,2}, {3,0,0,2}, {2,3,0,0}, {2,2,3,0}}; - int M5b9[5][4] = {{0,2,3,2}, {0,0,2,3}, {2,0,0,2}, {3,2,0,0}, {2,3,2,0}}; - int D7b9[5][4] = {{0,2,2,2}, {1,0,2,2}, {2,1,0,2}, {2,2,1,0}, {2,2,2,1}}; - int m7b9[5][4] = {{0,1,3,2}, {1,0,1,3}, {2,1,0,1}, {3,2,1,0}, {1,3,2,1}}; - int mb51[5][4] = {{0,1,2,0}, {4,0,1,2}, {0,4,0,1}, {2,0,4,0}, {1,2,0,4}}; - int d7b9[5][4] = {{0,1,2,3}, {1,0,1,2}, {3,1,0,1}, {2,3,1,0}, {1,2,3,1}}; - int mMb9[5][4] = {{0,1,3,3}, {0,0,1,3}, {3,0,0,1}, {3,3,0,0}, {1,3,3,0}}; - int dMb9[5][4] = {{0,1,2,4}, {0,0,1,2}, {4,0,0,1}, {2,4,0,0}, {1,2,4,0}}; - int dib9[5][4] = {{0,1,2,2}, {2,0,1,2}, {2,2,0,1}, {2,2,2,0}, {1,2,2,2}}; - int M7s9[5][4] = {{2,0,2,3}, {0,2,0,2}, {3,0,2,0}, {2,3,0,2}, {0,2,3,0}}; - int D7s9[5][4] = {{2,0,2,2}, {1,2,0,2}, {2,1,2,0}, {2,2,1,2}, {0,2,2,1}}; - int M7s1[5][4] = {{3,1,0,3}, {0,3,1,0}, {3,0,3,1}, {0,3,0,3}, {1,0,3,0}}; - int d9b3[5][4] = {{1,1,2,0}, {3,1,1,2}, {0,3,1,1}, {2,0,3,1}, {1,2,0,3}}; - int M9s3[5][4] = {{1,4,2,0}, {0,1,4,2}, {0,0,1,4}, {2,0,0,1}, {4,2,0,0}}; - int M9st[5][4] = {{1,1,5,0}, {0,1,1,5}, {0,0,1,1}, {5,0,0,1}, {1,5,0,0}}; - int s9s1[5][4] = {{2,0,1,0}, {4,2,0,1}, {0,4,2,0}, {1,0,4,2}, {0,1,0,4}}; - int h7b1[5][4] = {{2,0,1,3}, {1,2,0,1}, {3,1,2,0}, {1,3,1,2}, {0,1,3,1}}; - int M711[5][4] = {{3,0,1,3}, {0,3,0,1}, {3,0,3,0}, {1,3,0,3}, {0,1,3,0}}; - int M115[5][4] = {{1,1,0,5}, {0,1,1,0}, {5,0,1,1}, {0,5,0,1}, {1,0,5,0}}; - int d711[5][4] = {{3,0,1,2}, {1,3,0,1}, {2,1,3,0}, {1,2,1,3}, {0,1,2,1}}; - int d712[5][4] = {{1,1,0,1}, {4,1,1,0}, {1,4,1,1}, {0,1,4,1}, {1,0,1,4}}; - int d713[5][4] = {{1,1,0,4}, {1,1,1,0}, {4,1,1,1}, {0,4,1,1}, {1,0,4,1}}; - int m711[5][4] = {{2,1,1,2}, {1,2,1,1}, {2,1,2,1}, {1,2,1,2}, {1,1,2,1}}; - int m712[5][4] = {{1,0,1,1}, {4,1,0,1}, {1,4,1,0}, {1,1,4,1}, {0,1,1,4}}; - int di11[5][4] = {{1,0,1,0}, {5,1,0,1}, {0,5,1,0}, {1,0,5,1}, {0,1,0,5}}; - int mM11[5][4] = {{2,1,1,3}, {0,2,1,1}, {3,0,2,1}, {1,3,0,2}, {1,1,3,0}}; - int dM11[5][4] = {{2,1,0,4}, {0,2,1,0}, {4,0,2,1}, {0,4,0,2}, {1,0,4,0}}; - int Meb5[5][4] = {{3,0,0,4}, {0,3,0,0}, {4,0,3,0}, {0,4,0,3}, {0,0,4,0}}; - int Mes5[5][4] = {{3,0,2,2}, {0,3,0,2}, {2,0,3,0}, {2,2,0,3}, {0,2,2,0}}; - int Meb9[5][4] = {{0,2,0,5}, {0,0,2,0}, {5,0,0,2}, {0,5,0,0}, {2,0,5,0}}; - int Mes9[5][4] = {{2,0,0,5}, {0,2,0,0}, {5,0,2,0}, {0,5,0,2}, {0,0,5,0}}; - int Deb5[5][4] = {{3,0,0,3}, {1,3,0,0}, {3,1,3,0}, {0,3,1,3}, {0,0,3,1}}; - int Mes3[5][4] = {{3,0,4,0}, {0,3,0,4}, {0,0,3,0}, {4,0,0,3}, {0,4,0,0}}; - int Deb9[5][4] = {{0,2,0,4}, {1,0,2,0}, {4,1,0,2}, {0,4,1,0}, {2,0,4,1}}; - int De91[5][4] = {{0,2,0,1}, {4,0,2,0}, {1,4,0,2}, {0,1,4,0}, {2,0,1,4}}; - int Des9[5][4] = {{2,0,0,4}, {1,2,0,0}, {4,1,2,0}, {0,4,1,2}, {0,0,4,1}}; - int Ds11[5][4] = {{3,1,0,2}, {1,3,1,0}, {2,1,3,1}, {0,2,1,3}, {1,0,2,1}}; - int m7s1[5][4] = {{2,2,0,2}, {1,2,2,0}, {2,1,2,2}, {0,2,1,2}, {2,0,2,1}}; - int D3s1[5][4] = {{5,0,1,0}, {1,5,0,1}, {0,1,5,0}, {1,0,1,5}, {0,1,0,1}}; - int Mb9s[5][4] = {{0,2,5,0}, {0,0,2,5}, {0,0,0,2}, {5,0,0,0}, {2,5,0,0}}; - int D7b3[5][4] = {{3,2,0,1}, {1,3,2,0}, {1,1,3,2}, {0,1,1,3}, {2,0,1,1}}; - - if (!initialized) { - for (i=0; i<8; i++) - for (j=0; j<8; j++) - for (k=0; k<8; k++) - for (l=0; l<8; l++) { - quintads[i][j][k][l].type = kNone; - quintads[i][j][k][l].rootMember = kXX; - } - - - // major ninths - for (i=0; i<5; i++) { - st = maj9[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - t->type = kMaj9; - t->rootMember = i; - } - - // dominant ninths - for (i=0; i<5; i++) { - st = dom9[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "dom9"); - t->type = kDom9; - t->rootMember = i; - } - - // minor ninths - for (i=0; i<5; i++) { - st = min9[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "min9"); - t->type = kMin9; - t->rootMember = i; - } - - // half diminished ninths - for (i=0; i<5; i++) { - st = had9[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "had9"); - t->type = kHalfDim9; - t->rootMember = i; - } - - // minor/major ninths - for (i=0; i<5; i++) { - st = miM9[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "miM9"); - t->type = kMinMaj9; - t->rootMember = i; - } - - // diminished/major ninths - for (i=0; i<5; i++) { - st = diM9[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "diM9"); - t->type = kDimMaj9; - t->rootMember = i; - } - - // major ninth flat 5 - for (i=0; i<5; i++) { - st = M9b5[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "M9b5"); - t->type = kMaj9b5; - t->rootMember = i; - } - - // dominant ninth flat 5 - for (i=0; i<5; i++) { - st = D9b5[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "D9b5"); - t->type = kDom9b5; - t->rootMember = i; - } - - // minor/major ninth flat 11 - for (i=0; i<5; i++) { - st = mM91[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "mM91"); - t->type = kmM9b11; - t->rootMember = i; - } - - // major seventh flat nine - for (i=0; i<5; i++) { - st = M7b9[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "M7b9"); - t->type = kMaj7b9; - t->rootMember = i; - } - - // major seventh sharp five flat nine - for (i=0; i<5; i++) { - st = M5b9[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "M5b9"); - t->type = kMaj7s5b9; - t->rootMember = i; - } - - // dominant seventh flat nine - for (i=0; i<5; i++) { - st = D7b9[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "D7b9"); - t->type = kDom7b9; - t->rootMember = i; - } - - // minor seventh flat nine - for (i=0; i<5; i++) { - t = &(quintads[m7b9[i][0]][m7b9[i][1]][m7b9[i][2]][m7b9[i][3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "m7b9"); - t->type = kMin7b9; - t->rootMember = i; - } - - // minor flat nine sharp eleventh - for (i=0; i<5; i++) { - st = mb51[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "mb51"); - t->type = kMinb9s11; - t->rootMember = i; - } - - // half diminished seventh flat nine - for (i=0; i<5; i++) { - st = d7b9[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "d7b9"); - t->type = kHalfDimb9; - t->rootMember = i; - } - - // minor/major seventh flat nine - for (i=0; i<5; i++) { - st = mMb9[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "mMb9"); - t->type = kMinMajb9; - t->rootMember = i; - } - - // diminished major seventh flat nine - for (i=0; i<5; i++) { - st = dMb9[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "dMb9"); - t->type = kDimMajb9; - t->rootMember = i; - } - - // diminished seventh flat nine - for (i=0; i<5; i++) { - t = &(quintads[dib9[i][0]][dib9[i][1]][dib9[i][2]][dib9[i][3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "dib9"); - t->type = kDim7b9; - t->rootMember = i; - } - - // major seventh sharp nine - for (i=0; i<5; i++) { - t = &(quintads[M7s9[i][0]][M7s9[i][1]][M7s9[i][2]][M7s9[i][3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "M7s9"); - t->type = kMaj7s9; - t->rootMember = i; - } - - // dominant seventh sharp nine - for (i=0; i<5; i++) { - t = &(quintads[D7s9[i][0]][D7s9[i][1]][D7s9[i][2]][D7s9[i][3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "D7s9"); - t->type = kDom7s9; - t->rootMember = i; - } - - // major seventh sharp eleventh - for (i=0; i<5; i++) { - t = &(quintads[M7s1[i][0]][M7s1[i][1]][M7s1[i][2]][M7s1[i][3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "M7s1"); - t->type = kMaj7s11; - t->rootMember = i; - } - - // dominant ninth flat thirteenth - for (i=0; i<5; i++) { - st = d9b3[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "d9b3"); - t->type = kDom9b13; - t->rootMember = i; - } - - // major ninth sharp thirteenth - for (i=0; i<5; i++) { - st = M9s3[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "M9s3"); - t->type = kMaj9s13; - t->rootMember = i; - } - - // major ninth sharp thirteenth - for (i=0; i<5; i++) { - t = &(quintads[M9st[i][0]][M9st[i][1]][M9st[i][2]][M9st[i][3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "M9st"); - t->type = kMaj9s13; - t->rootMember = i; - } - - // major chord sharp ninth sharp eleventh - for (i=0; i<5; i++) { - st = s9s1[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "s9s1"); - t->type = kMs9s11; - t->rootMember = i; - } - - // half diminished seven flat 11 - for (i=0; i<5; i++) { - st = h7b1[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "h7b1"); - t->type = kHDimb11; - t->rootMember = i; - } - - // major eleventh - for (i=0; i<5; i++) { - t = &(quintads[M711[i][0]][M711[i][1]][M711[i][2]][M711[i][3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "M711"); - t->type = kMaj11; - t->rootMember = i; - } - - // major eleventh - for (i=0; i<5; i++) { - t = &(quintads[M115[i][0]][M115[i][1]][M115[i][2]][M115[i][3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "M711"); - t->type = kMaj11; - t->rootMember = i; - } - - // dominant eleventh - for (i=0; i<5; i++) { - t = &(quintads[d711[i][0]][d711[i][1]][d711[i][2]][d711[i][3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "d711"); - t->type = kDom11; - t->rootMember = i; - } - - // dominant eleventh - for (i=0; i<5; i++) { - t = &(quintads[d712[i][0]][d712[i][1]][d712[i][2]][d712[i][3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "d712"); - t->type = kDom11; - t->rootMember = i; - } - - // dominant eleventh - for (i=0; i<5; i++) { - st = d713[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "d713"); - t->type = kDom11; - t->rootMember = i; - } - - // minor eleventh - for (i=0; i<5; i++) { - t = &(quintads[m711[i][0]][m711[i][1]][m711[i][2]][m711[i][3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "m711"); - t->type = kMin11; - t->rootMember = i; - } - - // minor eleventh - for (i=0; i<5; i++) { - t = &(quintads[m712[i][0]][m712[i][1]][m712[i][2]][m712[i][3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "m712"); - t->type = kMin11; - t->rootMember = i; - } - - // diminished eleventh - for (i=0; i<5; i++) { - st = di11[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "di11"); - t->type = kDim11; - t->rootMember = i; - } - - // minor/major eleventh - for (i=0; i<5; i++) { - st = mM11[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "mM11"); - t->type = kMinMaj11; - t->rootMember = i; - } - - // diminished major eleventh - for (i=0; i<5; i++) { - st = dM11[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "dM11"); - t->type = kDimMaj11; - t->rootMember = i; - } - - // major eleventh flat fifth - for (i=0; i<5; i++) { - st = Meb5[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "Meb5"); - t->type = kMaj11b5; - t->rootMember = i; - } - - // major eleventh sharp fifth - for (i=0; i<5; i++) { - st = Mes5[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "Mes5"); - t->type = kMaj11s5; - t->rootMember = i; - } - - // major eleventh flat ninth - for (i=0; i<5; i++) { - st = Meb9[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "Meb9"); - t->type = kMaj11b9; - t->rootMember = i; - } - - // major eleventh sharp ninth - for (i=0; i<5; i++) { - st = Mes9[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "Mes9"); - t->type = kMaj11s9; - t->rootMember = i; - } - - // major eleventh sharp thirteenth - for (i=0; i<5; i++) { - st = Mes3[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "Mes3"); - t->type = kMaj11s13; - t->rootMember = i; - } - - // dominant eleventh flat fifth - for (i=0; i<5; i++) { - st = Deb5[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "Deb5"); - t->type = kDom11b5; - t->rootMember = i; - } - - // dominant eleventh flat ninth - for (i=0; i<5; i++) { - st = Deb9[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "Deb9"); - t->type = kDom11b9; - t->rootMember = i; - } - - // dominant eleventh flat ninth - for (i=0; i<5; i++) { - st = De91[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "De91"); - t->type = kDom11b9; - t->rootMember = i; - } - - // dominant eleventh sharp ninth - for (i=0; i<5; i++) { - st = Des9[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "Des9"); - t->type = kDom11s9; - t->rootMember = i; - } - - // dominant seventh sharp eleventh - for (i=0; i<5; i++) { - st = Ds11[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "Ds11"); - t->type = kDom7s11; - t->rootMember = i; - } - - // minor seventh sharp eleventh - for (i=0; i<5; i++) { - st = m7s1[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "m7s1"); - t->type = kMin7s11; - t->rootMember = i; - } - - // dominant thirteenth sharp eleventh - for (i=0; i<5; i++) { - st = D3s1[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "D3s1"); - t->type = kDom13s11; - t->rootMember = i; - } - - // major seventh flat ninth sharp thirteenth - for (i=0; i<5; i++) { - st = Mb9s[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "Mb9s"); - t->type = kM7b9s13; - t->rootMember = i; - } - - // dominant seventh flat thirteenth - for (i=0; i<5; i++) { - st = D7b3[i]; - t = &(quintads[st[0]][st[1]][st[2]][st[3]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "D7b3"); - t->type = kDom7b13; - t->rootMember = i; - } - - initialized = 1; - return; - } - - j = 0; - for (i=0; i<12; i++) - if (x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */ - interval1 = members[1] - members[0]; /* calculate interval between first two members */ - interval2 = members[2] - members[0]; /* calculate interval between first and third */ - interval3 = members[3] - members[0]; /* calculate interval between first and third */ - interval4 = members[4] - members[0]; /* calculate interval between first and fourth */ - interval4 = interval4 - interval3 - 1; /* reduce interval4 to start at zero */ - interval3 = interval3 - interval2 - 1; /* reduce interval3 to start at zero */ - interval2 = interval2 - interval1 - 1; /* reduce interval2 to start at zero */ - interval1 = interval1 - 1; /* reduce interval1 to start at zero */ - - // find TypeRoot struct for this interval set - t = &(quintads[interval1][interval2][interval3][interval4]); - if (t->rootMember != kXX) - { - x->x_chord_type = t->type; - x->x_chord_root = members[t->rootMember]; - switch(t->rootMember) { /* get state of inversion */ - case 0: - x->x_chord_inversion = 0; - break; - case 1: - x->x_chord_inversion = 2; - break; - case 2: - x->x_chord_inversion = 2; - break; - case 3: - x->x_chord_inversion = 2; - break; - case 4: - x->x_chord_inversion = 1; - } - chord_draw_chord_type(x, 5); /* output result */ - } else - chord_kick_out_member(x, 5, members); -} - -static void chord_sextad(t_chord *x) -{ - static int initialized = 0; - static t_type_root sextads[7][7][7][7][7]; - register int i, j, k, l, m; - register t_type_root *t; - register int* st; - t_int members[6]; - int interval1, interval2, interval3, interval4, interval5; - - int D9b3[6][5] = - {{1,1,2,0,1}, {1,1,1,2,0}, {1,1,1,1,2}, {0,1,1,1,1}, {2,0,1,1,1}, {1,2,0,1,1}}; - int m9s1[6][5] = - {{1,0,2,0,2}, {1,1,0,2,0}, {2,1,1,0,2}, {0,2,1,1,0}, {2,0,2,1,1}, {0,2,0,2,1}}; - int M711[6][5] = - {{1,1,0,1,3}, {0,1,1,0,1}, {3,0,1,1,0}, {1,3,0,1,1}, {0,1,3,0,1}, {1,0,1,3,0}}; - int D711[6][5] = - {{1,1,0,1,2}, {1,1,1,0,1}, {2,1,1,1,0}, {1,2,1,1,1}, {0,1,2,1,1}, {1,0,1,2,1}}; - int hd11[6][5] = - {{1,0,1,0,3}, {1,1,0,1,0}, {3,1,1,0,1}, {0,3,1,1,0}, {1,0,3,1,1}, {0,1,0,3,1}}; - int M1b5[6][5] = - {{1,1,0,0,4}, {0,1,1,0,0}, {4,0,1,1,0}, {0,4,0,1,1}, {0,0,4,0,1}, {1,0,0,4,0}}; - int M159[6][5] = - {{0,2,0,0,4}, {0,0,2,0,0}, {4,0,0,2,0}, {0,4,0,0,2}, {0,0,4,0,0}, {2,0,0,4,0}}; - int M1s3[6][5] = - {{1,1,0,4,0}, {0,1,1,0,4}, {0,0,1,1,0}, {4,0,0,1,1}, {0,4,0,0,1}, {1,0,4,0,0}}; - int hd19[6][5] = - {{0,1,1,0,3}, {1,0,1,1,0}, {3,1,0,1,1}, {0,3,1,0,1}, {1,0,3,1,0}, {1,1,0,3,1}}; - int M1b3[6][5] = - {{3,0,1,0,2}, {0,3,0,1,0}, {2,0,3,0,1}, {0,2,0,3,0}, {1,0,2,0,3}, {0,1,0,2,0}}; - int D1b5[6][5] = - {{1,1,0,0,3}, {1,1,1,0,0}, {3,1,1,1,0}, {0,3,1,1,1}, {0,0,3,1,1}, {1,0,0,3,1}}; - int D1s9[6][5] = - {{2,0,0,1,2}, {1,2,0,0,1}, {2,1,2,0,0}, {1,2,1,2,0}, {0,1,2,1,2}, {0,0,1,2,1}}; - int m791[6][5] = - {{0,1,2,0,2}, {1,0,1,2,0}, {2,1,0,1,2}, {0,2,1,0,1}, {2,0,2,1,0}, {1,2,0,2,1}}; - int d7s1[6][5] = - {{1,1,1,0,2}, {1,1,1,1,0}, {2,1,1,1,1}, {0,2,1,1,1}, {1,0,2,1,1}, {1,1,0,2,1}}; - int d3s1[6][5] = - {{3,1,0,1,0}, {1,3,1,0,1}, {0,1,3,1,0}, {1,0,1,3,1}, {0,1,0,1,3}, {1,0,1,0,1}}; - - - if (!initialized) { - for (i=0; i<7; i++) - for (j=0; j<7; j++) - for (k=0; k<7; k++) - for (l=0; l<7; l++) - for (m=0; m<7; m++) { - sextads[i][j][k][l][m].type = kNone; - sextads[i][j][k][l][m].rootMember = kXX; - } - - // dominant ninth flat thirteen - for (i=0; i<6; i++) { - st = D9b3[i]; - t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "D9b3"); - t->type = kDom9b13; - t->rootMember = i; - } - - // minor ninth sharp eleventh - for (i=0; i<6; i++) { - st = m9s1[i]; - t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "m9s1"); - t->type = kMin9s11; - t->rootMember = i; - } - - // major eleventh - for (i=0; i<6; i++) { - st = M711[i]; - t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "M711"); - t->type = kMaj11; - t->rootMember = i; - } - - // dominant eleventh - for (i=0; i<6; i++) { - st = D711[i]; - t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "D711"); - t->type = kDom11; - t->rootMember = i; - } - - // half diminished eleventh - for (i=0; i<6; i++) { - st = hd11[i]; - t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "hd11"); - t->type = kHalfDim11; - t->rootMember = i; - } - - // major eleventh flat 5 - for (i=0; i<6; i++) { - st = M1b5[i]; - t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "M1b5"); - t->type = kMaj11b5; - t->rootMember = i; - } - - // major eleventh flat 5 flat 9 - for (i=0; i<6; i++) { - st = M159[i]; - t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "M159"); - t->type = kM11b5b9; - t->rootMember = i; - } - - // major eleventh sharp 13 - for (i=0; i<6; i++) { - st = M1s3[i]; - t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "M1s3"); - t->type = kMaj11s13; - t->rootMember = i; - } - - // half diminished eleventh flat 9 - for (i=0; i<6; i++) { - st = hd19[i]; - t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "hd19"); - t->type = kHalfDim11b9; - t->rootMember = i; - } - - // major eleventh flat 13 - for (i=0; i<6; i++) { - st = M1b3[i]; - t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "M1b3"); - t->type = kMaj11b13; - t->rootMember = i; - } - - // dominant eleventh flat five - for (i=0; i<6; i++) { - st = D1b5[i]; - t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "D1b5"); - t->type = kDom11b5; - t->rootMember = i; - } - - // dominant eleventh sharp nine - for (i=0; i<6; i++) { - st = D1s9[i]; - t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "D1s9"); - t->type = kDom11s9; - t->rootMember = i; - } - - // minor seventh flat 9 sharp 11 - for (i=0; i<6; i++) { - st = m791[i]; - t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "m791"); - t->type = kMinb9s11; - t->rootMember = i; - } - - // dominant seventh sharp 11 - for (i=0; i<6; i++) { - st = d7s1[i]; - t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "d7s1"); - t->type = kDom7s11; - t->rootMember = i; - } - - // dominant thirteenth sharp 11 - for (i=0; i<6; i++) { - st = d3s1[i]; - t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); - if (t->type != kNone) chord_fatal_error("redefining chord", "d3s1"); - t->type = kDom13s11; - t->rootMember = i; - } - - initialized = 1; - return; - } - - j = 0; - for (i=0; i<12; i++) - if (x->x_pc[i]) members[j++] = i; // load members array with chord pitch classes - interval1 = members[1] - members[0]; // calculate interval between first two members - interval2 = members[2] - members[0]; // calculate interval between first and third - interval3 = members[3] - members[0]; // calculate interval between first and third - interval4 = members[4] - members[0]; // calculate interval between first and fourth - interval5 = members[5] - members[0]; // calculate interval between first and fifth - interval5 = interval5 - interval4 - 1; // reduce interval5 to start at zero - interval4 = interval4 - interval3 - 1; // reduce interval4 to start at zero - interval3 = interval3 - interval2 - 1; // reduce interval3 to start at zero - interval2 = interval2 - interval1 - 1; // reduce interval2 to start at zero - interval1 = interval1 - 1; // reduce interval1 to start at zero - - // find TypeRoot struct for this interval set - t = &(sextads[interval1][interval2][interval3][interval4][interval5]); - if (t->rootMember != kXX) { - x->x_chord_type = t->type; - x->x_chord_root = members[t->rootMember]; - switch(t->rootMember) { /* get state of inversion */ - case 0: - x->x_chord_inversion = 0; - break; - case 1: - x->x_chord_inversion = 2; - break; - case 2: - x->x_chord_inversion = 2; - break; - case 3: - x->x_chord_inversion = 2; - break; - case 4: - x->x_chord_inversion = 2; - break; - case 5: x->x_chord_inversion = 1; - } - chord_draw_chord_type(x, 6); // output onto the screen - } else - chord_kick_out_member(x, 6, members); -} - -static int chord_accidental(t_int pc) -{ - switch (pc) { - case 0: - case 2: - case 4: - case 5: - case 7: - case 9: - case 11: return 0; - case 1: - case 3: - case 6: - case 8: - case 10: - default: return 1; - } -} - -static int chord_name_third(t_chord *x, char* chord, int c, int rootName) -{ - int third = (x->x_chord_root+4)%12; // look for major third - if (x->x_pc[third]) { // if one is there - x->x_pc[third] = 0; // erase from pcs array - chord[c++] = name_class[(rootName+2)%7]; - if (chord_accidental(third)) { // if it has an chord_accidental - // make it a flat if the root also has an chord_accidental - if (chord_accidental(x->x_chord_root)) - chord[c++] = 'b'; - // otherwise make it a sharp - else - chord[c++] = '#'; - } - chord[c++] = ' '; - return c; // return if major third found - } - - third = (x->x_chord_root+3)%12; // no major, look for minor third - if (x->x_pc[third]) { // if one is there - x->x_pc[third] = 0; // erase from pcs array - chord[c++] = name_class[(rootName+2)%7]; - if (chord_accidental(third)) // if it has an chord_accidental - chord[c++] = 'b'; else // make it a flat - if (chord_accidental(x->x_chord_root)) { // if the root has an chord_accidental - chord[c++] = 'b'; // make the third a flat - if (chord[0] == 'G') // if the root is Gb - chord[c++] = 'b'; // this must be Bbb - } - chord[c++] = ' '; - return c; - } - - return c; // if we get here there was no third -} - -static int chord_name_fifth(t_chord *x, char* chord, int c, int rootName) -{ - int fifth = (x->x_chord_root+7)%12; - if (x->x_pc[fifth]) { - x->x_pc[fifth] = 0; - chord[c++] = name_class[(rootName+4)%7]; - if (chord_accidental(fifth)) { - if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; - else chord[c++] = '#'; - } - chord[c++] = ' '; - return c; - } - - fifth = (x->x_chord_root+6)%12; - if (x->x_pc[fifth]) { - x->x_pc[fifth] = 0; - chord[c++] = name_class[(rootName+4)%7]; - if (chord[0] != 'B') chord[c++] = 'b'; - if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; - chord[c++] = ' '; - return c; - } - - fifth = (x->x_chord_root+8)%12; - if (x->x_pc[fifth]) { - x->x_pc[fifth] = 0; - chord[c++] = name_class[(rootName+4)%7]; - if (chord_accidental(fifth)) chord[c++] = '#'; else - if (!chord_accidental(x->x_chord_root)) { - chord[c++] = '#'; - if (chord[0] == 'B') - chord[c++] = '#'; - } - chord[c++] = ' '; - return c; - } - - return c; -} - -static int chord_name_seventh(t_chord *x, char* chord, int c, int rootName) -{ - int seventh = (x->x_chord_root+11)%12; - if (x->x_pc[seventh]) { - x->x_pc[seventh] = 0; - chord[c++] = name_class[(rootName+6)%7]; - if (chord_accidental(seventh)) chord[c++] = '#'; - chord[c++] = ' '; - return c; - } - seventh = (x->x_chord_root+10)%12; - if (x->x_pc[seventh]) { - x->x_pc[seventh] = 0; - chord[c++] = name_class[(rootName+6)%7]; - if (chord_accidental(seventh) || chord_accidental(x->x_chord_root)) - chord[c++] = 'b'; - chord[c++] = ' '; - return c; - } - seventh = (x->x_chord_root+9)%12; - if (x->x_pc[seventh]) { - x->x_pc[seventh] = 0; - chord[c++] = name_class[(rootName+6)%7]; - chord[c++] = 'b'; - if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; else - if (chord_accidental((seventh+1)%12)) chord[c++] = 'b'; - chord[c++] = ' '; - return c; - } - return c; -} - -static int chord_name_ninth(t_chord *x, char* chord, int c, int rootName) -{ - int ninth = (x->x_chord_root+2)%12; - if (x->x_pc[ninth]) { - x->x_pc[ninth] = 0; - chord[c++] = name_class[(rootName+1)%7]; - if (chord_accidental(ninth)) { - if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; - else chord[c++] = '#'; - } - chord[c++] = ' '; - return c; - } - - ninth = (x->x_chord_root+1)%12; - if (x->x_pc[ninth]) { - x->x_pc[ninth] = 0; - chord[c++] = name_class[(rootName+1)%7]; - if (chord_accidental(ninth)) chord[c++] = 'b'; - else { - if (chord_accidental(x->x_chord_root)) { - chord[c++] = 'b'; - if ((x->x_chord_root == 1) || (x->x_chord_root == 6) || (x->x_chord_root == 8)) - chord[c++] = 'b'; - } - } - chord[c++] = ' '; - return c; - } - - ninth = (x->x_chord_root+3)%12; - if (x->x_pc[ninth]) { - x->x_pc[ninth] = 0; - chord[c++] = name_class[(rootName+1)%7]; - if (chord_accidental(ninth)) chord[c++] = '#'; else - if (!chord_accidental(x->x_chord_root)) { - chord[c++] = '#'; - if (chord_accidental((x->x_chord_root+2)%12)) - chord[c++] = '#'; - } - chord[c++] = ' '; - return c; - } - - return c; -} - -static int chord_name_eleventh(t_chord *x, char* chord, int c, int rootName) -{ - int eleventh = (x->x_chord_root+5)%12; - if (x->x_pc[eleventh]) { - x->x_pc[eleventh] = 0; - chord[c++] = name_class[(rootName+3)%7]; - if (chord_accidental(eleventh)) chord[c++] = 'b'; else - if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; - chord[c++] = ' '; - return c; - } - - eleventh = (x->x_chord_root+6)%12; - if (x->x_pc[eleventh]) { - x->x_pc[eleventh] = 0; - chord[c++] = name_class[(rootName+3)%7]; - if (chord_accidental(eleventh)) chord[c++] = '#'; else - if ((!chord_accidental(x->x_chord_root)) && (x->x_chord_root == 11)) - chord[c++] = '#'; - chord[c++] = ' '; - return c; - } - - return c; -} - -static int chord_name_thirteenth(t_chord *x, char* chord, int c, int rootName) -{ - int thirteenth = (x->x_chord_root+9)%12; - if (x->x_pc[thirteenth]) { - x->x_pc[thirteenth] = 0; - chord[c++] = name_class[(rootName+5)%7]; - if (chord_accidental(thirteenth)) { - if (chord_accidental(x->x_chord_root)) - chord[c++] = 'b'; - else - chord[c++] = '#'; - } - - chord[c++] = ' '; - return c; - } - - thirteenth = (x->x_chord_root+10)%12; - if (x->x_pc[thirteenth]) { - x->x_pc[thirteenth] = 0; - chord[c++] = name_class[(rootName+5)%7]; - if (chord_accidental(thirteenth)) chord[c++] = '#'; else - if (!chord_accidental(x->x_chord_root)) { - chord[c++] = '#'; - if (chord_accidental((x->x_chord_root+9)%12)) - chord[c++] = '#'; - } - chord[c++] = ' '; - return c; - } - - thirteenth = (x->x_chord_root+8)%12; - if (x->x_pc[thirteenth]) { - x->x_pc[thirteenth] = 0; - chord[c++] = name_class[(rootName+5)%7]; - if (chord_accidental(thirteenth)) chord[c++] = 'b'; else - if (chord_accidental(x->x_chord_root)) { - chord[c++] = 'b'; - if (chord_accidental(x->x_chord_root+9)%12) - chord[c++] = 'b'; - } - chord[c++] = ' '; - return c; - } - - return c; -} - - - -static void chord_spell_chord(t_chord *x, char *chord, t_int num_pcs) -{ - int rootName = 0; // keep index of root name class - int c = 0; // pointer to current character - int named = 0; // how many members have been named - int mark; - int i; - - // use chordRoot to set rootName index and store characters for name - switch (x->x_chord_root) - { - case 0: chord[c++] = name_class[rootName=0]; break; - case 1: chord[c++] = name_class[rootName=1]; - chord[c++] = 'b'; break; - case 2: chord[c++] = name_class[rootName=1]; break; - case 3: chord[c++] = name_class[rootName=2]; - chord[c++] = 'b'; break; - case 4: chord[c++] = name_class[rootName=2]; break; - case 5: chord[c++] = name_class[rootName=3]; break; - case 6: chord[c++] = name_class[rootName=4]; - chord[c++] = 'b'; break; - case 7: chord[c++] = name_class[rootName=4]; break; - case 8: chord[c++] = name_class[rootName=5]; - chord[c++] = 'b'; break; - case 9: chord[c++] = name_class[rootName=5]; break; - case 10: chord[c++] = name_class[rootName=6]; - chord[c++] = 'b'; break; - case 11: chord[c++] = name_class[rootName=6]; break; - default: break; - } - x->x_pc[x->x_chord_root] = 0; /* set this member to zero */ - - chord[c++] = ' '; // insert space - if (++named == num_pcs) { // if everything is named - chord[c] = '\0'; // terminate the string - return; // and return - } - - mark = c; // use mark to see if new names are added - for (i=0; i<6; i++) { - // advance search by thirds - switch (i) { - case 0: mark = chord_name_third (x, chord, c, rootName); break; - case 1: mark = chord_name_fifth (x, chord, c, rootName); break; - case 2: mark = chord_name_seventh (x, chord, c, rootName); break; - case 3: mark = chord_name_ninth (x, chord, c, rootName); break; - case 4: mark = chord_name_eleventh (x, chord, c, rootName); break; - case 5: mark = chord_name_thirteenth(x, chord, c, rootName); break; - } - if (mark != c) { // if new name is added - ++named; // increment count of named members - c = mark; // update character pointer - } - if (named == num_pcs) { // if everything is named - chord[c] = '\0'; // terminate the string - return; // and return - } - } - - chord[c] = '\0'; -} - - -static void chord_draw_chord_type(t_chord *x, t_int num_pcs) -{ - char chord[255]; /* output string */ - int i, j; - - /* get members of chord */ - j = 0; - for(i = 0; i < 12; i++) - { - if(x->x_pc[i]) - { - SETFLOAT(x->x_chordlist+j, x->x_abs_pc[i]); - j++; - } - } - - if (x->x_chord_type != kNone) - { - chord_spell_chord(x, chord, num_pcs); /* spell chord members */ - } - else - { - post("going..."); - chord[0] = '\0'; - for(i = 0; i < 12; i++) - if (x->x_pc[i]) - strcat(chord, pitch_class[i]); /* output single notes */ - post("did it"); - } - - strcat(chord, ": "); - strcat(chord, pitch_class[x->x_chord_root]); - - /* append name of chord type */ - switch (x->x_chord_type) { - case kUnison: strcat(chord, "unison"); break; - case kMaj: strcat(chord, "major"); break; - case kMin: strcat(chord, "minor"); break; - case kDim: strcat(chord, "diminished"); break; - case kAug: strcat(chord, "augmented"); break; - - case kMaj7: strcat(chord, "major 7th"); break; - case kDom7: strcat(chord, "dominant 7th"); break; - case kMin7: strcat(chord, "minor 7th"); break; - case kHalfDim7: strcat(chord, "half diminished 7th"); break; - case kDim7: strcat(chord, "diminished 7th"); break; - case kMinMaj7: strcat(chord, "minor/major 7th"); break; - - case kMaj7s5: strcat(chord, "major 7th #5"); break; - case kMaj7b5: strcat(chord, "major 7th b5"); break; - case kDom7s5: strcat(chord, "dominant 7th #5"); break; - case kDom7b5: strcat(chord, "dominant 7th b5"); break; - case kDomb9: strcat(chord, "dominant b9"); break; - - case kMaj9: strcat(chord, "major 9th"); break; - case kDom9: strcat(chord, "dominant 9th"); break; - case kMin9: strcat(chord, "minor 9th"); break; - case kHalfDim9: strcat(chord, "half diminished 9th"); break; - case kMinMaj9: strcat(chord, "minor major 9th"); break; - case kDimMaj9: strcat(chord, "diminished major 9th");break; - case kMaj9b5: strcat(chord, "major 9th b5"); break; - case kDom9b5: strcat(chord, "dominant 9th b5"); break; - case kDom9b13: strcat(chord, "dominant 9th b13"); break; - case kMin9s11: strcat(chord, "minor 9th #11"); break; - case kmM9b11: strcat(chord, "minor/maj 9th b11"); break; - - case kMaj7b9: strcat(chord, "major 7th b9"); break; - case kMaj7s5b9: strcat(chord, "major 7th #5 b9"); break; - case kDom7b9: strcat(chord, "dominant 7th b9"); break; - case kMin7b9: strcat(chord, "minor 7th b9"); break; - case kMinb9s11: strcat(chord, "minor b9 #11"); break; - case kHalfDimb9:strcat(chord, "half diminished b9"); break; - case kDim7b9: strcat(chord, "diminished b9"); break; - case kMinMajb9: strcat(chord, "minor/major b9"); break; - case kDimMajb9: strcat(chord, "diminished M7 b9"); break; - - case kMaj7s9: strcat(chord, "major 7th #9"); break; - case kDom7s9: strcat(chord, "dominant #9"); break; - case kMaj7s11: strcat(chord, "major 7th #11"); break; - case kMaj9s13: strcat(chord, "major 9th #13"); break; - case kMs9s11: strcat(chord, "major #9 #11"); break; - case kHDimb11: strcat(chord, "half diminished b11"); break; - - case kMaj11: strcat(chord, "major 11th"); break; - case kDom11: strcat(chord, "dominant 11th"); break; - case kMin11: strcat(chord, "minor 11th"); break; - case kHalfDim11:strcat(chord, "half diminished 11th");break; - case kDim11: strcat(chord, "diminished 11th"); break; - case kMinMaj11: strcat(chord, "minor/major 11th"); break; - case kDimMaj11: strcat(chord, "diminished maj 11th"); break; - - case kMaj11b5: strcat(chord, "major 11th b5"); break; - case kMaj11s5: strcat(chord, "major 11th #5"); break; - case kMaj11b9: strcat(chord, "major 11th b9"); break; - case kMaj11s9: strcat(chord, "major 11th #9"); break; - case kMaj11b13: strcat(chord, "major 11th b13"); break; - case kMaj11s13: strcat(chord, "major 11th #13"); break; - case kM11b5b9: strcat(chord, "major 11th b5 b9"); break; - case kDom11b5: strcat(chord, "dominant 11th b5"); break; - case kDom11b9: strcat(chord, "dominant 11th b9"); break; - case kDom11s9: strcat(chord, "dominant 11th #9"); break; - case kHalfDim11b9:strcat(chord, "half dim 11th b9"); break; - case kDom7s11: strcat(chord, "dominant #11"); break; - case kMin7s11: strcat(chord, "minor 7th #11"); break; - - case kDom13s11: strcat(chord, "dominant 13th #11"); break; - case kM7b913: strcat(chord, "major 7 b9 13"); break; - case kMaj7s13: strcat(chord, "major 7th #13"); break; - case kM7b9s13: strcat(chord, "major 7 b9 #13"); break; - case kDom7b13: strcat(chord, "dominant 7th b13"); break; - case kChrom: strcat(chord, "chromatic"); break; - case kNone: - default: strcat(chord, "unknown"); break; - } - - x->x_chord_bass = x->x_abs_pc[x->x_chord_root]; /* get MIDI note number of bass */ - - /* output results */ - outlet_list(x->x_outchordnotes, NULL, j, x->x_chordlist); - outlet_float(x->x_outchordinversion, x->x_chord_inversion); - outlet_symbol(x->x_outchordname, gensym(chord)); - outlet_float(x->x_outchordclass, x->x_chord_root); - outlet_float(x->x_outchordval, x->x_chord_bass); -} - -static void chord_kick_out_member(t_chord *x, t_int number, t_int *members) -{ - int *distances; - int minDistance = 1000; - int badMember = 0; - int i, j, interval; - - distances = getbytes(number*sizeof(int)); - - for (i=0; i 6) interval = 12 - interval; - // add absolute interval size to total - distances[i] += interval; - } - - // if this is the smallest total distance - if (distances[i] < minDistance) { - // remember it - minDistance = distances[i]; - badMember = i; - } - } - freebytes(distances, number * sizeof(int)); - x->x_pc[members[badMember]] = 0; // cancel out most dissonant member - chord_chord_finder(x, number-1); // call chord finder again without it - x->x_pc[members[badMember]] = 1; // replace most dissonant member -} - -static void chord_chord_finder(t_chord *x, t_int num_pcs) -{ - int i; - x->x_chord_type = kNone; - x->x_chord_root = kXX; /* none */ - switch (num_pcs) { - case 1: chord_unison(x); break; - case 2: chord_dyad(x); break; - case 3: chord_triad(x); break; - case 4: chord_quartad(x); break; - case 5: chord_quintad(x); break; - case 6: chord_sextad(x); break; - default: x->x_chord_type = kChrom; - for(i = 0; i < 12; i++) // 12 was num_pcs !? - { - if(x->x_pc[i]) - { - x->x_chord_root = i; - break; - } - } - } -} - -static void chord_float(t_chord *x, t_floatarg f) -{ - t_int velo = x->x_velo; - t_int allloc = 0; - t_int num_pc = 0; /* number of pitch classes present */ - int i, j, k, l; - - x->x_pitch = (t_int)f; - - if(x->x_pitch <= x->x_split) - { - /* first we need to put the note into the allocation table */ - if(velo == 0) /* got note-off: remove from allocation table */ - { - if(x->x_poly > 0)x->x_poly--; /* polyphony has decreased by one */ - for(i = 0; i < MAX_POLY; i++) /* search for voice allocation number */ - { - /* search for corresponding alloc number */ - if(x->x_alloctable[i] == x->x_pitch) - { - x->x_alloctable[i] = -1; /* free the alloc number */ - break; - } - /* couldn't find it ? */ - if(i == MAX_POLY - 1) - { - post("chord: no corresponding note-on found (ignored)"); - return; - } - } - return; /* no need to look for chord */ - } - else /* we got a note-on message */ - { - if(x->x_poly == MAX_POLY) - { - post("chord: too many note-on messages (ignored)"); - return; - } - - x->x_poly++; /* number of currently playing notes has increased */ - /* assign a voice allocation number */ - for(i = 0; i < MAX_POLY; i++) - { - /* search for free alloc number */ - if(x->x_alloctable[i] == -1) - { - x->x_alloctable[i] = x->x_pitch; /* ... and store pitch */ - break; - } - } - /* copy all notes into the pitch class array */ - for(i = 0; i < 12; i++) - { - x->x_pc[i] = 0; /* empty pitch class */ - x->x_abs_pc[i] = -1; /* empty absolute values */ - } - for(i = 0; i < MAX_POLY; i++) - { - /* check for presence of pitch class */ - if(x->x_alloctable[i] != -1) - { - if(!x->x_pc[x->x_alloctable[i]%12]) /* a new pitch class */ - { - x->x_abs_pc[x->x_alloctable[i]%12] = x->x_alloctable[i]; - } - else if(x->x_abs_pc[x->x_alloctable[i]%12] > x->x_alloctable[i]) /* remember lowest pitch */ - { - x->x_abs_pc[x->x_alloctable[i]%12] = x->x_alloctable[i]; - } - - x->x_pc[x->x_alloctable[i]%12] = 1; /* indicate presence of pc */ - } - } - /* count number of pitch classes */ - for(i = 0; i < 12; i++) - { - num_pc += x->x_pc[i]; - } - // post("%d pitch classes", num_pc); - } - } - - chord_chord_finder(x, num_pc); -} - -static void chord_ft1(t_chord *x, t_floatarg f) -{ - x->x_velo = (t_int)f; -} - -static t_class *chord_class; - -static void *chord_new(t_floatarg f) -{ - int i; - t_chord *x = (t_chord *)pd_new(chord_class); - inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); - x->x_outchordval = outlet_new(&x->x_ob, gensym("float")); - x->x_outchordclass = outlet_new(&x->x_ob, gensym("float")); - x->x_outchordname = outlet_new(&x->x_ob, gensym("symbol")); - x->x_outchordinversion = outlet_new(&x->x_ob, gensym("float")); - x->x_outchordnotes = outlet_new(&x->x_ob, gensym("float")); - - x->x_split = (t_int)f; - if(x->x_split == 0)x->x_split = 128; - for(i = 0; i < MAX_POLY; i++)x->x_alloctable[i] = -1; - - return (void *)x; -} - -#ifndef MAXLIB -void chord_setup(void) -{ - chord_class = class_new(gensym("chord"), (t_newmethod)chord_new, - 0, sizeof(t_chord), 0, A_DEFFLOAT, 0); -#else -void maxlib_chord_setup(void) -{ - chord_class = class_new(gensym("maxlib_chord"), (t_newmethod)chord_new, - 0, sizeof(t_chord), 0, A_DEFFLOAT, 0); -#endif - class_addfloat(chord_class, chord_float); - class_addmethod(chord_class, (t_method)chord_ft1, gensym("ft1"), A_FLOAT, 0); -#ifndef MAXLIB - - post(version); -#else - class_addcreator((t_newmethod)chord_new, gensym("chord"), A_DEFFLOAT, 0); - class_sethelpsymbol(chord_class, gensym("maxlib/chord-help.pd")); -#endif -} - +/* ------------------------- chord ------------------------------------------ */ +/* */ +/* Tries to detect a chord (or any harmonic relations) of incoming notes. */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include +#include +#ifndef _WIN32 +#include +#endif + + +#define MAX_POLY 32 /* maximum number of notes played at a time */ + +#define kUnison 0 +#define kMaj 1 +#define kMin 2 +#define kDim 3 +#define kAug 4 +#define kMaj7 5 +#define kDom7 6 +#define kMin7 7 +#define kHalfDim7 8 +#define kDim7 9 +#define kMinMaj7 10 +#define kMaj7s5 11 +#define kMaj7b5 12 +#define kDom7s5 13 +#define kDom7b5 14 +#define kDomb9 15 +#define kMaj9 16 +#define kDom9 17 +#define kMin9 18 +#define kHalfDim9 19 +#define kMinMaj9 20 +#define kDimMaj9 21 +#define kMaj9b5 22 +#define kDom9b5 23 +#define kDom9b13 24 +#define kMin9s11 25 +#define kmM9b11 26 +#define kMaj7b9 27 +#define kMaj7s5b9 28 +#define kDom7b9 29 +#define kMin7b9 30 +#define kMinb9s11 31 +#define kHalfDimb9 32 +#define kDim7b9 33 +#define kMinMajb9 34 +#define kDimMajb9 35 +#define kMaj7s9 36 +#define kDom7s9 37 +#define kMaj7s11 38 +#define kMs9s11 39 +#define kHDimb11 40 +#define kMaj11 41 +#define kDom11 42 +#define kMin11 43 +#define kHalfDim11 44 +#define kDim11 45 +#define kMinMaj11 46 +#define kDimMaj11 47 +#define kMaj11b5 48 +#define kMaj11s5 49 +#define kMaj11b9 50 +#define kMaj11s9 51 +#define kMaj11b13 52 +#define kMaj11s13 53 +#define kM11b5b9 54 +#define kDom11b5 55 +#define kDom11b9 56 +#define kDom11s9 57 +#define kHalfDim11b9 58 +#define kDom7s11 59 +#define kMin7s11 60 +#define kDom13s11 61 +#define kM7b913 62 +#define kMaj7s13 63 +#define kMaj9s13 64 +#define kM7b9s13 65 +#define kDom7b13 66 +#define kChrom 67 +#define kNone 68 + +#define kXX -1 + + +static char *version = "chord v0.2, written by Olaf Matthes "; + +static char* pitch_class[13] = {"C ", "Db ", "D ", "Eb ", "E ", "F ", "Gb ", "G ", "Ab ", "A ", "Bb ", "B ", "no root "}; +static char name_class[7] = {'C', 'D', 'E', 'F', 'G', 'A', 'B'}; + +typedef struct { + int type; + int rootMember; +} t_type_root; + +typedef struct chord +{ + t_object x_ob; + t_outlet *x_outchordval; /* chord as MIDI note number of base note */ + t_outlet *x_outchordclass; /* class of chord's bass note */ + t_outlet *x_outchordname; /* chord name, e.g. "Cmajor7" */ + t_outlet *x_outchordinversion; /* inversion of the chord (root = 0, 1st = 1, 2nd = 2) */ + t_outlet *x_outchordnotes; /* list with note numbers belonging to the chord */ + + t_int x_pitch; + t_int x_pc[12]; /* pitch class array */ + t_int x_abs_pc[12]; /* pitch class array: absolute MIDI note numbers */ + t_int x_velo; + t_int x_alloctable[MAX_POLY]; /* a table used to store all playing notes */ + t_int x_poly; /* number of notes currently playing */ + t_atom x_chordlist[12]; /* list that stores the note numbers for output */ + t_int x_split; /* highes note number to process */ + + t_int x_chord_type; /* chord's type (number between 0 and 68) */ + t_int x_chord_root; /* chord's root (pitch class) */ + t_int x_chord_bass; /* chord's bass note (MIDI note number) */ + t_int x_chord_inversion; /* chord's state of inversion (root, 1st, 2nd) */ + +} t_chord; + +/* functions */ +static void chord_kick_out_member(t_chord *x, t_int number, t_int *members); +static void chord_chord_finder(t_chord *x, t_int num_pcs); +static void chord_draw_chord_type(t_chord *x, t_int num_pcs); + + +static void chord_unison(t_chord *x) +{ + int i; + int member = 0; + for(i = 0; i < 12; i++) + if(x->x_pc[i]) + { + member = i; // find pitch class + break; + } + x->x_chord_type = 0; + x->x_chord_root = member; + chord_draw_chord_type(x, 1); // output onto the screen +} + +static void chord_dyad(t_chord *x) +{ + static t_type_root dyads[11] = + {{ kMaj7, 1 }, { kDom7, 1 }, { kMin, 0 }, { kMaj, 0 }, { kMaj, 1 }, + { kDom7 , 0 }, { kMaj, 0 }, { kMaj, 1 }, { kMin, 1 }, { kDom7, 0 }, { kMaj7, 0 }}; + register t_type_root* t; + + int members[2]; + int i, j = 0; + int interval1; + + for(i = 0; i < 12; i++) + if(x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */ + interval1 = members[1] - members[0]; /* calculate interval between first two members */ + interval1 = interval1 - 1; /* reduce interval1 to start at zero */ + t = &(dyads[interval1]); /* find TypeRoot struct for this interval */ + x->x_chord_type = t->type; + if (interval1 == 5) + x->x_chord_root = (members[0]+8)%12; + else + x->x_chord_root = members[t->rootMember]; + x->x_chord_inversion = t->rootMember; /* get state of inversion */ + chord_draw_chord_type(x, 2); /* output results */ +} + +static void chord_triad(t_chord *x) +{ + static t_type_root triads[10][10] = + {/* interval1 is a half step */ + {{ kMaj7b9, 1 }, { kMaj9, 1 }, { kMinMaj7, 1 }, { kMaj7, 1 }, { kDom7s11,2 }, + { kDomb9 , 0 }, { kMaj7, 1 }, { kMaj7s5, 1 }, { kMin9, 2 }, { kMaj7b9, 0 }}, + /* interval1 is a whole step */ + {{ kMin9, 0 }, { kDom9, 0 }, { kMin7, 1 }, { kDom7, 1 }, { kDom9, 0 }, + { kHalfDim7, 1 }, { kDom7, 1 }, { kDom9, 0 }, { kMaj9, 0 }}, + /* interval1 is a minor third */ + {{ kMaj7s5, 2 }, { kDom7, 2 }, { kDim, 0 }, { kMin, 0 }, { kMaj, 2 }, + { kDim, 2 }, { kMin7, 0 }, { kMinMaj7, 0 }}, + /* interval1 is a major third */ + {{ kMaj7, 2 }, { kHalfDim7, 2 }, { kMaj, 0 }, { kAug, 0 }, { kMin, 2 }, + { kDom7, 0 }, { kMaj7, 0 }}, + /* interval1 is a perfect fourth */ + {{ kDomb9, 1 }, { kDom9, 1 }, { kMin, 1 }, { kMaj, 1 }, { kDom9, 2 }, + { kDom7s11, 1 }}, + /* interval1 is an augmented fourth */ + {{ kDom7s11, 0 }, { kDom7, 2 }, { kDim, 1 }, { kHalfDim7, 0 }, { kDomb9, 2 }}, + /* interval1 is a perfect fifth */ + {{ kMaj7, 2 }, { kMin7, 2 }, { kDom7, 0 }, { kMaj7, 0 }}, + /* interval1 is a minor sixth */ + {{ kMinMaj7, 2 }, { kDom9, 1 }, { kMaj7s5, 0 }}, + /* interval1 is a major sixth */ + {{ kMaj9, 2 }, { kMin9, 1 }}, + /* interval1 is a minor seventh */ + {{ kMaj7b9, 2 }} + }; + register t_type_root* t; + + int members[3]; + int i, j = 0; + int interval1, interval2; + + for(i = 0; i < 12; i++) + if(x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */ + interval1 = members[1] - members[0]; /* calculate interval between first two members */ + interval2 = members[2] - members[0]; /* calculate interval between first and third */ + interval2 = interval2 - interval1 - 1; /* reduce interval2 to start at zero */ + interval1 = interval1 - 1; /* reduce interval1 to start at zero */ + t = &(triads[interval1][interval2]); /* find TypeRoot struct for this interval vector */ + x->x_chord_type = t->type; + x->x_chord_root = members[t->rootMember]; + switch(t->rootMember) { /* get state of inversion */ + case 0: + x->x_chord_inversion = 0; + break; + case 1: + x->x_chord_inversion = 2; + break; + case 2: + x->x_chord_inversion = 1; + } + chord_draw_chord_type(x, 3); /* output onto the screen */ +} + +static void chord_quartad(t_chord *x) +{ + static t_type_root quartads[9][9][9] = + { + {/* interval1 is a half step */ + {/* interval2 is a whole step */ + { kM7b9s13, 2 }, { kMinMajb9,1 }, { kMaj7b9, 1 }, { kMaj7s13, 2 }, { kDimMajb9, 1 }, + { kMaj7b9, 1 }, { kMaj7s13, 2 }, { kM7b913, 1 }, { kM7b9s13, 1 }}, + {/* interval2 is a minor third */ + { kMinMaj9, 1 }, { kMaj9, 1 }, { kHalfDimb9,0 }, { kMin7b9, 0 }, { kMaj9, 1 }, + { kDim7b9, 0 }, { kMin7b9, 0 }, { kMinMajb9, 0 }}, + {/* interval2 is a major third */ + { kMaj7s9, 1 }, { kDom7s11, 3 }, { kDomb9, 0 }, { kMinMaj7, 1 }, { kDom7s9, 3 }, + { kDomb9, 0 }, { kMaj7b9, 0 }}, + {/* interval2 is a perfect fourth */ + { kMaj11, 1 }, { kMaj7b5, 1 }, { kMaj7, 1 }, { kMaj7s5, 1 }, { kMin9, 3 }, + { kMaj7s13, 1 }}, + {/* interval2 is a tritone */ + { kDimMaj9, 3 }, { kDom11, 3 }, { kDim7b9, 0 }, { kHalfDimb9,0 }, { kDimMajb9, 0 }}, + {/* interval2 is a perfect fifth */ + { kMaj11, 3 }, { kDom7s9, 3 }, { kDomb9, 0 }, { kMaj7b9, 0 }}, + {/* interval2 is a minor sixth */ + { kMaj7s9, 3 }, { kMin9, 3 }, { kMaj7s13, 1 }}, + {/* interval2 is a major sixth */ + { kMinMaj9, 3 }, { kM7b913, 0 }}, + {/* interval2 is a minor seventh */ + { kM7b9s13, 0 }} + }, + {/* interval1 is a whole step */ + {/* interval2 is a minor third */ + { kM7b913, 2 }, { kMin7b9, 1 }, { kDomb9, 1 }, { kMin9, 0 }, { kHalfDimb9,1 }, + { kDomb9, 1 }, { kMin9, 0 }, { kMinMaj9, 0 }}, + {/* interval2 is a major third */ + { kMin9, 1 }, { kDom9, 1 }, { kDom9, 0 }, { kDom7s5, 2 }, { kDom9, 1 }, + { kDom9, 0 }, { kMaj9, 0 }}, + {/* interval2 is a perfect fourth */ + { kDom7s9, 1 }, { kDom11, 3 }, { kHalfDim7, 1 }, { kMin7, 1 }, { kDom9, 3 }, + { kHalfDimb9,3 }}, + {/* interval2 is a tritone */ + { kDom11, 1 }, { kDom7b5, 3 }, { kDom7, 1 }, { kDom7s5, 1 }, { kMin7b9, 3 }}, + {/* interval2 is a perfect fifth */ + { kMaj7b5, 3 }, { kDom11, 1 }, { kDom9, 0 }, { kMaj9, 0 }}, + {/* interval2 is a minor sixth */ + { kDom7s11, 1 }, { kDom9, 3 }, { kDim7b9, 3 }}, + {/* interval2 is a major sixth */ + { kMaj9, 3 }, { kMin7b9, 3 }}, + {/* interval2 is a minor seventh */ + { kMinMajb9, 3 }} + }, + {/* interval1 is a minor third */ + {/* interval2 is a major third */ + { kMaj7s13, 3 }, { kDim7b9, 1 }, { kDom7s9, 0 }, { kMaj7s5, 2 }, { kDim7b9, 1 }, + { kDom7s9, 0 }, { kMaj7s9, 0 }}, + {/* interval2 is a perfect fourth */ + { kDomb9, 2 }, { kDom9, 2 }, { kMin7, 2 }, { kDom7, 2 }, { kDom11, 2 }, + { kDom7s11, 2 }}, + {/* interval2 is a tritone */ + { kDim7b9, 2 }, { kDom7, 3 }, { kDim7, 0 }, { kHalfDim7, 0 }, { kDomb9, 3 }}, + {/* interval2 is a perfect fifth */ + { kMaj7, 3 }, { kHalfDim7,3 }, { kMin7, 0 }, { kMinMaj7, 0 }}, + {/* interval2 is a minor sixth */ + { kDomb9, 2 }, { kDom9, 2 }, { kDom7s9, 2 }}, + {/* interval2 is a major sixth */ + { kHalfDimb9,2 }, { kDomb9, 3 }}, + {/* interval2 is a minor seventh */ + { kMaj7b9, 3 }} + }, + {/* interval1 is a major third */ + {/* interval2 is a perfect fourth */ + { kMaj7b9, 2 }, { kMaj9, 2 }, { kMinMaj7, 2 }, { kMaj7, 2 }, { kDom11, 0 }, + { kMaj11, 0 }}, + {/* interval2 is a tritone */ + { kHalfDimb9,2 }, { kDom7s5, 3 }, { kHalfDim7, 2 }, { kDom7b5, 0 }, { kMaj7b5, 0 }}, + {/* interval2 is a perfect fifth */ + { kMaj7s5, 3 }, { kMin7, 3 }, { kDom7, 0 }, { kMaj7, 0 }}, + {/* interval2 is a minor sixth */ + { kMinMaj7, 3 }, { kDom7s5, 0 }, { kMaj7s5, 0 }}, + {/* interval2 is a major sixth */ + { kMin7b9, 2 }, { kMin9, 2 }}, + {/* interval2 is a minor seventh */ + { kMaj7s13, 0 }} + }, + {/* interval1 is a perfect fourth */ + {/* interval2 is a tritone */ + { kDimMajb9, 2 }, { kMin7b9, 1 }, { kDomb9, 1 }, { kMaj7b5, 2 }, { kDimMaj9, 0 }}, + {/* interval2 is a perfect fifth */ + { kMin9, 1 }, { kDom9, 1 }, { kDom11, 0 }, { kDom11, 2 }}, + {/* interval2 is a minor sixth */ + { kDom7s9, 1 }, { kDom9, 3 }, { kDim7b9, 3 }}, + {/* interval2 is a major sixth */ + { kMaj9, 3 }, { kHalfDimb9,3 }}, + {/* interval2 is a minor seventh */ + { kDimMajb9, 3 }} + }, + {/* interval1 is a tritone */ + {/* interval2 is a perfect fifth */ + { kMaj7s13, 3 }, { kHalfDimb9,1 }, { kDom7s11, 0 }, { kMaj11, 2 }}, + {/* interval2 is a minor sixth */ + { kDomb9, 2 }, { kDom9, 2 }, { kDom7s9, 2 }}, + {/* interval2 is a major sixth */ + { kDim7b9, 2 }, { kDomb9, 3 }}, + {/* interval2 is a minor seventh */ + { kMaj7b9, 3 }} + }, + {/* interval1 is a perfect fifth */ + {/* interval2 is a minor sixth */ + { kMaj7b9, 2 }, { kMaj9, 2 }, { kMaj7s9, 2 }}, + {/* interval2 is a major sixth */ + { kMin7b9, 2 }, { kMin9, 2 }}, + {/* interval2 is a minor seventh */ + { kMaj7s13, 0 }} + }, + {/* interval1 is a minor sixth */ + {/* interval2 is a major sixth */ + { kMinMajb9, 2 }, { kMinMaj9, 2 }}, + {/* interval2 is a minor seventh */ + { kM7b913, 3 }} + }, + {/* interval1 is a major sixth */ + {/* interval2 is a minor seventh */ + { kM7b9s13, 2 }} + } + }; + + register t_type_root* t; + + int members[4]; + int interval1, interval2, interval3; + int i, j = 0; + for (i=0; i<12; i++) + if (x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */ + interval1 = members[1] - members[0]; /* calculate interval between first two members */ + interval2 = members[2] - members[0]; /* calculate interval between first and third */ + interval3 = members[3] - members[0]; /* calculate interval between first and third */ + interval3 = interval3 - interval2 - 1; /* reduce interval3 to start at zero */ + interval2 = interval2 - interval1 - 1; /* reduce interval2 to start at zero */ + interval1 = interval1 - 1; /* reduce interval1 to start at zero */ + + /* find TypeRoot struct for this interval set */ + t = &(quartads[interval1][interval2][interval3]); + x->x_chord_type = t->type; + x->x_chord_root = members[t->rootMember]; + switch(t->rootMember) { /* get state of inversion */ + case 0: + x->x_chord_inversion = 0; + break; + case 1: + x->x_chord_inversion = 2; + break; + case 2: + x->x_chord_inversion = 2; + break; + case 3: + x->x_chord_inversion = 1; + } + chord_draw_chord_type(x, 4); /* output results */ +} + +static void chord_fatal_error(char* s1, char* s2) +{ + post("chord: error: %s : %s", s1, s2); +} + +static void chord_quintad(t_chord *x) +{ + static int initialized = 0; + static t_type_root quintads[8][8][8][8]; + register int i, j, k, l; + register t_type_root *t; + t_int members[5]; + int interval1, interval2, interval3, interval4; + int *st; + int maj9[5][4] = {{1,1,2,3}, {0,1,1,2}, {3,0,1,1}, {2,3,0,1}, {1,2,3,0}}; + int dom9[5][4] = {{1,1,2,2}, {1,1,1,2}, {2,1,1,1}, {2,2,1,1}, {1,2,2,1}}; + int min9[5][4] = {{1,0,3,2}, {1,1,0,3}, {2,1,1,0}, {3,2,1,1}, {0,3,2,1}}; + int had9[5][4] = {{1,0,2,3}, {1,1,0,2}, {3,1,1,0}, {2,3,1,1}, {0,2,3,1}}; + int miM9[5][4] = {{1,0,3,3}, {0,1,0,3}, {3,0,1,0}, {3,3,0,1}, {0,3,3,0}}; + int diM9[5][4] = {{1,0,2,4}, {0,1,0,2}, {4,0,1,0}, {2,4,0,1}, {0,2,4,0}}; + int M9b5[5][4] = {{1,1,1,4}, {0,1,1,1}, {4,0,1,1}, {1,4,0,1}, {1,1,4,0}}; + int D9b5[5][4] = {{1,1,1,3}, {1,1,1,1}, {3,1,1,1}, {1,3,1,1}, {1,1,3,1}}; + int mM91[5][4] = {{1,0,0,6}, {0,1,0,0}, {6,0,1,0}, {0,6,0,1}, {0,0,6,0}}; + int M7b9[5][4] = {{0,2,2,3}, {0,0,2,2}, {3,0,0,2}, {2,3,0,0}, {2,2,3,0}}; + int M5b9[5][4] = {{0,2,3,2}, {0,0,2,3}, {2,0,0,2}, {3,2,0,0}, {2,3,2,0}}; + int D7b9[5][4] = {{0,2,2,2}, {1,0,2,2}, {2,1,0,2}, {2,2,1,0}, {2,2,2,1}}; + int m7b9[5][4] = {{0,1,3,2}, {1,0,1,3}, {2,1,0,1}, {3,2,1,0}, {1,3,2,1}}; + int mb51[5][4] = {{0,1,2,0}, {4,0,1,2}, {0,4,0,1}, {2,0,4,0}, {1,2,0,4}}; + int d7b9[5][4] = {{0,1,2,3}, {1,0,1,2}, {3,1,0,1}, {2,3,1,0}, {1,2,3,1}}; + int mMb9[5][4] = {{0,1,3,3}, {0,0,1,3}, {3,0,0,1}, {3,3,0,0}, {1,3,3,0}}; + int dMb9[5][4] = {{0,1,2,4}, {0,0,1,2}, {4,0,0,1}, {2,4,0,0}, {1,2,4,0}}; + int dib9[5][4] = {{0,1,2,2}, {2,0,1,2}, {2,2,0,1}, {2,2,2,0}, {1,2,2,2}}; + int M7s9[5][4] = {{2,0,2,3}, {0,2,0,2}, {3,0,2,0}, {2,3,0,2}, {0,2,3,0}}; + int D7s9[5][4] = {{2,0,2,2}, {1,2,0,2}, {2,1,2,0}, {2,2,1,2}, {0,2,2,1}}; + int M7s1[5][4] = {{3,1,0,3}, {0,3,1,0}, {3,0,3,1}, {0,3,0,3}, {1,0,3,0}}; + int d9b3[5][4] = {{1,1,2,0}, {3,1,1,2}, {0,3,1,1}, {2,0,3,1}, {1,2,0,3}}; + int M9s3[5][4] = {{1,4,2,0}, {0,1,4,2}, {0,0,1,4}, {2,0,0,1}, {4,2,0,0}}; + int M9st[5][4] = {{1,1,5,0}, {0,1,1,5}, {0,0,1,1}, {5,0,0,1}, {1,5,0,0}}; + int s9s1[5][4] = {{2,0,1,0}, {4,2,0,1}, {0,4,2,0}, {1,0,4,2}, {0,1,0,4}}; + int h7b1[5][4] = {{2,0,1,3}, {1,2,0,1}, {3,1,2,0}, {1,3,1,2}, {0,1,3,1}}; + int M711[5][4] = {{3,0,1,3}, {0,3,0,1}, {3,0,3,0}, {1,3,0,3}, {0,1,3,0}}; + int M115[5][4] = {{1,1,0,5}, {0,1,1,0}, {5,0,1,1}, {0,5,0,1}, {1,0,5,0}}; + int d711[5][4] = {{3,0,1,2}, {1,3,0,1}, {2,1,3,0}, {1,2,1,3}, {0,1,2,1}}; + int d712[5][4] = {{1,1,0,1}, {4,1,1,0}, {1,4,1,1}, {0,1,4,1}, {1,0,1,4}}; + int d713[5][4] = {{1,1,0,4}, {1,1,1,0}, {4,1,1,1}, {0,4,1,1}, {1,0,4,1}}; + int m711[5][4] = {{2,1,1,2}, {1,2,1,1}, {2,1,2,1}, {1,2,1,2}, {1,1,2,1}}; + int m712[5][4] = {{1,0,1,1}, {4,1,0,1}, {1,4,1,0}, {1,1,4,1}, {0,1,1,4}}; + int di11[5][4] = {{1,0,1,0}, {5,1,0,1}, {0,5,1,0}, {1,0,5,1}, {0,1,0,5}}; + int mM11[5][4] = {{2,1,1,3}, {0,2,1,1}, {3,0,2,1}, {1,3,0,2}, {1,1,3,0}}; + int dM11[5][4] = {{2,1,0,4}, {0,2,1,0}, {4,0,2,1}, {0,4,0,2}, {1,0,4,0}}; + int Meb5[5][4] = {{3,0,0,4}, {0,3,0,0}, {4,0,3,0}, {0,4,0,3}, {0,0,4,0}}; + int Mes5[5][4] = {{3,0,2,2}, {0,3,0,2}, {2,0,3,0}, {2,2,0,3}, {0,2,2,0}}; + int Meb9[5][4] = {{0,2,0,5}, {0,0,2,0}, {5,0,0,2}, {0,5,0,0}, {2,0,5,0}}; + int Mes9[5][4] = {{2,0,0,5}, {0,2,0,0}, {5,0,2,0}, {0,5,0,2}, {0,0,5,0}}; + int Deb5[5][4] = {{3,0,0,3}, {1,3,0,0}, {3,1,3,0}, {0,3,1,3}, {0,0,3,1}}; + int Mes3[5][4] = {{3,0,4,0}, {0,3,0,4}, {0,0,3,0}, {4,0,0,3}, {0,4,0,0}}; + int Deb9[5][4] = {{0,2,0,4}, {1,0,2,0}, {4,1,0,2}, {0,4,1,0}, {2,0,4,1}}; + int De91[5][4] = {{0,2,0,1}, {4,0,2,0}, {1,4,0,2}, {0,1,4,0}, {2,0,1,4}}; + int Des9[5][4] = {{2,0,0,4}, {1,2,0,0}, {4,1,2,0}, {0,4,1,2}, {0,0,4,1}}; + int Ds11[5][4] = {{3,1,0,2}, {1,3,1,0}, {2,1,3,1}, {0,2,1,3}, {1,0,2,1}}; + int m7s1[5][4] = {{2,2,0,2}, {1,2,2,0}, {2,1,2,2}, {0,2,1,2}, {2,0,2,1}}; + int D3s1[5][4] = {{5,0,1,0}, {1,5,0,1}, {0,1,5,0}, {1,0,1,5}, {0,1,0,1}}; + int Mb9s[5][4] = {{0,2,5,0}, {0,0,2,5}, {0,0,0,2}, {5,0,0,0}, {2,5,0,0}}; + int D7b3[5][4] = {{3,2,0,1}, {1,3,2,0}, {1,1,3,2}, {0,1,1,3}, {2,0,1,1}}; + + if (!initialized) { + for (i=0; i<8; i++) + for (j=0; j<8; j++) + for (k=0; k<8; k++) + for (l=0; l<8; l++) { + quintads[i][j][k][l].type = kNone; + quintads[i][j][k][l].rootMember = kXX; + } + + + // major ninths + for (i=0; i<5; i++) { + st = maj9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + t->type = kMaj9; + t->rootMember = i; + } + + // dominant ninths + for (i=0; i<5; i++) { + st = dom9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "dom9"); + t->type = kDom9; + t->rootMember = i; + } + + // minor ninths + for (i=0; i<5; i++) { + st = min9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "min9"); + t->type = kMin9; + t->rootMember = i; + } + + // half diminished ninths + for (i=0; i<5; i++) { + st = had9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "had9"); + t->type = kHalfDim9; + t->rootMember = i; + } + + // minor/major ninths + for (i=0; i<5; i++) { + st = miM9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "miM9"); + t->type = kMinMaj9; + t->rootMember = i; + } + + // diminished/major ninths + for (i=0; i<5; i++) { + st = diM9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "diM9"); + t->type = kDimMaj9; + t->rootMember = i; + } + + // major ninth flat 5 + for (i=0; i<5; i++) { + st = M9b5[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M9b5"); + t->type = kMaj9b5; + t->rootMember = i; + } + + // dominant ninth flat 5 + for (i=0; i<5; i++) { + st = D9b5[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D9b5"); + t->type = kDom9b5; + t->rootMember = i; + } + + // minor/major ninth flat 11 + for (i=0; i<5; i++) { + st = mM91[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "mM91"); + t->type = kmM9b11; + t->rootMember = i; + } + + // major seventh flat nine + for (i=0; i<5; i++) { + st = M7b9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M7b9"); + t->type = kMaj7b9; + t->rootMember = i; + } + + // major seventh sharp five flat nine + for (i=0; i<5; i++) { + st = M5b9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M5b9"); + t->type = kMaj7s5b9; + t->rootMember = i; + } + + // dominant seventh flat nine + for (i=0; i<5; i++) { + st = D7b9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D7b9"); + t->type = kDom7b9; + t->rootMember = i; + } + + // minor seventh flat nine + for (i=0; i<5; i++) { + t = &(quintads[m7b9[i][0]][m7b9[i][1]][m7b9[i][2]][m7b9[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "m7b9"); + t->type = kMin7b9; + t->rootMember = i; + } + + // minor flat nine sharp eleventh + for (i=0; i<5; i++) { + st = mb51[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "mb51"); + t->type = kMinb9s11; + t->rootMember = i; + } + + // half diminished seventh flat nine + for (i=0; i<5; i++) { + st = d7b9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "d7b9"); + t->type = kHalfDimb9; + t->rootMember = i; + } + + // minor/major seventh flat nine + for (i=0; i<5; i++) { + st = mMb9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "mMb9"); + t->type = kMinMajb9; + t->rootMember = i; + } + + // diminished major seventh flat nine + for (i=0; i<5; i++) { + st = dMb9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "dMb9"); + t->type = kDimMajb9; + t->rootMember = i; + } + + // diminished seventh flat nine + for (i=0; i<5; i++) { + t = &(quintads[dib9[i][0]][dib9[i][1]][dib9[i][2]][dib9[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "dib9"); + t->type = kDim7b9; + t->rootMember = i; + } + + // major seventh sharp nine + for (i=0; i<5; i++) { + t = &(quintads[M7s9[i][0]][M7s9[i][1]][M7s9[i][2]][M7s9[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M7s9"); + t->type = kMaj7s9; + t->rootMember = i; + } + + // dominant seventh sharp nine + for (i=0; i<5; i++) { + t = &(quintads[D7s9[i][0]][D7s9[i][1]][D7s9[i][2]][D7s9[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D7s9"); + t->type = kDom7s9; + t->rootMember = i; + } + + // major seventh sharp eleventh + for (i=0; i<5; i++) { + t = &(quintads[M7s1[i][0]][M7s1[i][1]][M7s1[i][2]][M7s1[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M7s1"); + t->type = kMaj7s11; + t->rootMember = i; + } + + // dominant ninth flat thirteenth + for (i=0; i<5; i++) { + st = d9b3[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "d9b3"); + t->type = kDom9b13; + t->rootMember = i; + } + + // major ninth sharp thirteenth + for (i=0; i<5; i++) { + st = M9s3[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M9s3"); + t->type = kMaj9s13; + t->rootMember = i; + } + + // major ninth sharp thirteenth + for (i=0; i<5; i++) { + t = &(quintads[M9st[i][0]][M9st[i][1]][M9st[i][2]][M9st[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M9st"); + t->type = kMaj9s13; + t->rootMember = i; + } + + // major chord sharp ninth sharp eleventh + for (i=0; i<5; i++) { + st = s9s1[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "s9s1"); + t->type = kMs9s11; + t->rootMember = i; + } + + // half diminished seven flat 11 + for (i=0; i<5; i++) { + st = h7b1[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "h7b1"); + t->type = kHDimb11; + t->rootMember = i; + } + + // major eleventh + for (i=0; i<5; i++) { + t = &(quintads[M711[i][0]][M711[i][1]][M711[i][2]][M711[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M711"); + t->type = kMaj11; + t->rootMember = i; + } + + // major eleventh + for (i=0; i<5; i++) { + t = &(quintads[M115[i][0]][M115[i][1]][M115[i][2]][M115[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M711"); + t->type = kMaj11; + t->rootMember = i; + } + + // dominant eleventh + for (i=0; i<5; i++) { + t = &(quintads[d711[i][0]][d711[i][1]][d711[i][2]][d711[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "d711"); + t->type = kDom11; + t->rootMember = i; + } + + // dominant eleventh + for (i=0; i<5; i++) { + t = &(quintads[d712[i][0]][d712[i][1]][d712[i][2]][d712[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "d712"); + t->type = kDom11; + t->rootMember = i; + } + + // dominant eleventh + for (i=0; i<5; i++) { + st = d713[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "d713"); + t->type = kDom11; + t->rootMember = i; + } + + // minor eleventh + for (i=0; i<5; i++) { + t = &(quintads[m711[i][0]][m711[i][1]][m711[i][2]][m711[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "m711"); + t->type = kMin11; + t->rootMember = i; + } + + // minor eleventh + for (i=0; i<5; i++) { + t = &(quintads[m712[i][0]][m712[i][1]][m712[i][2]][m712[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "m712"); + t->type = kMin11; + t->rootMember = i; + } + + // diminished eleventh + for (i=0; i<5; i++) { + st = di11[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "di11"); + t->type = kDim11; + t->rootMember = i; + } + + // minor/major eleventh + for (i=0; i<5; i++) { + st = mM11[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "mM11"); + t->type = kMinMaj11; + t->rootMember = i; + } + + // diminished major eleventh + for (i=0; i<5; i++) { + st = dM11[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "dM11"); + t->type = kDimMaj11; + t->rootMember = i; + } + + // major eleventh flat fifth + for (i=0; i<5; i++) { + st = Meb5[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Meb5"); + t->type = kMaj11b5; + t->rootMember = i; + } + + // major eleventh sharp fifth + for (i=0; i<5; i++) { + st = Mes5[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Mes5"); + t->type = kMaj11s5; + t->rootMember = i; + } + + // major eleventh flat ninth + for (i=0; i<5; i++) { + st = Meb9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Meb9"); + t->type = kMaj11b9; + t->rootMember = i; + } + + // major eleventh sharp ninth + for (i=0; i<5; i++) { + st = Mes9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Mes9"); + t->type = kMaj11s9; + t->rootMember = i; + } + + // major eleventh sharp thirteenth + for (i=0; i<5; i++) { + st = Mes3[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Mes3"); + t->type = kMaj11s13; + t->rootMember = i; + } + + // dominant eleventh flat fifth + for (i=0; i<5; i++) { + st = Deb5[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Deb5"); + t->type = kDom11b5; + t->rootMember = i; + } + + // dominant eleventh flat ninth + for (i=0; i<5; i++) { + st = Deb9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Deb9"); + t->type = kDom11b9; + t->rootMember = i; + } + + // dominant eleventh flat ninth + for (i=0; i<5; i++) { + st = De91[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "De91"); + t->type = kDom11b9; + t->rootMember = i; + } + + // dominant eleventh sharp ninth + for (i=0; i<5; i++) { + st = Des9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Des9"); + t->type = kDom11s9; + t->rootMember = i; + } + + // dominant seventh sharp eleventh + for (i=0; i<5; i++) { + st = Ds11[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Ds11"); + t->type = kDom7s11; + t->rootMember = i; + } + + // minor seventh sharp eleventh + for (i=0; i<5; i++) { + st = m7s1[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "m7s1"); + t->type = kMin7s11; + t->rootMember = i; + } + + // dominant thirteenth sharp eleventh + for (i=0; i<5; i++) { + st = D3s1[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D3s1"); + t->type = kDom13s11; + t->rootMember = i; + } + + // major seventh flat ninth sharp thirteenth + for (i=0; i<5; i++) { + st = Mb9s[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Mb9s"); + t->type = kM7b9s13; + t->rootMember = i; + } + + // dominant seventh flat thirteenth + for (i=0; i<5; i++) { + st = D7b3[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D7b3"); + t->type = kDom7b13; + t->rootMember = i; + } + + initialized = 1; + return; + } + + j = 0; + for (i=0; i<12; i++) + if (x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */ + interval1 = members[1] - members[0]; /* calculate interval between first two members */ + interval2 = members[2] - members[0]; /* calculate interval between first and third */ + interval3 = members[3] - members[0]; /* calculate interval between first and third */ + interval4 = members[4] - members[0]; /* calculate interval between first and fourth */ + interval4 = interval4 - interval3 - 1; /* reduce interval4 to start at zero */ + interval3 = interval3 - interval2 - 1; /* reduce interval3 to start at zero */ + interval2 = interval2 - interval1 - 1; /* reduce interval2 to start at zero */ + interval1 = interval1 - 1; /* reduce interval1 to start at zero */ + + // find TypeRoot struct for this interval set + t = &(quintads[interval1][interval2][interval3][interval4]); + if (t->rootMember != kXX) + { + x->x_chord_type = t->type; + x->x_chord_root = members[t->rootMember]; + switch(t->rootMember) { /* get state of inversion */ + case 0: + x->x_chord_inversion = 0; + break; + case 1: + x->x_chord_inversion = 2; + break; + case 2: + x->x_chord_inversion = 2; + break; + case 3: + x->x_chord_inversion = 2; + break; + case 4: + x->x_chord_inversion = 1; + } + chord_draw_chord_type(x, 5); /* output result */ + } else + chord_kick_out_member(x, 5, members); +} + +static void chord_sextad(t_chord *x) +{ + static int initialized = 0; + static t_type_root sextads[7][7][7][7][7]; + register int i, j, k, l, m; + register t_type_root *t; + register int* st; + t_int members[6]; + int interval1, interval2, interval3, interval4, interval5; + + int D9b3[6][5] = + {{1,1,2,0,1}, {1,1,1,2,0}, {1,1,1,1,2}, {0,1,1,1,1}, {2,0,1,1,1}, {1,2,0,1,1}}; + int m9s1[6][5] = + {{1,0,2,0,2}, {1,1,0,2,0}, {2,1,1,0,2}, {0,2,1,1,0}, {2,0,2,1,1}, {0,2,0,2,1}}; + int M711[6][5] = + {{1,1,0,1,3}, {0,1,1,0,1}, {3,0,1,1,0}, {1,3,0,1,1}, {0,1,3,0,1}, {1,0,1,3,0}}; + int D711[6][5] = + {{1,1,0,1,2}, {1,1,1,0,1}, {2,1,1,1,0}, {1,2,1,1,1}, {0,1,2,1,1}, {1,0,1,2,1}}; + int hd11[6][5] = + {{1,0,1,0,3}, {1,1,0,1,0}, {3,1,1,0,1}, {0,3,1,1,0}, {1,0,3,1,1}, {0,1,0,3,1}}; + int M1b5[6][5] = + {{1,1,0,0,4}, {0,1,1,0,0}, {4,0,1,1,0}, {0,4,0,1,1}, {0,0,4,0,1}, {1,0,0,4,0}}; + int M159[6][5] = + {{0,2,0,0,4}, {0,0,2,0,0}, {4,0,0,2,0}, {0,4,0,0,2}, {0,0,4,0,0}, {2,0,0,4,0}}; + int M1s3[6][5] = + {{1,1,0,4,0}, {0,1,1,0,4}, {0,0,1,1,0}, {4,0,0,1,1}, {0,4,0,0,1}, {1,0,4,0,0}}; + int hd19[6][5] = + {{0,1,1,0,3}, {1,0,1,1,0}, {3,1,0,1,1}, {0,3,1,0,1}, {1,0,3,1,0}, {1,1,0,3,1}}; + int M1b3[6][5] = + {{3,0,1,0,2}, {0,3,0,1,0}, {2,0,3,0,1}, {0,2,0,3,0}, {1,0,2,0,3}, {0,1,0,2,0}}; + int D1b5[6][5] = + {{1,1,0,0,3}, {1,1,1,0,0}, {3,1,1,1,0}, {0,3,1,1,1}, {0,0,3,1,1}, {1,0,0,3,1}}; + int D1s9[6][5] = + {{2,0,0,1,2}, {1,2,0,0,1}, {2,1,2,0,0}, {1,2,1,2,0}, {0,1,2,1,2}, {0,0,1,2,1}}; + int m791[6][5] = + {{0,1,2,0,2}, {1,0,1,2,0}, {2,1,0,1,2}, {0,2,1,0,1}, {2,0,2,1,0}, {1,2,0,2,1}}; + int d7s1[6][5] = + {{1,1,1,0,2}, {1,1,1,1,0}, {2,1,1,1,1}, {0,2,1,1,1}, {1,0,2,1,1}, {1,1,0,2,1}}; + int d3s1[6][5] = + {{3,1,0,1,0}, {1,3,1,0,1}, {0,1,3,1,0}, {1,0,1,3,1}, {0,1,0,1,3}, {1,0,1,0,1}}; + + + if (!initialized) { + for (i=0; i<7; i++) + for (j=0; j<7; j++) + for (k=0; k<7; k++) + for (l=0; l<7; l++) + for (m=0; m<7; m++) { + sextads[i][j][k][l][m].type = kNone; + sextads[i][j][k][l][m].rootMember = kXX; + } + + // dominant ninth flat thirteen + for (i=0; i<6; i++) { + st = D9b3[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D9b3"); + t->type = kDom9b13; + t->rootMember = i; + } + + // minor ninth sharp eleventh + for (i=0; i<6; i++) { + st = m9s1[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "m9s1"); + t->type = kMin9s11; + t->rootMember = i; + } + + // major eleventh + for (i=0; i<6; i++) { + st = M711[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M711"); + t->type = kMaj11; + t->rootMember = i; + } + + // dominant eleventh + for (i=0; i<6; i++) { + st = D711[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D711"); + t->type = kDom11; + t->rootMember = i; + } + + // half diminished eleventh + for (i=0; i<6; i++) { + st = hd11[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "hd11"); + t->type = kHalfDim11; + t->rootMember = i; + } + + // major eleventh flat 5 + for (i=0; i<6; i++) { + st = M1b5[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M1b5"); + t->type = kMaj11b5; + t->rootMember = i; + } + + // major eleventh flat 5 flat 9 + for (i=0; i<6; i++) { + st = M159[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M159"); + t->type = kM11b5b9; + t->rootMember = i; + } + + // major eleventh sharp 13 + for (i=0; i<6; i++) { + st = M1s3[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M1s3"); + t->type = kMaj11s13; + t->rootMember = i; + } + + // half diminished eleventh flat 9 + for (i=0; i<6; i++) { + st = hd19[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "hd19"); + t->type = kHalfDim11b9; + t->rootMember = i; + } + + // major eleventh flat 13 + for (i=0; i<6; i++) { + st = M1b3[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M1b3"); + t->type = kMaj11b13; + t->rootMember = i; + } + + // dominant eleventh flat five + for (i=0; i<6; i++) { + st = D1b5[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D1b5"); + t->type = kDom11b5; + t->rootMember = i; + } + + // dominant eleventh sharp nine + for (i=0; i<6; i++) { + st = D1s9[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D1s9"); + t->type = kDom11s9; + t->rootMember = i; + } + + // minor seventh flat 9 sharp 11 + for (i=0; i<6; i++) { + st = m791[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "m791"); + t->type = kMinb9s11; + t->rootMember = i; + } + + // dominant seventh sharp 11 + for (i=0; i<6; i++) { + st = d7s1[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "d7s1"); + t->type = kDom7s11; + t->rootMember = i; + } + + // dominant thirteenth sharp 11 + for (i=0; i<6; i++) { + st = d3s1[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "d3s1"); + t->type = kDom13s11; + t->rootMember = i; + } + + initialized = 1; + return; + } + + j = 0; + for (i=0; i<12; i++) + if (x->x_pc[i]) members[j++] = i; // load members array with chord pitch classes + interval1 = members[1] - members[0]; // calculate interval between first two members + interval2 = members[2] - members[0]; // calculate interval between first and third + interval3 = members[3] - members[0]; // calculate interval between first and third + interval4 = members[4] - members[0]; // calculate interval between first and fourth + interval5 = members[5] - members[0]; // calculate interval between first and fifth + interval5 = interval5 - interval4 - 1; // reduce interval5 to start at zero + interval4 = interval4 - interval3 - 1; // reduce interval4 to start at zero + interval3 = interval3 - interval2 - 1; // reduce interval3 to start at zero + interval2 = interval2 - interval1 - 1; // reduce interval2 to start at zero + interval1 = interval1 - 1; // reduce interval1 to start at zero + + // find TypeRoot struct for this interval set + t = &(sextads[interval1][interval2][interval3][interval4][interval5]); + if (t->rootMember != kXX) { + x->x_chord_type = t->type; + x->x_chord_root = members[t->rootMember]; + switch(t->rootMember) { /* get state of inversion */ + case 0: + x->x_chord_inversion = 0; + break; + case 1: + x->x_chord_inversion = 2; + break; + case 2: + x->x_chord_inversion = 2; + break; + case 3: + x->x_chord_inversion = 2; + break; + case 4: + x->x_chord_inversion = 2; + break; + case 5: x->x_chord_inversion = 1; + } + chord_draw_chord_type(x, 6); // output onto the screen + } else + chord_kick_out_member(x, 6, members); +} + +static int chord_accidental(t_int pc) +{ + switch (pc) { + case 0: + case 2: + case 4: + case 5: + case 7: + case 9: + case 11: return 0; + case 1: + case 3: + case 6: + case 8: + case 10: + default: return 1; + } +} + +static int chord_name_third(t_chord *x, char* chord, int c, int rootName) +{ + int third = (x->x_chord_root+4)%12; // look for major third + if (x->x_pc[third]) { // if one is there + x->x_pc[third] = 0; // erase from pcs array + chord[c++] = name_class[(rootName+2)%7]; + if (chord_accidental(third)) { // if it has an chord_accidental + // make it a flat if the root also has an chord_accidental + if (chord_accidental(x->x_chord_root)) + chord[c++] = 'b'; + // otherwise make it a sharp + else + chord[c++] = '#'; + } + chord[c++] = ' '; + return c; // return if major third found + } + + third = (x->x_chord_root+3)%12; // no major, look for minor third + if (x->x_pc[third]) { // if one is there + x->x_pc[third] = 0; // erase from pcs array + chord[c++] = name_class[(rootName+2)%7]; + if (chord_accidental(third)) // if it has an chord_accidental + chord[c++] = 'b'; else // make it a flat + if (chord_accidental(x->x_chord_root)) { // if the root has an chord_accidental + chord[c++] = 'b'; // make the third a flat + if (chord[0] == 'G') // if the root is Gb + chord[c++] = 'b'; // this must be Bbb + } + chord[c++] = ' '; + return c; + } + + return c; // if we get here there was no third +} + +static int chord_name_fifth(t_chord *x, char* chord, int c, int rootName) +{ + int fifth = (x->x_chord_root+7)%12; + if (x->x_pc[fifth]) { + x->x_pc[fifth] = 0; + chord[c++] = name_class[(rootName+4)%7]; + if (chord_accidental(fifth)) { + if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; + else chord[c++] = '#'; + } + chord[c++] = ' '; + return c; + } + + fifth = (x->x_chord_root+6)%12; + if (x->x_pc[fifth]) { + x->x_pc[fifth] = 0; + chord[c++] = name_class[(rootName+4)%7]; + if (chord[0] != 'B') chord[c++] = 'b'; + if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; + chord[c++] = ' '; + return c; + } + + fifth = (x->x_chord_root+8)%12; + if (x->x_pc[fifth]) { + x->x_pc[fifth] = 0; + chord[c++] = name_class[(rootName+4)%7]; + if (chord_accidental(fifth)) chord[c++] = '#'; else + if (!chord_accidental(x->x_chord_root)) { + chord[c++] = '#'; + if (chord[0] == 'B') + chord[c++] = '#'; + } + chord[c++] = ' '; + return c; + } + + return c; +} + +static int chord_name_seventh(t_chord *x, char* chord, int c, int rootName) +{ + int seventh = (x->x_chord_root+11)%12; + if (x->x_pc[seventh]) { + x->x_pc[seventh] = 0; + chord[c++] = name_class[(rootName+6)%7]; + if (chord_accidental(seventh)) chord[c++] = '#'; + chord[c++] = ' '; + return c; + } + seventh = (x->x_chord_root+10)%12; + if (x->x_pc[seventh]) { + x->x_pc[seventh] = 0; + chord[c++] = name_class[(rootName+6)%7]; + if (chord_accidental(seventh) || chord_accidental(x->x_chord_root)) + chord[c++] = 'b'; + chord[c++] = ' '; + return c; + } + seventh = (x->x_chord_root+9)%12; + if (x->x_pc[seventh]) { + x->x_pc[seventh] = 0; + chord[c++] = name_class[(rootName+6)%7]; + chord[c++] = 'b'; + if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; else + if (chord_accidental((seventh+1)%12)) chord[c++] = 'b'; + chord[c++] = ' '; + return c; + } + return c; +} + +static int chord_name_ninth(t_chord *x, char* chord, int c, int rootName) +{ + int ninth = (x->x_chord_root+2)%12; + if (x->x_pc[ninth]) { + x->x_pc[ninth] = 0; + chord[c++] = name_class[(rootName+1)%7]; + if (chord_accidental(ninth)) { + if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; + else chord[c++] = '#'; + } + chord[c++] = ' '; + return c; + } + + ninth = (x->x_chord_root+1)%12; + if (x->x_pc[ninth]) { + x->x_pc[ninth] = 0; + chord[c++] = name_class[(rootName+1)%7]; + if (chord_accidental(ninth)) chord[c++] = 'b'; + else { + if (chord_accidental(x->x_chord_root)) { + chord[c++] = 'b'; + if ((x->x_chord_root == 1) || (x->x_chord_root == 6) || (x->x_chord_root == 8)) + chord[c++] = 'b'; + } + } + chord[c++] = ' '; + return c; + } + + ninth = (x->x_chord_root+3)%12; + if (x->x_pc[ninth]) { + x->x_pc[ninth] = 0; + chord[c++] = name_class[(rootName+1)%7]; + if (chord_accidental(ninth)) chord[c++] = '#'; else + if (!chord_accidental(x->x_chord_root)) { + chord[c++] = '#'; + if (chord_accidental((x->x_chord_root+2)%12)) + chord[c++] = '#'; + } + chord[c++] = ' '; + return c; + } + + return c; +} + +static int chord_name_eleventh(t_chord *x, char* chord, int c, int rootName) +{ + int eleventh = (x->x_chord_root+5)%12; + if (x->x_pc[eleventh]) { + x->x_pc[eleventh] = 0; + chord[c++] = name_class[(rootName+3)%7]; + if (chord_accidental(eleventh)) chord[c++] = 'b'; else + if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; + chord[c++] = ' '; + return c; + } + + eleventh = (x->x_chord_root+6)%12; + if (x->x_pc[eleventh]) { + x->x_pc[eleventh] = 0; + chord[c++] = name_class[(rootName+3)%7]; + if (chord_accidental(eleventh)) chord[c++] = '#'; else + if ((!chord_accidental(x->x_chord_root)) && (x->x_chord_root == 11)) + chord[c++] = '#'; + chord[c++] = ' '; + return c; + } + + return c; +} + +static int chord_name_thirteenth(t_chord *x, char* chord, int c, int rootName) +{ + int thirteenth = (x->x_chord_root+9)%12; + if (x->x_pc[thirteenth]) { + x->x_pc[thirteenth] = 0; + chord[c++] = name_class[(rootName+5)%7]; + if (chord_accidental(thirteenth)) { + if (chord_accidental(x->x_chord_root)) + chord[c++] = 'b'; + else + chord[c++] = '#'; + } + + chord[c++] = ' '; + return c; + } + + thirteenth = (x->x_chord_root+10)%12; + if (x->x_pc[thirteenth]) { + x->x_pc[thirteenth] = 0; + chord[c++] = name_class[(rootName+5)%7]; + if (chord_accidental(thirteenth)) chord[c++] = '#'; else + if (!chord_accidental(x->x_chord_root)) { + chord[c++] = '#'; + if (chord_accidental((x->x_chord_root+9)%12)) + chord[c++] = '#'; + } + chord[c++] = ' '; + return c; + } + + thirteenth = (x->x_chord_root+8)%12; + if (x->x_pc[thirteenth]) { + x->x_pc[thirteenth] = 0; + chord[c++] = name_class[(rootName+5)%7]; + if (chord_accidental(thirteenth)) chord[c++] = 'b'; else + if (chord_accidental(x->x_chord_root)) { + chord[c++] = 'b'; + if (chord_accidental(x->x_chord_root+9)%12) + chord[c++] = 'b'; + } + chord[c++] = ' '; + return c; + } + + return c; +} + + + +static void chord_spell_chord(t_chord *x, char *chord, t_int num_pcs) +{ + int rootName = 0; // keep index of root name class + int c = 0; // pointer to current character + int named = 0; // how many members have been named + int mark; + int i; + + // use chordRoot to set rootName index and store characters for name + switch (x->x_chord_root) + { + case 0: chord[c++] = name_class[rootName=0]; break; + case 1: chord[c++] = name_class[rootName=1]; + chord[c++] = 'b'; break; + case 2: chord[c++] = name_class[rootName=1]; break; + case 3: chord[c++] = name_class[rootName=2]; + chord[c++] = 'b'; break; + case 4: chord[c++] = name_class[rootName=2]; break; + case 5: chord[c++] = name_class[rootName=3]; break; + case 6: chord[c++] = name_class[rootName=4]; + chord[c++] = 'b'; break; + case 7: chord[c++] = name_class[rootName=4]; break; + case 8: chord[c++] = name_class[rootName=5]; + chord[c++] = 'b'; break; + case 9: chord[c++] = name_class[rootName=5]; break; + case 10: chord[c++] = name_class[rootName=6]; + chord[c++] = 'b'; break; + case 11: chord[c++] = name_class[rootName=6]; break; + default: break; + } + x->x_pc[x->x_chord_root] = 0; /* set this member to zero */ + + chord[c++] = ' '; // insert space + if (++named == num_pcs) { // if everything is named + chord[c] = '\0'; // terminate the string + return; // and return + } + + mark = c; // use mark to see if new names are added + for (i=0; i<6; i++) { + // advance search by thirds + switch (i) { + case 0: mark = chord_name_third (x, chord, c, rootName); break; + case 1: mark = chord_name_fifth (x, chord, c, rootName); break; + case 2: mark = chord_name_seventh (x, chord, c, rootName); break; + case 3: mark = chord_name_ninth (x, chord, c, rootName); break; + case 4: mark = chord_name_eleventh (x, chord, c, rootName); break; + case 5: mark = chord_name_thirteenth(x, chord, c, rootName); break; + } + if (mark != c) { // if new name is added + ++named; // increment count of named members + c = mark; // update character pointer + } + if (named == num_pcs) { // if everything is named + chord[c] = '\0'; // terminate the string + return; // and return + } + } + + chord[c] = '\0'; +} + + +static void chord_draw_chord_type(t_chord *x, t_int num_pcs) +{ + char chord[255]; /* output string */ + int i, j; + + /* get members of chord */ + j = 0; + for(i = 0; i < 12; i++) + { + if(x->x_pc[i]) + { + SETFLOAT(x->x_chordlist+j, x->x_abs_pc[i]); + j++; + } + } + + if (x->x_chord_type != kNone) + { + chord_spell_chord(x, chord, num_pcs); /* spell chord members */ + } + else + { + post("going..."); + chord[0] = '\0'; + for(i = 0; i < 12; i++) + if (x->x_pc[i]) + strcat(chord, pitch_class[i]); /* output single notes */ + post("did it"); + } + + strcat(chord, ": "); + strcat(chord, pitch_class[x->x_chord_root]); + + /* append name of chord type */ + switch (x->x_chord_type) { + case kUnison: strcat(chord, "unison"); break; + case kMaj: strcat(chord, "major"); break; + case kMin: strcat(chord, "minor"); break; + case kDim: strcat(chord, "diminished"); break; + case kAug: strcat(chord, "augmented"); break; + + case kMaj7: strcat(chord, "major 7th"); break; + case kDom7: strcat(chord, "dominant 7th"); break; + case kMin7: strcat(chord, "minor 7th"); break; + case kHalfDim7: strcat(chord, "half diminished 7th"); break; + case kDim7: strcat(chord, "diminished 7th"); break; + case kMinMaj7: strcat(chord, "minor/major 7th"); break; + + case kMaj7s5: strcat(chord, "major 7th #5"); break; + case kMaj7b5: strcat(chord, "major 7th b5"); break; + case kDom7s5: strcat(chord, "dominant 7th #5"); break; + case kDom7b5: strcat(chord, "dominant 7th b5"); break; + case kDomb9: strcat(chord, "dominant b9"); break; + + case kMaj9: strcat(chord, "major 9th"); break; + case kDom9: strcat(chord, "dominant 9th"); break; + case kMin9: strcat(chord, "minor 9th"); break; + case kHalfDim9: strcat(chord, "half diminished 9th"); break; + case kMinMaj9: strcat(chord, "minor major 9th"); break; + case kDimMaj9: strcat(chord, "diminished major 9th");break; + case kMaj9b5: strcat(chord, "major 9th b5"); break; + case kDom9b5: strcat(chord, "dominant 9th b5"); break; + case kDom9b13: strcat(chord, "dominant 9th b13"); break; + case kMin9s11: strcat(chord, "minor 9th #11"); break; + case kmM9b11: strcat(chord, "minor/maj 9th b11"); break; + + case kMaj7b9: strcat(chord, "major 7th b9"); break; + case kMaj7s5b9: strcat(chord, "major 7th #5 b9"); break; + case kDom7b9: strcat(chord, "dominant 7th b9"); break; + case kMin7b9: strcat(chord, "minor 7th b9"); break; + case kMinb9s11: strcat(chord, "minor b9 #11"); break; + case kHalfDimb9:strcat(chord, "half diminished b9"); break; + case kDim7b9: strcat(chord, "diminished b9"); break; + case kMinMajb9: strcat(chord, "minor/major b9"); break; + case kDimMajb9: strcat(chord, "diminished M7 b9"); break; + + case kMaj7s9: strcat(chord, "major 7th #9"); break; + case kDom7s9: strcat(chord, "dominant #9"); break; + case kMaj7s11: strcat(chord, "major 7th #11"); break; + case kMaj9s13: strcat(chord, "major 9th #13"); break; + case kMs9s11: strcat(chord, "major #9 #11"); break; + case kHDimb11: strcat(chord, "half diminished b11"); break; + + case kMaj11: strcat(chord, "major 11th"); break; + case kDom11: strcat(chord, "dominant 11th"); break; + case kMin11: strcat(chord, "minor 11th"); break; + case kHalfDim11:strcat(chord, "half diminished 11th");break; + case kDim11: strcat(chord, "diminished 11th"); break; + case kMinMaj11: strcat(chord, "minor/major 11th"); break; + case kDimMaj11: strcat(chord, "diminished maj 11th"); break; + + case kMaj11b5: strcat(chord, "major 11th b5"); break; + case kMaj11s5: strcat(chord, "major 11th #5"); break; + case kMaj11b9: strcat(chord, "major 11th b9"); break; + case kMaj11s9: strcat(chord, "major 11th #9"); break; + case kMaj11b13: strcat(chord, "major 11th b13"); break; + case kMaj11s13: strcat(chord, "major 11th #13"); break; + case kM11b5b9: strcat(chord, "major 11th b5 b9"); break; + case kDom11b5: strcat(chord, "dominant 11th b5"); break; + case kDom11b9: strcat(chord, "dominant 11th b9"); break; + case kDom11s9: strcat(chord, "dominant 11th #9"); break; + case kHalfDim11b9:strcat(chord, "half dim 11th b9"); break; + case kDom7s11: strcat(chord, "dominant #11"); break; + case kMin7s11: strcat(chord, "minor 7th #11"); break; + + case kDom13s11: strcat(chord, "dominant 13th #11"); break; + case kM7b913: strcat(chord, "major 7 b9 13"); break; + case kMaj7s13: strcat(chord, "major 7th #13"); break; + case kM7b9s13: strcat(chord, "major 7 b9 #13"); break; + case kDom7b13: strcat(chord, "dominant 7th b13"); break; + case kChrom: strcat(chord, "chromatic"); break; + case kNone: + default: strcat(chord, "unknown"); break; + } + + x->x_chord_bass = x->x_abs_pc[x->x_chord_root]; /* get MIDI note number of bass */ + + /* output results */ + outlet_list(x->x_outchordnotes, NULL, j, x->x_chordlist); + outlet_float(x->x_outchordinversion, x->x_chord_inversion); + outlet_symbol(x->x_outchordname, gensym(chord)); + outlet_float(x->x_outchordclass, x->x_chord_root); + outlet_float(x->x_outchordval, x->x_chord_bass); +} + +static void chord_kick_out_member(t_chord *x, t_int number, t_int *members) +{ + int *distances; + int minDistance = 1000; + int badMember = 0; + int i, j, interval; + + distances = getbytes(number*sizeof(int)); + + for (i=0; i 6) interval = 12 - interval; + // add absolute interval size to total + distances[i] += interval; + } + + // if this is the smallest total distance + if (distances[i] < minDistance) { + // remember it + minDistance = distances[i]; + badMember = i; + } + } + freebytes(distances, number * sizeof(int)); + x->x_pc[members[badMember]] = 0; // cancel out most dissonant member + chord_chord_finder(x, number-1); // call chord finder again without it + x->x_pc[members[badMember]] = 1; // replace most dissonant member +} + +static void chord_chord_finder(t_chord *x, t_int num_pcs) +{ + int i; + x->x_chord_type = kNone; + x->x_chord_root = kXX; /* none */ + switch (num_pcs) { + case 1: chord_unison(x); break; + case 2: chord_dyad(x); break; + case 3: chord_triad(x); break; + case 4: chord_quartad(x); break; + case 5: chord_quintad(x); break; + case 6: chord_sextad(x); break; + default: x->x_chord_type = kChrom; + for(i = 0; i < 12; i++) // 12 was num_pcs !? + { + if(x->x_pc[i]) + { + x->x_chord_root = i; + break; + } + } + } +} + +static void chord_float(t_chord *x, t_floatarg f) +{ + t_int velo = x->x_velo; + t_int allloc = 0; + t_int num_pc = 0; /* number of pitch classes present */ + int i, j, k, l; + + x->x_pitch = (t_int)f; + + if(x->x_pitch <= x->x_split) + { + /* first we need to put the note into the allocation table */ + if(velo == 0) /* got note-off: remove from allocation table */ + { + if(x->x_poly > 0)x->x_poly--; /* polyphony has decreased by one */ + for(i = 0; i < MAX_POLY; i++) /* search for voice allocation number */ + { + /* search for corresponding alloc number */ + if(x->x_alloctable[i] == x->x_pitch) + { + x->x_alloctable[i] = -1; /* free the alloc number */ + break; + } + /* couldn't find it ? */ + if(i == MAX_POLY - 1) + { + post("chord: no corresponding note-on found (ignored)"); + return; + } + } + return; /* no need to look for chord */ + } + else /* we got a note-on message */ + { + if(x->x_poly == MAX_POLY) + { + post("chord: too many note-on messages (ignored)"); + return; + } + + x->x_poly++; /* number of currently playing notes has increased */ + /* assign a voice allocation number */ + for(i = 0; i < MAX_POLY; i++) + { + /* search for free alloc number */ + if(x->x_alloctable[i] == -1) + { + x->x_alloctable[i] = x->x_pitch; /* ... and store pitch */ + break; + } + } + /* copy all notes into the pitch class array */ + for(i = 0; i < 12; i++) + { + x->x_pc[i] = 0; /* empty pitch class */ + x->x_abs_pc[i] = -1; /* empty absolute values */ + } + for(i = 0; i < MAX_POLY; i++) + { + /* check for presence of pitch class */ + if(x->x_alloctable[i] != -1) + { + if(!x->x_pc[x->x_alloctable[i]%12]) /* a new pitch class */ + { + x->x_abs_pc[x->x_alloctable[i]%12] = x->x_alloctable[i]; + } + else if(x->x_abs_pc[x->x_alloctable[i]%12] > x->x_alloctable[i]) /* remember lowest pitch */ + { + x->x_abs_pc[x->x_alloctable[i]%12] = x->x_alloctable[i]; + } + + x->x_pc[x->x_alloctable[i]%12] = 1; /* indicate presence of pc */ + } + } + /* count number of pitch classes */ + for(i = 0; i < 12; i++) + { + num_pc += x->x_pc[i]; + } + // post("%d pitch classes", num_pc); + } + } + + chord_chord_finder(x, num_pc); +} + +static void chord_ft1(t_chord *x, t_floatarg f) +{ + x->x_velo = (t_int)f; +} + +static t_class *chord_class; + +static void *chord_new(t_floatarg f) +{ + int i; + t_chord *x = (t_chord *)pd_new(chord_class); + inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); + x->x_outchordval = outlet_new(&x->x_ob, gensym("float")); + x->x_outchordclass = outlet_new(&x->x_ob, gensym("float")); + x->x_outchordname = outlet_new(&x->x_ob, gensym("symbol")); + x->x_outchordinversion = outlet_new(&x->x_ob, gensym("float")); + x->x_outchordnotes = outlet_new(&x->x_ob, gensym("float")); + + x->x_split = (t_int)f; + if(x->x_split == 0)x->x_split = 128; + for(i = 0; i < MAX_POLY; i++)x->x_alloctable[i] = -1; + + return (void *)x; +} + +#ifndef MAXLIB +void chord_setup(void) +{ + chord_class = class_new(gensym("chord"), (t_newmethod)chord_new, + 0, sizeof(t_chord), 0, A_DEFFLOAT, 0); +#else +void maxlib_chord_setup(void) +{ + chord_class = class_new(gensym("maxlib_chord"), (t_newmethod)chord_new, + 0, sizeof(t_chord), 0, A_DEFFLOAT, 0); +#endif + class_addfloat(chord_class, chord_float); + class_addmethod(chord_class, (t_method)chord_ft1, gensym("ft1"), A_FLOAT, 0); +#ifndef MAXLIB + + logpost(NULL, 4, version); +#else + class_addcreator((t_newmethod)chord_new, gensym("chord"), A_DEFFLOAT, 0); + class_sethelpsymbol(chord_class, gensym("maxlib/chord-help.pd")); +#endif +} + -- cgit v1.2.1