[frogs] chord name engraver plus capo

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


 At last :-)

I've managed to work my way through (having lost my first attempt), and
here's my crack at doing the engraver.  I've just done process_music in
this mail, since it's the only thing I've really changed.

I've added the capo variables, filled them in, and got down almost to
the bottom.  There's just a couple of things to fix before I can try a
"compile and test". How do I actually get hold of the property capoFret?
And how do I combine the markups? I'm not going to bother with vertical
markup at the moment. That'll be easier once I've got to grips with the
rest of it.

Note that all my added comments are C++ style - // - and I tend to mark
"to dos" in my code with a triple bang !!!

So how do I fix those two issues? and then you'll probably hear the
screaming as it blows up (or hopefully the cheering as it works :-)

Cheers,
Wol

------------------------------------------------------

void
Chord_name_engraver::process_music ()
// This is called for each note or rest.
// It is called as a result of being registered with
IMPLEMENT_TRANSLATOR_LISTENER
{
  SCM markup;        // to store markup in
  SCM bass = SCM_EOL;    // remember notes to create chord
  SCM inversion = SCM_EOL;
  SCM pitches = SCM_EOL;

  SCM capo_markup;    // and transposed notes for capo chord
  SCM capo_bass = SCM_EOL;
  SCM capo_inversion = SCM_EOL;
  SCM capo_pitches = SCM_EOL;
 
  if (rest_event_)
    {    // process a rest
      SCM no_chord_markup = get_property ("noChordSymbol");
      if (!Text_interface::is_markup (no_chord_markup))
        return;
      markup = no_chord_markup;
    }
  else
    {  // process a note event
      if (!notes_.size ())
        return;

      // get capo fret !!!
      // This is set by "\set ChordNames.capoFret = #3" in the lily
source file
      SCM capofret = whatever->get_property ("capoFret");
      int capo = 0;
      if (scm_is_number (capofret))
    capo = scm_to_int (capofret);
     
      Stream_event *inversion_event = 0;
      for (vsize i = 0; i < notes_.size (); i++)
      {    // step through each note in turn
        Stream_event *n = notes_[i];
        SCM p = n->get_property ("pitch");
        if (!unsmob_pitch (p))
          continue;

        if (n->get_property ("inversion") == SCM_BOOL_T)
        {
          inversion_event = n;
          inversion = p;
      if (capo)
        capo_inversion = p->transposed (Pitch (-capo, 0, 0));
    }
        else if (n->get_property ("bass") == SCM_BOOL_T)
          bass = p;
      if (capo)
        capo_bass = p->transposed (Pitch (-capo, 0, 0));
        else
          pitches = scm_cons (p, pitches);
      if (capo)
        capo_pitches = scm_cons ( p->transposed (Pitch (-capo, 0, 0)),
capo_pitches);
      }

      if (inversion_event)
      {
        SCM oct = inversion_event->get_property ("octavation");
        if (scm_is_number (oct))
        {
          Pitch *p = unsmob_pitch (inversion_event->get_property ("pitch"));
          int octavation = scm_to_int (oct);
          Pitch orig = p->transposed (Pitch (-octavation, 0, 0));

          pitches = scm_cons (orig.smobbed_copy (), pitches);
     
      // if capo sort this out later !!!
     
        }
        else
          programming_error ("inversion does not have original pitch");
      }

      pitches = scm_sort_list (pitches, Pitch::less_p_proc);
      if (capo)
    capo_pitches = scm_sort_list (capo_pitches, Pitch::less_p_proc);
   
      SCM name_proc = get_property ("chordNameFunction");
      markup = scm_call_4 (name_proc, pitches, bass, inversion,
          context ()->self_scm ());
      if (capo)
    capo_markup = scm_call_4 (name_proc, capo_pitches, capo_bass,
capo_inversion,
        context ()->self_scm ());
    }
  /*
    Ugh. // Why's this ughly?
  */
 
  // do we need any more capo stuff here beyond setting the chord name text?
 
  SCM chord_as_scm = scm_cons (pitches, scm_cons (bass, inversion));

  chord_name_ = make_item ("ChordName",
      rest_event_ ? rest_event_->self_scm () : notes_[0]->self_scm ());
  if (!capo)
    chord_name_->set_property ("text", markup);
  else
    // how do I combine text and markup to get "markup (capo_markup)" !!!

  SCM chord_changes = get_property("chordChanges");
  if (to_boolean (chord_changes) && scm_is_pair (last_chord_)
      && ly_is_equal (chord_as_scm, last_chord_))
    chord_name_->set_property ("begin-of-line-visible", SCM_BOOL_T);

  last_chord_ = chord_as_scm;
}

---
----
Join the Frogs!


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