// // Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu> // Creation Date: Wed Mar 23 19:44:07 PDT 2011 // Last Modified: Wed Mar 23 19:44:10 PDT 2011 // Filename: ...sig/examples/all/onset.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/onset.cpp // Syntax: C++; museinfo // // Description: Analyzes **kern data for onset data. // #include "humdrum.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 processData(HumdrumFile& infile, RationalNumber& sampledur); void printBrief(Array<int> positions, Array<int> mpositions, HumdrumFile& infile, RationalNumber& sampledur); void printScore(Array<int> positions, Array<int> mpositions, HumdrumFile& infile, RationalNumber& sampledur); // global variables Options options; // database for command-line arguments RationalNumber Sampledur; // used with -t option int timebaseQ = 0; // used with -t option int briefQ = 0; // used with -b option int csvQ = 1; // used with -C 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("4"); if (timebaseQ == 0) { Sampledur = infile.getMinTimeBaseR(); Sampledur.invert(); } processData(infile, Sampledur); } return 0; } /////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // processData -- // void processData(HumdrumFile& infile, RationalNumber& sampledur) { RationalNumber scoreduration = infile.getTotalDurationR(); Array<int> positions; RationalNumber psize = scoreduration / sampledur; RationalNumber position; positions.setSize(int(psize.getFloat()+1)); positions.setAll(0); Array<int> mpositions; // location of measures mpositions.setSize(positions.getSize()); mpositions.setAll(0); char buffer[1024] = {0}; int pindex = 0; // position index int rcount = 0; // number of attacks on the line int acount = 0; // number of attacks on the line int tcount = 0; // for keeping track of chords int lastindex = 0; // for suppressing double rest markers int i, j, k; for (i=0; i<infile.getNumLines(); i++) { if (infile[i].isMeasure()) { if (strchr(infile[i][0], '-') != NULL) { // don't mark invisible measures continue; } position = infile[i].getAbsBeatR() / sampledur; if (position.getDenominator() == 1) { pindex = position.getNumerator(); } else { pindex = int(position.getFloat()); } mpositions[pindex] = 1; } if (!infile[i].isData()) { continue; } if (infile[i].getDuration() == 0.0) { // ignore grace notes. continue; } position = infile[i].getAbsBeatR() / sampledur; if (position.getDenominator() == 1) { pindex = position.getNumerator(); } else { // not at the requested rhythmic sampling position in the file. continue; } rcount = 0; acount = 0; for (j=0; j<infile[i].getFieldCount(); j++) { if (!infile[i].isExInterp(j, "**kern")) { continue; } if (strcmp(infile[i][j], ".") == 0) { // ignore sustained items continue; } if (strchr(infile[i][j], 'r') != NULL) { rcount++; continue; } tcount = infile[i].getTokenCount(j); for (k=0; k<tcount; k++) { infile[i].getToken(buffer, j, k); if (strchr(buffer, '_') != NULL) { // ignore the middle notes of ties continue; } if (strchr(buffer, ']') != NULL) { // ignore the ending notes of ties continue; } acount++; // found a note onset } } if (acount > 0) { positions[pindex] = acount; lastindex = pindex; } else { // print the rest marker only if the last marker was not a rest if (positions[lastindex] >= 0) { positions[pindex] = -rcount; } } } if (briefQ) { printBrief(positions, mpositions, infile, sampledur); } else { printScore(positions, mpositions, infile, sampledur); } } ////////////////////////////// // // printScore -- // void printScore(Array<int> positions, Array<int> mpositions, HumdrumFile& infile, RationalNumber& sampledur) { RationalNumber rpos; int position; int i; for (i=0; i<infile.getNumLines(); i++) { cout << infile[i]; if (infile[i].isBibliographic()) { cout << "\n"; continue; } if (infile[i].isGlobalComment()) { cout << "\n"; continue; } if (infile[i].isLocalComment()) { cout << "\t!\n"; continue; } if (infile[i].isMeasure()) { cout << "\t" << infile[i][0] << "\n"; continue; } if (infile[i].isInterpretation()) { if (strncmp(infile[i][0], "**", 2) == 0) { cout << "\t**onset\n"; continue; } if (strcmp(infile[i][0], "*-") == 0) { cout << "\t*-\n"; continue; } cout << "\t*\n"; continue; } if (!infile[i].isData()) { cout << "\n"; } cout << "\t"; rpos = infile[i].getAbsBeatR() / sampledur; if (rpos.getDenominator() == 1) { position = int(rpos.getFloat()); cout << positions[position]; } else { cout << 0; } cout << "\n"; } } ////////////////////////////// // // printBrief -- // void printBrief(Array<int> positions, Array<int> mpositions, HumdrumFile& infile, RationalNumber& sampledur) { RationalNumber maxR = infile.getTotalDurationR() / sampledur; int max = int(maxR.getFloat()); int i; for (i=0; i<max; i++) { if (mpositions[i]) { cout << "\n"; } if (positions[i]) { cout << 1; } else { cout << 0; } if (csvQ && (i < mpositions.getSize()-1) && !mpositions[i+1]) { cout << ", "; } } cout << "\n"; } ////////////////////////////// // // checkOptions -- validate and process command-line options. // void checkOptions(Options& opts, int argc, char* argv[]) { opts.define("t|timebase=s:2", "rhythm at which to sample onsets"); opts.define("b|brief=b", "print brief form of output data"); 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: 23 Mar 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); } briefQ = opts.getBoolean("brief"); timebaseQ = opts.getBoolean("timebase"); if (strchr(opts.getString("timebase"), '/') != NULL) { int top = 1; int bottom = 4; sscanf(opts.getString("timebase"), "%d/%d", &bottom, &top); Sampledur = top; Sampledur /= bottom; Sampledur *= 4; // convert from whole note units to quarter notes } else { Sampledur = Convert::kernToDurationR(opts.getString("timebase")); } } ////////////////////////////// // // example -- example usage of the sonority program // void example(void) { cout << " \n" << endl; } ////////////////////////////// // // usage -- gives the usage statement for the sonority program // void usage(const char* command) { cout << " \n" << endl; } // md5sum: fba4c547c330f2cc4e940fca35cc1790 onset.cpp [20110325]