Merge pull request #12214 from asattely/beamlet-directions
Fix #10205: Beam groups calculation fix
This commit is contained in:
commit
f6d12d96eb
2 changed files with 30 additions and 9 deletions
|
@ -978,11 +978,13 @@ void Beam::createBeamSegments(const std::vector<ChordRest*>& chordRests)
|
|||
bool breakBeam = false;
|
||||
bool previousBreak32 = false;
|
||||
bool previousBreak64 = false;
|
||||
int prevRests = 0;
|
||||
|
||||
for (uint i = 0; i < chordRests.size(); i++) {
|
||||
ChordRest* chordRest = chordRests[i];
|
||||
ChordRest* prevChordRest = i < 1 ? nullptr : chordRests[i - 1];
|
||||
if (!chordRest->isChord()) {
|
||||
prevRests++;
|
||||
continue;
|
||||
}
|
||||
Chord* chord = toChord(chordRest);
|
||||
|
@ -1002,7 +1004,7 @@ void Beam::createBeamSegments(const std::vector<ChordRest*>& chordRests)
|
|||
} else {
|
||||
if (startChord && endChord) {
|
||||
if (startChord == endChord) {
|
||||
bool isBeamletBefore = calcIsBeamletBefore(startChord, i - 1, level, previousBreak32, previousBreak64);
|
||||
bool isBeamletBefore = calcIsBeamletBefore(startChord, i - 1 - prevRests, level, previousBreak32, previousBreak64);
|
||||
createBeamletSegment(startChord, isBeamletBefore, level);
|
||||
} else {
|
||||
createBeamSegment(startChord, endChord, level);
|
||||
|
@ -1013,6 +1015,7 @@ void Beam::createBeamSegments(const std::vector<ChordRest*>& chordRests)
|
|||
}
|
||||
previousBreak32 = isBroken32;
|
||||
previousBreak64 = isBroken64;
|
||||
prevRests = 0;
|
||||
}
|
||||
|
||||
// if the beam ends on the last chord
|
||||
|
|
|
@ -97,21 +97,39 @@ BeamMode Groups::endBeam(const ChordRest* cr, const ChordRest* prev)
|
|||
}
|
||||
assert(cr->staff());
|
||||
|
||||
TDuration d = cr->durationType();
|
||||
const Groups& g = cr->staff()->group(cr->tick());
|
||||
Fraction stretch = cr->staff()->timeStretch(cr->tick());
|
||||
Fraction tick = cr->rtick() * stretch;
|
||||
// we need to figure out the longest note value beat upon which cr falls in the measure
|
||||
int maxTickLen = std::max(cr->ticks().ticks(), prev ? prev->ticks().ticks() : 0);
|
||||
int smallestTickLen = Fraction(1, 8).ticks(); // start with 8th
|
||||
int tickLenLimit = Fraction(1, 32).ticks(); // only check up to 32nds because that's all thats available
|
||||
// in timesig properties
|
||||
while (smallestTickLen > maxTickLen || cr->tick().ticks() % smallestTickLen != 0) {
|
||||
smallestTickLen /= 2; // proceed to 16th, 32nd, etc
|
||||
if (smallestTickLen < tickLenLimit) {
|
||||
smallestTickLen = cr->ticks().ticks();
|
||||
break;
|
||||
}
|
||||
}
|
||||
DurationType bigBeatDuration = TDuration(Fraction::fromTicks(smallestTickLen)).type();
|
||||
|
||||
BeamMode val = g.beamMode(tick.ticks(), d.type());
|
||||
TDuration crDuration = cr->durationType();
|
||||
const Groups& g = cr->staff()->group(cr->tick());
|
||||
Fraction stretch = cr->staff()->timeStretch(cr->tick());
|
||||
Fraction tick = cr->rtick() * stretch;
|
||||
|
||||
// We can choose to break beams based on its place in the measure, or by its duration. These
|
||||
// can be consolidated mostly, with bias towards its duration.
|
||||
BeamMode byType = g.beamMode(tick.ticks(), crDuration.type());
|
||||
BeamMode byPos = g.beamMode(tick.ticks(), bigBeatDuration);
|
||||
BeamMode val = byType == BeamMode::AUTO ? byPos : byType;
|
||||
|
||||
// context-dependent checks
|
||||
if (val == BeamMode::AUTO && tick.isNotZero()) {
|
||||
// if current or previous cr is in tuplet (but not both in same tuplet):
|
||||
// consider it as if this were next shorter duration
|
||||
if (prev && (cr->tuplet() != prev->tuplet()) && (d == prev->durationType())) {
|
||||
if (d >= DurationType::V_EIGHTH) {
|
||||
if (prev && (cr->tuplet() != prev->tuplet()) && (crDuration == prev->durationType())) {
|
||||
if (crDuration >= DurationType::V_EIGHTH) {
|
||||
val = g.beamMode(tick.ticks(), DurationType::V_16TH);
|
||||
} else if (d == DurationType::V_16TH) {
|
||||
} else if (crDuration == DurationType::V_16TH) {
|
||||
val = g.beamMode(tick.ticks(), DurationType::V_32ND);
|
||||
} else {
|
||||
val = g.beamMode(tick.ticks(), DurationType::V_64TH);
|
||||
|
|
Loading…
Reference in a new issue