Hello Timothy, > For a long run of triplets, once the pattern is established I typically > switch to \scaleDurations 2/3. Since 2.26, beam subdivision does not > work with scaleDurations. Sample code and output from 2.24 and 2.26 > attached. (A work-around is to continue with \tuplet 3/2 and \omit the > tuplet number and bracket).
This is caused by the change in how automatic subdivisions works. Previously
this would simply be based on beat structure, now it is controlled by a more
complex algorithm. But one shortcoming of this algorithm is that it generally
assumes a power of 2 subdivision and rounds everything thus (ignoring time
signature and beat structure entirely), failing in any non-power-of-2 situation.
We find this also in regular non-power-of-2 times:
{
\time 12/16
\set subdivideBeams = ##t
c'16 c' c' c' c' c'
c'[ c' c' c' c' c']
}
and AFAIK there is not really a workaround for this, since the problem is an
assumption heavily baked into the new system:
The new system uses assigns to each stem a “rhythmical importance” given by
[lily/beaming-pattern.cc]:
static int
rhythmic_importance_for_position (Rational const &r)
{
return intlog2 (r.den ()) - 2 - (r.den () == 1 ? intlog2 (r.num ()) : 0);
}
static int
rhythmic_importance_for_length (Rational const &r)
{
return intlog2 (r.den ()) - 2 - intlog2 (r.num ());
}
If a stem falls on the beat its rhythmical importance is then given by the
length of the current beat, scaled by the tuplet ratio. If the stem does not
fall on the beat it is given by the position within the beat, as well scaled by
tuplet factor.
0|1/16|1/8|3/16|1/4|5/16|1/2| ...|15/16|
we get (base = 1/1) importances of
-2|2|1|2|0|2|1|2|-1|...|2
(so the priority kind of gives how many beams the position has).
Then using the values beamMinimumSubdivision and beamMaximumSubdivision it
calculates a maximum_subdivision_count and a minimum_subdivision_count,
Then it looks at the rhythmical importance of the current and the next stem
and calculates naive beam counts, where the left beam count is the rhythmical
importance of the current stem (but at least minimum_subdivision_count) and
the right beam count is the importance of the next stem (but at least
minimum_subdivision_count).
Then if the left importance is not higher than the maximum_subdivision_count
and the actual number of beams is higher than the naive beam count and it has
full beam count to the right the left side is reduced to the naive beam count.
Else the right side is reduce (with same types of constraints).
So we see that the system is explicitely designed to assume subbeaming only in
places of binary division.
To actually properly fix this we’d need to implement a proper logic for this
rhythmic importance, that is to say, don’t snap to a grid defined by binary
subdivisions, but by one properly defined by beat structure and tuplet spans:
Start of measure has highest priority, then beat groups, then beats, then
subdivision of beats and subbeats. But then subdivisions must take into
account:
1. If a beat is of length n/d with n≠1 assume n subdivisions of 1/d
2. If a m:n tuplet is encountered the start of the tuplet and the next note
should generally have higher importance (to clearly distinguish highly beamed
tuplets from neighboring notes). Tuplets should be handled as a single beatoid
(it does not inherit the parent subdivision, since it defines it’s own
subdivision)
3. Due to Tuplets or simply scaled durations any beatoid can be divided in
different ways. On Tuplets this is explicit. On simply scaled durations it
isn’t. This means if we have common subdivisions of our beatoid like “divide
the beatoid in 6” this could both be modelled as “divide in 3, then in 2” but
also “divide in 2, then in 3”. If we wanted to proper handle all cases of this
things would thus need to rely so heavily on guesswork that I think we
shouldn’t.
This would probably be possible to integrate into current code, but it would
require a significant amount of additional logic.
Cheers,
Tina
signature.asc
Description: This is a digitally signed message part.
