// // Programmer: Craig Stuart Sapp // Creation Date: Sun May 2 23:56:35 PDT 2004 // Last Modified: Sun May 2 23:56:37 PDT 2004 // Last Modified: Thu Jun 3 19:54:09 PDT 2004 (added polyphonic feature) // Last Modified: Fri Jun 25 00:17:43 PDT 2004 allowed for correcting two // or more ties in a row: [[ to [_] // Last Modified: Tue Sep 7 01:39:07 PDT 2004 (allowed for basic splitting // into two subspines) // Filename: ...sig/examples/all/tiefix.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/tiefix.cpp // Syntax: C++; museinfo // // Description: Fix tie errors in essen music (single voice parts only) // Will usually work with upto two subspines as well. // Currently ignores the secondary subspine. // #include #include #include #include /* for qsort and bsearch functions */ #include #include #include "humdrum.h" using namespace std; #define TIENONE 0 #define TIESTART 1 #define TIECONT 2 #define TIESTOP 3 /////////////////////////////////////////////////////////////////////////// // function declarations void checkOptions (Options& opts, int argc, char* argv[]); void example (void); void usage (const char* command); void processFile (HumdrumFile& infile, int index); void getPitchesAndTies (HumdrumFile& infile, vector& lines, vector& pitches, vector& tiestates, int index, vector& localindex); int getTieCorrections (vector& tiecorrections, vector& pitches, vector& tiestates); void printTieCorrection (ostream& out, HumdrumRecord& line, int tiecorrection, int index); void printStringWithoutTie(ostream& out, const char* string); void printStringWithTie (ostream& out, const char* string, int correction); void printFileWithCorrections(ostream& out, HumdrumFile& infile, vector& lines, vector& tiecorrections, vector& localindex); // global variables Options options; // database for command-line arguments int testQ = 0; // used with -t option string filename; /////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { HumdrumFile infile; // process the command-line options checkOptions(options, argc, argv); infile.clear(); // if no command-line arguments read data file from standard input int numinputs = options.getArgCount(); if (numinputs < 1) { infile.read(cin); } else { filename = options.getArg(1); infile.read(options.getArg(1)); } int i; for (i=0; i lines; vector pitches; vector tiestates; vector tiecorrections; vector localindex; for (int i=0; i& lines, vector& tiecorrections, vector& localindex) { int i; int lindex = 0; for (i=0; i= (int)lines.size()) { out << infile[i] << "\n"; continue; } if (lines[lindex] == i) { if (tiecorrections[lindex]) { // print a tie correction printTieCorrection(out, infile[i], tiecorrections[lindex], localindex[lindex]); } else { out << infile[i] << "\n"; } lindex++; } else { out << infile[i] << "\n"; } } } ////////////////////////////// // // printTieCorrection -- // void printTieCorrection(ostream& out, HumdrumRecord& line, int tiecorrection, int index) { int i; for (i=0; i 0) { printStringWithTie(out, line[index], tiecorrection); } else { out << line[index]; } if (i < line.getFieldCount() - 1) { out << "\t"; } } out << "\n"; } ////////////////////////////// // // printStringWithTie -- // void printStringWithTie(ostream& out, const char* string, int correction) { int hasslurstart = 0; int hasslurstop = 0; if (strchr(string, '{') != NULL) { // these are really phrase markers hasslurstart = 1; } if (strchr(string, '}') != NULL) { // these are really phrase markers hasslurstop = 1; } int hasoldtie = 0; if (strchr(string, '[') != NULL) { hasoldtie = 1; } if (strchr(string, '_') != NULL) { hasoldtie = 2; } if (strchr(string, ']') != NULL) { hasoldtie = 3; } int i; int len = strlen(string); switch (correction) { case TIESTART: if (!hasslurstart) { out << "[" << string; return; } for (i=0; i& tiecorrections, vector& pitches, vector& tiestates) { int output = 0; tiecorrections.resize(pitches.size()); std::fill(tiecorrections.begin(), tiecorrections.end(), 0); for (int i=0; i<(int)pitches.size(); i++) { if (tiestates[i] == TIESTART) { if (i==(int)pitches.size()-1) { tiecorrections[i] = -tiestates[i]; output += 1; } else { if ((pitches[i] == pitches[i+1]) && (tiestates[i+1] == TIENONE)) { tiecorrections[i+1] = TIESTOP; output += 1; tiestates[i+1] = TIESTOP; } else if (pitches[i] != pitches[i+1]) { tiecorrections[i] = -TIESTART; output += 1; } } } else if (tiestates[i] == TIECONT) { if (i==(int)pitches.size()-1) { tiecorrections[i] = -tiestates[i]; output += 1; } else { if ((pitches[i] == pitches[i+1]) && (tiestates[i+1] == TIENONE)) { tiecorrections[i+1] = TIESTOP; output += 1; tiestates[i+1] = TIESTOP; } else if (pitches[i] != pitches[i+1]) { tiecorrections[i] = -TIESTART; output += 1; } } } else if (tiestates[i] == TIESTOP) { if (i==0) { tiecorrections[i] = tiestates[i]; output += 1; } else { if ((pitches[i] == pitches[i-1]) && (tiestates[i-1] == TIENONE)) { tiecorrections[i-1] = TIESTART; output += 1; tiestates[i-1] = TIESTART; } else if (pitches[i] !=pitches[i-1]) { tiecorrections[i] = -TIESTOP; output += 1; } else if ((pitches[i] == pitches[i-1]) && (tiestates[i-1] == TIESTOP)) { tiecorrections[i-1] = TIECONT; tiestates[i-1] = TIECONT; output += 1; } } } } // readjust the ties taking into account continuing ties // which might need to be added. for (int i=(int)pitches.size()-1; i>=2; i--) { if ((tiestates[i] == TIESTOP) && (tiestates[i-1] == TIESTART) && (tiestates[i-2] == TIESTART)) { tiecorrections[i-1] = TIECONT; tiestates[i-1] = TIECONT; output += 1; } else if ((tiestates[i] == TIECONT) && (tiestates[i-1] == TIESTART) && (tiestates[i-2] == TIESTART)) { tiecorrections[i-1] = TIECONT; tiestates[i-1] = TIECONT; output += 1; } } return output; } ////////////////////////////// // // getPitchesAndTies -- // void getPitchesAndTies(HumdrumFile& infile, vector& lines, vector& pitches, vector& tiestates, int index, vector& localindex) { int pitch; int tiestate; lines.reserve(infile.getNumLines()); lines.resize(0); pitches.reserve(infile.getNumLines()); pitches.resize(0); tiestates.reserve(infile.getNumLines()); tiestates.resize(0); localindex.reserve(infile.getNumLines()); localindex.resize(0); int pindex = index; // the primary index for (int i=0; i