diff --git a/Sources/VLLilypondWriter.cpp b/Sources/VLLilypondWriter.cpp index 6a55303..2cc19f5 100644 --- a/Sources/VLLilypondWriter.cpp +++ b/Sources/VLLilypondWriter.cpp @@ -294,7 +294,7 @@ void VLLilypondWriter::VisitChord(VLChord & c) if (name == "r") name = "s"; char duration[16]; - if (c.fDuration.fNum == 1 && !(c.fDuration.fDenom & (c.fDuration.fDenom-1))) // Power of two + if (c.fDuration.IsPowerOfTwo()) sprintf(duration, "%d", c.fDuration.fDenom); else sprintf(duration, "1*%d/%d", c.fDuration.fNum, c.fDuration.fDenom); diff --git a/Sources/VLMMAWriter.cpp b/Sources/VLMMAWriter.cpp index 764c50d..2141d86 100644 --- a/Sources/VLMMAWriter.cpp +++ b/Sources/VLMMAWriter.cpp @@ -117,7 +117,7 @@ void VLMMAWriter::VisitNote(VLLyricsNote & n) char buf[4]; std::string dur; if (n.fDuration.fNum == 1) - if (!(n.fDuration.fDenom & (n.fDuration.fDenom-1))) { + if (n.fDuration.IsPowerOfTwo()) { sprintf(buf, "%d", n.fDuration.fDenom); dur = buf; } else if (n.fDuration.fDenom == 3) { diff --git a/Sources/VLModel.cpp b/Sources/VLModel.cpp index 7dabbd2..8fa14ae 100644 --- a/Sources/VLModel.cpp +++ b/Sources/VLModel.cpp @@ -78,6 +78,15 @@ VLFraction & VLFraction::operator%=(VLFraction other) return *this *= other; } +bool VLFraction::IsPowerOfTwo() const +{ + // + // !(x & (x-1)) is true if x had only a single bit set and thus + // is a power of two. We're not really interested in the case >1 + // + return fNum == 1 && !(fDenom & (fDenom-1)); +} + #pragma mark - #pragma mark class VLNote @@ -114,10 +123,7 @@ void VLNote::MakeRepresentable() fVisual = kWhole | (fVisual & kAccidentalsMask); VLFraction part(1,1); VLFraction triplet(2,3); - // - // Power of 2 denominators are not triplets - // - bool nonTriplet(!(fDuration.fDenom & (fDuration.fDenom-1))); + bool nonTriplet = fDuration.IsPowerOfTwo(); while (part.fDenom < 64) { if (fDuration >= part) { fDuration = part; diff --git a/Sources/VLModel.h b/Sources/VLModel.h index 7e093f8..c7500cc 100644 --- a/Sources/VLModel.h +++ b/Sources/VLModel.h @@ -36,6 +36,8 @@ struct VLFraction : VLFract { VLFraction & operator%=(VLFraction other); VLFraction & Normalize(); + + bool IsPowerOfTwo() const; }; inline float operator*(VLFraction f, float sc) diff --git a/Sources/VLPListDocument.mm b/Sources/VLPListDocument.mm index b95f1d3..a284760 100644 --- a/Sources/VLPListDocument.mm +++ b/Sources/VLPListDocument.mm @@ -202,7 +202,7 @@ void VLPlistVisitor::VisitNote(VLLyricsNote & n) // 4th 4th 8th // [nd setObject:[NSNumber numberWithInt:fTupletNote] forKey:@"normalType"]; - if (fTupletDur.fNum == 1 && !(fTupletDur.fDenom&(fTupletDur.fDenom-1))) + if (fTupletDur.IsPowerOfTwo()) fInTuplet = 0; } } else if (fInTuplet == tupletNum) diff --git a/Sources/VLSheetViewNotes.mm b/Sources/VLSheetViewNotes.mm index 8bfda84..730a0fa 100644 --- a/Sources/VLSheetViewNotes.mm +++ b/Sources/VLSheetViewNotes.mm @@ -388,8 +388,8 @@ } ++inTuplet; tupletDur += note->fDuration / VLNote::TupletDenom(tuplet); - if (tuplet == VLNote::kTriplet ? (tupletDur.fNum == 1 && !(tupletDur.fDenom & (tupletDur.fDenom-1))) - : inTuplet == VLNote::TupletNum(tuplet) + if (tuplet == VLNote::kTriplet + ? tupletDur.IsPowerOfTwo() : inTuplet == VLNote::TupletNum(tuplet) ) { // // Tuplet adds up to power of two fraction