beam beats in X/4 according to minimum durations
This commit is contained in:
parent
d477e585f4
commit
fef82c1a10
|
@ -1568,9 +1568,10 @@ void Beam::layout2(QList<ChordRest*>crl, SpannerSegmentType, int frag)
|
|||
++i;
|
||||
for (; i < n; ++i) {
|
||||
ChordRest* c = crl[i];
|
||||
ChordRest* p = i ? crl[i - 1] : 0;
|
||||
int l = c->durationType().hooks() - 1;
|
||||
|
||||
Mode bm = Groups::endBeam(c);
|
||||
Mode bm = Groups::endBeam(c, p);
|
||||
bool b32 = (beamLevel >= 1) && (bm == Mode::BEGIN32);
|
||||
bool b64 = (beamLevel >= 2) && (bm == Mode::BEGIN64);
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ static std::vector<NoteGroup> noteGroups {
|
|||
// endBeam
|
||||
//---------------------------------------------------------
|
||||
|
||||
Beam::Mode Groups::endBeam(ChordRest* cr)
|
||||
Beam::Mode Groups::endBeam(ChordRest* cr, ChordRest* prev)
|
||||
{
|
||||
if (cr->isGrace() || cr->beamMode() != Beam::Mode::AUTO)
|
||||
return cr->beamMode();
|
||||
|
@ -76,7 +76,23 @@ Beam::Mode Groups::endBeam(ChordRest* cr)
|
|||
const Groups& g = cr->staff()->group(cr->tick());
|
||||
Fraction stretch = cr->staff()->timeStretch(cr->tick());
|
||||
int tick = (cr->rtick() * stretch.numerator()) / stretch.denominator();
|
||||
return g.beamMode(tick, d.type());
|
||||
Beam::Mode val = g.beamMode(tick, d.type());
|
||||
|
||||
// context-dependent checks
|
||||
if (val == Beam::Mode::AUTO && tick) {
|
||||
// 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 >= TDuration::DurationType::V_EIGHTH)
|
||||
val = g.beamMode(tick, TDuration::DurationType::V_16TH);
|
||||
else if (d == TDuration::DurationType::V_16TH)
|
||||
val = g.beamMode(tick, TDuration::DurationType::V_32ND);
|
||||
else
|
||||
val = g.beamMode(tick, TDuration::DurationType::V_64TH);
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -68,7 +68,7 @@ class Groups : public std::vector<GroupNode> {
|
|||
void dump(const char*) const;
|
||||
|
||||
static const Groups& endings(const Fraction& f);
|
||||
static Beam::Mode endBeam(ChordRest* cr);
|
||||
static Beam::Mode endBeam(ChordRest* cr, ChordRest* prev = 0);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1162,34 +1162,76 @@ void Score::layoutStage2()
|
|||
Beam* beam = 0; // current beam
|
||||
Measure* measure = 0;
|
||||
|
||||
Beam::Mode bm = Beam::Mode::AUTO;
|
||||
Beam::Mode bm = Beam::Mode::AUTO;
|
||||
Segment::Type st = Segment::Type::ChordRest;
|
||||
ChordRest* prev = 0;
|
||||
ChordRest* prev = 0;
|
||||
bool checkBeats = false;
|
||||
Fraction stretch = 1;
|
||||
QHash<int, TDuration> beatSubdivision;
|
||||
|
||||
for (Segment* segment = firstSegment(st); segment; segment = segment->next1(st)) {
|
||||
ChordRest* cr = static_cast<ChordRest*>(segment->element(track));
|
||||
if (cr == 0)
|
||||
continue;
|
||||
|
||||
// handle grace notes and cross-measure beaming
|
||||
if (cr->type() == Element::Type::CHORD) {
|
||||
Chord* chord = static_cast<Chord*>(cr);
|
||||
beamGraceNotes(chord, false); // grace before
|
||||
beamGraceNotes(chord, true); // grace after
|
||||
beamGraceNotes(chord, false); // grace before
|
||||
beamGraceNotes(chord, true); // grace after
|
||||
// set up for cross-measure values as soon as possible
|
||||
// to have all computations (stems, hooks, ...) consistent with it
|
||||
if (!chord->isGrace())
|
||||
chord->crossMeasureSetup(crossMeasure);
|
||||
}
|
||||
|
||||
bm = Groups::endBeam(cr);
|
||||
// if this is a new measure, and it's simple meter (actually X/4),
|
||||
// then perform a prepass to determine the subdivision of each beat
|
||||
if (segment->measure() != measure) {
|
||||
Measure* m = segment->measure();
|
||||
TimeSig* ts = cr->staff()->timeSig(m->tick());
|
||||
beatSubdivision.clear();
|
||||
checkBeats = false;
|
||||
stretch = ts ? ts->stretch() : 1;
|
||||
if (ts && ts->denominator() == 4) {
|
||||
checkBeats = true;
|
||||
for (Segment* s = m->first(st); s; s = s->next(st)) {
|
||||
ChordRest* mcr = static_cast<ChordRest*>(s->element(track));
|
||||
if (mcr == 0)
|
||||
continue;
|
||||
int beat = ((mcr->rtick() * stretch.numerator()) / stretch.denominator()) / MScore::division;
|
||||
if (beatSubdivision.contains(beat))
|
||||
beatSubdivision[beat] = qMin(beatSubdivision[beat], mcr->durationType());
|
||||
else
|
||||
beatSubdivision[beat] = mcr->durationType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get defaults from time signature properties
|
||||
bm = Groups::endBeam(cr, prev);
|
||||
|
||||
// perform additional context-dependent checks
|
||||
if (bm == Beam::Mode::AUTO) {
|
||||
|
||||
// check if we need to break beams according to minimum duration in current / previous beat
|
||||
if (checkBeats && cr->rtick()) {
|
||||
int tick = (cr->rtick() * stretch.numerator()) / stretch.denominator();
|
||||
// check if on the beat
|
||||
if (tick % MScore::division == 0) {
|
||||
int beat = tick / MScore::division;
|
||||
// get minimum duration for this & previous beat
|
||||
TDuration minDuration = qMin(beatSubdivision[beat], beatSubdivision[beat - 1]);
|
||||
// re-calculate beam as if this were the duration of current chordrest
|
||||
TDuration saveDuration = cr->durationType();
|
||||
cr->setDurationType(minDuration);
|
||||
bm = Groups::endBeam(cr, prev);
|
||||
cr->setDurationType(saveDuration);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// end beam at new tuplet or end tuplet, if the next/prev duration type is different
|
||||
if (cr->tuplet()
|
||||
&& !cr->tuplet()->elements().isEmpty()
|
||||
&& cr->tuplet()->elements().front() == cr
|
||||
&& prev && prev->durationType() == cr->durationType())
|
||||
bm = Beam::Mode::BEGIN;
|
||||
else if (prev && prev->tuplet() && !prev->tuplet()->elements().isEmpty()
|
||||
&& prev->tuplet()->elements().last() == prev && prev->durationType() == cr->durationType())
|
||||
bm = Beam::Mode::BEGIN;
|
||||
prev = cr;
|
||||
|
||||
// if chord has hooks and is 2nd element of a cross-measure value
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 10 KiB |
BIN
vtest/beams-4-ref.png
Normal file
BIN
vtest/beams-4-ref.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
vtest/beams-4.mscz
Normal file
BIN
vtest/beams-4.mscz
Normal file
Binary file not shown.
BIN
vtest/beams-5-ref.png
Normal file
BIN
vtest/beams-5-ref.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
vtest/beams-5.mscz
Normal file
BIN
vtest/beams-5.mscz
Normal file
Binary file not shown.
BIN
vtest/beams-6-ref.png
Normal file
BIN
vtest/beams-6-ref.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
BIN
vtest/beams-6.mscz
Normal file
BIN
vtest/beams-6.mscz
Normal file
Binary file not shown.
BIN
vtest/beams-7-ref.png
Normal file
BIN
vtest/beams-7-ref.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.8 KiB |
BIN
vtest/beams-7.mscz
Normal file
BIN
vtest/beams-7.mscz
Normal file
Binary file not shown.
|
@ -39,7 +39,7 @@ else
|
|||
accidental-1 accidental-2 accidental-3 accidental-4 accidental-5\
|
||||
accidental-6 accidental-7 accidental-8 accidental-9\
|
||||
tie-1 tie-2 tie-3 grace-1 grace-2 grace-3 harmony-1 harmony-2 harmony-3 harmony-4\
|
||||
beams-1 beams-2 beams-3\
|
||||
beams-1 beams-2 beams-3 beams-4 beams-5 beams-6 beams-7\
|
||||
user-offset-1 user-offset-2 chord-space-1 tablature-1 image-1\
|
||||
lyrics-1 lyrics-2 lyrics-3 voice-1"
|
||||
fi
|
||||
|
|
|
@ -20,7 +20,7 @@ set SRC=mmrest-1,bravura-mmrest,gonville-mmrest,mmrest-2,mmrest-4,mmrest-5,mmres
|
|||
accidental-1,accidental-2,accidental-3,accidental-4,accidental-5, ^
|
||||
accidental-6,accidental-7,accidental-8,accidental-9, ^
|
||||
tie-1,tie-2,tie-3,grace-1,grace-2,grace-3,harmony-1,harmony-2,harmony-3,harmony-4, ^
|
||||
beams-1,beams-2,beams-3, ^
|
||||
beams-1,beams-2,beams-3,beams-4,beams-5,beams-6,beams-7, ^
|
||||
user-offset-1,user-offset-2,chord-space-1,tablature-1,image-1, ^
|
||||
lyrics-1,lyrics-2,lyrics-3,voice-1
|
||||
|
||||
|
|
Loading…
Reference in a new issue