// // Programmer: Craig Stuart Sapp // Creation Date: Mon Jun 24 20:05:15 PDT 2002 // Last Modified: Wed Jul 10 13:50:11 PDT 2002 // Filename: ...sig/examples/all/chordplot.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/chordplot.cpp // Syntax: C++; museinfo // // Description: Determine the root of a pitch set according to // different root-interval class sizes. // #define MYPI 3.141592653589793238462643383279 #include "humdrum.h" #include #include // function declarations void checkOptions (Options& opts, int argc, char* argv[]); void example (void); void usage (const char* command); void printScores (Array& rootscores); int analyzeChromatic (Array& rootscores, HumdrumFile& infile, double theta1, double theta2, int startline, int stopline, int debugQ = 0); double base40ToBase7 (int pitch); char base7pcToName (int value); void identifyErrorsChromatic (HumdrumFile& infile, int type, int debugQ); void getDistancesChromatic1 (Array& distances, double theta); void getDistancesChromatic2 (Array& distances, double theta1, double theta2); // global variables Options options; // database for command-line arguments int debugQ = 0; // used with --debug option int appendQ = 0; // used with -a option int rootQ = 0; // used with -R option double theta1 = 60.0; // used with -t option double theta2 = 60.0; // used with -u option int invertQ = 0; // used with -i option int distanceQ = 0; // used with -d option int notesQ = 0; // used with -n option /////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { HumdrumFile infile; // process the command-line options checkOptions(options, argc, argv); infile.clear(); // if no command-line arguments read data file from standard input if (options.getArgCount() < 1) { infile.read(cin); } else { infile.read(options.getArg(1)); } if (errorsQ) { if (options.getBoolean("theta2")) { identifyErrorsChromatic(infile, 2, debugQ); } else { identifyErrorsChromatic(infile, 1, debugQ); } } else { //if (options.getBoolean("theta2")) { // analyzeChromatic(rootscores, infile, theta1, theta2, 0, 0, -1, debugQ); // printScores(rootscores); //} else { // analyzeChromatic(rootscores, infile, theta1, theta2, 0, 0, -1, debugQ); // printScores(rootscores); //} } return 0; } /////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // findErrorsX -- compare root scores value to root in data. // void findErrorsX(HumdrumFile& infile, int debugQ) { int oldline = 0; int init = 0; int best; int correct = 0; int i; int j; Array rootscores(7); rootscores.setAll(0); for (i=0; i rootscores(40); rootscores.setAll(0); for (i=0; i& rootscores, HumdrumFile& infile, double t1, double t2, int startline, int stopline, int root, int debugQ) { // p1 = perfect 5th distance static int p1[40] = { 6, /* C-- */ 5, /* C- */ 0, /* C */ 4, /* C# */ 5, /* C## */ 10000, /* X */ 4, /* D-- */ 3, /* D- */ 2, /* D */ 3, /* D# */ 4, /* D## */ 10000, /* X */ 6, /* E-- */ 1, /* E- */ 1, /* E */ 5, /* E# */ 6, /* E## */ 5, /* F-- */ 4, /* F- */ 3, /* F */ 3, /* F# */ 4, /* F## */ 10000, /* X */ 7, /* G-- */ 2, /* G- */ 1, /* G */ 2, /* G# */ 6, /* G## */ 10000, /* X */ 5, /* A-- */ 4, /* A- */ 3, /* A */ 4, /* A# */ 5, /* A## */ 10000, /* X */ 3, /* B-- */ 2, /* B- */ 2, /* B */ 3, /* B# */ 7 /* B## */ }; // p2 = major or minor third distance; negative are for majors static int p2[40] = { -5, /* C-- */ -3, /* C- */ 0, /* C */ 1, /* C# */ 3, /* C## */ 10000, /* X */ -4, /* D-- */ -2, /* D- */ 0, /* D */ 2, /* D# */ 4, /* D## */ 10000, /* X */ -4, /* E-- */ -1, /* E- */ 1, /* E */ 2, /* E# */ 4, /* E## */ -5, /* F-- */ -3, /* F- */ -1, /* F */ 1, /* F# */ 3, /* F## */ 10000, /* X */ -5, /* G-- */ -2, /* G- */ 0, /* G */ 2, /* G# */ 3, /* G## */ 10000, /* X */ -4, /* A-- */ -2, /* A- */ 0, /* A */ 2, /* A# */ 4, /* A## */ 10000, /* X */ -3, /* B-- */ -1, /* B- */ 1, /* B */ 3, /* B# */ 4 /* B## */ }; // p3 = theta 1 or theta 2 static double p3[40] = { 1, /* C-- */ 1, /* C- */ 0, /* C */ 2, /* C# */ 2, /* C## */ 10000, /* X */ 1, /* D-- */ 1, /* D- */ 0, /* D */ 2, /* D# */ 2, /* D## */ 10000, /* X */ 1, /* E-- */ 1, /* E- */ 2, /* E */ 2, /* E# */ 2, /* E## */ 1, /* F-- */ 1, /* F- */ 1, /* F */ 2, /* F# */ 2, /* F## */ 10000, /* X */ 1, /* G-- */ 1, /* G- */ 0, /* G */ 2, /* G# */ 2, /* G## */ 10000, /* X */ 1, /* A-- */ 1, /* A- */ 0, /* A */ 2, /* A# */ 2, /* A## */ 10000, /* X */ 1, /* B-- */ 1, /* B- */ 2, /* B */ 2, /* B# */ 2 /* B## */ }; // convert thetas to radians: theta1 = t1 * MYPI / 180.0; theta2 = t2 * MYPI / 180.0; int i; double theta; double avalue; double bvalue = 0.0; double distance[40]; for (i=0; i<40; i++) { avalue = p1[i] * sin(MYPI - theta1 - theta2)/sin(theta2); if (p2[i] < 0) { bvalue = -p2[i]; } else { bvalue = p2[i] * sin(theta1)/sin(theta2); } if (p3[i] == 1) { theta = theta1; } else if (p3[i] == 2) { theta = theta2; } else if (p3[i] == 0) { theta = 0; } else { theta = MYPI; } distance[i] = sqrt(avalue * avalue + bvalue * bvalue - 2.0 * avalue * bvalue * cos(theta)); } if (distanceQ) { char buffer[64] = {0}; cout << "# theta1 = " << theta1 * 180.0 / MYPI << "\n"; cout << "# theta2 = " << theta2 * 180.0 / MYPI << "\n"; for (i=0; i<40; i++) { cout << Convert::base40ToKern(buffer, i+4*40); cout << "\t" << distance[i] << "\n"; } exit(0); } // extract note data Array absbeat; Array pitches; Array durations; Array levels; infile.getNoteArray(absbeat, pitches, durations, levels, startline, stopline); char buffer[64] = {0}; if (debugQ) { cout << "====================" << endl; for (i=startline; i<=stopline; i++) { cout << infile[i] << "\n"; } cout << "--------------------" << endl; cout << "Start line=" << startline+1 << "\tEnd line=" << stopline+1 << endl; for (i=0; i& distances, double theta1, double theta2) { // p1 = perfect 5th distance static int p1[40] = { 6, /* C-- */ 5, /* C- */ 0, /* C */ 4, /* C# */ 5, /* C## */ 10000, /* X */ 4, /* D-- */ 3, /* D- */ 2, /* D */ 3, /* D# */ 4, /* D## */ 10000, /* X */ 6, /* E-- */ 1, /* E- */ 1, /* E */ 5, /* E# */ 6, /* E## */ 5, /* F-- */ 4, /* F- */ 3, /* F */ 3, /* F# */ 4, /* F## */ 10000, /* X */ 7, /* G-- */ 2, /* G- */ 1, /* G */ 2, /* G# */ 6, /* G## */ 10000, /* X */ 5, /* A-- */ 4, /* A- */ 3, /* A */ 4, /* A# */ 5, /* A## */ 10000, /* X */ 3, /* B-- */ 2, /* B- */ 2, /* B */ 3, /* B# */ 7 /* B## */ }; // p2 = major or minor third distance; negative are for majors static int p2[40] = { -5, /* C-- */ -3, /* C- */ 0, /* C */ 1, /* C# */ 3, /* C## */ 10000, /* X */ -4, /* D-- */ -2, /* D- */ 0, /* D */ 2, /* D# */ 4, /* D## */ 10000, /* X */ -4, /* E-- */ -1, /* E- */ 1, /* E */ 2, /* E# */ 4, /* E## */ -5, /* F-- */ -3, /* F- */ -1, /* F */ 1, /* F# */ 3, /* F## */ 10000, /* X */ -5, /* G-- */ -2, /* G- */ 0, /* G */ 2, /* G# */ 3, /* G## */ 10000, /* X */ -4, /* A-- */ -2, /* A- */ 0, /* A */ 2, /* A# */ 4, /* A## */ 10000, /* X */ -3, /* B-- */ -1, /* B- */ 1, /* B */ 3, /* B# */ 4 /* B## */ }; // p3 = theta 1 or theta 2 static double p3[40] = { 1, /* C-- */ 1, /* C- */ 0, /* C */ 2, /* C# */ 2, /* C## */ 10000, /* X */ 1, /* D-- */ 1, /* D- */ 0, /* D */ 2, /* D# */ 2, /* D## */ 10000, /* X */ 1, /* E-- */ 1, /* E- */ 2, /* E */ 2, /* E# */ 2, /* E## */ 1, /* F-- */ 1, /* F- */ 1, /* F */ 2, /* F# */ 2, /* F## */ 10000, /* X */ 1, /* G-- */ 1, /* G- */ 0, /* G */ 2, /* G# */ 2, /* G## */ 10000, /* X */ 1, /* A-- */ 1, /* A- */ 0, /* A */ 2, /* A# */ 2, /* A## */ 10000, /* X */ 1, /* B-- */ 1, /* B- */ 2, /* B */ 2, /* B# */ 2 /* B## */ }; // convert thetas to radians: theta1 = theta1 * MYPI / 180.0; theta2 = theta2 * MYPI / 180.0; int i; double theta; double avalue; double bvalue = 0.0; distance.setSize(40); for (i=0; i<40; i++) { avalue = p1[i] * sin(MYPI - theta1 - theta2)/sin(theta2); if (p2[i] < 0) { bvalue = -p2[i]; } else { bvalue = p2[i] * sin(theta1)/sin(theta2); } if (p3[i] == 1) { theta = theta1; } else if (p3[i] == 2) { theta = theta2; } else if (p3[i] == 0) { theta = 0; } else { theta = MYPI; } distance[i] = sqrt(avalue * avalue + bvalue * bvalue - 2.0 * avalue * bvalue * cos(theta)); } if (distanceQ) { char buffer[64] = {0}; cout << "# theta1 = " << theta1 * 180.0 / MYPI << "\n"; cout << "# theta2 = " << theta2 * 180.0 / MYPI << "\n"; for (i=0; i<40; i++) { cout << Convert::base40ToKern(buffer, i+4*40); cout << "\t" << distance[i] << "\n"; } exit(0); } }