// // Programmer: Craig Stuart Sapp // Creation Date: Thu Sep 26 11:29:58 PDT 2013 // Last Modified: Thu Sep 26 11:30:01 PDT 2013 // Filename: ...sig/examples/all/strong.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/strong.cpp // Syntax: C++; museinfo // // Description: Marks strong rhythmic positions (beats). // // Mensurations: // // Usually semibreve (=whole-note) beat, but occasionally breve beat: // 13438 *met(C|) MenCutC // // Dotted-Semibreve beat: // 3828 *met(O) MenCircle // 521 *met(O|) MenCutCircle // 319 *met(O/3) MenCircleOver3 // 23 *met(O|3/2) MenCutCircle3Over2 // // Semibreve beat: // 1888 *met(3) Men3 [except in cases where 3 follows a // sign other than Cut-C] // 1307 *met(C2) MenC2 // 1169 *met(C) MenC // 282 *met(C|3) MenCutC3 // 42 *met(3/2) Men3Over2 // 18 *met(C|/3) MenCutCOver3 // // Dotted-Breve beat: // 246 *met(O2) MenCircle2 // // Breve beat: // 50 *met(C|2) MenCutC2 // 40 *met(2) Men2 // 11 *met(Cr) MenReverseC // // Dotted-whole-note beat: // 175 *met(C3) MenC3 // 124 *met(O.) MenCircleDot // 114 *met(C.) MenCDot // 18 *met(C.|) MenCutCDot // // Where are these? // 10 *met(O3) MenCircle3 // 30 *met(O|3) MenCutCircle3 // 12 *met(C|/2) MenCutCOver2 // #include "humdrum.h" #include #include #include #ifndef OLDCPP #include #define SSTREAM stringstream #define CSTRING str().c_str() using namespace std; #else #ifdef VISUAL #include /* for windows 95 */ #else #include #endif #define SSTREAM strstream #define CSTRING str() #endif #include // function declarations void checkOptions (Options& opts, int argc, char* argv[]); void example (void); void usage (const char* command); void processFile (HumdrumFile& infile, const string& filename); void calculateBeats (Array& beats, HumdrumFile& infile); void markBeats (HumdrumFile& infile, Array& beats); // global variables Options options; // database for command-line arguments int restQ = 1; // used with -R option int sustainQ = 1; // used with -S option /////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { checkOptions(options, argc, argv); HumdrumStream streamer(options); HumdrumFile infile; while (streamer.read(infile)) { processFile(infile, infile.getFileName()); } return 0; } /////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // processFile -- // void processFile(HumdrumFile& infile, const string& filename) { infile.analyzeRhythm("4"); Array beats; calculateBeats(beats, infile); markBeats(infile, beats); cout << infile; cout << "!!!RDF**kern: @ = matched note, color=\"#ff0000\"\n"; } ////////////////////////////// // // markBeats -- // void markBeats(HumdrumFile& infile, Array& beats) { int i, j; SigString buffer; for (i=0; i& beats, HumdrumFile& infile) { PerlRegularExpression pre; beats.setSize(infile.getNumLines()); beats.setAll(0); int i; // int measurenumber = 0; int tempmeasurenum = 0; int topnum; int botnum, botnum2; RationalNumber measuretime(0); RationalNumber currenttime(0); RationalNumber beatsize(1); RationalNumber diff(0); for (i=0; i= 0) { // measurenumber = tempmeasurenum; } measuretime = infile[i].getAbsBeatR(); } // This code assumes that the first spine in the // Humdrum file is a **kern spine. Won't work // otherwise, but should almost always be true. if (infile[i].isInterpretation() && infile[i].isTimeSig(0)) { if (!infile[i].equalFieldsQ("**kern")) { continue; } if (pre.search(infile[i][0], "^\\*M(\\d+)/(\\d+)%(\\d+)")) { topnum = atoi(pre.getSubmatch(1)); botnum = atoi(pre.getSubmatch(2)); botnum2 = atoi(pre.getSubmatch(3)); beatsize.setValue(botnum2, botnum); beatsize *= 4; // set units to quarter notes if ((topnum % 3 == 0) && (topnum > 3)) { beatsize *= 3; } } else if (pre.search(infile[i][0], "^\\*M(\\d+)/(\\d+)")) { topnum = atoi(pre.getSubmatch(1)); botnum = atoi(pre.getSubmatch(2)); beatsize.setValue(1, botnum); beatsize *= 4; // set units to quarter notes if ((topnum % 3 == 0) && (topnum > 3)) { beatsize *= 3; } } } else if (infile[i].isGlobalComment()) { int num1, num2; if (pre.search(infile[i][0], "!!beat:\\s*(\\d+)")) { num1 = atoi(pre.getSubmatch(1)); if (pre.search(infile[i][0], "!!beat:\\s*(\\d+)%(\\d+)")) { num2 = atoi(pre.getSubmatch(2)); beatsize.setValue(num2, num1); } else { beatsize.setValue(1, num1); } } if (!pre.search(infile[i][0], "!!primary-mensuration:\\s*met\\(([^\\)]+)\\)")) { continue; } // Dotted-semibreve (dotted wholenote) beat: if (strcmp(pre.getSubmatch(1), "O") == 0) { beatsize.setValue(3,2); // 3828 *met(O) MenCircle } else if (strcmp(pre.getSubmatch(), "O|") == 0) { beatsize.setValue(3,2); // 521 *met(O|) MenCutCircle } else if (strcmp(pre.getSubmatch(), "O/3") == 0) { beatsize.setValue(3,2); // 319 *met(O/3) MenCircleOver3 } else if (strcmp(pre.getSubmatch(), "O|3/2") == 0) { beatsize.setValue(3,2); // 23 *met(O|3/2) MenCutCircle3Over2 } else if (strcmp(pre.getSubmatch(), "3") == 0) { // This mensuration sign is dependent on the previous // mensuration. beatsize *= 3; // 1888 *met(3) Men 3 beatsize /= 2; } // Semibreve (whole note) beat: else if (strcmp(pre.getSubmatch(), "C2") == 0) { beatsize.setValue(1,1); // 1307 *met(C2) MenC2 } else if (strcmp(pre.getSubmatch(), "C") == 0) { beatsize.setValue(1,1); // 1169 *met(C) MenC } else if (strcmp(pre.getSubmatch(), "C|3") == 0) { beatsize.setValue(1,1); // 282 *met(C|3) MenCutC3 } // Triplet Semibreve (triplet whole note) beat: else if (strcmp(pre.getSubmatch(), "2/3") == 0) { beatsize.setValue(3,2); // 42 *met(3/2) Men3Over2 } else if (strcmp(pre.getSubmatch(), "C|/3") == 0) { beatsize.setValue(3,2); // 18 *met(C|/3) MenCutCOver3 } // Dotted breve (dotted double wholenote) beat: else if (strcmp(pre.getSubmatch(), "O2") == 0) { beatsize.setValue(3,1); // 246 *met(O2) MenCircle2 } // Breve beat (double wholenote) beat: else if (strcmp(pre.getSubmatch(), "C|2") == 0) { beatsize.setValue(2,1); // 50 *met(O2) MenCutC2 } else if (strcmp(pre.getSubmatch(), "2") == 0) { beatsize.setValue(2,1); // 40 *met(2) Men2 } else if (strcmp(pre.getSubmatch(), "Cr") == 0) { beatsize.setValue(2,1); // 11 *met(Cr) MenReverseC } // Dotted semibreve (dotted wholenote) beat: else if (strcmp(pre.getSubmatch(), "C3") == 0) { beatsize.setValue(2,1); // 175 *met(C3) MenC3 } else if (strcmp(pre.getSubmatch(), "O.") == 0) { beatsize.setValue(2,1); // 124 *met(O.) MenCircleDot } else if (strcmp(pre.getSubmatch(), "C.") == 0) { beatsize.setValue(2,1); // 114 *met(C.) MenCDot } else if (strcmp(pre.getSubmatch(), "C.|") == 0) { beatsize.setValue(2,1); // 114 *met(C.|) MenCutCDot } // Where are these? // 10 *met(O3) MenCircle3 // 30 *met(O|3) MenCutCircle3 // 12 *met(C|/2) MenCutCOver2 } beats[i] = (infile[i].getAbsBeatR() - measuretime) / beatsize; // deal with primary mensurations here. } } ////////////////////////////// // // checkOptions -- validate and process command-line options. // void checkOptions(Options& opts, int argc, char* argv[]) { opts.define("R|no-rest|no-rests=b", "don't mark rests"); opts.define("S|no-sustain|no-sustains=b", "don't mark sustains"); opts.define("debug=b"); // determine bad input line num opts.define("author=b"); // author of program opts.define("version=b"); // compilation info opts.define("example=b"); // example usages opts.define("h|help=b"); // short description opts.process(argc, argv); // handle basic options: if (opts.getBoolean("author")) { cout << "Written by Craig Stuart Sapp, " << "craig@ccrma.stanford.edu, Sept 2013" << endl; exit(0); } else if (opts.getBoolean("version")) { cout << argv[0] << ", version: 27 Sept 2013" << endl; cout << "compiled: " << __DATE__ << endl; cout << MUSEINFO_VERSION << endl; exit(0); } else if (opts.getBoolean("help")) { usage(opts.getCommand().c_str()); exit(0); } else if (opts.getBoolean("example")) { example(); exit(0); } restQ = !opts.getBoolean("no-rests"); sustainQ = !opts.getBoolean("no-sustains"); } ////////////////////////////// // // example -- example usage of the quality program // void example(void) { cout << " \n" << endl; } ////////////////////////////// // // usage -- gives the usage statement for the meter program // void usage(const char* command) { cout << " \n" << endl; } // md5sum: 4e54dffe197d2daa891f9ba95e95c409 strong.cpp [20170605]