// // Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu> // Creation Date: Wed Oct 15 04:30:17 PDT 2008 // Last Modified: Wed Oct 15 08:13:13 PDT 2008 // Filename: ...sig/examples/all/marcello1.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/marcello1.cpp // Syntax: C++; museinfo // // Description: Feature extractor which extract the metrical position // of each beat, the number of events in the left hand, // and the number of events in a beat for the right hand // in piano music (two primary spines of music, the first // **kern spine contains the left hand, the second **kern spine // contains the right hand. Any primary **kern spines after // the first two will be ignored. #ifndef OLDCPP #include <iostream> using namespace std; #else #include <iostream.h> #endif #include "humdrum.h" #define FIELDCOUNT 5 ////////////////////////////////////////////////////////////////////////// // function declarations: void checkOptions(Options& opts, int argc, char** argv); void example(void); void usage(const char* command); void countEvents(int& lh, int &rh, HumdrumFile& infile, int line); void createAnalysisOne(ostream& out, HumdrumFile& infile); // User interface variables: Options options; ////////////////////////////////////////////////////////////////////////// int main(int argc, char** argv) { // process the command-line options checkOptions(options, argc, argv); HumdrumFile infile; infile.read(options.getArg(1)); createAnalysisOne(std::cout, infile); return 0; } ////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // createAnalysisOne -- print the metrical position, the number of // events in the left hand (bottom staff), the number of events in // the right hand (top staff). // void createAnalysisOne(ostream& out, HumdrumFile& infile) { int i, j; int absbeat = -1; int lastabsbeat = -1; int metrical = -1; int lastmetrical = -1; int lhcounter = -1; int rhcounter = -1; int rh; int lh; int datafound = 0; int endofdata = -1; int measureQ = 0; int difference; int measurenum; char measure[32] = {0}; infile.analyzeRhythm("4"); for (i=0; i<infile.getNumLines(); i++) { if (infile[i].getType() == E_humrec_bibliography) { if (endofdata < 0) { // only print the bibliographic records which start before // end of the data. Ignore any bibliographic records at // the end of the data until later. out << infile[i] << "\n"; } continue; } if (infile[i].getType() == E_humrec_interpretation) { if (strncmp(infile[i][0], "**", 2) == 0) { // store the of end of data location in the input file // for printing bibliographic data after the end of the // data in the original file. endofdata = i; } } if (infile[i].getType() == E_humrec_data_measure) { measurenum = -1; if (sscanf(infile[i][0], "=%d", &measurenum) == 1) { sprintf(measure, "%d", measurenum); } else { measure[0] = '\0'; } measureQ = 1; } if (infile[i].getType() != E_humrec_data) { continue; } if (datafound == 0) { out << "**kern\t**absbt\t**meter\t**lhcnt\t**rhcnt\n"; if (measureQ) { out << "=" << measure; for (j=1; j<FIELDCOUNT; j++) { out << "\t=" << measure; } out << "\n"; measureQ = 0; } datafound = 1; } absbeat = int(infile[i].getAbsBeat() + 0.001); metrical = int(infile[i].getBeat() + 0.001); if (lastabsbeat < 0) { lastabsbeat = absbeat; lastmetrical = metrical; lhcounter = 0; rhcounter = 0; } else if (absbeat != lastabsbeat) { out << "4" << "\t" << lastabsbeat << "\t" << lastmetrical << "\t" << lhcounter << "\t" << rhcounter << endl; difference = absbeat - lastabsbeat; if (difference > 1) { for (j=1; j<difference; j++) { out << "4" << "\t" << lastabsbeat + j << "\t" << (((lastmetrical-1) + j)%3)+1 << "\t" << 0 << "\t" << 0 << endl; } } if (measureQ) { out << "=" << measure; for (j=1; j<FIELDCOUNT; j++) { out << "\t=" << measure; } out << "\n"; measureQ = 0; } lastabsbeat = absbeat; lastmetrical = metrical; lhcounter = 0; rhcounter = 0; } countEvents(lh, rh, infile, i); lhcounter += lh; rhcounter += rh; } difference = int(infile.getTotalDuration()+0.99) - absbeat; for (j=0; j<difference; j++) { out << "4" << "\t" << absbeat + j << "\t" << (((lastmetrical-1) + j)%3)+1 << "\t" << 0 << "\t" << 0 << endl; } out << "==\t==\t==\t==\t==\n"; out << "*-\t*-\t*-\t*-\t*-\n"; // print Bibliographic records after the end of the data if (endofdata < 0) { // this should never occur. return; } for (i=endofdata; i<infile.getNumLines(); i++) { if (infile[i].getType() == E_humrec_bibliography) { out << infile[i] << "\n"; } } } ////////////////////////////// // // countEvents -- count the number of events in the primary and // secondary track for the current line. The number of // events is the number of notes or chords found in sequence. // (one chord counts is equal to one note). If notes are // found in separate voices, they could be counted, or not. // But currently they are not counted. // void countEvents(int& lh, int &rh, HumdrumFile& infile, int line) { int i; int trackindex; int primary; Array<int> trackfound; trackfound.setSize(2); trackfound.setAll(0); Array<int> trackcounts; trackcounts.setSize(2); trackcounts.setAll(0); for (i=0; i<infile[line].getFieldCount(); i++) { if (infile[line].getExInterpNum(i) != E_KERN_EXINT) { continue; } primary = infile[line].getPrimaryTrack(i); if (trackfound[0] == 0) { trackfound[0] = primary; trackindex = 0; } else if (trackfound[0] == primary) { trackindex = 0; } else if (trackfound[1] == 0) { trackfound[1] = primary; trackindex = 1; } else if (trackfound[1] == primary) { trackindex = 1; } else { break; // some other spine of **kern data other than the first two } if (strcmp(infile[line][i], ".") == 0) { // don't count null tokens continue; } if (strchr(infile[line][i], 'r') != NULL) { // don't count rests continue; } trackcounts[trackindex]++; } lh = trackcounts[0] ? 1 : 0; rh = trackcounts[1] ? 1 : 0; } ////////////////////////////// // // checkOptions -- // void checkOptions(Options& opts, int argc, char* argv[]) { 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, October 2008" << endl; exit(0); } else if (opts.getBoolean("version")) { cout << argv[0] << ", version: 15 October 2008" << 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); } } ////////////////////////////// // // example -- example function calls to the program. // void example(void) { } ////////////////////////////// // // usage -- command-line usage description and brief summary // void usage(const char* command) { } // md5sum: e4b0b470fd381c0e8bf1fedaa0428043 marcello1.cpp [20081017]