// // Programmer: Craig Stuart Sapp // Creation Date: Sat Jul 19 12:09:12 PDT 2003 // Last Modified: Tue Jul 22 21:01:22 PDT 2003 // Last Modified: Sun Sep 7 10:42:09 PDT 2003 (added multiple systems) // Last Modified: Mon Dec 6 22:09:12 PST 2004 (minor improvements) // Filename: ...sig/examples/all/chor2scor.cpp // Web Address: http://sig.sapp.org/examples/museinfo/score/chor2scor.cpp // Syntax: C++; museinfo // // Description: Convert a Humdrum chorale file into a SCORE data file. // #include "humdrum.h" #include #include #include #include #include using namespace std; // function declarations void checkOptions (Options& opts, int argc, char* argv[]); void recheckOptions (Options& opts, char* command, const char* string); void example (void); void usage (const char* command); void convertToScore (ostream& output, HumdrumFile& infile, int segment, vector& breaks); void printNote (ostream& output, const char* data, double hpos, HumdrumFile& infile, int line, int staff, int direction, int voice); void printStaffInfo (ostream& output, HumdrumFile& infile, int segment); int noteheadtype (double duration); void printMeasure (ostream& output, HumdrumFile& infile, int line, double hpos, int measurecount, int systemno); void printHarm (ostream& output, const char* text, double hpos, HumdrumFile& infile, int harmspine); void printTrailer (ostream& output); int getdots (double duration, int voice); int getflags (double duration); double makeaccidental (HumdrumFile& infile, int line, int voice, vector& lkey); void resetkey (void); int peekAccidental (HumdrumFile& infile, int line, int voice, vector& lkey); double getHpos (HumdrumFile& infile, int line, double start = -1, double ending = -1); void generateBeams (ostream& output, HumdrumFile& infile, int voice, int startline, int stopline); void checkForBeam (ostream& output, HumdrumFile& infile, int voice, vector& index, int i); double getBeamStart (double vpos1, double vpos2, int dir); double getBeamEnd (double vpos1, double vpos2, int dir); void fillnindex (HumdrumFile& infile, vector >& nindex); void initoffset (vector >& offset, vector >& nindex); void storeoffset (double offset, int voice, int line); double getoffset (const char* lower, const char* upper); void printTitle (ostream& output, const char* title); void printKeyInfo (ostream& output, const char* key, double hpos, double vpos); void calculateBreaks (vector& breaks, HumdrumFile& infile, int lines); void makeFilename (char* buffer, const char* zbasename, char* ext, int total, int n); int findHarmSpine (HumdrumFile& infile); int findHarmSpine (HumdrumRecord& aRecord); // global variables Options options; // database for command-line arguments int debugQ = 0; // used with --debug option int quietQ = 0; // used with -q option double scale = 0.6; // used with -s option int readQ = 1; // used with -R option int harmonyQ = 1; // used with -H option int lines = 1; // used with -l option char inputbase[1024] = {0}; // used with -o option (for %b expansion) char zbasename[1024] = {0}; // used with -o option char extension[1024] = {0}; // used with -o option vector xtie(4); // for keeping track of ties vector key(7); // for keeping track of key vector > vkey(4); // for keeping track of accidentals vector > offsets(4); // for keeping track of beam offsets vector > nindex(4); // for keeping track of beam offsets vector breaks; // for keeping track of line breaks /////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { checkOptions(options, argc, argv); HumdrumFile infile; string filenameIn = options.getArg(1); infile.read(filenameIn.c_str()); infile.analyzeRhythm(); int i; if (readQ) { for (i=0; iopen(buffer); convertToScore(*output, infile, i, breaks); output->close(); delete output; } else { if (!quietQ) { cout << "ZZZ System " << i+1 << "/" << lines << " ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" << endl; } convertToScore(cout, infile, i, breaks); } } return 0; } /////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // makeFilename -- // void makeFilename(char* buffer, const char* zbasename, char* ext, int total, int n) { if (total > 10 && n < 10) { sprintf(buffer, "%s0%d.%s", zbasename, n+1, ext); } else if (total > 100 && n < 10) { sprintf(buffer, "%s00%d.%s", zbasename, n+1, ext); } else if (total > 100 && n < 100) { sprintf(buffer, "%s00%d.%s", zbasename, n+1, ext); } else { sprintf(buffer, "%s%d.%s", zbasename, n+1, ext); } } /////////////////////////////// // // calculateBreaks -- determine line breaks in the music // void calculateBreaks(vector& breaks, HumdrumFile& infile, int lines) { vector items; items.reserve(infile.getNumLines()); if (lines <= 1) { return; } int temp; vector explicitbreaks; explicitbreaks.reserve(infile.getNumLines()); int i; for (i=1; i=0; j--) { if (infile[items[j]].getType() == E_humrec_data_measure) { durafter = infile[items[j]].getAbsBeat(); divbefore = j; break; } } dis1 = duron - durbefore; dis2 = durafter - duron; if (dis1 < dis2) { breaks.push_back(items[divbefore]); } else { breaks.push_back(items[divafter]); } } if (!quietQ) { for (i=0; i<(int)breaks.size(); i++) { cout << "ZZZ Break " << i+1 << ": " << breaks[i]+1 << endl; } } } ////////////////////////////// // // printTitle -- // void printTitle(ostream& output, const char* title) { int i; int length = strlen(title); for (i=0; i >& offsets, vector >& nindex) { int i; offsets.resize(4); for (i=0; i<4; i++) { offsets[i].resize(nindex[i].size()); fill(offsets[i].begin(), offsets[i].end(), 0.0); } } ////////////////////////////// // // fillnindex -- create an index of the notes in each voice // for beam maintenance. // void fillnindex(HumdrumFile& infile, vector >& nindex) { int i, j; for (i=0; i<4; i++) { nindex[i].reserve(infile.getNumLines()); nindex[i].resize(0); for (j=0; j 0) { if (keynum >= 1) key[3] = 1; // F if (keynum >= 2) key[0] = 1; // C if (keynum >= 3) key[4] = 1; // G if (keynum >= 4) key[1] = 1; // D if (keynum >= 5) key[5] = 1; // A if (keynum >= 6) key[2] = 1; // E if (keynum >= 7) key[6] = 1; // B } } ////////////////////////////// // // printStaffInfo -- print staff, keysignature, Title, and meter // // 40% p4 = 2:-45 3:-67 4:-112 // 50% p4 = 2:-36 3:-48 4:-84 // 60% p4 = 2:-30 3:-37 4:-67 // 100% p4 = 2:-18 3:-12 4:-30 // // staff 2 (tenor) vertical position calculated from this formula: // p4 = -18/p5 // staff 3 (alto) vertical position calculated from this formula (approximate) // p4 = -6*2/(p5*p5) // staff 3 (soprano) vertical position calculated from this formula: // p4 = -6*2/(p5*p5) - 18/p5 // void printStaffInfo(ostream& output, HumdrumFile& infile, int segment) { double trebleoffset = (int)(-6.0 * 2.0 / (scale*scale) + 0.5); // fix approximation for 60% and 40% scalings: if (scale == 0.6) { trebleoffset = -37.0; } else if (scale == 0.4) { trebleoffset = -67.0; } // print bass staff: output << "8 1 0 0 " << scale << " 200\n"; // print tenor staff: output << "8 2 0 " << (-18.0/scale) << " " << scale << " 200\n"; // print alto staff: output << "8 3 0 " << trebleoffset << " " << scale << " 200\n"; // print treble staff: output << "8 4 0 " << (trebleoffset - 18.0/scale) << " " << scale << " 200\n"; // print bass clef: output << "3 1 2 0 1\n"; // print bass clef: output << "3 2 2 0 1\n"; // print treble clef: output << "3 3 2 0 0\n"; // print treble clef: output << "3 4 2 0 0\n"; // print opening barlines output << "14 1 0 4 0\n"; output << "14 1 0 4 8\n"; // print key signatures int i; int keynum = 0; for (i=0; i 0) { output << "_00" << bhnum << ". "; printTitle(output, title); output << "\n"; } else { output << "_00"; printTitle(output, title); output << "\n"; } } // // print final barline // output << "14 1 200 4 2\n"; } ////////////////////////////// // // convertToScore -- convert humdrum data into a SCORE file // void convertToScore(ostream& output, HumdrumFile& infile, int segment, vector& breaks) { int i; double hpos = 0.0; double lastharmhpos = 0.0; const char* nextkey = NULL; printStaffInfo(output, infile, segment); int startline = 0; int stopline = 0; if (breaks.size() == 0) { startline = 0; stopline = infile.getNumLines() - 1; } else { if (segment == 0) { startline = 0; } else { startline = breaks[segment-1]; } if (segment == lines - 1) { stopline = infile.getNumLines() - 1; } else { stopline = breaks[segment]; } } int measureitem = 0; int harmspine = findHarmSpine(infile); int staff = 0; int direction = 0; int voice = 0; int length; for (i=startline; i<=stopline; i++) { hpos = getHpos(infile, i, infile[startline].getAbsBeat(), infile[stopline].getAbsBeat()); if (infile[i].isInterpretation()) { if (infile[i].isInterpretation()) { length = strlen(infile[i][0]); if ((infile[i][0][length-1] == ':') && (Convert::kernToBase40(infile[i][0]) > 0)) { nextkey = infile[i][0]; } } } else if (infile[i].isMeasure()) { printMeasure(output, infile, i, hpos, measureitem++, segment); } else if (infile[i].isData()) { // output << infile[i].getAbsBeat() << ":\t" << hpos << endl; // check bass note if (strcmp(infile[i][0], ".") != 0) { staff = 1; voice = 0; direction = 20; printNote(output, infile[i][0], hpos, infile, i, staff, direction, voice); } // check tenor note if (strcmp(infile[i][1], ".") != 0) { staff = 2; voice = 1; direction = 10; printNote(output, infile[i][1], hpos, infile, i, staff, direction, voice); } // check alto note if (strcmp(infile[i][2], ".") != 0) { staff = 3; voice = 2; direction = 20; printNote(output, infile[i][2], hpos, infile, i, staff, direction, voice); } // check soprano note if (strcmp(infile[i][3], ".") != 0) { staff = 4; voice = 3; direction = 10; printNote(output, infile[i][3], hpos, infile, i, staff, direction, voice); } // print **harm data harmspine = findHarmSpine(infile[i]);; if ((harmspine >= 0) && (strcmp(infile[i][harmspine], ".") != 0)) { if (nextkey != NULL) { printKeyInfo(output, nextkey, (hpos - lastharmhpos)/2.0+lastharmhpos+scale, -9); nextkey = NULL; } printHarm(output, infile[i][harmspine], hpos, infile, harmspine); lastharmhpos = hpos; } } } for (i=0; i<4; i++) { generateBeams(output, infile, i, startline, stopline); } printTrailer(output); } ////////////////////////////// // // findHarmSpine -- find the spine number for the **harm data // int findHarmSpine(HumdrumRecord& aRecord) { int output = -1; if (harmonyQ == 0) { return output; } int i; for (i=0; i19 and (p4<8 or p5<8) then p4=p4+0.5, p5=p5+0.5\n" // "IF p1=6 and p7>19 and (p4<6 or p5<6) then p4=p4+0.5, p5=p5+0.5\n" // "IF p1=6 and p7>19 and (p4<4 or p5<4) then p4=p4+0.5, p5=p5+0.5\n" "AD 99\n" "STM 99\n" "LJ\n" "1 4\n\n\n" // These next lines fix extra low fermatas so that they do not collide // with the harmonic analysis line. These commands have to go below the // STM 99 command: "IF p1=1 and p2=1 and p11=-14 and p4=2 then p8=-3\n" "IF p1=1 and p2=1 and p11=-14 and p4=1 then p8=-3\n" "IF p1=1 and p2=1 and p11=-14 and p4=0 then p8=-3, p14=0.5\n" "IF p1=1 and p2=1 and p11=-14 and p4=-1 then p8=-3.75, p14=0.75\n" ; } ////////////////////////////// // // printHarm -- print Harmonic analysis // void printHarm(ostream& output, const char* text, double hpos, HumdrumFile& infile, int harmspine) { if (strchr(text, 'r') != NULL) { return; } output << "t 1 " << hpos << " -7 0 0 0 0 90\n"; output << "_29" ; int i; int length = strlen(text); for (i=0; i 0) && (measurecount == 0)) { // don't draw the measure line if it is of type 0 switch (btype) { case 0: case 1: case 3: // do nothing -- supress printing of this barline break; case 6: case 5: btype = 4; // no break; case 4: output << "14 1 " << hposition << " 4 " << btype << "\n"; break; } } else { output << "14 1 " << hposition << " 4 " << btype << "\n"; } int measureno = 0; // print measure number, if it is there if ((systemno > 0) && (measurecount == 0)) { // print measure number at start of system before clefs if (sscanf(data, "=%d", &measureno)) { output << "10 4 " << 0 << " 13 " << measureno << " 0.8 1\n"; output << "I\nCM\n\n"; } } else if (hposition < 199.8) { if (sscanf(data, "=%d", &measureno)) { output << "10 4 " << hposition << " 13 " << measureno << " 0.8 1\n"; output << "I\nCM\n\n"; } } resetkey(); } ////////////////////////////// // // getoffset -- return the note offset to avoid collisions due // to closeness of two voices on the same staff. // double getoffset(const char* lower, const char* upper) { if (strcmp(lower, ".") == 0) { return 0; } if (strcmp(upper, ".") == 0) { return 0; } int lowp = Convert::kernToBase40(lower); int upp = Convert::kernToBase40(upper); if ((upp - lowp > 0) && (upp - lowp < 10)) { return 10; } int lowtype = noteheadtype(Convert::kernToDuration(lower)); int uptype = noteheadtype(Convert::kernToDuration(upper)); if ((upp - lowp >= 0) && (upp - lowp < 5)) { if (lowtype != uptype) { return 10; } } return 0; } ////////////////////////////// // // makeaccidental -- // double makeaccidental(HumdrumFile& infile, int line, int voice, vector& lkey) { int acc = 0; int length = strlen(infile[line][voice]); int i; for (i=0; i= 40)) { return output + fraction; } int dup = Convert::base40ToDiatonic(b40u) % 7; int ddn = Convert::base40ToDiatonic(b40d) % 7; int dint = dup - ddn; if (dint < 0) { dint += 7; } // Here are the accidental offset separations by diatonic interval for // sharps, flats and naturals (doubles to be done later, if ever) // // bot top 2 3 4 5 6 7 // b b 0.24 0.24 0.15 0.15 0.12 0.00 // b s 0.25 0.25 0.25 0.20 0.18 0.11 // b n 0.22 0.22 0.18 0.12 0.12 0.00 // s b 0.24 0.24 0.24 0.18 0.00 0.00 // s s 0.29 0.29 0.29 0.22 0.20 0.00 // s n 0.24 0.24 0.23 0.11 0.11 0.00 // n b 0.24 0.24 0.20 0.13 0.00 0.00 // n s 0.26 0.26 0.25 0.20 0.12 0.00 // n n 0.22 0.22 0.16 0.12 0.00 0.00 // // ignoring spacing when dealing with double sharps or double flats if ((poutput > 3) || (output > 3)) { return output + fraction; } // ignoring spacing for unison accidentals: if (dint == 0) { return output + fraction; } switch (output * 10 + poutput) { case 11: // b b 0.24 0.24 0.15 0.15 0.12 0.00 switch (dint) { case 1: case 2: fraction = 0.24; break; case 3: case 4: fraction = 0.15; break; case 5: fraction = 0.12; break; case 6: fraction = 0.12; break; } break; case 12: // b s 0.25 0.25 0.25 0.20 0.18 0.11 switch (dint) { case 1: case 2: case 3: fraction = 0.25; break; case 4: fraction = 0.20; break; case 5: fraction = 0.18; break; case 6: fraction = 0.11; break; } break; case 13: // b n 0.22 0.22 0.18 0.12 0.12 0.00 switch (dint) { case 1: case 2: fraction = 0.22; break; case 3: fraction = 0.18; break; case 4: case 5: fraction = 0.12; break; } break; case 21: // s b 0.24 0.24 0.24 0.18 0.00 0.00 switch (dint) { case 1: case 2: case 3: fraction = 0.24; break; case 4: fraction = 0.18; break; } break; case 22: // s s 0.29 0.29 0.29 0.22 0.20 0.00 switch (dint) { case 1: case 2: case 3: fraction = 0.29; break; case 4: fraction = 0.22; break; case 5: fraction = 0.20; break; } break; case 23: // s n 0.24 0.24 0.23 0.11 0.11 0.00 switch (dint) { case 1: case 2: fraction = 0.24; break; case 3: fraction = 0.22; break; case 4: case 5: fraction = 0.11; break; } break; case 31: // n b 0.24 0.24 0.20 0.13 0.00 0.00 switch (dint) { case 1: case 2: fraction = 0.24; break; case 3: fraction = 0.20; break; case 4: fraction = 0.13; break; } break; case 32: // n s 0.26 0.26 0.25 0.20 0.12 0.00 switch (dint) { case 1: case 2: fraction = 0.26; break; case 3: fraction = 0.25; break; case 4: fraction = 0.20; break; case 5: fraction = 0.12; break; } break; case 33: // n n 0.22 0.22 0.16 0.12 0.00 0.00 switch (dint) { case 1: case 2: fraction = 0.22; break; case 3: fraction = 0.16; break; case 4: fraction = 0.12; break; } break; } return output + fraction; } ////////////////////////////// // // peekAccidental -- // int peekAccidental(HumdrumFile& infile, int line, int voice, vector& lkey) { if (strcmp(infile[line][voice], ".") == 0) { return 0; } int acc = 0; int length = strlen(infile[line][voice]); int i; for (i=0; i 0) { voffset += -0.5; } else { voffset += 0.5; } if ((tiedir > 0) && (vpos > 11) && (vpos % 2 == 0)) { voffset += -1; } else if ((tiedir > 0) && (vpos > 11) && (vpos % 2 == 1)) { voffset += 0.5; } if ((tiedir < 0) && (vpos < 4) && (vpos % 2 == 0)) { voffset += 0.5; } else if ((tiedir < 0) && (vpos < 2) && (vpos % 2 == 1)) { voffset -= 0.5; } if (strchr(data, '[') != NULL) { xtie[voice] = hpos; } else if (strchr(data, '_') != NULL) { output << "5 " << staff << " " << xtie[voice] - 0.25 << " " << vpos+voffset << " " << vpos+voffset << " " << hpos + roffset << " " << tiedir << " -2 0 0 0 0 0.6\n"; if ((tiedir < 0) && (vpos <= 3)) { output << "I\nCR\n\n"; } xtie[voice] = hpos; } else if (strchr(data, ']') != NULL) { output << "5 " << staff << " " << xtie[voice] - 0.25 << " " << vpos+voffset << " " << vpos+voffset << " " << hpos + roffset << " " << tiedir << " -2 0 0 0 0 0.6\n"; if ((tiedir < 0) && (vpos <= 3)) { output << "I\nCR\n\n"; } xtie[voice] = 0.0; } else { xtie[voice] = 0.0; } } } ////////////////////////////// // // storeoffset -- store the note offset so that the beams can be // coordinated when they are written at a later stage. // void storeoffset(double offset, int voice, int line) { int index = -1; int i; for (i=0; i<(int)nindex[voice].size(); i++) { if (nindex[voice][i] == line) { index = i; } } if (index >= 0) { offsets[voice][index] = offset; } } ////////////////////////////// // // getflags -- // int getflags(double duration) { if (duration <= 1.0/128.0) { return 8; } else if (duration < 1.0/64.0 ) { return 7; } else if (duration < 1.0/32.0 ) { return 6; } else if (duration < 1.0/16.0 ) { return 5; } else if (duration < 1.0/8.0 ) { return 4; } else if (duration < 1.0/4.0 ) { return 3; } else if (duration < 1.0/2.0 ) { return 2; } else if (duration < 1.0/1.0 ) { return 1; } else { return 0; } } ////////////////////////////// // // getdots -- return the number of rhythm augmentation dots // int getdots(double duration, int voice) { char buffer[128] = {0}; Convert::durationToKernRhythm(buffer, duration); int i = 0; int count = 0; while (buffer[i] != '\0') { if (buffer[i] == '.') { count++; } i++; } if ((count > 0) && (voice == 0 || voice == 2)) { count += 10; // 10 multiplied later } return count; } ////////////////////////////// // // noteheadtype -- // int noteheadtype(double duration) { if (duration < 1.9) { return 0; } else if (duration < 3.9) { return 1; } else if (duration < 7.9) { return 2; } else { return 3; } } ////////////////////////////// // // recheckOptions -- validate and process command-line options again // void recheckOptions(Options& opts, char* command, const char* string) { char buffer[1024] = {0}; strncpy(buffer, string, 1000); char* array[1024] = {0}; int argc = 0; array[argc++] = command; array[argc++] = strtok(buffer, " \t\n"); if (array[argc-1] != NULL) { while ((array[argc++] = strtok(NULL, " \t\n")) != NULL) { if (argc > 1000) { break; } } } argc--; opts.process(argc, array); debugQ = opts.getBoolean("debug"); scale = opts.getDouble("scale"); lines = opts.getInteger("lines"); quietQ = opts.getBoolean("quiet"); readQ = !opts.getBoolean("do-not-read-file-options"); harmonyQ = !opts.getBoolean("no-harmony"); char buffer2[1024] = {0}; char* ptr; if (options.getBoolean("output")) { strcpy(buffer2, options.getString("output").c_str()); if ((ptr = strrchr(buffer2, '.')) != NULL) { strcpy(extension, ptr+1); strcpy(zbasename, options.getString("output").c_str()); ptr = strrchr(zbasename, '.'); ptr[0] = '\0'; } else { strcpy(zbasename, options.getString("output").c_str()); extension[0] = '\0'; } } if ((strcmp(zbasename, "%b") == 0) && (strlen(inputbase) > 0)) { strcpy(zbasename, inputbase); } } ////////////////////////////// // // checkOptions -- validate and process command-line options. // void checkOptions(Options& opts, int argc, char* argv[]) { opts.define("debug=b", "trace input parsing"); opts.define("q|quiet=b", "do not print line parsing info"); opts.define("H|no-harmony=b", "do not print harmony under music"); opts.define("s|scale=d:0.6", "staff scaling"); opts.define("R|do-not-read-file-options=b","prevent reading opts in file"); opts.define("l|lines=i:1", "number of lines"); opts.define("o|output=s:file.pmx", "output file template"); opts.define("author=b", "author of the program"); opts.define("version=b", "compilation information"); opts.define("example=b", "example usage"); opts.define("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, July 2003" << endl; exit(0); } else if (opts.getBoolean("version")) { cout << argv[0] << ", version: September 2003" << endl; cout << "compiled: " << __DATE__ << endl; cout << MUSEINFO_VERSION << endl; exit(0); } else if (opts.getBoolean("help")) { usage(opts.getCommand().c_str()); exit(0); } else if (opts.getBoolean("example")) { example(); exit(0); } debugQ = opts.getBoolean("debug"); scale = opts.getDouble("scale"); lines = opts.getInteger("lines"); quietQ = opts.getBoolean("quiet"); readQ = !opts.getBoolean("do-not-read-file-options"); char buffer[1024] = {0}; char* ptr; if (options.getBoolean("output")) { strcpy(buffer, options.getString("output").c_str()); if ((ptr = strrchr(buffer, '.')) != NULL) { strcpy(extension, ptr+1); strcpy(zbasename, options.getString("output").c_str()); ptr = strrchr(zbasename, '.'); ptr[0] = '\0'; } else { strcpy(zbasename, options.getString("output").c_str()); extension[0] = '\0'; } } char tbuffer[1024] = {0}; strcpy(tbuffer, options.getArg(1).c_str()); ptr = strrchr(tbuffer, '.'); if (ptr != NULL) { ptr[0] = '\0'; } ptr = strrchr(tbuffer, '/'); if (ptr != NULL) { strcpy(inputbase, &ptr[1]); } else { strcpy(inputbase, tbuffer); } if ((strcmp(zbasename, "%b") == 0) &&(strlen(inputbase) > 0)) { strcpy(zbasename, inputbase); } } ////////////////////////////// // // example -- example usage of the program // void example(void) { cout << " \n" << endl; } ////////////////////////////// // // usage -- gives the usage statement for the program // void usage(const char* command) { cout << " \n" << endl; } ////////////////////////////// // // generateBeams -- // void generateBeams(ostream& output, HumdrumFile& infile, int voice, int startline, int stopline) { int i; vector index; index.reserve(infile.getNumLines()); // fix this for loop to prevent starting at 0 // for (i=startline; i<=stopline; i++) { for (i=0; i<=stopline; i++) { if (infile[i].isData()) { if (strcmp(infile[i][voice], ".") == 0) { continue; } if (strchr(infile[i][voice], 'r') != NULL) { continue; } index.push_back(i); } } for (i=0; i<(int)index.size(); i++) { if ((index[i]>=startline) && (index[i]<=stopline)) { checkForBeam(output, infile, voice, index, i); } } } ////////////////////////////// // // checkForBeam -- see if a beam is supposed to start here // void checkForBeam(ostream& output, HumdrumFile& infile, int voice, vector& index, int ind) { int startbeat = 0; int endbeat = 0; // assume that there are no pickups less than a quarter note. int beat = (int)(infile[index[ind]].getAbsBeat()+ 0.001); double fraction = infile[index[ind]].getAbsBeat() - beat; int tbeat = 0; int j; for (j=ind; j<(int)index.size(); j++) { tbeat = (int)(infile[index[j]].getAbsBeat()+ 0.001); if (tbeat == beat) { endbeat = j; } else { break; } } for (j=ind; j>=0; j--) { tbeat = (int)(infile[index[j]].getAbsBeat()+ 0.001); if (tbeat == beat) { startbeat = j; } else { break; } } // don't beam quarter notes or larger if (startbeat == endbeat) { return; } // know that some beaming action necessary vector durs; durs.resize(endbeat-startbeat+1); fill(durs.begin(), durs.end(), 0.0); for (j=0; j<(int)durs.size(); j++) { durs[j] = Convert::kernToDuration(infile[index[j+startbeat]][voice]); } // beam on a case-by-case basis double hpos1 = 0.0; double hpos2 = 0.0; double hpos3 = 0.0; double vpos1 = 0.0; double vpos2 = 0.0; double vpos3 = 0.0; ////////// int pitch1; int pitch2; int pitch3; int dir = 0; // beam two eighth notes together if ((durs.size() == 2) && (durs[0] == 0.5) && (durs[1] == 0.5) && fraction < 0.001) { hpos1 = getHpos(infile, index[startbeat]); hpos2 = getHpos(infile, index[endbeat]); pitch1 = Convert::kernToBase40(infile[index[startbeat]][voice]); pitch2 = Convert::kernToBase40(infile[index[endbeat]][voice]); switch (voice) { case 0: case 2: if (voice == 0) { vpos1 = Convert::base40ToScoreVPos(pitch1, 1); vpos2 = Convert::base40ToScoreVPos(pitch2, 1); } else { vpos1 = Convert::base40ToScoreVPos(pitch1, 0); vpos2 = Convert::base40ToScoreVPos(pitch2, 0); } dir = 21; output << "6 " << voice+1 << " " << hpos1 << " " << getBeamStart(vpos1, vpos2, 20) << " " << getBeamEnd(vpos1, vpos2, 20) << " " << hpos2 << " " << dir; if (offsets[voice][startbeat] != 0.0) { output << " 0 0 0 0 0 0 " << offsets[voice][startbeat]; if (offsets[voice][endbeat] != 0.0) { output << " " << offsets[voice][endbeat]; } } else if (offsets[voice][endbeat] != 0.0) { output << " 0 0 0 0 0 0 0 " << offsets[voice][endbeat]; } output << "\n"; break; case 1: case 3: if (voice == 1) { vpos1 = Convert::base40ToScoreVPos(pitch1, 1); vpos2 = Convert::base40ToScoreVPos(pitch2, 1); } else { vpos1 = Convert::base40ToScoreVPos(pitch1, 0); vpos2 = Convert::base40ToScoreVPos(pitch2, 0); } dir = 11; output << "6 " << voice+1 << " " << hpos1 << " " << getBeamStart(vpos1, vpos2, 10) << " " << getBeamEnd(vpos1, vpos2, 10) << " " << hpos2 << " " << dir; if (offsets[voice][startbeat] != 0.0) { output << " 0 0 0 0 0 0 " << offsets[voice][startbeat]; if (offsets[voice][endbeat] != 0.0) { output << " " << offsets[voice][endbeat]; } } else if (offsets[voice][endbeat] != 0.0) { output << " 0 0 0 0 0 0 0 " << offsets[voice][endbeat]; } output << "\n"; break; } } ////////// // beam two sixteenth notes together on the half beat else if ((durs.size() == 2) && (durs[0] == 0.25) && (durs[1] == 0.25) && fraction == 0.5) { hpos1 = getHpos(infile, index[startbeat]); hpos2 = getHpos(infile, index[endbeat]); pitch1 = Convert::kernToBase40(infile[index[startbeat]][voice]); pitch2 = Convert::kernToBase40(infile[index[endbeat]][voice]); switch (voice) { case 0: case 2: if (voice == 0) { vpos1 = Convert::base40ToScoreVPos(pitch1, 1); vpos2 = Convert::base40ToScoreVPos(pitch2, 1); } else { vpos1 = Convert::base40ToScoreVPos(pitch1, 0); vpos2 = Convert::base40ToScoreVPos(pitch2, 0); } dir = 22; output << "6 " << voice+1 << " " << hpos1 << " " << getBeamStart(vpos1, vpos2, 20) << " " << getBeamEnd(vpos1, vpos2, 20) << " " << hpos2 << " " << dir; if (offsets[voice][startbeat] > 0.0) { output << " 0 0 0 0 0 0 " << offsets[voice][startbeat]; if (offsets[voice][endbeat] > 0.0) { output << " " << offsets[voice][endbeat]; } } else if (offsets[voice][endbeat] > 0.0) { output << " 0 0 0 0 0 0 0 " << offsets[voice][endbeat]; } output << "\n"; break; case 1: case 3: if (voice == 1) { vpos1 = Convert::base40ToScoreVPos(pitch1, 1); vpos2 = Convert::base40ToScoreVPos(pitch2, 1); } else { vpos1 = Convert::base40ToScoreVPos(pitch1, 0); vpos2 = Convert::base40ToScoreVPos(pitch2, 0); } dir = 12; output << "6 " << voice+1 << " " << hpos1 << " " << getBeamStart(vpos1, vpos2, 10) << " " << getBeamEnd(vpos1, vpos2, 10) << " " << hpos2 << " " << dir; if (offsets[voice][startbeat] > 0.0) { output << " 0 0 0 0 0 0 " << offsets[voice][startbeat]; if (offsets[voice][endbeat] > 0.0) { output << " " << offsets[voice][endbeat]; } } else if (offsets[voice][endbeat] > 0.0) { output << " 0 0 0 0 0 0 0 " << offsets[voice][endbeat]; } output << "\n"; break; } } ////////// // beam two sixteenth notes starting on the beat (long note or rest // on the second half of the beat else if (((durs.size() == 2) && (durs[0] == 0.25) && (durs[1] == 0.25) && fraction == 0.0) || ((durs.size() == 3) && (durs[0] == 0.25) && (durs[1] == 0.25) && (durs[2] >= 1.0) && fraction == 0.0) ) { hpos1 = getHpos(infile, index[startbeat]); hpos2 = getHpos(infile, index[startbeat+1]); pitch1 = Convert::kernToBase40(infile[index[startbeat]][voice]); pitch2 = Convert::kernToBase40(infile[index[startbeat+1]][voice]); switch (voice) { case 0: case 2: if (voice == 0) { vpos1 = Convert::base40ToScoreVPos(pitch1, 1); vpos2 = Convert::base40ToScoreVPos(pitch2, 1); } else { vpos1 = Convert::base40ToScoreVPos(pitch1, 0); vpos2 = Convert::base40ToScoreVPos(pitch2, 0); } dir = 22; output << "6 " << voice+1 << " " << hpos1 << " " << getBeamStart(vpos1, vpos2, 20) << " " << getBeamEnd(vpos1, vpos2, 20) << " " << hpos2 << " " << dir; if (offsets[voice][startbeat] > 0.0) { output << " 0 0 0 0 0 0 " << offsets[voice][startbeat]; if (offsets[voice][startbeat+1] > 0.0) { output << " " << offsets[voice][startbeat+1]; } } else if (offsets[voice][startbeat+1] > 0.0) { output << " 0 0 0 0 0 0 0 " << offsets[voice][startbeat+1]; } output << "\n"; break; case 1: case 3: if (voice == 1) { vpos1 = Convert::base40ToScoreVPos(pitch1, 1); vpos2 = Convert::base40ToScoreVPos(pitch2, 1); } else { vpos1 = Convert::base40ToScoreVPos(pitch1, 0); vpos2 = Convert::base40ToScoreVPos(pitch2, 0); } dir = 12; output << "6 " << voice+1 << " " << hpos1 << " " << getBeamStart(vpos1, vpos2, 10) << " " << getBeamEnd(vpos1, vpos2, 10) << " " << hpos2 << " " << dir; if (offsets[voice][startbeat] > 0.0) { output << " 0 0 0 0 0 0 " << offsets[voice][startbeat]; if (offsets[voice][startbeat+1] > 0.0) { output << " " << offsets[voice][startbeat+1]; } } else if (offsets[voice][startbeat+1] > 0.0) { output << " 0 0 0 0 0 0 0 " << offsets[voice][startbeat+1]; } output << "\n"; break; } } ////////// // beam one eighth and two sixteenth notes together else if ((durs.size() == 3) && (durs[0] == 0.5) && (durs[1] == 0.25) && (durs[2] == 0.25) && fraction == 0.0) { hpos1 = getHpos(infile, index[startbeat]); hpos2 = getHpos(infile, index[startbeat+1]); hpos3 = getHpos(infile, index[endbeat]); pitch1 = Convert::kernToBase40(infile[index[startbeat]][voice]); pitch2 = Convert::kernToBase40(infile[index[startbeat+1]][voice]); pitch3 = Convert::kernToBase40(infile[index[endbeat]][voice]); switch (voice) { case 0: case 2: if (voice == 0) { vpos1 = Convert::base40ToScoreVPos(pitch1, 1); vpos2 = Convert::base40ToScoreVPos(pitch2, 1); vpos3 = Convert::base40ToScoreVPos(pitch3, 1); } else { vpos1 = Convert::base40ToScoreVPos(pitch1, 0); vpos2 = Convert::base40ToScoreVPos(pitch2, 0); vpos3 = Convert::base40ToScoreVPos(pitch3, 0); } dir = 21; output << "6 " << voice+1 << " " << hpos1 << " " << getBeamStart(vpos1, vpos3, 20) << " " << getBeamEnd(vpos1, vpos3, 20) - 0.5 << " " << hpos3 << " " << dir << " 0 0 " << 11 << " " << hpos2 << " " << hpos3; if (offsets[voice][startbeat] > 0.0) { output << " 0 " << offsets[voice][startbeat]; if (offsets[voice][endbeat] > 0.0) { output << " " << offsets[voice][endbeat]; } } else if (offsets[voice][endbeat] > 0.0) { output << " 0 0 " << offsets[voice][endbeat]; } output << "\n"; break; case 1: case 3: if (voice == 1) { vpos1 = Convert::base40ToScoreVPos(pitch1, 1); vpos2 = Convert::base40ToScoreVPos(pitch2, 1); vpos3 = Convert::base40ToScoreVPos(pitch3, 1); } else { vpos1 = Convert::base40ToScoreVPos(pitch1, 0); vpos2 = Convert::base40ToScoreVPos(pitch2, 0); vpos3 = Convert::base40ToScoreVPos(pitch3, 0); } dir = 11; if (vpos2 > vpos1 && vpos2 > vpos3) { output << "6 " << voice+1 << " " << hpos1 << " " << getBeamEnd(vpos1, vpos3, 10) + 0.5 << " " << getBeamEnd(vpos1, vpos3, 10) + 0.5 << " " << hpos3 << " " << dir << " 0 0 " << 11 << " " << hpos2 << " " << hpos3; } else { output << "6 " << voice+1 << " " << hpos1 << " " << getBeamStart(vpos1, vpos3, 10) << " " << getBeamEnd(vpos1, vpos3, 10) + 0.5 << " " << hpos3 << " " << dir << " 0 0 " << 11 << " " << hpos2 << " " << hpos3; } if (offsets[voice][startbeat] > 0.0) { output << " 0 " << offsets[voice][startbeat]; if (offsets[voice][endbeat] > 0.0) { output << " " << offsets[voice][endbeat]; } } else if (offsets[voice][endbeat] > 0.0) { output << " 0 0 " << offsets[voice][endbeat]; } output << "\n"; break; } } ////////// // beam two sixteenths and one eighth note together else if ((durs.size() == 3) && (durs[0] == 0.25) && (durs[1] == 0.25) && (durs[2] == 0.5) && fraction == 0.0) { hpos1 = getHpos(infile, index[startbeat]); hpos2 = getHpos(infile, index[startbeat+1]); hpos3 = getHpos(infile, index[endbeat]); pitch1 = Convert::kernToBase40(infile[index[startbeat]][voice]); pitch2 = Convert::kernToBase40(infile[index[startbeat+1]][voice]); pitch3 = Convert::kernToBase40(infile[index[endbeat]][voice]); switch (voice) { case 0: case 2: if (voice == 0) { vpos1 = Convert::base40ToScoreVPos(pitch1, 1); vpos2 = Convert::base40ToScoreVPos(pitch2, 1); vpos3 = Convert::base40ToScoreVPos(pitch3, 1); } else { vpos1 = Convert::base40ToScoreVPos(pitch1, 0); vpos2 = Convert::base40ToScoreVPos(pitch2, 0); vpos3 = Convert::base40ToScoreVPos(pitch3, 0); } dir = 21; output << "6 " << voice+1 << " " << hpos1 << " " << getBeamStart(vpos1, vpos3, 20) << " " << getBeamEnd(vpos1, vpos3, 20) - 0.5 << " " << hpos3 << " " << dir << " 0 0 " << 11 << " " << hpos1 << " " << hpos2; if (offsets[voice][startbeat] > 0.0) { output << " 0 " << offsets[voice][startbeat]; if (offsets[voice][endbeat] > 0.0) { output << " " << offsets[voice][endbeat]; } } else if (offsets[voice][endbeat] > 0.0) { output << " 0 0 " << offsets[voice][endbeat]; } output << "\n"; break; case 1: case 3: if (voice == 1) { vpos1 = Convert::base40ToScoreVPos(pitch1, 1); vpos2 = Convert::base40ToScoreVPos(pitch2, 1); vpos3 = Convert::base40ToScoreVPos(pitch3, 1); } else { vpos1 = Convert::base40ToScoreVPos(pitch1, 0); vpos2 = Convert::base40ToScoreVPos(pitch2, 0); vpos3 = Convert::base40ToScoreVPos(pitch3, 0); } dir = 11; output << "6 " << voice+1 << " " << hpos1 << " " << getBeamStart(vpos1, vpos3, 10) << " " << getBeamEnd(vpos1, vpos3, 10) + 0.5 << " " << hpos3 << " " << dir << " 0 0 " << 11 << " " << hpos1 << " " << hpos2; if (offsets[voice][startbeat] > 0.0) { output << " 0 " << offsets[voice][startbeat]; if (offsets[voice][endbeat] > 0.0) { output << " " << offsets[voice][endbeat]; } } else if (offsets[voice][endbeat] > 0.0) { output << " 0 0 " << offsets[voice][endbeat]; } output << "\n"; break; } } ////////// // beam dotted eight and sixteenth else if ((durs.size() == 2) && (durs[0] == 0.75) && (durs[1] == 0.25) && fraction == 0.0) { hpos1 = getHpos(infile, index[startbeat]); hpos2 = getHpos(infile, index[endbeat]); pitch1 = Convert::kernToBase40(infile[index[startbeat]][voice]); pitch2 = Convert::kernToBase40(infile[index[endbeat]][voice]); switch (voice) { case 0: case 2: if (voice == 0) { vpos1 = Convert::base40ToScoreVPos(pitch1, 1); vpos2 = Convert::base40ToScoreVPos(pitch2, 1); } else { vpos1 = Convert::base40ToScoreVPos(pitch1, 0); vpos2 = Convert::base40ToScoreVPos(pitch2, 0); } dir = 21; output << "6 " << voice+1 << " " << hpos1 << " " << getBeamStart(vpos1, vpos2, 20) << " " << getBeamEnd(vpos1, vpos2, 20) << " " << hpos2 << " " << dir << " 0 0 " << 11 << " 0 " << hpos2; if (offsets[voice][startbeat] > 0.0) { output << " 0 " << offsets[voice][startbeat]; if (offsets[voice][endbeat] > 0.0) { output << " " << offsets[voice][endbeat]; } } else if (offsets[voice][endbeat] > 0.0) { output << " 0 0 " << offsets[voice][endbeat]; } output << "\n"; break; case 1: case 3: if (voice == 1) { vpos1 = Convert::base40ToScoreVPos(pitch1, 1); vpos2 = Convert::base40ToScoreVPos(pitch2, 1); } else { vpos1 = Convert::base40ToScoreVPos(pitch1, 0); vpos2 = Convert::base40ToScoreVPos(pitch2, 0); } dir = 11; output << "6 " << voice+1 << " " << hpos1 << " " << getBeamStart(vpos1, vpos2, 10) << " " << getBeamEnd(vpos1, vpos2, 10) << " " << hpos2 << " " << dir << " 0 0 " << 11 << " 0 " << hpos2; if (offsets[voice][startbeat] > 0.0) { output << " 0 " << offsets[voice][startbeat]; if (offsets[voice][endbeat] > 0.0) { output << " " << offsets[voice][endbeat]; } } else if (offsets[voice][endbeat] > 0.0) { output << " 0 0 " << offsets[voice][endbeat]; } output << "\n"; break; } } } ////////////////////////////// // // getHpos -- return the horizontal postion of an item in the score // double getHpos(HumdrumFile& infile, int line, double start, double ending) { static double startDur = -1; static double endDur = -1; if (startDur < 0) { startDur = start; } if (endDur < 0) { endDur = ending; } if (start >= 0.0) { startDur = start; } if (ending >= 0.0) { endDur = ending; } double beatwidth = endDur - startDur; double output; output = (infile[line].getAbsBeat() - startDur) / beatwidth * 190 + 10; output = ((int)(output*100.0 + 0.5))/100.0; return output; // originally: // output = infile[line].getAbsBeat() / infile.getTotalDuration() * 190 + 10; // output = ((int)(output*100.0 + 0.5))/100.0; } ////////////////////////////// // // getBeamStart -- // double getBeamStart(double vpos1, double vpos2, int dir) { double upbeam1[23][23] = {{0, 0, 0, 0, 0, 0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 7.75, 8.25, 9, 10, 11, 12, 13, 14, 15}, {0, 0, 0, 0, 0, 0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 7.75, 8.25, 9, 10, 11, 12, 13, 14, 15}, {0, 0, 0, 0, 0, 0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 7.75, 8.25, 9, 10, 11, 12, 13, 14, 15}, {0, 0, 0, 0, 0, 0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 7.75, 8.25, 9, 10, 11, 12, 13, 14, 15}, {1, 1, 1, 1, 1, 1, 1.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 7.75, 8.25, 9, 10, 11, 12, 13, 14, 15}, {2, 2, 2, 2, 2, 2, 2, 2.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 7.75, 8.25, 9, 10, 11, 12, 13, 14, 15}, {2, 2, 2, 2, 3, 3, 3, 3, 3.5, 3.5, 4.5, 5.5, 6.5, 7.5, 7.75, 8.25, 9, 10, 11, 12, 13, 14, 15}, {3, 3, 3, 3, 3, 4, 4, 4, 4, 4.5, 4.5, 5.5, 6.5, 7.5, 7.75, 8.25, 9, 10, 11, 12, 13, 14, 15}, {4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5.5, 5.5, 6.5, 7.5, 7.75, 8.25, 9, 10, 11, 12, 13, 14, 15}, {5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6.5, 6.5, 7.5, 7.75, 8.25, 9, 10, 11, 12, 13, 14, 15}, {6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7.5, 7.5, 7.75, 8.25, 9, 10, 11, 12, 13, 14, 15}, {7, 7, 7, 7, 7, 7, 7, 7, 7, 7.5, 7.5, 7.5, 7.5, 7.75, 7.75, 8.25, 9, 10, 11, 12, 13, 14, 15}, {8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8, 8, 8, 8, 8.25, 8.25, 9, 10, 11, 12, 13, 14, 15}, {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8.5, 8.5, 9, 8.5, 9, 9, 10, 11, 12, 13, 14, 15}, {9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 9.5, 10, 10, 11, 12, 13, 14, 15}, {10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 11, 11, 12, 13, 14, 15}, {11.5, 11.5, 11.5, 11.5, 11.5, 11.5, 11.5, 11.5, 11.5, 11.5, 11.5, 11.5, 11.5, 11.5, 11.5, 11.5, 11.5, 11.5, 12, 12, 13, 14, 15}, {12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 13, 13, 14, 15}, {13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 13.5, 14, 14, 15}, {14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 14.5, 15, 15}, {15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5, 16}, {16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5, 16.5}, {17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5}}; double downbeam1[23][23] = {{-1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5}, {-0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5}, {0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5}, {1, 1, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5}, {1, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5}, {1, 1.5, 2.5, 2.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5}, {1, 1.5, 2.5, 3.5, 3.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5}, {1, 1.5, 2.5, 3.5, 4.5, 4.5, 5.5, 5, 5.5, 5.5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}, {1, 1.5, 2.5, 3.5, 4.5, 5.5, 5.5, 6, 6, 6, 6, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5}, {1, 1.5, 2.5, 3.5, 4.5, 5.5, 6, 6, 6.5, 6.5, 6.5, 6.5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}, {1, 1.5, 2.5, 3.5, 4.5, 5.5, 6, 6.5, 6.5, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}, {1, 1.5, 2.5, 3.5, 4.5, 5.5, 6, 6.5, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9}, {1, 1.5, 2.5, 3.5, 4.5, 5.5, 6, 6.5, 7, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10}, {1, 1.5, 2.5, 3.5, 4.5, 5.5, 6, 6.5, 7, 8, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11}, {1, 1.5, 2.5, 3.5, 4.5, 5.5, 6, 6.5, 7, 8, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12}, {1, 1.5, 2.5, 3.5, 4.5, 5.5, 6, 6.5, 7, 8, 9, 10, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12}, {1, 1.5, 2.5, 3.5, 4.5, 5.5, 6, 6.5, 7, 8, 9, 10, 11, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13}, {1, 1.5, 2.5, 3.5, 4.5, 5.5, 6, 6.5, 7, 8, 9, 10, 11, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, {1, 1.5, 2.5, 3.5, 4.5, 5.5, 6, 6.5, 7, 8, 9, 10, 11, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, {1, 1.5, 2.5, 3.5, 4.5, 5.5, 6, 6.5, 7, 8, 9, 10, 11, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, {1, 1.5, 2.5, 3.5, 4.5, 5.5, 6, 6.5, 7, 8, 9, 10, 11, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, {1, 1.5, 2.5, 3.5, 4.5, 5.5, 6, 6.5, 7, 8, 9, 10, 11, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, {1, 1.5, 2.5, 3.5, 4.5, 5.5, 6, 6.5, 7, 8, 9, 10, 11, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}}; if (vpos1 < -3 || vpos2 < -3 || vpos1 > 22 || vpos2 > 22) { return vpos1; } switch (dir) { case 10: return upbeam1[(int)vpos1+3][(int)vpos2+3]; case 20: return downbeam1[(int)vpos1+3][(int)vpos2+3]; } return vpos1; } ////////////////////////////// // // getBeamEnd -- // double getBeamEnd(double vpos1, double vpos2, int dir) { double upbeam2[23][23] = {{0, 0, 0, 0, 1, 2, 2, 3, 4, 5, 6, 7, 8.5, 9, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {0, 0, 0, 0, 1, 2, 2, 3, 4, 5, 6, 7, 8.5, 9, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {0, 0, 0, 0, 1, 2, 2, 3, 4, 5, 6, 7, 8.5, 9, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {0, 0, 0, 0, 1, 2, 2, 3, 4, 5, 6, 7, 8.5, 9, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {0, 0, 0, 0, 1, 2, 3, 3, 4, 5, 6, 7, 8.5, 9, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {0.5, 0.5, 0.5, 0.5, 1, 2, 3, 4, 4, 5, 6, 7, 8.5, 9, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {0.5, 0.5, 0.5, 0.5, 1.5, 2, 3, 4, 5, 5, 6, 7, 8.5, 9, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {1.5, 1.5, 1.5, 1.5, 1.5, 2.5, 3, 4, 5, 6, 6, 7, 8.5, 9, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 3.5, 4, 5, 6, 7, 7, 8.5, 9, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 4.5, 5, 6, 7, 7.5, 8.5, 9, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 5.5, 6, 7, 7.5, 8, 9, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 6.5, 7, 7.5, 8, 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 7.5, 7.5, 8, 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.75, 8, 9, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {7.75, 7.75, 7.75, 7.75, 7.75, 7.75, 7.75, 7.75, 7.75, 7.75, 7.75, 7.75, 8.25, 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {8.25, 8.25, 8.25, 8.25, 8.25, 8.25, 8.25, 8.25, 8.25, 8.25, 8.25, 8.25, 8.25, 9, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5}, {12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13.5, 14.5, 15.5, 16.5, 17.5}, {13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14.5, 15.5, 16.5, 17.5}, {14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15.5, 16.5, 17.5}, {15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16.5, 17.5}}; double downbeam2[23][23] = {{-1.5, -0.5, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {-1.5, -0.5, 0.5, 1, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5}, {-1.5, -0.5, 0.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5}, {-1.5, -0.5, 0.5, 1.5, 2.5, 2.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 3.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 4.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 5.5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5, 6, 6, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6, 6.5, 6.5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6, 6.5, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5, 6, 6.5, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5, 5.5, 6.5, 7, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5, 5.5, 7, 7, 8, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5, 5.5, 7, 8, 8, 9, 10, 11, 11, 12, 12, 12, 12, 12, 12, 12}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5, 5.5, 7, 8, 9, 9, 10, 11, 12, 12, 13, 13, 13, 13, 13, 13}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5, 5.5, 7, 8, 9, 10, 10, 11, 12, 13, 13, 13, 13, 13, 13, 13}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5, 5.5, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 14, 14, 14, 14}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5, 5.5, 7, 8, 9, 10, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5, 5.5, 7, 8, 9, 10, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5, 5.5, 7, 8, 9, 10, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5, 5.5, 7, 8, 9, 10, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5, 5.5, 7, 8, 9, 10, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14}, {-1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5, 5.5, 7, 8, 9, 10, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14}}; if (vpos1 < -3 || vpos2 < -3 || vpos1 > 22 || vpos2 > 22) { return vpos2; } switch (dir) { case 10: return upbeam2[(int)vpos1+3][(int)vpos2+3]; case 20: return downbeam2[(int)vpos1+3][(int)vpos2+3]; } return vpos2; } // md5sum: 1f8c4a48f4bf634c01628e01b93527ca chor2scor.cpp [20160320]