// // Programmer: Craig Stuart Sapp // Creation Date: Tue Oct 4 21:57:39 PDT 2011 // Last Modified: Fri Oct 24 16:49:55 PDT 2014 Do not count non-**kern data. // Filename: ...museinfo/examples/all/activity.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/activity.cpp // Syntax: C++; museinfo // // Description: Cumulative articulation plot generator. Counts the number // of notes within each measure of the score and then outputs // either raw data or instructions for creating a plot. // // Interesting webpages: // http://gnuplot-tricks.blogspot.com #include "humdrum.h" #include "PerlRegularExpression.h" #include /////////////////////////////////////////////////////////////////////////// // function declarations void checkOptions (Options& opts, int argc, char* argv[]); void example (void); void usage (const string& command); void processFile (HumdrumFile& infile); void processFileSeparate (HumdrumFile& infile); int countObject (const string& buffer); ostream& drawArrows (HumdrumFile& infile, ostream& out, vector& barvals); int getTrackMap (vector& trackmap, HumdrumFile& infile); int allEqual (vector& array, int value); double getMaximum (vector >& array); void printTickLabels (ostream& out, int maxval); void printMensurations (ostream& out, HumdrumFile& infile); void printSeparateMensurations(ostream& out, HumdrumFile& infile); void printTitle (ostream& out, HumdrumFile& infile); ostream& encodeText (ostream& out, const string& string); ostream& printPartAbbreviations(ostream& out, HumdrumFile& infile); ostream& placeMensuration (ostream& out, const string& mensur, double xpos, double ypos, const string& color, const string& graph); int checkSounding (HumdrumFile& infile, int row, int col); // global variables Options options; // database for command-line arguments int gnuplotQ = 0; // used with --gnuplot option int separateQ = 0; // used with -s option int LabelCount = 0; // used for printing gnuplot labels int ciconiaQ = 1; int Scale = 2; string yrange = ""; // used with --yrange option /////////////////////////////////////////////////////////////////////////// int main(int argc, char** argv) { checkOptions(options, argc, argv); HumdrumFile infile; int i; // figure out the number of input files to process int numinputs = options.getArgCount(); for (i=0; i& array, int value) { int i; if (array.size() <= 1) { return 1; } for (i=1; i<(int)array.size(); i++) { if (array[i] != array[i-1]) { return 0; } } return 1; } ////////////////////////////// // // processFileSeparate -- // void processFileSeparate(HumdrumFile& infile) { int i, j, k; char buffer[1024] = {0}; int tcount; int measure = 0; int firstQ = 0; PerlRegularExpression pre; vector barvals; vector > cumvals; barvals.reserve(100000); cumvals.reserve(100000); vector trackmap; int vcount = getTrackMap(trackmap, infile); vector cumsum; cumsum.resize(vcount); std::fill(cumsum.begin(), cumsum.end(), 0); vector sounding; sounding.resize(vcount); std::fill(sounding.begin(), sounding.end(), 0); int vindex; for (i=0; i 0)) { // no notes attacked in the current measure // but notes are sounding from the previous // measure, so mark with special 0.5 code: cumvals.back()[j] = 0.5; } } std::fill(sounding.begin(), sounding.end(), 0); } if (pre.search(infile[i][0], "(\\d+)")) { measure = atoi(pre.getSubmatch(1)); } std::fill(cumsum.begin(), cumsum.end(), 0); continue; } if (!infile[i].isData()) { continue; } for (j=0; j 0.0) { cout << barvals[i]; cout << "\t" << j; cout << "\t" << color; cout << "\t" << color; cout << "\t" << color; cout << endl; // } } } } else { // print the results int sum = 0; for (i=0; i<(int)barvals.size(); i++) { cout << barvals[i]; sum = 0; for (j=0; j<(int)cumvals[i].size(); j++) { sum += cumvals[i][j]; } cout << "\t" << sum; for (j=0; j<(int)cumvals[i].size(); j++) { cout << "\t" << cumvals[i][j]; } cout << "\n"; } } if (gnuplotQ) { cout << "e\n"; } } ////////////////////////////// // // checkSounding -- returns true if there is a note sounding. // (not just if an attack). // int checkSounding(HumdrumFile& infile, int row, int col) { int& i = row; int& j = col; int ii; int jj; if (!infile[i].isExInterp(j, "**kern")) { return 0; } ii = i; jj = j; if (strcmp(infile[i][j], ".") == 0) { ii = infile[i].getDotLine(j); jj = infile[i].getDotSpine(j); } if (strchr(infile[ii][jj], 'r') != NULL) { return 0; } return 1; } ////////////////////////////// // // printPartAbbreviations -- search for the abbreviations line // in the file. The abbreviations. start with *I' and then the // part's abbreviation name. Assuming no spine splits // before abbreviation name. Also assuming abbreviations occurs // before any data. // ostream& printPartAbbreviations(ostream& out, HumdrumFile& infile) { vector names(infile.getMaxTracks()); int kmax = 0; int kindex = 0; for (int i=0; i kmax) { kmax = kindex + 1; } if (strncmp("*I'", infile[i][j], 3) == 0) { names[kindex] = infile[i][j]+3; } } } names.resize(kmax); if (kmax > 0) { out << "set ytics ("; for (int i=0; i 0) { encodeText(out, OPR); out << " "; } encodeText(out, OTL); if (strlen(SCT) > 0) { out << " ("; encodeText(out, SCT); out << ")"; } // out << "\" offset 0,-1 font \"VeraSe," << Scale * 12 << "\"\n"; out << "\" offset 0,-0.75 font \"tt1095m_.ttf," << Scale * 16 << "\"\n"; // tt1095m_.ttf roman // tt1096m_.ttf italic // tt1099m_.ttf bold // tt1100m_.ttf bold-italic } ////////////////////////////// // // encodeText -- convert HTML style accented characters into printable form. // http://www.pjb.com.au/comp/diacritics.html // ostream& encodeText(ostream& out, const string& astring) { string newstring = astring; PerlRegularExpression pre; pre.sar(newstring, "à", "\340", "g"); pre.sar(newstring, "á", "\341", "g"); pre.sar(newstring, "â", "\342", "g"); pre.sar(newstring, "ã", "\343", "g"); pre.sar(newstring, "ä", "\344", "g"); pre.sar(newstring, "å", "\345", "g"); pre.sar(newstring, "æ", "\346", "g"); pre.sar(newstring, "ç", "\347", "g"); pre.sar(newstring, "è", "\350", "g"); pre.sar(newstring, "é", "\351", "g"); out << newstring; return out; } ////////////////////////////// // // getMaximum -- return the largest value in the matrix. // double getMaximum(vector >& array) { int i, j; int output = 0; for (i=0; i<(int)array.size(); i++) { for (j=0; j<(int)array[i].size(); j++) { if (output < array[i][j]) { output = array[i][j]; } } } return output; } /////////////////////////////// // // printMensurations -- // void printMensurations(ostream& out, HumdrumFile& infile) { int i, j; int barnum = 1; PerlRegularExpression pre; int first = 0; int pfirst = 0; char lastbuffer[1024] = {0}; char buffer[1024] = {0}; for (i=0; i lastmensur; lastmensur.resize(infile.getMaxTracks()); for (i=0; i<(int)lastmensur.size(); i++) { lastmensur[i][0] = '\0'; } vector track2part(infile.getMaxTracks()+1, -1); int kindex = -1; for (i=0; i& trackmap, HumdrumFile& infile) { trackmap.resize(infile.getMaxTracks()+1); std::fill(trackmap.begin(), trackmap.end(), -1); int counter = 0; for (int i=0; i barvals(100000); vector cumvals(100000); barvals.resize(0); cumvals.resize(0); for (i=0; i 271) { cout << "set xtics 25\n"; // horizontal ticks every 25 measures } else if (maxval < 139) { cout << "set xtics 5\n"; // horizontal ticks every 5 measures } else { cout << "set xtics 10\n"; // horizontal ticks every 10 measures } } ////////////////////////////// // // drawArrows -- draw arrows at double barlines // ostream& drawArrows(HumdrumFile& infile, ostream& out, vector& barvals) { int count = 0; PerlRegularExpression pre; int i, j; double barnum = 0; string omd; char buffer[1024] = {0}; for (i=0; i