// // Programmer: Craig Stuart Sapp // Creation Date: Tue Jan 16 11:25:31 PST 2001 // Last Modified: Mon Jan 29 14:02:45 PST 2001 // Last Modified: Fri Feb 2 12:05:51 PST 2001 (added weights display) // Last Modified: Tue Feb 6 19:13:51 PST 2001 (fixed -r option for large dur) // Last Modified: Wed Mar 21 13:31:19 PST 2001 (duration normalization added) // Filename: ...sig/examples/all/croot.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/croot.cpp // Syntax: C++; museinfo // // Description: determine the root of a chord in a given timespan. // #include "humdrum.h" #include #include // function declarations void checkOptions (Options& opts, int argc, char* argv[]); void example (void); void usage (const char* command); void printAnalysis (HumdrumFile& infile, Array& rootanalysis, Array& rootscores, double duration); void generateAnalysis (HumdrumFile& infile, Array& rootanalysis, Array& rootscores, double duration); // global variables Options options; // database for command-line arguments int debugQ = 0; // used with the --debug option int rawQ = 0; // used with the --raw option int appendQ = 0; // used with the -a option int compoundQ = 1; // used with the -c option double rval = 1.0; // used with the -r option double rlevel = 1.0; // used with the -r option double duration = 1.0; // used with the -r option int srhythm = 4; // used with the -r option double empirical1 = -4; // used with the --e1 option double empirical2 = -3; // used with the --e2 option double sx = 0.578; // used with the --sx option double sy = 1.0; // used with the --sx option int octave = -1; // used with the -o option int weightsQ = 0; // used with the -w option /////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { HumdrumFile infile; // process the command-line options checkOptions(options, argc, argv); // figure out the number of input files to process int numinputs = options.getArgCount(); Array rootanalysis; // roots analysed at various times Array rootbeat; // absolute start beat of root Array rootscores; // score of best root for (int i=0; i& rootanalysis, Array& rootscores, double duration) { char buffer[1024] = {0}; int i; double fraction; int oldlocation = -1; int location; int n, m; if (rawQ) { for (i=0; i 0) { cout << "beat: " << i * duration << "\t= " << Convert::base40ToKern(buffer, rootanalysis[i]) << ",\tscore = " << rootscores[i] << endl; } else { cout << "beat: " << i * duration << "\t= " << "rest" << "\tscore = " << 0 << endl; } } } else { for (i=0; i 0.999) { fraction = 0.0; } if (location - oldlocation > 1 && oldlocation > 0) { for (n=1; n 0) { cout << Convert::base40ToKern(buffer, rootanalysis[oldlocation + n]); } else { cout << "r"; } if (weightsQ) { cout << "\t" << rootscores[oldlocation + n]; } cout << "\n"; } } oldlocation = location; cout << infile[i].getLine(); cout << "\t"; if (fraction < 0.001) { cout << Convert::durationToKernRhythm(buffer, duration); if (rootanalysis[location] > 0) { cout << Convert::base40ToKern(buffer, rootanalysis[location]); } else { cout << "r"; } } else { cout << "."; } if (weightsQ && fraction < 0.001) { cout << "\t" << rootscores[location]; } else if (weightsQ) { cout << "\t."; } cout << "\n"; break; case E_humrec_data_measure: fraction = fabs(infile[i].getAbsBeat()/duration); location = (int)fraction; fraction = fraction - (int)fraction; if (fraction > 0.999) { fraction = 0.0; } if (location - oldlocation > 1 && oldlocation > 0) { for (n=1; n 0) { cout << Convert::base40ToKern(buffer, rootanalysis[oldlocation + n]); } else { cout << "r"; } if (weightsQ) { cout << "\t" << rootscores[oldlocation + n]; } cout << "\n"; } } oldlocation = location - 1; cout << infile[i].getLine(); cout << "\t" << infile[i][0]; if (weightsQ) { cout << "\t" << infile[i][0]; } cout << "\n"; break; case E_humrec_data_comment: cout << infile[i].getLine(); if (infile[i].equalFieldsQ()) { cout << "\t" << infile[i][0]; } else { cout << "\t!"; } if (weightsQ && infile[i].equalFieldsQ()) { cout << "\t" << infile[i][0]; } else if (weightsQ) { cout << "\t!"; } cout << "\n"; break; case E_humrec_data_interpretation: cout << infile[i].getLine(); if (strncmp(infile[i][0], "**", 2) == 0) { cout << "\t**kern"; if (weightsQ) { cout << "\t**weight"; } cout << "\n"; } else { if (infile[i].equalFieldsQ()) { cout << "\t" << infile[i][0]; } else { cout << "\t*"; } if (weightsQ && infile[i].equalFieldsQ()) { cout << "\t" << infile[i][0]; } else if (weightsQ) { cout << "\t*"; } cout << "\n"; } break; case E_humrec_global_comment: case E_humrec_bibliography: case E_humrec_none: case E_humrec_empty: default: fraction = fabs(infile[i].getAbsBeat()/duration); location = (int)fraction; fraction = fraction - (int)fraction; if (fraction > 0.999) { fraction = 0.0; } if (location - oldlocation > 1 && oldlocation > 0) { for (n=1; n 0) { cout << Convert::base40ToKern(buffer, rootanalysis[oldlocation + n]); } else { cout << "r"; } if (weightsQ) { cout << "\t" << rootscores[oldlocation + n]; } cout << "\n"; } } oldlocation = location - 1; cout << infile[i].getLine() << "\n"; } } } } ////////////////////////////// // // generateAnalysis -- analyze the roots of the chords // void generateAnalysis(HumdrumFile& infile, Array& rootanalysis, Array& rootscores, double duration) { infile.analyzeRhythm("4"); // force the beat to be quarter notes for now Array rhylev; infile.analyzeMetricLevel(rhylev); Array tonicscores; int most = 0; Array values; values.setSize(0); double startbeat = 0.0; double endbeat = 0.0; double totaldur = infile.getTotalDuration(); int size = (int)(totaldur/duration); int nextroot = 0; int lastroot = 0; int i; rootscores.setSize(size); rootscores.setSize(0); rootanalysis.setSize(size); rootanalysis.setSize(0); char buffer[128] = {0}; for (i=0; i