// // Programmer: Craig Stuart Sapp // Creation Date: Thu Dec 15 15:00:17 PST 2011 // Last Modified: Thu Dec 15 15:00:22 PST 2011 // Last Modified: Wed Jun 20 16:22:44 PDT 2012 Added instruments abbreviations // Last Modified: Tue Aug 28 10:24:57 PDT 2012 Default metric bug fix // Last Modified: Fri Jul 19 13:39:52 PDT 2013 MenC2 implicit barlines:2,dash // Filename: ...sig/examples/all/jrpize.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/jrpize.cpp // Syntax: C++; museinfo // // Description: // // Things this program does: // (1) Add "l" markers on terminal and medial longs // (2) Adds a RWG entry for terminal longs // (3) Adds % RWG entry if "%" enhanced rhythmic values are used // (4) default mensuration signs. // (5) Section: text to !!section: comments and !!!OMD: records // // Things to add in the future: // (a) automatic triplet brackets? // (b) textual items. // (c) mensuration sign exceptions. // #include "PerlRegularExpression.h" #include "humdrum.h" #ifndef OLDCPP #include #define SSTREAM stringstream #define CSTRING str().c_str() using namespace std; #else #ifdef VISUAL #include /* for windows 95 */ #else #include #endif #define SSTREAM strstream #define CSTRING str() #endif // function declarations void checkOptions (Options& opts, int argc, char* argv[]); void example (void); void usage (const char* command); int addTerminalLongs (HumdrumFile& infile); int addTrackLongs (HumdrumFile& infile, int track); void printOutput (HumdrumFile& infile, int terminalQ); int hasEditorial (HumdrumFile& infile); int hasEditorialRDF (HumdrumFile& infile); int hasLongRDF (HumdrumFile& infile); void handleMensuration (HumdrumFile& infile, int line); void printAbbreviation (const char* fullname); void checkAndPrintInstAbbr (HumdrumFile& infile, int line); void checkAndPrintVox (HumdrumFile& infile, int line); int hasSectionLabel (HumdrumFile& infile, int line); void printSectionLabel (HumdrumFile& infile, int line); void printDefaultKeyTimeMet(HumdrumFile& infile, int line); void processMensuration (HumdrumFile& infile, int line); char* getMensuration (char* buffer, HumdrumFile& infile, int line, int spine); char* convertMenIntoMet (char* buffer, const char* mensur); void clearMensurationComment(HumdrumFile& infile, int line); void setItem (Array >& anArray, int i, const char* aString); void printSectionInfo (void); int wrongSideOfBarline (HumdrumFile& infile, int line); int convertRscaleTextToInterpretation(HumdrumFile& infile, int line); void processBarlineComment (HumdrumFile& infile); void applyBarlineMarker (HumdrumFile& infile, int line, int column, int barjump, int dashQ); void makeBarlineInvisible (HumdrumFile& infile, int line, int track, char addchar, int dashQ); void printLabel (HumdrumFile& infile, int line); void printDefaultLabelExpansion(HumdrumFile& infile, int line); int hasDataBelow (HumdrumFile& infile, int line); void turnOffAnyActiveRscales(HumdrumFile& infile, int line); void mergeAdjacentNotes (HumdrumFile& infile, int line, int track); void fixAccentedText (HumdrumRecord& aRecord); void checkText (HumdrumRecord& aRecord, int index); void checkForPrimaryMensurationNeed(HumdrumFile& infile, int line); int cleanDefaultInterpretations(HumdrumFile& infile, int line); void absorbMensurations (HumdrumFile& infile, int line); // global variables Options options; // database for command-line arguments int hasTerminalLong = 0; // true if "l" marker added to data. Array > Clef; // used for prevailing clef by voice Array > Keysig; // used for prevailing key signature by voice Array > Timesig; // used for prevailing time signature by voice Array > Metsig; // used for prevailing meter signature by voice Array Rscale; // used to turn off *rscale: Array Section; // used to flip on other side of measure line char SectionLabel = 'A'-1; int debugQ = 0; /////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { HumdrumFile infile; Section.setSize(1); Section[0] = '\0'; // 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 0) { break; } } for (i=line-1; i>0; i--) { if (!infile[i].isData()) { continue; } for (j=0; j 0) { break; } } if ((nexti == 0) || (lasti == 0)) { return; } char buffer[1024] = {0}; PerlRegularExpression pre; Array buffer2; if ((strchr(infile[lasti][lastj], 'r') != NULL) && (strchr(infile[nexti][nextj], 'r') != NULL) ) { if ((strchr(infile[nexti][nextj], 'y') != NULL) && (strchr(infile[lasti][lastj], 'y') != NULL)) { return; } strcpy(buffer, infile[nexti][nextj]); strcat(buffer, "yy"); infile[nexti].setToken(nextj, buffer); return; } if (strchr(infile[lasti][lastj], 'l') != NULL) { // avoid terminal nulls return; } if ((strchr(infile[lasti][lastj], '[') != NULL) && (strchr(infile[nexti][nextj], ']') != NULL) ) { if ((strchr(infile[nexti][nextj], 'y') != NULL) && (strchr(infile[lasti][lastj], 'y') != NULL)) { return; } // hide tie on first note buffer2.setSize(strlen(infile[lasti][lastj]) + 1); strcpy(buffer2.getBase(), infile[lasti][lastj]); pre.sar(buffer2, "\\[", "[y", "g"); infile[lasti].setToken(lastj, buffer2.getBase()); // hide the entire second note strcpy(buffer, infile[nexti][nextj]); strcat(buffer, "yy"); infile[nexti].setToken(nextj, buffer); } } ////////////////////////////// // // addTerminalLongs -- place "l" marker on the last note of each voice // (or chord in each voice). Also the last note befour any // double barlines. // int addTerminalLongs(HumdrumFile& infile) { int result = 0; Array ktracks; infile.getTracksByExInterp(ktracks, "**kern"); int i; for (i=0; i=0; i--) { if (addQ == 0) { if (infile[i].isMeasure()) { for (j=0; j >& anArray, int i, const char* aString) { anArray[i].setSize(strlen(aString)+1); strcpy(anArray[i].getBase(), aString); } ////////////////////////////// // // printSectionInfo -- // void printSectionInfo(void) { if (Section[0] == '\0') { return; } cout << "!!section: " << Section << "\n"; cout << "!!!OMD:\t" << Section << "\n"; Section[0] = '\0'; Section.setSize(1); } ////////////////////////////// // // convertRscaleTextToInterpretation -- // int convertRscaleTextToInterpretation(HumdrumFile& infile, int line) { if (!infile[line].isComment()) { return 0; } int j; char buffer[1024] = {0}; int hasRscale = 0; PerlRegularExpression pre; for (j=0; j["); strcat(buffer, label); int count = 1; PerlRegularExpression pre; for (i=0; iA label now for (j=0; jA"; if (j < infile[line].getFieldCount() - 1) { cout << "\t"; } } cout << "\n"; } ////////////////////////////// // // hasDataBelow - // int hasDataBelow(HumdrumFile& infile, int line) { int i; for (i=line+1; i 0) && (strcmp(infile[i-1][0], "!!LO:LB:i:g=z") != 0)) { // printing line break provided that there is not one here already // (this filters out extra linebreaks for repeated use of jrpize program) cout << "!!LO:LB:i:g=z" << "\n"; } } if (infile[i].isMeasure() && ((strstr(infile[i][0], "||") != NULL) || (strstr(infile[i][0], ":") != NULL) || (strstr(infile[i][0], "==") != NULL))) { turnOffAnyActiveRscales(infile, i); } if (infile[i].isInterpretation()) { checkAndPrintVox(infile, i); } if ((labelinitQ == 0) && infile[i].isAllClef()) { printDefaultLabelExpansion(infile, i); } convertRscaleTextToInterpretation(infile, i); if (infile[i].isSpineManipulator() && (firstBarline > 0)) { cout << infile[firstBarline] << "\n"; firstBarline = 0; } if (hasSectionLabel(infile, i)) { printSectionLabel(infile, i); continue; } if ((infile[i].isLocalComment() || infile[i].isData()) && (dataFoundQ == 0) && (firstBarline > 0)) { cout << infile[firstBarline] << "\n"; firstBarline = 0; dataFoundQ = 1; } if (infile[i].isGlobalComment() || infile[i].isBibliographic()) { // filter out line/page breaks from the MusicXML, they are // not intended to be actual system breaks. if (pre.search(infile[i][0], "break:original")) { continue; } } clearMensurationComment(infile, i); if (infile[i].isNull()) { continue; } fixAccentedText(infile[i]); if (defaultPrinted) { if (cleanDefaultInterpretations(infile, i)) { continue; } } cout << infile[i] << "\n"; if (infile[i].isMeasure()) { if (Section[0] != '\0') { printSectionInfo(); } } if (defaultPrinted == 0) { if (infile[i].isAllTimeSig()) { processMensuration(infile, i); } } if (infile[i].isInterpretation()) { checkAndPrintInstAbbr(infile, i); } if ((!insertedQ) && (strcmp(infile[i][0], "*-") == 0)) { if (terminalQ && (!hasLongRDF(infile))) { cout << "!!!RDF**kern: l=long note in original notation" << "\n"; } if (editorialQ && (!hasEditorialRDF(infile))) { cout << "!!!RDF**kern: i=editorial accidental" << "\n"; } insertedQ = 1; for (int ii=i+1; ii" << SectionLabel; if (j < infile[line].getFieldCount() - 1) { cout << "\t"; } } cout << "\n"; } ////////////////////////////// // // clearMensurationComment -- // void clearMensurationComment(HumdrumFile& infile, int line) { int j; if (!infile[line].isLocalComment()) { return; } PerlRegularExpression pre; for (j=0; j 0) { if (strcmp(buffer, "*ZZY") == 0) { // no mensuration, handle default for meter elsewhere. } else { setItem(Metsig, infile[i].getPrimaryTrack(j), buffer); } } } } } ////////////////////////////// // // checkForPrimaryMenurationNeed -- If all mensurations in **kern spines are // not the same, then print the majority mensuration in a global comment. // void checkForPrimaryMensurationNeed(HumdrumFile& infile, int line) { int i, j; int track, lasttrack; Array ktracks; infile[line].getTracksByExInterp(ktracks, "**kern"); if (ktracks.getSize() <= 1) { return; } int equalQ = 1; for (i=1; i counts; counts.setSize(ktracks.getSize()); counts.setAll(0); int ti; int tj; for (i=0; i counts[maxi]) { maxi = i; } } if (strcmp(Metsig[ktracks[maxi]].getBase(), "*") == 0) { return; } if (strcmp(Metsig[ktracks[maxi]].getBase(), "") == 0) { return; } // found the most common mensuration, so assume it is the // primary mensuration: cout << "!!primary-mensuration: " << Metsig[ktracks[maxi]].getBase()+1 << endl; } ////////////////////////////// // // getMensuration -- // char* getMensuration(char* buffer, HumdrumFile& infile, int line, int spine) { strcpy(buffer, "*ZZY"); int foundDataQ = 0; int i, j; PerlRegularExpression pre; if (!infile[line].isExInterp(spine, "**kern")) { strcpy(buffer, "*"); return buffer; } int targettrack = infile[line].getPrimaryTrack(spine); int tracki = 0; int trackj = 0; int mencount = 0; int lasti = 0; int lastj = 0; int timesigi = 0; // int timesigj = 0; int track; for (i=line+1; i string; PerlRegularExpression pre; for (j=0; j= infile.getNumLines()-1) { // should never get here, but just in case... return; } int hasmeter = 0; for (j=0; j=0; i--) { if (!infile[i].isBibliographic()) { continue; } if (pre.search(infile[i][0], "^!!!RDF\\*\\*kern\\s*:\\s*l\\s*=\\s*long", "i")) { return 1; } } return 0; } ////////////////////////////// // // hadEditorial -- true if any **kern note has an "i" marker on it. // int hasEditorial(HumdrumFile& infile) { int i, j; for (i=0; i=0; i--) { if (!infile[i].isBibliographic()) { continue; } if (pre.search(infile[i][0], "^!!!RDF\\*\\*kern\\s*:\\s*i\\s*=\\s*edit", "i")) { return 1; } } return 0; } //////////////////// // // fixAccentedText -- // void fixAccentedText(HumdrumRecord& aRecord) { int i; for (i=0; i