void printSingleKernSubtoken(const char* buff, RationalNumber& factor) { PerlRegularExpression pre; RationalNumber value; int level = 0; if (factor == 2) { level = 1; } else if (factor == 4) { level = 2; } if (!rebeamQ) { level = 0; } char prebuffer[1024] = {0}; char postbuffer[1024] = {0}; if (pre.search(buff, "([^\\d]*)(\\d+)(%?)(\\d*)(.*)", "")) { int top = atoi(pre.getSubmatch(2)); int bot; if (strlen(pre.getSubmatch(4)) != 0) { bot = atoi(pre.getSubmatch()); if (bot == 0) { bot = 1; } } else { bot = 1; } if (top == 0) { // handle cases where breve=0; long=00; maxima=000 int tcount = 0; int i; int len = strlen(buff); for (i=0; i<len; i++) { if (buff[i] == '0') { tcount++; } } top = 1; bot = int(pow(2.0,tcount)); } value.setValue(top, bot); value /= factor; // factor is duration so inverse strcpy(prebuffer, pre.getSubmatch(1)); strcpy(postbuffer, pre.getSubmatch(5)); cleanUpBeams(prebuffer, postbuffer, level); cout << prebuffer; printSpecialRational(value); // print stuff after numeric part of rhythm cout << postbuffer; } else { cout << buff; } }
void getAlternateFactor(HumdrumFile& infile, RationalNumber& factor) { PerlRegularExpression pre; int i; int top; int bot; RationalNumber value; RationalNumber orig(1,1); getOriginalFactor(infile, orig); for (i=0; i<infile.getNumLines(); i++) { if (!infile[i].isBibliographic()) { continue; } if (!pre.search(infile[i][0], "^!!!rscale-alt\\s*:\\s*(\\d+)(/?)(\\d*)", "")) { continue; } top = atoi(pre.getSubmatch(1)); bot = 1; if (strlen(pre.getSubmatch(2)) != 0) { if (strlen(pre.getSubmatch(3)) != 0) { bot = atoi(pre.getSubmatch()); } } if (top == 0) { top = 1; } if (bot == 0) { bot = 1; } value.setValue(top, bot); factor = value * orig; return; } }
void handleBibliographic(HumdrumFile& infile, int row, RationalNumber& num) { char buffer[1024] = {0}; infile[row].getBibKey(buffer, 1000); if (strcmp(buffer, "rscale") != 0) { cout << infile[row] << endl; return; } RationalNumber onum; PerlRegularExpression pre; if (!pre.search(infile[row][0], "!!!rscale([^\\d]*)(\\d+)(/?)(\\d*)(.*)", "")) { cout << infile[row] << endl; return; } int top = atoi(pre.getSubmatch(2)); int bot = 1; if (strlen(pre.getSubmatch(3)) != 0) { if (strlen(pre.getSubmatch(4)) != 0) { bot = atoi(pre.getSubmatch()); } } if (bot == 0) { bot = 1; } onum.setValue(top, bot); onum *= num; FoundRef = 1; if (onum == 1) { // don't print !!!rscale: entry if scaling is 1. return; } if (originalQ) { // original rhythmic values are being generated, don't print ref rec. return; } cout << "!!!rscale"; cout << pre.getSubmatch(1); cout << onum; cout << pre.getSubmatch(5); cout << "\n"; }
void MuseRecordBasic::append(const char* format, ...) { va_list valist; int i; va_start(valist, format); union Format_t { int i; char *s; int *r; // array of two integers for rational number } FormatData; RationalNumber rn; for (i=0; format[i] != '\0'; i++) { switch (format[i]) { // Type to expect. case 'i': FormatData.i = va_arg(valist, int); appendInteger(FormatData.i); break; case 's': FormatData.s = va_arg(valist, char *); if (strlen(FormatData.s) > 0) { appendString(FormatData.s); } break; case 'r': FormatData.r = va_arg(valist, int *); rn.setValue(FormatData.r[0], FormatData.r[1]); appendRational(rn); break; default: // don't put any character other than "i", "r" or "s" // in the format string break; } } va_end(valist); }
int getBeatGroupCount(HumdrumFile& infile, Array<Coordinate>& items, Array<int>& notes, int noteindex) { int output = 0; int i; RationalNumber dursum; dursum.setValue(0,1); int ii, jj; for (i=noteindex; i<notes.getSize(); i++) { ii = items[notes[i]].i; jj = items[notes[i]].j; dursum += Convert::kernToDurationR(infile[ii][jj]); output++; if (dursum.isInteger()) { return output; } } cerr << "ERROR: measure does not sum to an integer amount of beats." << endl; cerr << "Instead the group duration is: " << dursum << endl; exit(1); return -1; }
RationalNumber getSmallestRhythm(HumdrumFile& infile, Array<Coordinate>& items, Array<int>& notes, int noteindex, int groupcount) { int i; RationalNumber minrhy; RationalNumber testrhy; minrhy.setValue(1,1); int ii, jj; for (i=noteindex; i<noteindex+groupcount; i++) { ii = items[notes[i]].i; jj = items[notes[i]].j; testrhy = Convert::kernToDurationR(infile[ii][jj]); if (testrhy.getNumerator() == 0) { cerr << "ERROR: grace notes are not yet handled by program" << endl; exit(1); } if (minrhy > testrhy) { minrhy = testrhy; } } return minrhy; }
void checkOptions(Options& opts, int argc, char* argv[]) { opts.define("d|f|factor=s:1/1", "Factor to multiply durations by"); opts.define("F=b", "Read rscale factors from !!!RSCALE: lines"); opts.define("M|T|nometer=b", "Do not alter time signatures"); opts.define("o|original=b", "Revert to original rhythms"); opts.define("a|alternate=b", "Change to alternate rhythm set"); opts.define("r|long=b", "Do not use short form for breve,long,maxima"); opts.define("B|adjust-beams=b", "Adjust beaming for powers of 2 rscaling"); opts.define("debug=b"); // determine bad input line num opts.define("author=b"); // author of program opts.define("version=b"); // compilation info opts.define("example=b"); // example usages opts.define("h|help=b"); // short description opts.process(argc, argv); // handle basic options: if (opts.getBoolean("author")) { cout << "Written by Craig Stuart Sapp, " << "[email protected], Jan 2011" << endl; exit(0); } else if (opts.getBoolean("version")) { cout << argv[0] << ", version: 6 Jan 2011" << 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); } PerlRegularExpression pre; if (pre.search(opts.getString("factor").data(), "(\\d+)\\/?(\\d*)", "")) { int top = 1; int bot = 1; top = atoi(pre.getSubmatch(1)); if (strlen(pre.getSubmatch(2)) != 0) { bot = atoi(pre.getSubmatch()); if (bot == 0) { bot = 1; } } else { bot = 1; } factor.setValue(top, bot); } else { factor.setValue(1,1); cerr << "Scaling factor set to " << factor << endl; } debugQ = opts.getBoolean("debug"); if (debugQ) { cerr << "Scaling factor set to " << factor << endl; } autoQ = opts.getBoolean("F"); meterQ = !opts.getBoolean("nometer"); originalQ = opts.getBoolean("original"); alternateQ = opts.getBoolean("alternate"); longQ = opts.getBoolean("long"); rebeamQ = opts.getBoolean("adjust-beams"); }
void processTimeSignature(HumdrumFile& infile, int row, RationalNumber& factor) { int j; RationalNumber beat; int mtop; int top; int bot; PerlRegularExpression pre; for (j=0; j<infile[row].getFieldCount(); j++) { if (pre.search(infile[row][j], "^\\*tb(\\d+)(%?)(\\d*)$", "")) { // process a timebase interpretation top = atoi(pre.getSubmatch(1)); bot = 1; if (strlen(pre.getSubmatch(2)) != 0) { if (strlen(pre.getSubmatch(3)) != 0) { bot = atoi(pre.getSubmatch()); if (bot == 0) { bot = 1; } } } beat.setValue(top, bot); beat /= factor; cout << "*tb"; printSpecialRational(beat); if (j < infile[row].getFieldCount() - 1) { cout << "\t"; } continue; } if ((!meterQ) || (!pre.search(infile[row][j], "^\\*M(\\d+)/(\\d+)(%?)(\\d*)(.*)", ""))) { cout << infile[row][j]; if (j < infile[row].getFieldCount() - 1) { cout << "\t"; } continue; } mtop = atoi(pre.getSubmatch(1)); top = atoi(pre.getSubmatch(2)); bot = 1; if (strlen(pre.getSubmatch(3)) != 0) { if (strlen(pre.getSubmatch(4)) != 0) { bot = atoi(pre.getSubmatch()); if (bot == 0) { bot = 1; } } } beat.setValue(top, bot); beat /= factor; cout << "*M"; cout << mtop; cout << "/"; printSpecialRational(beat); cout << pre.getSubmatch(5); if (j < infile[row].getFieldCount() - 1) { cout << "\t"; } } cout << "\n"; }
void checkOptions(Options& opts, int argc, char* argv[]) { opts.define("a|append=b", "append analysis data to input"); opts.define("p|prepend=b", "prepend analysis data to input"); opts.define("b|beat=b", "list beat in measure"); opts.define("q|quarter=b", "list absolute beat in quarter notes"); opts.define("h|half=b", "list absolute beat in half notes"); opts.define("w|whole=b", "list absolute beat in whole notes"); opts.define("e|eighth=b", "list absolute beat in eighth notes"); opts.define("x|sixteenth=b", "list absolute beat in sixteenth notes"); opts.define("S|no-space=b", "do not put spaces between location items"); opts.define("Q|no-quotes=b", "do not put quotes around filenames"); opts.define("R|rational=b", "use rational numbers instead of floats"); opts.define("m|measure|bar|barlines=b", "display measure numbers"); opts.define("L|no-labels=b", "do not display labels on data"); opts.define("d|double=b", "double labels before and after data"); opts.define("f|filename=b", "show filename"); opts.define("l|line=b", "show line numbers indexed from 1"); opts.define("debug=b"); // determine bad input line num opts.define("author=b"); // author of program opts.define("version=b"); // compilation info opts.define("example=b"); // example usages opts.define("help=b"); // short description opts.process(argc, argv); // handle basic options: if (opts.getBoolean("author")) { cout << "Written by Craig Stuart Sapp, " << "[email protected], October 2013" << endl; exit(0); } else if (opts.getBoolean("version")) { cout << argv[0] << ", version: 10 October 2013" << 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); } appendQ = opts.getBoolean("append"); prependQ = opts.getBoolean("prepend"); measureQ = opts.getBoolean("measure"); doubleQ = opts.getBoolean("double"); labelQ = !opts.getBoolean("no-labels"); lineQ = opts.getBoolean("line"); fileQ = opts.getBoolean("filename"); beatQ = opts.getBoolean("beat"); spaceQ = !opts.getBoolean("no-space"); quotesQ = !opts.getBoolean("no-quotes"); rationalQ = opts.getBoolean("rational"); int counter = 0; if (opts.getBoolean("quarter")) { absQ = 1; absFactor = 1; absChar = 'Q'; counter++; } if (opts.getBoolean("half")) { absQ = 1; absFactor.setValue(1,2); absChar = 'H'; counter++; } if (opts.getBoolean("whole")) { absQ = 1; absFactor.setValue(1,4); absChar = 'W'; counter++; } if (opts.getBoolean("eighth")) { absQ = 1; absFactor = 2; absChar = 'E'; counter++; } if (opts.getBoolean("sixteenth")) { absQ = 1; absFactor = 4; absChar = 'X'; counter++; } if (counter > 1) { // use only quarter notes if more than one timebase is given. absFactor = 1; } if (appendQ) { // mutually exclusive options prependQ = 0; } if (!(measureQ || lineQ || fileQ)) { // if no location type selected, turn them all on fileQ = 1; lineQ = 1; measureQ = 1; beatQ = 1; absQ = 1; absFactor = 1; } }
void printOutput(HumdrumFile& file, Array<RationalNumber>& Bfeatures, Array<int>& Blines, Array<RationalNumber>& Dfeatures, Array<int>& Dlines, Array<int>& tickanalysis) { int lastmeasureline = -1; int pickupstate = 0; int suppressreturn = 0; int i; Array<unsigned long> abstick; if (tickQ) { unsigned long csum = 0; abstick.setSize(tickanalysis.getSize()); abstick.setAll(0); for (i=0; i<tickanalysis.getSize(); i++) { abstick[i] = csum; csum += tickanalysis[i]; } } RationalNumber minrhy(file.getMinTimeBase(), 4); RationalNumber rat; Array<RationalNumber> Binfo; Array<RationalNumber> Dinfo; Binfo.setSize(file.getNumLines()); Binfo.allowGrowth(0); Binfo.setAll(-1); Dinfo.setSize(file.getNumLines()); Dinfo.allowGrowth(0); Dinfo.setAll(-1); int measurecount = 0; for (i=0; i<Blines.getSize(); i++) { Binfo[Blines[i]] = Bfeatures[i]; if (Binfo[Blines[i]] == file[Blines[i]].getAbsBeatR()) { Binfo[Blines[i]]++; Binfo[Blines[i]] -= file.getPickupDurationR(); } if (zeroQ) { Binfo[Blines[i]]--; } } for (i=0; i<Dlines.getSize(); i++) { Dinfo[Dlines[i]] = Dfeatures[i]; } for (i=0; i<file.getNumLines(); i++) { switch (file[i].getType()) { /*case E_humrec_data_comment: if (appendQ) { cout << file[i] << "\t" << "!" << "\n"; } else if (prependQ) { cout << "!\t" << file[i] << "\n"; } else { cout << file[i] << "\n"; } break; */ case E_humrec_data_kern_measure: if (prependQ) { cout << file[i][0] << "\t"; cout << file[i] << "\n"; } else if (appendQ) { cout << file[i] << "\t"; cout << file[i][0] << "\n"; } else { cout << file[i][0] << "\n"; } lastmeasureline = i; measurecount++; break; case E_humrec_interpretation: if (appendQ) { cout << file[i] << "\t"; } if (strncmp(file[i][0], "**", 2) == 0) { if (absQ && !tickQ) { cout << "**absb"; } else if (absQ && tickQ && !rationalQ) { cout << "**atick"; } else if (absQ && tickQ && rationalQ) { cout << "**adur"; } else if (tickQ && durQ && !rationalQ) { cout << "**dtick"; } else if (tickQ && durQ && rationalQ) { cout << "**dur"; } else if (durQ && !tickQ) { cout << "**dur"; } else if (sumQ) { cout << "**beatsum"; } else { cout << "**beat"; } } else if (strcmp(file[i][0], "*-") == 0) { cout << "*-"; } else if (strncmp(file[i][0], "*>", 2) == 0) { cout << file[i][0]; } else { if ((strncmp(file[i][0], "*M", 2) == 0) && (strchr(file[i][0], '/') != NULL)) { cout << file[i][0]; } else if (strncmp(file[i][0], "*MM", 3) == 0) { cout << file[i][0]; } else if (appendQ || prependQ) { cout << "*"; } else { cout << "*"; } } if (prependQ) { cout << "\t" << file[i]; } cout << "\n"; break; case E_humrec_data: if (appendQ) { cout << file[i] << "\t"; } if (file[i][0][0] == '=') { pickupstate++; } if (durQ) { // cout << file[i].getDuration(); if (Dinfo[i] >= 0) { if (tickQ && !rationalQ) { cout << tickanalysis[i]; } else if (tickQ && rationalQ) { rat.setValue(tickanalysis[i], file.getMinTimeBase()); if (uQ) { rat *= 4; } cout << rat; } else { cout << Dinfo[i].getFloat(); } } else { if (nullQ || appendQ || prependQ) { cout << "."; } else { suppressreturn = 1; } } } else if (absQ) { if (tickQ && !rationalQ) { cout << abstick[i]; } else if (tickQ && rationalQ) { RationalNumber anumber(abstick[i], file.getMinTimeBase()); if (uQ) { anumber *= 4; } anumber.printTwoPart(cout); } else { cout << file[i].getAbsBeat(); } } else if (sumQ) { if (lastmeasureline > 0) { cout << fabs(file[lastmeasureline].getBeat()); pickupstate++; lastmeasureline = -1; } else if (pickupstate < 1) { if (!file.getPickupDurationR().isNegative()) { if (measurecount == 0) { cout << getDurationOfFirstMeasure(file).getFloat(); } else { cout << file.getPickupDuration(); } } else if (file.getPickupDurationR().isZero()) { cout << file.getTotalDurationR().getFloat(); } else { cout << file.getTotalDurationR().getFloat(); } pickupstate++; lastmeasureline = -1; } else { if (appendQ || prependQ) { cout << "."; } else { if (nullQ) { cout << "."; } else { suppressreturn = 1; } } } } else if (beatQ) { if (Binfo[i] >= 0) { if (!tickQ && !rationalQ) { cout << Binfo[i].getFloat(); } else if (tickQ && !rationalQ) { cout << (Binfo[i] * minrhy); } else { Binfo[i].printTwoPart(cout); } } else { if (nullQ || appendQ || prependQ) { cout << "."; } else { suppressreturn = 1; } } } if (prependQ) { cout << "\t" << file[i]; } if (suppressreturn) { suppressreturn = 0; } else { cout << "\n"; } break; case E_humrec_local_comment: if (appendQ) { cout << file[i] << "\t"; } cout << "!"; if (prependQ) { cout << "\t" << file[i]; } cout << "\n"; break; case E_humrec_none: case E_humrec_empty: case E_humrec_global_comment: case E_humrec_bibliography: default: cout << file[i] << "\n"; break; } } }
int printSubBeatLevel(ostream& out, HumdrumFile& infile, Array<Coordinate>& items, Array<int>& notes, int noteindex, int keysig, int defaultclef, int currentclef) { // groupcount is the number of notes in an integer number // of beats within the measure. int groupcount = getBeatGroupCount(infile, items, notes, noteindex); RationalNumber groupduration; RationalNumber startpos; RationalNumber endpos; RationalNumber enddur; int ii, jj; ii = items[notes[noteindex]].i; jj = items[notes[noteindex]].j; startpos = infile[ii].getAbsBeatR(); ii = items[notes[noteindex+groupcount-1]].i; jj = items[notes[noteindex+groupcount-1]].j; endpos = infile[ii].getAbsBeatR(); enddur = Convert::kernToDurationR(infile[ii][jj]); groupduration = (endpos - startpos) + enddur; if (!groupduration.isInteger()) { cerr << "Funny error: group duration is not an integer" << endl; exit(1); } RationalNumber minrhy; minrhy.setValue(1,2); // minrhy is smallest duration in terms of quarter notes. minrhy = getSmallestRhythm(infile, items, notes, noteindex, groupcount); indent(out, LEVEL++); out << "(" << groupduration << " ("<< endl; RationalNumber quarternote(1,4); // print group notes int i; RationalNumber notediv; for (i=noteindex; i<noteindex+groupcount; i++) { ii = items[notes[i]].i; jj = items[notes[i]].j; notediv = Convert::kernToDurationR(infile[ii][jj]) / minrhy; printChord(out, infile, ii, jj, notediv, keysig, defaultclef, currentclef); /* if (strchr(infile[ii][jj], 'r') != NULL) { // out << "(" << notediv; // out << "("; // add this paren if rest has attributes out << "-1"; // rest // out << ")"; // add this paren if rest has attributes // out << ")"; } else { out << "(" << notediv; out << " :notes ("; printMidiNotes(out, infile, ii, jj); out << ")"; // end of MIDI pitch list out << ")"; // end of note } */ } indent(out, --LEVEL); out << "))" << endl; // end of beat group list return noteindex + groupcount - 1; }