lilypond-devel
[Top][All Lists]
Advanced

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

Re: How to do this correctly?


From: Carl Sorensen
Subject: Re: How to do this correctly?
Date: Thu, 28 Jan 2010 09:58:04 -0700



On 1/28/10 7:25 AM, "David Kastrup" <address@hidden> wrote:

> Carl Sorensen <address@hidden> writes:
> 
>> On 1/28/10 6:25 AM, "David Kastrup" <address@hidden> wrote:
>> 
>>> Neil Puttock <address@hidden> writes:
>>> 
>>>> 2010/1/27 Carl Sorensen <address@hidden>:
>>>> 
>>>>> I don't think there is a way to do this better as the code sits now.  The
>>>>> accidentals in the ambitus are AmbitusAccidentals, and are create by the
>>>>> Ambitus_engraver, so the standard accidental styles (which might do what
>>>>> you
>>>>> want) don't apply.
>>>> 
>>>> Agreed.  I think you'd have to add a property to the Ambitus_engraver
>>>> which tells it to ignore the key signature.
>>> 
>>> Well, I don't like extra interfaces.  I would be quite interested to
>>> know why the posted code actually works, engraving the proper key and
>>> using correct accidentals for it.  Is it because the Ambitus engraver
>>> pulls its signature from the Voice context (where the engraver sits),
>>> while the standard accidental engraver and key signature engraver take
>>> it (unmodified) from the Staff, where it presumably is set by the \key
>>> command?  Then probably per-voice accidentals would cease working.
>> 
>> I haven't looked thoroughly into this, but I suspect you are correct.
>> 
>>> 
>>> Maybe it would be possible to just make \override Ambitus #'keySignature
>>> = #'() work as expected.
>>> 
>> 
>> How do you expect it to work?  'keySignature is a property of a
>> context, not a property of a grob.  Ambitus doesn't have a
>> 'keySignature; the context containing Ambitus has a 'keySignature.
> 
> Oops.  Misremembered from:
> 
>     2.2.2 Ambitus_engraver
>     ----------------------
> 
>     Create an ambitus.
> 
>        Properties (read)
> 
>         `keySignature' (list)
>               The current key signature.  This is an alist containing
>               `(STEP . ALTER)' or `((OCTAVE .  STEP) . ALTER)',  where STEP
>               is a number in the range 0 to 6 and ALTER a fraction,
>               denoting alteration.  For alterations, use symbols, e.g.
>               `keySignature = #`((6 . ,FLAT))'.
> 
>> How can one override a property that doesn't exist?
> 
> Right.
> 
>> Two ways I see of getting the output you want:
>> 
>> 1) Add a property ambitusKeySignature.  This would be the keySignature used
>> by the Ambitus_engraver, and would allow one to have any keySignature for
>> the ambitus, which would be different from the staff/voice.  You would then
>> 
>> \set ambitusKeySignature = #'()
>> 
>> 2) Add a property ambitusIgnoreKeySignature that would cause the
>> Ambitus_engraver to ignore the keySignature of the containing context.  You
>> would then do
> 
> I think it might be better to have the ambitus engraver copy the key
> signature at the time where it is consulted.  Then it would be
> tweakable.
> 
> I currently have no idea just how and when the key signature gets
> consulted by the engraver.

So, if you look at lily/ambitus-engraver.cc, you'll see the following:

1) The ambitus is created in the very first time step (see lines 103-111).

2) The key signature is consulted at the very end of the first time step in
stop_translation_timestep (and uses the start_key_sig_ variable).  (see
lines 113-129)

3. The accidentals are added based on start_key_signature_ in finalize
(lines 153-214).

So one could hack things by using \set keySignature = #'(...) after the
first note, and as long as the first note was not part of the key signature,
things wouldn't work well.

But it would be trivial to implement an ambitusIgnoreKeySignature property
in the current engraver.

> 
> Anyway, I think that likely the ambitus engraver would be a good
> candidate for reimplementing as a Scheme engraver.  It would appear
> reasonably straightforward but not trivially so, and it is one of those
> things where augmenting the _code_ and behavior is likely to be better
> extensible in Scheme.

I think it would be difficult to implement as a Scheme engraver, because
there need to be variables stored as part of the context that are modified
by different event handlers.  But I could be wrong.  It wouldn't be the
first time and is not likely to be the last.

> 
> For example, I'd like the max-min interval finder prefer notes
> compatible with the ambitus key.  I have code here where the ambitus is
> in c major and shows an ambitus from f to fes' (because the fes' indeed
> occurs before the equivalent e' appears in the voice).

It should be possible to make this change in the current engraver.

> 
> Another extension would be to deal with clef changes and/or octavation:
> if those are different for high and low end of the ambitus interval, it
> might make sense to engrave lower and upper ambitus limits separately.
> 

I haven't been able to imagine how the ambitus would (graphically) deal with
clef changes.

There is code in the engraver that recognizes the possibility of changes in
the clef.

> And semi-visual composition is less of a pain in Scheme than in C++.

The semi-visual composition is done in the output end, not in the engraver.

The engraver creates the grob, and the grob's 'stencil function actually
creates the ink on the page.  So all the engraver needs to do is populate a
data structure that tells  what is to be typeset; all of the visual stuff is
done in the output functions.

As an example, consider a FretBoard.  This is a fairly complex piece of
visual composition, and it is all done in Scheme.  The engraver is quite
simple.  It simply creates a FretBoard grob and gives its 'string-count and
'dot-placement-list poperties values.  All of the graphical composition is
done in Scheme and outside of the engraver.

HTH,

Carl





reply via email to

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