// // Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu> // Creation Date: Wed May 23 15:07:46 PDT 2012 // Last Modified: Wed May 23 15:07:51 PDT 2012 // Filename: ...sig/examples/all/sinko.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/sinko.cpp // Syntax: C++; museinfo // // Description: Identify syncopations in a piano texture. // #include "humdrum.h" #include "PerlRegularExpression.h" #ifndef OLDCPP #include <iostream> #else #include <iostream.h> #endif // function declarations void checkOptions(Options& opts, int argc, char* argv[]); void example(void); void usage(const char* command); void printLine(HumdrumFile& infile, int line, int measure, int lh, int rh, int metlev, int trackcount); void processRecords(HumdrumFile& infile); int getKernTracks(HumdrumFile& infile); // global variables Options options; // database for command-line arguments int emptyQ = 0; // used with -d option /////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { HumdrumFile infile, outfile; // process the command-line options checkOptions(options, argc, argv); // figure out the number of input files to process int numinputs = options.getArgCount(); for (int i=0; i<numinputs || i==0; i++) { infile.clear(); // if no command-line arguments read data file from standard input if (numinputs < 1) { infile.read(cin); } else { infile.read(options.getArg(i+1)); } infile.analyzeRhythm(); processRecords(infile); } return 0; } /////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // getKernTracks -- // int getKernTracks(HumdrumFile& infile) { Array<int> tracks; infile.getTracksByExInterp(tracks, "**kern"); return tracks.getSize(); } ////////////////////////////// // // processRecords -- // void processRecords(HumdrumFile& infile) { PerlRegularExpression pre; int i, j, track; int lh, rh, state; int measure = 0; int kerntracks = getKernTracks(infile); if (kerntracks > 2 || kerntracks < 1) { cerr << "ERROR: there must be one or two **kern spines\n"; exit(1); } Array<int> metlev; infile.analyzeMetricLevel(metlev); if (kerntracks == 2) { cout << "**bar\t**beat\t**mlev\t**LH\t**RH\n"; } else if (kerntracks == 1) { cout << "**bar\t**beat\t**mlev\t**H\n"; } for (i=0; i<infile.getNumLines(); i++) { if (infile[i].isMeasure()) { if (pre.search(infile[i][0], "=(\\d+)")) { measure = atoi(pre.getSubmatch(1)); } } if (!infile[i].isData()) { continue; } rh = 0; lh = 0; track = 0; for (j=0; j<infile[i].getFieldCount(); j++) { track = infile[i].getPrimaryTrack(j); if (strcmp(infile[i][j], ".") == 0) { state = 0; } else if (strchr(infile[i][j], '_') != NULL) { state = 0; } else if (strchr(infile[i][j], ']') != NULL) { state = 0; } else if (strchr(infile[i][j], 'r') != NULL) { state = 0; } else { state = 1; } if (track == 1) { lh = state; } else if (track == 2) { rh = state; } } printLine(infile, i, measure, lh, rh, metlev[i], kerntracks); } if (kerntracks == 2) { cout << "*-\t*-\t*-\t*-\t*-\n"; } else { cout << "*-\t*-\t*-\t*-\n"; } } ////////////////////////////// // // printLine -- // void printLine(HumdrumFile& infile, int line, int measure, int lh, int rh, int metlev, int trackcount) { if (emptyQ) { if ((trackcount == 1) && (lh == 0)) { return; } if ((trackcount == 2) && (lh == 0) && (rh == 0)) { return; } } cout << measure; cout << "\t"; cout << infile[line].getBeat(); cout << "\t"; cout << metlev; cout << "\t"; if (trackcount == 2) { if (lh) { cout << "LH"; } else { cout << "."; } cout << "\t"; if (rh) { cout << "RH"; } else { cout << "."; } cout << endl; } else { if (lh) { cout << "H"; } else { cout << "."; } cout << endl; } } ////////////////////////////// // // checkOptions -- validate and process command-line options. // void checkOptions(Options& opts, int argc, char* argv[]) { opts.define("d|empty|no-empty|no-empties=b","do not display null tokens in hands"); 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, Mar 2011" << endl; exit(0); } else if (opts.getBoolean("version")) { cout << argv[0] << ", version: Nov 2000" << endl; cout << "compiled: " << __DATE__ << endl; cout << MUSEINFO_VERSION << endl; exit(0); } else if (opts.getBoolean("help")) { usage(opts.getCommand()); exit(0); } else if (opts.getBoolean("example")) { example(); exit(0); } emptyQ = opts.getBoolean("empty"); } ////////////////////////////// // // example -- example usage of the sonority program // void example(void) { cout << " \n" "# example usage of the sonority program. \n" "# analyze a Bach chorale for chord qualities: \n" " sonority chor217.krn \n" " \n" "# display the chord analysis with original data: \n" " sonority -a chor217.krn \n" " \n" "# display only the roots of chords: \n" " sonority -r chor217.krn \n" " \n" << endl; } ////////////////////////////// // // usage -- gives the usage statement for the sonority program // void usage(const char* command) { cout << " \n" << endl; } // md5sum: 65af416bcb15089e7bde541b923d0b97 sinko.cpp [20120614]