// // Programmer: Craig Stuart Sapp // Creation Date: Thu Oct 13 21:48:04 PDT 2011 // Last Modified: Thu Oct 13 21:48:07 PDT 2011 // Filename: ...sig/examples/all/addtempo.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/addtempo.cpp // Syntax: C++; museinfo // // Description: Add tempo settings to a Humdrum file with **kern spines. // #include "humdrum.h" #include "PerlRegularExpression.h" #include #include #include using namespace std; ////////////////////////////////////////////////////////////////////////// // function declarations: void checkOptions (Options& opts, int argc, char** argv); void example (void); void usage (const string& command); void processFile (HumdrumFile& infile, vector >& tempos); int assignTempoLine (vector& tempos, HumdrumFile& infile); void printTempo (HumdrumFile& infile, int line, vector& tempo); void setTempoValues (vector >& settings, const string& string); // User interface variables: Options options; int debugQ = 0; // used with --debug option vector > TempoSettings; // used with -t option ////////////////////////////////////////////////////////////////////////// int main(int argc, char** argv) { HumdrumFile infile; // initial processing of the command-line options checkOptions(options, argc, argv); if (options.getArgCount() < 1) { infile.read(cin); } else { infile.read(options.getArg(1)); } processFile(infile, TempoSettings); return 0; } ////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // processFile -- insert tempo marks into Humdrum file. // void processFile(HumdrumFile& infile, vector >& tempos) { vector tline(tempos.size(), -1); infile.analyzeRhythm("4"); for (int i=0; i<(int)tempos.size(); i++) { tline[i] = assignTempoLine(tempos[i], infile); if (debugQ) { cout << "!! LINE " << i << "\t" << tline[i] << endl; } } int ii = 0; for (int i=0; i& tempo) { int& i = line; int j; if (infile[i].isGlobalComment()) { cerr << "Global comment case not handled yet" << endl; exit(1); } if (infile[i].isBibliographic()) { cerr << "Reference record case not handled yet" << endl; exit(1); } for (j=0; j 0) { return metline; } else if (meterline > 0) { return meterline; } else if (measureline > 0) { return measureline-1; } else if (dataline > 0) { return dataline-1; } else { return exinterp; } } // place tempo with a particular measure int curmeasure = -1; double basebeat = -1; double curbeat = -1; int workingline = -1; int j; for (i=0; i beat) { workingline = j-1; break; } } // refine working line later... return workingline; } } cerr << "GOT TO A FUNNY PLACE" << endl; exit(1); } ////////////////////////////// // // checkOptions -- // void checkOptions(Options& opts, int argc, char** argv) { opts.define("d|debug=b", "Debugging information"); opts.define("t|tempo=s:", "Tempo setting(s)"); opts.define("author=b", "Program author"); opts.define("version=b", "Program version"); opts.define("example=b", "Program examples"); 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, Feb 2011" << endl; exit(0); } else if (opts.getBoolean("version")) { cout << argv[0] << ", version: 5 Feb 2011" << 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"); if (opts.getBoolean("tempo")) { setTempoValues(TempoSettings, opts.getString("tempo")); if (TempoSettings.size() == 0) { usage(opts.getCommand()); } } else { usage(opts.getCommand()); } } ////////////////////////////// // // setTempoValues -- read the tempo values from the // void setTempoValues(vector >& settings, const string& astring) { PerlRegularExpression pre; vector tokens; pre.getTokens(tokens, "[\\s,:;]+", astring); settings.resize(tokens.size()); for (int i=0; i<(int)settings.size(); i++) { settings[i].resize(3); std::fill(settings[i].begin(), settings[i].end(), -1); } double tempo; double measure; double beat; for (int i=0; i<(int)tokens.size(); i++) { if (pre.search(tokens[i], "([\\d.]+)@m(\\d+)b([\\d.]+)")) { // read tempo for specific measure and beat sscanf(pre.getSubmatch(1), "%lf", &tempo); sscanf(pre.getSubmatch(2), "%lf", &measure); sscanf(pre.getSubmatch(3), "%lf", &beat); } else if (pre.search(tokens[i], "(\\d+)@m(\\d+)")) { // read tempo for a measure, set beat to 1 sscanf(pre.getSubmatch(1), "%lf", &tempo); sscanf(pre.getSubmatch(2), "%lf", &measure); beat = 1; } else if (pre.search(tokens[i], "(\\d+)")) { // read default tempo, set measure to -1 and beat to -1 sscanf(pre.getSubmatch(1), "%lf", &tempo); measure = -1; beat = -1; } else { continue; } settings[i][0] = tempo; settings[i][1] = measure; settings[i][2] = beat; } if (debugQ) { for (int i=0; i<(int)settings.size(); i++) { cout << "!! " << i << "\t" << settings[i][0] << "\t" << settings[i][1] << "\t" << settings[i][2] << endl; } } } ////////////////////////////// // // example -- example function calls to the program. // void example(void) { } ////////////////////////////// // // usage -- command-line usage description and brief summary // void usage(const string& command) { cout << "Usage: " << command << " -t tempostring file.in > file.out\n"; exit(1); } // md5sum: 85e00b2fe2dff6f448d7bc3e0e8d6f47 addtempo.cpp [20160320]