lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: PATCH: Issue 638 Autobeaming


From: Carl Sorensen
Subject: Re: PATCH: Issue 638 Autobeaming
Date: Thu, 17 Dec 2009 09:40:52 -0700



On 12/17/09 7:54 AM, "David Kastrup" <address@hidden> wrote:

> Carl Sorensen <address@hidden> writes:
> 
>> On 12/17/09 1:25 AM, "David Kastrup" <address@hidden> wrote:
>> 
>>> Carl Sorensen <address@hidden> writes:
>>> 
>>>> On 12/16/09 10:23 PM, "Frédéric Bron" <address@hidden> wrote:
>>>> 
>>> 
>>> Deep breath.
>>> 
>>> So it would appear that no terminal/irreversible decision based on the
>>> minimum duration has been done yet at this point of time.
>>> 
>>> If that is the case, why not postpone all of the minimum-duration
>>> dependent accounting to the time where it is actually _needed_?
>>> 
>>> There does not seem to be much sense in making some temporary
>>> calculation based on possibly wrong assumptions when one can safely do
>>> it at a later point of time anyway.
>> 
>> Further thought on the issue has led me to this point that will
>> hopefully clarify things.
> 
> I am getting clearer on that, yes.
> 
>> After a note has been added to a beam, we ask the question "Should we
>> end the beam now?"  An answer that says we *should* end the beam is
>> final and irrevocable.  This is the code that has been implemented for
>> a long time in LilyPond.
>> 
>> The problem we have had in the past is that a decision to continue the
>> beam is *not* final.  If shorter notes are added to the beam, the beam
>> may need to be divided.  The classic example is beaming in 4/4 time.
>> If only eighth notes are in the beam, the beam should cover the first
>> two (or the last two) beats of the measure, i.e. be broken only
>> between beats 2 and 3.  However, if a sixteenth note is added to the
>> beam, it should be broken between beats 1 and 2, 2 and 3, and 3 and 4.
>> 
>> Given that breaking decisions are final, it seems appropriate to me to
>> keep typesetting a beam anytime a break condition is found.
>> 
>> And given that continuation decisions are subject to review if a shorter
>> duration is added to the beam, it seems appropriate to me to review the
>> continuation decisions whenever the shortest duration changes.
> 
> The problem I keep having is the following: if you put it like that, no
> code _can_ rely on the consequences of a continuation decision.  Because
> that decision may be revisited.  If revisiting the decision is an
> option, then maybe postponing the decision is a better option.

I don't see that it can be postponed, because the break decision *is* a
final decision.

Consider, in 4 4 time

{
  \repeat unfold 8 {a''8}
  \repeat unfold 16 { c''16}
}

The break decision must be made at moment (1 . 2), because otherwise we
would get an incorrect decision to break at (1. 4) since the beam has a 1/16
note starting at moment (9 . 16).

But the 1/16 note at (9.16) is (and should be) part of a new beam, so it
shouldn't affect the previous beam.  And that's why we need an irrevocable
break decision, but a provisional keep decision.

*All* keep decisions are provisional.

> 
> Because then we can make all the decisions in one go.  If
> reverting/revising decisions happens in a different code path than the
> code path making the initial decision, the code becomes harder to
> maintain, since any changes at one decision point have to be reconciled
> with the revert/revise code path as well.

As far as I can see, there *must* be multiple decision points.  If I tried
to autobeam a whole measure, I'd still use the same algorithm that currently
exists, but it would be more of a pain, because I'd have to do more futzing
with Beaming_patterns, which are not particularly easy to futz with.

I guess I could create some methods for Beaming_pattern that would, for
example, split or extract a Beaming_pattern.

And I suppose I could create (or find the code somewhere) for a vector split
routine to handle stems_ properly.  And define a new class that would be a
vector <Item*> that had a split method.

Those changes might make the code more concise, and hence easier to
understand.

But at its core I'd still be making a provisional beam.  I'd be doing it
from a fully-scanned measure, instead of from the event stream.  But the
algorithm would be the same, so I don't see the benefit of changing the
algorithm.

> 
> Also a programmer might expect that the choice that the code makes is
> persistent, and misses the other half of the story written at a
> different point of the code.

If the programmer can't read code that says we need to recheck the beam,
then I guess the programmer isn't very well qualified.  But just in case I
can add a comment to the code that mentions that ending decisions are
permanent, but continue decisions are provisional.

> 
> Let me take an example: the following code is by default set
> inconsistently (I have not yet tried your patch on it).
>

Yes, there is an inconsistency with the beaming with the current code and
the current beaming rules.

With the revised code and adding an autobeaming rule for 1/64 notes to the
default beam settings, the beaming is consistent.

Without the addition of an autobeaming rule for 1/64 notes the beaming
appears to be inconsistent.  I will investigate this further.


Now, from the bottom half of your email, which turned into an attachment for
some reason:

> What behavior can a composer expect when he changes the beaming patterns
> in mid-measure?  With the revised code, it appears to me that the
> initial choice of beaming might happen with one set of patterns, and the
> revision with a different one.  Is the code robust enough to cope with
> that situation?

Well, I guess the answer is a qualified maybe.  But it's kind of hard to say
what it means when the beaming pattern changes in the middle of the measure.
Suppose I have a rule in the first half of the measure that says beam the
whole measure together, and a rule in the second half of the measure that
says beam every 1/4 note together.  What should apply?  Both rules can't
apply to that measure simultaneously, and all beaming rules are defined for
a whole measure.

If a composer really wants to change beaming performance in the middle of a
measure, my answer would be to manually beam the transition measure (after
all, the composer knows what is wanted) rather than trying to make the
autobeaming work.  Then you can change the autobeaming either in the middle
of the measure or at the end of the measure, and the manual beam decisions
will override the autobeam decisions.

As far as I'm concerned, if the code doesn't segfault when it hits a
logically undefined situation, such as two different autobeam patterns
applied to the same measure, then I'm fine with the code.

Thanks,

Carl

Attachment: dak-beaming-test.png
Description: dak-beaming-test.png


reply via email to

[Prev in Thread] Current Thread [Next in Thread]