RationalNumber operator ^ (const RationalNumber& B) const throw(std::invalid_argument) { if (!isFraction() || !B.isInteger()) { return RationalNumber(powl(getRealNumber(), B.getRealNumber())); } RationalNumber S(1, 1); RationalNumber A = *this; long long n = B.numerator; if (n < 0) { A = RationalNumber(1, 1) / A; n = -n; } while (n) { if (n & 1) { S = S * A; } A = A * A; n >>= 1; } return S; }
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; }
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; }