// // Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu> // Creation Date: Mon Nov 12 22:57:24 PST 2012 // Last Modified: Mon Nov 12 22:57:30 PST 2012 // Filename: ...sig/examples/all/menchop.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/menchop.cpp // Syntax: C++; museinfo // // Description: Extract music with a specific mensurations from input. // // Limitations: Presumes no spine splits or subtracks. // #include "humdrum.h" #include "PerlRegularExpression.h" #include <fstream> // function declarations void checkOptions(Options& opts, int argc, char* argv[]); void example(void); void usage(const char* command); void processFile(const char* filename); void processTrack(HumdrumFile& infile, int track, const char* basename); char* getFileName(char* buffer, HumdrumFile& infile, int line, const char* basename, int track); char* buildFileName(char* buffer, const char* basename, int track, int line, const char* met); // global variables Options options; // database for command-line arguments int debugQ = 0; // used with the --debug option int jrpQ = 0; // used with --jrp option /////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { HumdrumFile infile; // process the command-line options checkOptions(options, argc, argv); const char* filename = ""; int i; for (i=1; i<=options.getArgCount(); i++) { filename = options.getArg(i); processFile(filename); } return 0; } /////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // processFile -- // void processFile(const char* filename) { Array<char> basename; basename.setSize(strlen(filename)+1); strcpy(basename.getBase(), filename); PerlRegularExpression pre; pre.sar(basename, ".*/", ""); pre.sar(basename, "\\....$", ""); Array<int> kerntracks; HumdrumFile infile(filename); infile.getTracksByExInterp(kerntracks, "**kern"); int i; for (i=0; i<kerntracks.getSize(); i++) { processTrack(infile, kerntracks[i], basename.getBase()); } } ////////////////////////////// // // processTrack -- // void processTrack(HumdrumFile& infile, int track, const char* basename) { int i, j; int ttrack; int exinterpline = -1; char buffer[1024] = {0}; int dataQ = 1; int endQ = 0; int notecount = 0; fstream output; Array<char> shortname; shortname.setSize(strlen(basename)+1); strcpy(shortname.getBase(), basename); PerlRegularExpression pre; if (jrpQ) { pre.sar(shortname, "-.*", ""); } for (i=0; i<infile.getNumLines(); i++) { if (infile[i].isGlobalComment()) { continue; } if (infile[i].isBibliographic()) { continue; } if (infile[i].isEmpty()) { continue; } if (infile[i].isInterpretation() || infile[i].isLocalComment() || infile[i].isMeasure()) { if (dataQ) { getFileName(buffer, infile, i, shortname.getBase(), track); if (strcmp(buffer, "") != 0) { if ((endQ == 0) && (exinterpline >= 0)) { output << "*-" << endl; } if (output.is_open()) { output.close(); } cout << "!!FILENAME: " << buffer << endl; output.open(buffer, ios::out); if (!output.is_open()) { cerr << "ERROR: cannot write to " << buffer << endl; exit(1); } output << "!!original-filename:\t"<< basename << ".krn" << endl; if (exinterpline >= 0) { output << "**kern" << endl; if (notecount > 1) { // how to deal with tied notes starting a segement // will need to be considered. In this case the tied // note will (probably) be ignored. output << "!noff:" << track << ";" << notecount+1 << endl; } } } dataQ = 0; } } if (infile[i].isData()) { dataQ = 1; } if (strcmp(infile[i][0], "*-") == 0) { endQ = 1; } for (j=0; j<infile[i].getFieldCount(); j++) { ttrack = infile[i].getPrimaryTrack(j); if (ttrack != track) { continue; } if (strcmp(infile[i][j], ".") == 0) { continue; } if (strcmp(infile[i][j], "*") == 0) { continue; } if (strcmp(infile[i][j], "!") == 0) { continue; } if (strcmp(infile[i][j], "*^") == 0) { // no spine changes allowed in output data continue; } if (strcmp(infile[i][j], "*v") == 0) { // no spine changes allowed in output data continue; } if (strcmp(infile[i][j], "=-") == 0) { continue; } if (strncmp(infile[i][j], "**", 2) == 0) { exinterpline = i; output << infile[i][j] << "\n"; output << "!noff:" << track << ";" << 1 << endl; continue; } if (infile[i].isData()) { if (pre.search(infile[i][j], "[a-z]", "i")) { if (!((strchr(infile[i][j], ']') != NULL) || (strchr(infile[i][j], ']') != NULL) || (strchr(infile[i][j], 'r') != NULL))) { // should consider what to do with rest counting. notecount++; } } } output << infile[i][j] << "\n"; } } // cout << "\n\n"; if (output.is_open()) { output.close(); } } /////////////////////////////// // // getFileName -- // char* getFileName(char* buffer, HumdrumFile& infile, int line, const char* basename, int track) { int i, j; int ttrack; PerlRegularExpression pre; for (i=line; i<infile.getNumLines(); i++) { if (infile[i].isData()) { break; } if (!infile[i].isInterpretation()) { continue; } for (j=0; j<infile[i].getFieldCount(); j++) { ttrack = infile[i].getPrimaryTrack(j); if (ttrack != track) { continue; } if (strncmp(infile[i][j], "*met(", 5) != 0) { continue; } if (pre.search(infile[i][j], "^\\*met\\((.*?)\\)")) { if (strcmp(pre.getSubmatch(1), "") == 0) { buffer[0] = '\0'; return buffer; } return buildFileName(buffer, basename, track, i+1, pre.getSubmatch()); } } } buffer[0] = '\0'; return buffer; } ////////////////////////////// // // buildFileName -- // char* buildFileName(char* buffer, const char* basename, int track, int line, const char* met) { char voicenum[32] = {0}; strcpy(buffer, basename); strcat(buffer, "-T"); sprintf(voicenum, "%d", track); strcat(buffer, voicenum); strcat(buffer, "L"); sprintf(voicenum, "%d", line); strcat(buffer, voicenum); strcat(buffer, "-"); if (strcmp(met, "C|") == 0) { strcat(buffer, "MenCutC"); } else if (strcmp(met, "O") == 0) { strcat(buffer, "MenCircle"); } else if (strcmp(met, "C3") == 0) { strcat(buffer, "MenC3"); } else if (strcmp(met, "O/3") == 0) { strcat(buffer, "MenOOver3"); } else if (strcmp(met, "C") == 0) { strcat(buffer, "MenC"); } else if (strcmp(met, "O2") == 0) { strcat(buffer, "MenCircle2"); } else if (strcmp(met, "O|") == 0) { strcat(buffer, "MenCutCircle"); } else if (strcmp(met, "C|3") == 0) { strcat(buffer, "MenCutC3"); } else if (strcmp(met, "O.") == 0) { strcat(buffer, "MenCircleDot"); } else if (strcmp(met, "C2") == 0) { strcat(buffer, "MenC2"); } else if (strcmp(met, "C|2") == 0) { strcat(buffer, "MenCutC2"); } else if (strcmp(met, "2") == 0) { strcat(buffer, "Men2"); } else if (strcmp(met, "3") == 0) { strcat(buffer, "Men3"); } else if (strcmp(met, "Cr") == 0) { strcat(buffer, "MenCReverse"); } else if (strcmp(met, "C.") == 0) { strcat(buffer, "MenCDot"); } else if (strcmp(met, "3/2") == 0) { strcat(buffer, "Men3Over2"); } else if (strcmp(met, "O|3") == 0) { strcat(buffer, "MenCutCircle3"); } else if (strcmp(met, "O|3/2") == 0) { strcat(buffer, "MenCutCircle3Over2"); } else if (strcmp(met, "O3") == 0) { strcat(buffer, "MenCircle3"); } else if (strcmp(met, "C|/2") == 0) { strcat(buffer, "MenCutCOver2"); } else if (strcmp(met, "C|/3") == 0) { strcat(buffer, "MenCutCOver3"); } else if (strcmp(met, "O/3") == 0) { strcat(buffer, "MenCircleOver3"); } else if (strcmp(met, "C.|") == 0) { // preferred strcat(buffer, "MenCutCDot"); } else if (strcmp(met, "C|.") == 0) { // in case of alternates strcat(buffer, "MenCutCDot"); } else { strcat(buffer, "MenUnknown"); } strcat(buffer, ".krn"); return buffer; } ////////////////////////////// // // checkOptions -- validate and process command-line options. // void checkOptions(Options& opts, int argc, char* argv[]) { opts.define("jrp=b", "JRP catalog extraction from filename"); opts.define("debug=b", "trace input parsing"); opts.define("author=b", "author of the program"); opts.define("version=b", "compilation information"); opts.define("example=b", "example usage"); 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, Nov 2012" << endl; exit(0); } else if (opts.getBoolean("version")) { cout << argv[0] << ", version: 12 Nov 2012" << 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); } debugQ = opts.getBoolean("debug"); jrpQ = opts.getBoolean("jrp"); } ////////////////////////////// // // example -- example usage of the program // void example(void) { cout << " \n" << endl; } ////////////////////////////// // // usage -- gives the usage statement for the program // void usage(const char* command) { cout << " \n" << endl; } // md5sum: d8db7c428a8274f9ffba82ae03efd376 menchop.cpp [20090419]