Re: [frogs] Another new tadpole? |
[ Thread Index |
Date Index
| More lilynet.net/frogs Archives
]
On 10/08/10 00:54, Carl Sorensen wrote:
>>>
>>> Okay. I've looked through chord-name-engraver.cc, and I think I've
>>> understood roughly what's going on. It looks like the main thing
>>> I've
>>> got to change is Chord_name_engraver::process_music(). As far as I
>>> can
>>> see, this is building up a list of note pitches in the variable
>>> "pitches" and then passing it to a function to convert it to a
>>> chord name.
>> This sounds right to me.
> Yes, this is so.
>
Okay. So I'm on the right track.
>>> So what I need to do, is create a new variable "capo_pitches", and
>>> just
>>> as pitches are assigned to "pitches", I need to transpose them and
>>> assign them to "capo_pitches". I can then create "capo_markup",
>>> which
>>> will (if I've understood the code correctly) contain a text
>>> description
>>> of the transposed chord. So I now have - hopefully - "markup" ==
>>> eg "Gm"
>>> giving me "capo_markup" == "Em" if capo is 3. I now need
>>> chord_name_->set_property("text", "markup ( capo_markup )" )
> Not quite. It's not a text description, but actually a markup description.
> The property name is "text", but the result from calling the scheme
> procedure stored in the context property chordNameFunction returns a markup.
>
> Better I think to just have line 95 change to something like
>
> SCM raw_pitch = n->get_property ("pitch");
> SCM p = raw_pitch->transposed (Pitch (0, 0, capo_semitones));
>
> Now you have p transposed, and everything should work properly, IIUC.
Great. I assume to transpose down I need a negative, so if capo is 3, I
either print 3 and set capo_semitones to -3, or I pass -capo_semitones.
Either way, I'll cross that bridge when I get to it.
Don't forget I need both "raw_pitch" and "p", though. My pseudo-code may
have misled (the joys of multiple meanings of parentheses :-). So I'll
be asking how to combine markup next :-) because the output needs to be
eg "C(A)".
>> So far so good, but I'm beginning to wonder if this is not
>> duplicating something...
>>
>>> The other thing I need to do is write a new engraver ...
>> Hhm. Why is that? Would that be better than modifying
>> the existing chord name engraver to be aware of capos (capi?).
>>
> I'm guessing that you're wanting a capo_indicating_engraver to write the
> statement that tells you what fret to put the capo on, and indicates the key
> in the "capo" worldview. I don't think you should need to do the key
> signature engraver. Something like the metronome engraver is probably a
> better pattern.
>
Spot on again. Okay, I'll investigate that engraver and see how I can
revamp it as a capo_indicating_engraver.
>>> I've tried to look at the key signature engraver, but that doesn't
>>> seem
>>> to be so simple (I'm not surprised ...). What I need to do is have
>>> some
>>> lilypond syntax "\capo 3 vertical|horizontal", with it defaulting
>>> to
>>> horizontal.
> If you really need a new engraver, then you'll also need to create a new
> event (a capoEvent) that both the Capo engraver and the ChordName engraver
> will need to listen to. You might want to consider Trevor's suggestion, of
> just defining a new context property.
>
Bear in mind I've just jumped into the pond and am already out of my
depth :-) How do I create a context property? And if I go down that
route how will I get the capo indicator to print at the start of the
piece? Basically, my idea is that the user will simply put the capo
command with the key signature command in their .ly file, and that will
trigger the capo indicator plus automatically transpose any chord-names
they choose to print.
>> This sounds like a new context property set in the ChordName
>> context and used by the ChordName engraver to decide whether
>> to transpose and by how much.
>>> This will then need to get the key signature and print
>>> (assuming a key of G minor, the example in front of me) "Capo 3
>>> (Em)",
>>> transposing the key down three semitones. It'll also need to leave
>>> the 3
>>> somewhere (along with vertical/horizontal), so the chord engraver
>>> knows
>>> what to do. Wherever it stores the transposition, should that
>>> default to
>>> null or 0?
> No, you don't "leave the 3 somewhere". You have an event that both the Capo
> engraver and the ChordName engraver listen to. Then the ChordName engraver
> puts the 3 in the appropriate place. And the Capo engraver creates the
> appropriate output.
>
> Just out of curiosity, what does vertical/horizontal do?
>
As you guessed, places the two chords side-by-side or vertically
stacked. Can an event return two values, so the chord name engraver gets
the transposition and stacking?
>> I'm getting puzzled now. \transpose can already be invoked to
>> change chord names, can't it? What functionality does
>> it lack that you need? (Sorry if the answer's obvious - I'm not
>> a guitar player.) I can see the capo is not fully supported in
>> fret diagrams. AFAICS this currently has to be provided for every
>> fret diagram. But if you only want chord names perhaps a slightly
>> different way of invoking \transpose would suffice?
>>
>>> Okay. Where do I start with writing my new engraver? And have I
>>> got my
>>> changes to chord-name-engraver close? One of the things that gets
>>> me
>>> (dunno if it's common practice, it isn't to me) is the almost
>>> complete
>>> lack of comments in the code. What I'll probably do is write up
>>> what I'm
>>> doing as I do it, and heavily comment my engraver so that even if
>>> the
>>> comments don't make it into production code, they can make
>>> documentation
>>> as a "sample engraver".
>> Assuming you really do need a new engraver this is where
>> I have to hand over to someone more competent. But a commented
>> engraver would be a useful addition to the CG.
> I agree wholeheartedly. The real problem (IMO) with engravers is that he
> general structure of an engraver is not documented anywhere very well
> (although we're adding some stuff to the CG). Most of the comments that
> would help to understand an engraver are unneeded once you understand an
> engraver structure (e.g. we don't really want to have a comment in every
> engraver describing what stop_translation_timestep (), process_music (),
> etc. do -- that would just clutter up the code). Once you understand
> process_music (), you only really want comments related to the *specific*
> procsess_for this engraver, and with good variable names, it's not really
> that hard in most cases to figure most of it out.
>
> But the overall structure is *very* hard to get figured out, in my
> experience.
So if I can crack and document this, it'll be a worthwhile effort. Good!
Cheers,
Wol
---
----
Join the Frogs!