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