I'm trying to make a FretDiagram context and a Fret_diagram_engraver to
better implement fret diagrams.

Here's what I've done:

1.  Copied ChordNames context in ly/engraver-init.ly 
Modified as it seemed to make sense to me.
\context {
    \type "Engraver_group_engraver"
    \name FretDiagram

    \description "Typesets fret diagrams."

    \consists "Fret_diagram_engraver"
    \consists "Volta_engraver"
    
    \consists "Rest_swallow_translator" 
    \consists "Output_property_engraver"        
    \consists "Separating_line_group_engraver"
    \consists "Skip_event_swallow_translator"
    \consists "Hara_kiri_engraver"
    
    fretDiagramCreator = #fret-diagram-markup
    voltaOnThisStaff = ##f
    minimumVerticalExtent = #'(0 . 2.5)
    extraVerticalExtent = ##f
    \override SeparatingGroupSpanner #'padding = #0.8
    verticalExtent = ##f 
}
2.  Copied chord-name-engraver.cc to fret-diagram-engraver.cc.  Made
changes as seemed appropriate.  For testing, I have a hard-coded fret
diagram markup.  Got the code to compile and link without error.  Copy
is attached.

3.  Added an entry in scm/define-context-properties.scm for
fretDiagramCreator.

     (fretDiagramCreator ,procedure? "Function used to create fret
diagrams, given a diagram string.")

4.  Created a .ly file to try out the engraver:

\score{
  <<
    \chords{d}
    \new FretDiagram {d}
    \chordmode{d}

  >>
}


Tried executing lilypond: 

[EMAIL PROTECTED] lilypond]$ lily/out/lilypond fretc2.ly
GNU LilyPond 2.5.0.hwn1
Processing `fretc2.ly'
Parsing...
Interpreting music... warning: Cannot find or create `FretDiagram'
called `uniqueContext1'
[1]
Preprocessing graphical objects...
Calculating line breaks... [2]
Layout output to `fretc2.tex'...
Converting to `fretc2.dvi'...
Converting to `fretc2.ps'...
Converting to `fretc2.pdf'...

I checked with gdb, and, as expected, the code is never executing
Fret_diagram_engraver::process_music.

What step have I missed?

Thanks,

Carl



/*
  fret-diagram-engraver.cc -- implement Chord_name_engraver

  source file of the GNU LilyPond music typesetter

  (c) 1998--2004 Jan Nieuwenhuizen <[EMAIL PROTECTED]>
*/

#include "engraver.hh"
#include "chord-name.hh"
#include "event.hh"
#include "output-def.hh"
#include "font-interface.hh"
#include "output-def.hh"
#include "dimensions.hh"
#include "item.hh"
#include "pitch.hh"
#include "protected-scm.hh"
#include "context.hh"
#include "warn.hh"

class Fret_diagram_engraver : public Engraver 
{
  TRANSLATOR_DECLARATIONS ( Fret_diagram_engraver);
protected:
  virtual void stop_translation_timestep ();
  virtual void process_music ();
  virtual bool try_music (Music *);
  virtual void finalize ();
  virtual void derived_mark () const;
private:
  void add_note (Music *);
  
  Item* fret_diagram_;
  Link_array<Music> notes_;
  
  SCM last_chord_;
};



void
Fret_diagram_engraver::finalize ()
{
}

void
Fret_diagram_engraver::derived_mark() const
{
  scm_gc_mark (last_chord_);
}

Fret_diagram_engraver::Fret_diagram_engraver ()
{
  fret_diagram_ = 0;
  last_chord_ = SCM_EOL;
}

void
Fret_diagram_engraver::add_note (Music * n)
{
  notes_.push (n);
}

void
Fret_diagram_engraver::process_music ()
{
  if (!notes_.size () )
    return;
  
  SCM bass = SCM_EOL;
  SCM inversion = SCM_EOL;
  SCM pitches = SCM_EOL;

  Music* inversion_event = 0;
  for (int i =0 ; i < notes_.size (); i++)
    {
      Music *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;
	}
      else if (n->get_property ("bass") == SCM_BOOL_T)
	bass = p;
      else
	pitches = scm_cons (p, 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);
	}
      else
	programming_error ("Inversion does not have original pitch.");
    }

  pitches = scm_sort_list (pitches, Pitch::less_p_proc);

  SCM name_proc = get_property ("fretDiagramCreator");
  //  SCM markup = scm_call_4 (name_proc, pitches, bass, inversion,
  //			   context ()->self_scm ());
   SCM markup = scm_listify (name_proc, 
          scm_makfrom0str("6-x;5-x;4-o;3-2;2-3;1-2;"), SCM_UNDEFINED);
   //SCM junkstr = scm_makfrom0str("ABC");
   //SCM junkstr2 = scm_makfrom0str("DEF");
   //SCM markup = scm_listify (junkstr, junkstr2, SCM_UNDEFINED);
 
  /*
    Ugh. 
   */
   SCM chord_as_scm = scm_cons (pitches, scm_cons (bass, inversion));
  
  //chord_name_ = make_item ("ChordName",notes_[0]->self_scm ());
  //chord_name_->set_property ("text", markup);
  fret_diagram_ = make_item ("FretDiagram",SCM_EOL); //WHAT GOES HERE?
  fret_diagram_->set_property ("text",markup);
    /*
  SCM s = get_property ("chordChanges");
  if (to_boolean (s) && scm_is_pair (last_chord_) 
      && ly_c_equal_p (chord_as_scm, last_chord_))
    chord_name_->set_property ("begin-of-line-visible", SCM_BOOL_T);
    */
   last_chord_ = chord_as_scm;
}

bool
Fret_diagram_engraver::try_music (Music* m)
{
  /*
    hmm. Should check? 
   */
  if (m->is_mus_type ("note-event"))
    {
      add_note (m);
      return true;
    }
  return false;
}

void
Fret_diagram_engraver::stop_translation_timestep ()
{
  fret_diagram_ = 0;
  notes_.clear ();
}

/*
  The READs description is not strictly accurate:
  which properties are read depend on the chord naming function active.
*/
ENTER_DESCRIPTION (Fret_diagram_engraver,
/* descr */       "Catch note-events "
"and generate the appropriate fret diagram.",
/* creats*/       "FretDiagram",
/* accepts */     "note-event",
/* acks  */      "",
/* reads */       "",
/* write */       "");
_______________________________________________
lilypond-devel mailing list
[EMAIL PROTECTED]
http://lists.gnu.org/mailman/listinfo/lilypond-devel

Reply via email to