// // Programmer: Craig Stuart Sapp // Creation Date: Sun Dec 26 17:03:54 PST 2010 // Last Modified: Fri Jan 14 17:06:32 PST 2011 Added --mark and --mdsep // Last Modified: Wed Feb 2 12:13:11 PST 2011 Added *met extraction // Last Modified: Mon Apr 1 00:28:01 PDT 2013 Enabled multiple segment input // Last Modified: Tue Feb 23 04:40:04 PST 2016 Added --section option // Filename: ...sig/examples/all/myank.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/myank.cpp // Syntax: C++; museinfo // // Description: Extract measures from input data. // #include "humdrum.h" #include "PerlRegularExpression.h" #include "MuseData.h" #include #include #include #include #include using namespace std; class Coord { public: Coord(void) { clear(); } void clear(void) { x = y = -1; } int isValid(void) { return ((x < 0) || (y < 0)) ? 0 : 1; } int x; int y; }; ostream& operator<<(ostream& out, Coord& value) { out << "(" << value.x << "," << value.y << ")"; return out; } class MeasureInfo { public: MeasureInfo(void) { clear(); } void clear(void) { num = seg = start = stop = -1; sclef.setSize(0); skeysig.setSize(0); skey.setSize(0); stimesig.setSize(0); smet.setSize(0); stempo.setSize(0); eclef.setSize(0); ekeysig.setSize(0); ekey.setSize(0); etimesig.setSize(0); emet.setSize(0); etempo.setSize(0); file = NULL; } void setTrackCount(int tcount) { sclef.setSize(tcount+1); skeysig.setSize(tcount+1); skey.setSize(tcount+1); stimesig.setSize(tcount+1); smet.setSize(tcount+1); stempo.setSize(tcount+1); eclef.setSize(tcount+1); ekeysig.setSize(tcount+1); ekey.setSize(tcount+1); etimesig.setSize(tcount+1); emet.setSize(tcount+1); etempo.setSize(tcount+1); int i; for (i=0; i sclef; // starting clef of segment Array skeysig; // starting keysig of segment Array skey; // starting key of segment Array stimesig; // starting timesig of segment Array smet; // starting met of segment Array stempo; // starting tempo of segment // musical settings at start of measure Array eclef; // ending clef of segment Array ekeysig; // ending keysig of segment Array ekey; // ending key of segment Array etimesig; // ending timesig of segment Array emet; // ending met of segment Array etempo; // ending tempo of segment }; ostream& operator<<(ostream& out, MeasureInfo& info) { if (info.file == NULL) { return out; } HumdrumFile& infile = *(info.file); out << "================================== " << endl; out << "NUMBER = " << info.num << endl; out << "SEGMENT = " << info.seg << endl; out << "START = " << info.start << endl; out << "STOP = " << info.stop << endl; int i; for (i=1; i 1) { infile.printNonemptySegmentLabel(cout); } myank(infile, MeasureOutList); } ////////////////////////////////////////////////////////////////////////// //////////////////////// // // getMetStates -- Store the current *met for every token // in the score, keeping track of meter without metric symbols. // void getMetStates(Array >& metstates, HumdrumFile& infile) { Array current; current.setSize(infile.getMaxTracks()+1); metstates.setSize(infile.getNumLines()); PerlRegularExpression pre; int i, j, track; for (i=0; i=0) { if (infile[i].isData()) { startline = i+1; break; } i--; } if (startline < 0) { startline = 0; } i = row; while (i= infile.getNumLines()) { stopline = infile.getNumLines()-1; } for (i=startline; i<=stopline; i++) { if (!infile[i].isInterpretation()) { continue; } for (j=0; j mchar; // list of characters which are marks mchar.setSize(0); int i, j, k, m; char target; PerlRegularExpression pre; for (i=0; i& outmeasures) { if (outmeasures.getSize() > 0) { printStarting(infile); } int lastline = -1; int h, i, j; int counter; int printed = 0; int mcount = 0; int measurestart = 1; int datastart = 0; int bartextcount = 0; for (h=0; h 0) { reconcileSpineBoundary(infile, outmeasures[h-1].stop, outmeasures[h].start); } else { reconcileStartingPosition(infile, outmeasures[0].start); } for (i=outmeasures[h].start; i 0)) { cout << "!!LO:TX:Z=20:X=-90:t=" << barline << endl; } } } else if (doubleQ && measurestart) { printDoubleBarline(infile, i); measurestart = 0; } else { cout << infile[i] << "\n"; if (barnumtextQ && (bartextcount++ == 0) && infile[i].isMeasure()) { int barline = 0; sscanf(infile[i][0], "=%d", &barline); if (barline > 0) { cout << "!!LO:TX:Z=20:X=-25:t=" << barline << endl; } } } lastline = i; } } PerlRegularExpression pre; Array token; int lasti; if (outmeasures.getSize() > 0) { lasti = outmeasures.last().stop; } else { lasti = -1; } if ((!nolastbarQ) && (lasti >= 0) && infile[lasti].isMeasure()) { for (j=0; j= 0) { //printEnding(infile, lastline); printEnding(infile, outmeasures.last().stop, lasti); } } ////////////////////////////// // // adjustGlobalInterpretations -- // void adjustGlobalInterpretations(HumdrumFile& infile, int ii, Array& outmeasures, int index) { if (index <= 0) { adjustGlobalInterpretationsStart(infile, ii, outmeasures, index); return; } // the following lines will not work when non-contiguous measures are // elided. // if (!infile[ii].isInterpretation()) { // return; // } int i; int clefQ = 0; int keysigQ = 0; int keyQ = 0; int timesigQ = 0; int metQ = 0; int tempoQ = 0; int x, y; int xo, yo; int tracks = infile.getMaxTracks(); // these lines may cause bugs, but they get rid of zeroth measure // problem. // ggg // if ((outmeasures.getSize() > 1) && (outmeasures[index-1].num == 0)) { // return; // } // if ((outmeasures.getSize() > 0) && (outmeasures[index].num == 0)) { // return; // } for (i=1; i<=tracks; i++) { if (!clefQ && (outmeasures[index].sclef.getSize() > 0)) { x = outmeasures[index].sclef[i].x; y = outmeasures[index].sclef[i].y; xo = outmeasures[index-1].eclef[i].x; yo = outmeasures[index-1].eclef[i].y; if ((x>=0)&&(y>=0)&&(xo>=0)&&(yo>=0)) { if (strcmp(infile[x][y], infile[xo][yo]) != 0) { clefQ = 1; } } } if (!keysigQ && (outmeasures[index].skeysig.getSize() > 0)) { x = outmeasures[index].skeysig[i].x; y = outmeasures[index].skeysig[i].y; xo = outmeasures[index-1].ekeysig[i].x; yo = outmeasures[index-1].ekeysig[i].y; if ((x>=0)&&(y>=0)&&(xo>=0)&&(yo>=0)) { if (strcmp(infile[x][y], infile[xo][yo]) != 0) { keysigQ = 1; } } } if (!keyQ && (outmeasures[index].skey.getSize() > 0)) { x = outmeasures[index].skey[i].x; y = outmeasures[index].skey[i].y; xo = outmeasures[index-1].ekey[i].x; yo = outmeasures[index-1].ekey[i].y; if ((x>=0)&&(y>=0)&&(xo>=0)&&(yo>=0)) { if (strcmp(infile[x][y], infile[xo][yo]) != 0) { keyQ = 1; } } } if (!timesigQ && (outmeasures[index].stimesig.getSize() > 0)) { x = outmeasures[index].stimesig[i].x; y = outmeasures[index].stimesig[i].y; xo = outmeasures[index-1].etimesig[i].x; yo = outmeasures[index-1].etimesig[i].y; if ((x>=0)&&(y>=0)&&(xo>=0)&&(yo>=0)) { if (strcmp(infile[x][y], infile[xo][yo]) != 0) { timesigQ = 1; } } } if (!metQ && (outmeasures[index].smet.getSize() > 0)) { x = outmeasures[index].smet[i].x; y = outmeasures[index].smet[i].y; xo = outmeasures[index-1].emet[i].x; yo = outmeasures[index-1].emet[i].y; if ((x>=0)&&(y>=0)&&(xo>=0)&&(yo>=0)) { if (strcmp(infile[x][y], infile[xo][yo]) != 0) { metQ = 1; } } } if (!tempoQ && (outmeasures[index].stempo.getSize() > 0)) { x = outmeasures[index].stempo[i].x; y = outmeasures[index].stempo[i].y; xo = outmeasures[index-1].etempo[i].x; yo = outmeasures[index-1].etempo[i].y; if ((x>=0)&&(y>=0)&&(xo>=0)&&(yo>=0)) { if (strcmp(infile[x][y], infile[xo][yo]) != 0) { tempoQ = 1; } } } } int track; if (clefQ) { for (i=0; i=0)&&(y>=0)&&(xo>=0)&&(yo>=0)) { if (strcmp(infile[x][y], infile[xo][yo]) != 0) { cout << infile[x][y]; } else { cout << "*"; } } else { cout << "*"; } if (i < infile[ii].getFieldCount()-1) { cout << "\t"; } } cout << "\n"; } if (keysigQ) { for (i=0; i=0)&&(y>=0)&&(xo>=0)&&(yo>=0)) { if (strcmp(infile[x][y], infile[xo][yo]) != 0) { cout << infile[x][y]; } else { cout << "*"; } } else { cout << "*"; } if (i < infile[ii].getFieldCount()-1) { cout << "\t"; } } cout << "\n"; } if (keyQ) { for (i=0; i=0)&&(y>=0)&&(xo>=0)&&(yo>=0)) { if (strcmp(infile[x][y], infile[xo][yo]) != 0) { cout << infile[x][y]; } else { cout << "*"; } } else { cout << "*"; } if (i < infile[ii].getFieldCount()-1) { cout << "\t"; } } cout << "\n"; } if (timesigQ) { for (i=0; i=0)&&(y>=0)&&(xo>=0)&&(yo>=0)) { if (strcmp(infile[x][y], infile[xo][yo]) != 0) { cout << infile[x][y]; } else { cout << "*"; } } else { cout << "*"; } if (i < infile[ii].getFieldCount()-1) { cout << "\t"; } } cout << "\n"; } if (metQ) { for (i=0; i=0)&&(y>=0)&&(xo>=0)&&(yo>=0)) { if (strcmp(infile[x][y], infile[xo][yo]) != 0) { cout << infile[x][y]; } else { cout << "*"; } } else { cout << "*"; } if (i < infile[ii].getFieldCount()-1) { cout << "\t"; } } cout << "\n"; } if (tempoQ) { for (i=0; i=0)&&(y>=0)&&(xo>=0)&&(yo>=0)) { if (strcmp(infile[x][y], infile[xo][yo]) != 0) { cout << infile[x][y]; } else { cout << "*"; } } else { cout << "*"; } if (i < infile[ii].getFieldCount()-1) { cout << "\t"; } } cout << "\n"; } } ////////////////////////////// // // adjustGlobalInterpretationsStart -- // void adjustGlobalInterpretationsStart(HumdrumFile& infile, int ii, Array& outmeasures, int index) { if (index != 0) { cerr << "Error in adjustGlobalInterpetationsStart" << endl; exit(1); } int i; int clefQ = 0; int keysigQ = 0; int keyQ = 0; int timesigQ = 0; int metQ = 0; int tempoQ = 0; int x, y; // ignore the zeroth measure // (may not be proper). // ggg if (outmeasures[index].num == 0) { return; } int tracks = infile.getMaxTracks(); for (i=1; i<=tracks; i++) { if (!clefQ) { x = outmeasures[index].sclef[i].x; y = outmeasures[index].sclef[i].y; if ((x>=0)&&(y>=0)) { clefQ = 1; } } if (!keysigQ) { x = outmeasures[index].skeysig[i].x; y = outmeasures[index].skeysig[i].y; if ((x>=0)&&(y>=0)) { keysigQ = 1; } } if (!keyQ) { x = outmeasures[index].skey[i].x; y = outmeasures[index].skey[i].y; if ((x>=0)&&(y>=0)) { keyQ = 1; } } if (!timesigQ) { x = outmeasures[index].stimesig[i].x; y = outmeasures[index].stimesig[i].y; if ((x>=0)&&(y>=0)) { timesigQ = 1; } } if (!metQ) { x = outmeasures[index].smet[i].x; y = outmeasures[index].smet[i].y; if ((x>=0)&&(y>=0)) { metQ = 1; } } if (!tempoQ) { x = outmeasures[index].stempo[i].x; y = outmeasures[index].stempo[i].y; if ((x>=0)&&(y>=0)) { tempoQ = 1; } } } int ptrack; if (clefQ) { for (i=0; i=0)&&(y>=0)) { cout << infile[x][y]; } else { cout << "*"; } if (i < infile[ii].getFieldCount()-1) { cout << "\t"; } } cout << "\n"; } if (keysigQ) { for (i=0; i=0)&&(y>=0)) { cout << infile[x][y]; } else { cout << "*"; } if (i < infile[ii].getFieldCount()-1) { cout << "\t"; } } cout << "\n"; } if (keyQ) { for (i=0; i=0)&&(y>=0)) { cout << infile[x][y]; } else { cout << "*"; } if (i < infile[ii].getFieldCount()-1) { cout << "\t"; } } cout << "\n"; } if (timesigQ) { for (i=0; i=0)&&(y>=0)) { cout << infile[x][y]; } else { cout << "*"; } if (i < infile[ii].getFieldCount()-1) { cout << "\t"; } } cout << "\n"; } if (metQ) { for (i=0; i=0)&&(y>=0)) { cout << infile[x][y]; } else { cout << "*"; } if (i < infile[ii].getFieldCount()-1) { cout << "\t"; } } cout << "\n"; } if (tempoQ) { for (i=0; i=0)&&(y>=0)) { cout << infile[x][y]; } else { cout << "*"; } if (i < infile[ii].getFieldCount()-1) { cout << "\t"; } } cout << "\n"; } } ////////////////////////////// // // printDoubleBarline -- // void printDoubleBarline(HumdrumFile& infile, int line) { if (!infile[line].isMeasure()) { cout << infile[line] << "\n"; return; } PerlRegularExpression pre; int j; for (j=0; j 0) { cout << "!!LO:TX:Z=20:X=-25:t=" << barline << endl; } } } ////////////////////////////// // // printInvisibleMeasure -- // void printInvisibleMeasure(HumdrumFile& infile, int line) { if (!infile[line].isMeasure()) { cout << infile[line] << "\n"; return; } PerlRegularExpression pre; int j; for (j=0; j splits(infile[index1].getFieldCount()); splits.setAll(0); int hassplit = 0; for (i=0; i& splits, int index, int count) { int i; for (i=0; i=0; i--) { if (infile[i].isInterpretation() && (ending <0) && (strcmp(infile[i][0], "*-") == 0)) { ending = i; } if (infile[i].isData()) { marker = i+1; break; } if (infile[i].isMeasure()) { marker = i+1; break; } } if (ending >= 0) { reconcileSpineBoundary(infile, adjlin, ending); } int startline = ending; if (marker >= 0) { // capture any comment which occur after the last measure // line in the data. startline = marker; } // reconcileSpineBoundary(infile, lastline, startline); if (startline >= 0) { for (i=startline; i& measurelist, HumdrumFile& infile) { measurelist.setSize(infile.getNumLines()); measurelist.setSize(0); MeasureInfo current; int i, ii; int lastend = -1; int dataend = -1; int barnum1 = -1; int barnum2 = -1; PerlRegularExpression pre; insertZerothMeasure(measurelist, infile); for (i=0; i=0; i--) { if ((lastdata < 0) && infile[i].isData()) { lastdata = i; } if ((lastmeasure < 0) && infile[i].isMeasure()) { lastmeasure = i; } if ((lastmeasure >= 0) && (lastdata >= 0)) { break; } } if (lastmeasure < lastdata) { // no final barline, so set to ignore lastmeasure = -1; lastdata = -1; } if ((barnum2 >= 0) && (lastend >= 0) && (dataend >= 0)) { current.clear(); current.num = barnum2; current.start = lastend; current.stop = dataend; if (lastmeasure > lastdata) { current.stop = lastmeasure; } current.file = &infile; measurelist.append(current); } } ////////////////////////////// // // getSectionCount -- Count the number of sections in a file according to // JRP rules: sections are defined by double barlines. There may be some // corner cases to consider. // int getSectionCount(HumdrumFile& infile) { int i; int count = 0; int dataQ = 0; for (i=0; i& measurelist, HumdrumFile& infile) { PerlRegularExpression pre; int exinterpline = -1; int startline = -1; int stopline = -1; int i; for (i=9; i& measureout, Array& measurein, HumdrumFile& infile, const char* optionstring) { PerlRegularExpression pre; // find the largest measure number in the score int maxmeasure = -1; int minmeasure = -1; int i; for (i=0; i measurein[i].num)) { minmeasure = measurein[i].num; } } if (maxmeasure <= 0) { cerr << "Error: There are no measure numbers present in the data" << endl; exit(1); } if (maxmeasure > 1123123) { cerr << "Error: ridiculusly large measure number: " << maxmeasure << endl; exit(1); } if (maxQ) { if (measurein.getSize() == 0) { cout << 0 << endl; } else { cout << maxmeasure << endl; } exit(0); } else if (minQ) { int ii; for (ii=0; ii inmap(maxmeasure+1); inmap.setAll(-1); for (i=0; i=0) { inmap[number] = i; } } fillGlobalDefaults(infile, measurein, inmap); Array ostring; ostring.setSize(strlen(optionstring)+1); strcpy(ostring.getBase(), optionstring); removeDollarsFromString(ostring, maxmeasure); if (debugQ) { cout << "Option string expanded: " << ostring << endl; } pre.sar(ostring, "\\s+", "", "g"); // remove any spaces between items. pre.sar(ostring, "--+", "-", "g"); // remove extra dashes int value = 0; int start = 0; Array& range = measureout; range.setSize(10000); range.setSize(0); range.setGrowth(5123123); value = pre.search(ostring.getBase(), "^([^,]+,?)"); while (value != 0) { start += value - 1; start += strlen(pre.getSubmatch(1)); processFieldEntry(range, pre.getSubmatch(), infile, maxmeasure, measurein, inmap); value = pre.search(ostring.getBase() + start, "^([^,]+,?)"); } } ////////////////////////////// // // fillGlobalDefaults -- keep track of the clef, key signature, key, etc. // void fillGlobalDefaults(HumdrumFile& infile, Array& measurein, Array& inmap) { int i, j; PerlRegularExpression pre; int tracks = infile.getMaxTracks(); Array currclef(tracks+1); Array currkeysig(tracks+1); Array currkey(tracks+1); Array currtimesig(tracks+1); Array currmet(tracks+1); Array currtempo(tracks+1); Coord undefCoord; undefCoord.clear(); currclef.setAll(undefCoord); currkeysig.setAll(undefCoord); currkey.setAll(undefCoord); currtimesig.setAll(undefCoord); currmet.setAll(undefCoord); currtempo.setAll(undefCoord); int currmeasure = -1; int lastmeasure = -1; int datafound = 0; int track; int thingy = 0; for (i=0; i= 0) { measurein[mnum].eclef = currclef; measurein[mnum].ekeysig = currkeysig; measurein[mnum].ekey = currkey; measurein[mnum].etimesig = currtimesig; measurein[mnum].emet = currmet; measurein[mnum].etempo = currtempo; } lastmeasure = currmeasure; currmeasure = atoi(pre.getSubmatch(1)); if ((currmeasure >= 0) && (currmeasure < inmap.getSize())) { // [20120818] Had to compensate for last measure being single // and un-numbered. if (inmap[currmeasure] < 0) { // [20111008] Had to compensate for "==85" barline datafound = 0; break; } measurein[inmap[currmeasure]].sclef = currclef; measurein[inmap[currmeasure]].skeysig = currkeysig; measurein[inmap[currmeasure]].skey = currkey; measurein[inmap[currmeasure]].stimesig = currtimesig; measurein[inmap[currmeasure]].smet = metstates[i]; measurein[inmap[currmeasure]].stempo = currtempo; } datafound = 0; continue; } if (infile[i].isInterpretation()) { for (j=0; j= 0)) { if (strncmp(infile[i][j], "*clef", 5) == 0) { measurein[inmap[currmeasure]].sclef[track].x = -1; measurein[inmap[currmeasure]].sclef[track].y = -1; } else if (pre.search(infile[i][j], "^\\*k\\[.*\\]", "")) { measurein[inmap[currmeasure]].skeysig[track].x = -1; measurein[inmap[currmeasure]].skeysig[track].y = -1; } else if (pre.search(infile[i][j], "^\\*[A-G][#-]?:", "i")) { measurein[inmap[currmeasure]].skey[track].x = -1; measurein[inmap[currmeasure]].skey[track].y = -1; } else if (pre.search(infile[i][j], "^\\*M\\d+/\\d+", "i")) { measurein[inmap[currmeasure]].stimesig[track].x = -1; measurein[inmap[currmeasure]].stimesig[track].y = -1; measurein[inmap[currmeasure]].smet[track].x = -1; measurein[inmap[currmeasure]].smet[track].y = -1; } else if (pre.search(infile[i][j], "^\\*MM\\d+", "i")) { measurein[inmap[currmeasure]].stempo[track].x = -1; measurein[inmap[currmeasure]].stempo[track].y = -1; } } if (strncmp(infile[i][j], "*clef", 5) == 0) { currclef[track].x = i; currclef[track].y = j; continue; } if (pre.search(infile[i][j], "^\\*k\\[.*\\]", "")) { currkeysig[track].x = i; currkeysig[track].y = j; continue; } if (pre.search(infile[i][j], "^\\*[A-G][#-]?:", "i")) { currkey[track].x = i; currkey[track].y = j; continue; } if (pre.search(infile[i][j], "^\\*M\\d+/\\d+", "i")) { currtimesig[track].x = i; currtimesig[track].y = j; continue; } if (pre.search(infile[i][j], "^\\*MM[\\d.]+", "i")) { currtempo[track].x = i; currtempo[track].y = j; continue; } } } if (infile[i].isData()) { datafound = 1; } } // store state of global music values at end of music if ((currmeasure >= 0) && (currmeasure < inmap.getSize()) && (inmap[currmeasure] >= 0)) { measurein[inmap[currmeasure]].eclef = currclef; measurein[inmap[currmeasure]].ekeysig = currkeysig; measurein[inmap[currmeasure]].ekey = currkey; measurein[inmap[currmeasure]].etimesig = currtimesig; measurein[inmap[currmeasure]].emet = currmet; measurein[inmap[currmeasure]].etempo = currtempo; } // go through the measure list and clean up start/end states for (i=0; i& field, const char* string, HumdrumFile& infile, int maxmeasure, Array& inmeasures, Array& inmap) { MeasureInfo current; PerlRegularExpression pre; Array buffer; buffer.setSize(strlen(string)+1); strcpy(buffer.getBase(), string); // remove any comma left at end of input string (or anywhere else) pre.sar(buffer, ",", "", "g"); if (pre.search(buffer.getBase(), "^(\\d+)[a-z]?-(\\d+)[a-z]?$")) { int firstone = strtol(pre.getSubmatch(1), NULL, 10); int lastone = strtol(pre.getSubmatch(2), NULL, 10); // limit the range to 0 to maxmeasure if (firstone > maxmeasure) { firstone = maxmeasure; } if (lastone > maxmeasure) { lastone = maxmeasure; } if (firstone < 0 ) { firstone = 0 ; } if (lastone < 0 ) { lastone = 0 ; } if ((firstone < 1) && (firstone != 0)) { cerr << "Error: range token: \"" << string << "\"" << " contains too small a number at start: " << firstone << endl; cerr << "Minimum number allowed is " << 1 << endl; exit(1); } if ((lastone < 1) && (lastone != 0)) { cerr << "Error: range token: \"" << string << "\"" << " contains too small a number at end: " << lastone << endl; cerr << "Minimum number allowed is " << 1 << endl; exit(1); } int i; if (firstone > lastone) { for (i=firstone; i>=lastone; i--) { if (inmap[i] >= 0) { if ((field.getSize() > 0) && (field.last().stop == inmeasures[inmap[i]].start)) { field.last().stop = inmeasures[inmap[i]].stop; } else { current.clear(); current.file = &infile; current.num = i; current.start = inmeasures[inmap[i]].start; current.stop = inmeasures[inmap[i]].stop; current.sclef = inmeasures[inmap[i]].sclef; current.skeysig = inmeasures[inmap[i]].skeysig; current.skey = inmeasures[inmap[i]].skey; current.stimesig = inmeasures[inmap[i]].stimesig; current.smet = inmeasures[inmap[i]].smet; current.stempo = inmeasures[inmap[i]].stempo; current.eclef = inmeasures[inmap[i]].eclef; current.ekeysig = inmeasures[inmap[i]].ekeysig; current.ekey = inmeasures[inmap[i]].ekey; current.etimesig = inmeasures[inmap[i]].etimesig; current.emet = inmeasures[inmap[i]].emet; current.etempo = inmeasures[inmap[i]].etempo; field.append(current); } } } } else { for (i=firstone; i<=lastone; i++) { if (inmap[i] >= 0) { if ((field.getSize() > 0) && (field.last().stop == inmeasures[inmap[i]].start)) { field.last().stop = inmeasures[inmap[i]].stop; } else { current.clear(); current.file = &infile; current.num = i; current.start = inmeasures[inmap[i]].start; current.stop = inmeasures[inmap[i]].stop; current.sclef = inmeasures[inmap[i]].sclef; current.skeysig = inmeasures[inmap[i]].skeysig; current.skey = inmeasures[inmap[i]].skey; current.stimesig = inmeasures[inmap[i]].stimesig; current.smet = inmeasures[inmap[i]].smet; current.stempo = inmeasures[inmap[i]].stempo; current.eclef = inmeasures[inmap[i]].eclef; current.ekeysig = inmeasures[inmap[i]].ekeysig; current.ekey = inmeasures[inmap[i]].ekey; current.etimesig = inmeasures[inmap[i]].etimesig; current.emet = inmeasures[inmap[i]].emet; current.etempo = inmeasures[inmap[i]].etempo; field.append(current); } } } } } else if (pre.search(buffer.getBase(), "^(\\d+)([a-z]*)")) { int value = strtol(pre.getSubmatch(1), NULL, 10); // do something with letter later... if ((value < 1) && (value != 0)) { cerr << "Error: range token: \"" << string << "\"" << " contains too small a number at end: " << value << endl; cerr << "Minimum number allowed is " << 1 << endl; exit(1); } if (inmap[value] >= 0) { if ((field.getSize() > 0) && (field.last().stop == inmeasures[inmap[value]].start)) { field.last().stop = inmeasures[inmap[value]].stop; } else { current.clear(); current.file = &infile; current.num = value; current.start = inmeasures[inmap[value]].start; current.stop = inmeasures[inmap[value]].stop; current.sclef = inmeasures[inmap[value]].sclef; current.skeysig = inmeasures[inmap[value]].skeysig; current.skey = inmeasures[inmap[value]].skey; current.stimesig = inmeasures[inmap[value]].stimesig; current.smet = inmeasures[inmap[value]].smet; current.stempo = inmeasures[inmap[value]].stempo; current.eclef = inmeasures[inmap[value]].eclef; current.ekeysig = inmeasures[inmap[value]].ekeysig; current.ekey = inmeasures[inmap[value]].ekey; current.etimesig = inmeasures[inmap[value]].etimesig; current.emet = inmeasures[inmap[value]].emet; current.etempo = inmeasures[inmap[value]].etempo; field.append(current); } } } } ////////////////////////////// // // removeDollarsFromString -- substitute $ sign for maximum track count. // void removeDollarsFromString(Array& buffer, int maxx) { PerlRegularExpression pre; PerlRegularExpression pre2; char tbuf[1024] = {0}; char obuf[1024] = {0}; int outval; int value; if (debugQ) { cout << "MEASURE STRING BEFORE DOLLAR REMOVAL: " << buffer << endl; } while (pre.search(buffer, "(\\$\\d*)", "")) { strcpy(tbuf, pre.getSubmatch(1)); if (pre2.search(tbuf, "(\\$\\d+)")) { sscanf(pre2.getSubmatch(1), "$%d", &value); outval = maxx - value; } else { outval = maxx; } if (outval < 0) { outval = 0; } sprintf(tbuf, "%d", outval); strcpy(obuf, "\\"); strcat(obuf, pre.getSubmatch()); pre.sar(buffer, obuf, tbuf, ""); } if (debugQ) { cout << "DOLLAR EXPAND: " << buffer << endl; } } ////////////////////////////// // // checkOptions -- // void checkOptions(Options& opts, int argc, char** argv) { opts.define("v|verbose=b", "Verbose output of data"); opts.define("debug=b", "Debugging information"); opts.define("inlist=b", "Show input measure list"); opts.define("outlist=b", "Show output measure list"); opts.define("mark|marks=b", "Yank measure with marked notes"); opts.define("T|M|bar-number-text=b", "print barnum with LO text above system "); opts.define("d|double|dm|md|mdsep|mdseparator=b", "Put double barline between non-consecutive measure segments"); opts.define("m|b|measures|bars|measure|bar=s", "Measures to yank"); opts.define("I|i|instrument=b", "Include instrument codes from start of data"); opts.define("visible|not-invisible=b", "Do not make initial measure invisible"); opts.define("B|noendbar=b", "Do not print barline at end of data"); opts.define("max=b", "print maximum measure number"); opts.define("min=b", "print minimum measure number"); opts.define("section-count=b", "count the number of sections, JRP style"); opts.define("section=i:0", "extract given section number (indexed from 1"); 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, December 2010" << endl; exit(0); } else if (opts.getBoolean("version")) { cout << argv[0] << ", version: 26 December 2010" << endl; cout << "compiled: " << __DATE__ << endl; cout << MUSEINFO_VERSION << endl; exit(0); } else if (opts.getBoolean("help")) { usage(opts.getCommand().data()); exit(0); } else if (opts.getBoolean("example")) { example(); exit(0); } debugQ = opts.getBoolean("debug"); inlistQ = opts.getBoolean("inlist"); outlistQ = opts.getBoolean("outlist"); verboseQ = opts.getBoolean("verbose"); maxQ = opts.getBoolean("max"); minQ = opts.getBoolean("min"); invisibleQ = !opts.getBoolean("not-invisible"); instrumentQ = opts.getBoolean("instrument"); nolastbarQ = opts.getBoolean("noendbar"); markQ = opts.getBoolean("mark"); doubleQ = opts.getBoolean("mdsep"); barnumtextQ = opts.getBoolean("bar-number-text"); sectionCountQ = opts.getBoolean("section-count"); Section = opts.getInteger("section"); if (!Section) { if (!(opts.getBoolean("measures") || markQ)) { // if -m option is not given, then --mark option presumed markQ = 1; // cerr << "Error: the -m option is required" << endl; // exit(1); } } } ////////////////////////////// // // example -- example function calls to the program. // void example(void) { } ////////////////////////////// // // usage -- command-line usage description and brief summary // void usage(const char* command) { }