Re: [frogs] Another new tadpole?

[ Thread Index | Date Index | More lilynet.net/frogs Archives ]


On 8/10/10 3:44 PM, "Wols Lists" <antlists@xxxxxxxxxxxxxxx> wrote:

>  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!
Achtung!  Just a small aside that someone did a really good job with this:

http://lilypond.org/doc/v2.13/Documentation/contributor/engraver-tutorial

The only thing that is missing (assuming that I haven't overlooked it, which
is often an incorrect assumption) is a good definition of what a translation
timestep is (a definition that, unfortunately, I cannot furnish), although
perhaps that's somewhere else in the dox.

Anyway, I thought I'd bring it to your attention to save you a bit of work.

I've just implemented a host of scheme engraver stuff (meaning engravers
100% implemented in Scheme) if you want to check that out.  Let me know.

On that subject, any takers to try out my new patch for adding event-classes
via scheme?  There's a 15 second two-part-invention in it for the first
person who applies it and tries it!

~Mike

> Cheers,
> Wol
> 
> ---
> ----
> Join the Frogs!
> 
> 



---
----
Join the Frogs!


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/