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