]> git.donarmstrong.com Git - lilypond.git/blob - lily/fretboard-engraver.cc
Merge commit 'origin/dev/jneeman' into systems-per-page
[lilypond.git] / lily / fretboard-engraver.cc
1 /*
2   fretboard-engraver.cc -- part of GNU LilyPond
3
4   (c)  2006  Han-Wen Nienhuys
5 */
6
7 #include <cctype>
8 #include <cstdio>
9 using namespace std;
10
11 #include "context.hh"
12 #include "item.hh"
13 #include "engraver.hh"
14 #include "pitch.hh"
15 #include "stream-event.hh"
16 #include "warn.hh"
17
18 #include "translator.icc"
19
20 /**
21    make (guitar-like) tablature note
22 */
23 class Fretboard_engraver : public Engraver
24 {
25   Item *fret_board_;
26   
27   vector<Stream_event*> note_events_;
28   vector<Stream_event*> tabstring_events_;
29 public:
30   TRANSLATOR_DECLARATIONS (Fretboard_engraver);
31
32 protected:
33   void stop_translation_timestep ();
34   void process_music ();
35   virtual void derived_mark() const;
36   DECLARE_TRANSLATOR_LISTENER (note);
37   DECLARE_TRANSLATOR_LISTENER (string_number);
38
39 private:
40   SCM last_fret_notes_;
41 };
42
43
44 void
45 Fretboard_engraver::derived_mark () const
46 {
47   scm_gc_mark (last_fret_notes_);
48 }
49
50 Fretboard_engraver::Fretboard_engraver ()
51 {
52   fret_board_ = 0;
53   last_fret_notes_ = SCM_EOL;
54 }
55
56 IMPLEMENT_TRANSLATOR_LISTENER (Fretboard_engraver, note);
57 void
58 Fretboard_engraver::listen_note (Stream_event *ev)
59 {
60   note_events_.push_back (ev);
61 }
62
63 IMPLEMENT_TRANSLATOR_LISTENER (Fretboard_engraver, string_number);
64 void
65 Fretboard_engraver::listen_string_number (Stream_event *ev)
66 {
67   tabstring_events_.push_back (ev);
68 }
69
70 void
71 Fretboard_engraver::process_music ()
72 {
73   if (!note_events_.size ())
74     return ;
75
76   fret_board_ = make_item ("FretBoard", note_events_[0]->self_scm ());
77   SCM fret_notes = ly_cxx_vector_to_list (note_events_);
78   SCM proc = get_property ("noteToFretFunction");
79   if (ly_is_procedure (proc))
80     {
81      scm_call_4 (proc,
82                  context ()->self_scm (),
83                  fret_board_->self_scm (),
84                  fret_notes,           
85                  ly_cxx_vector_to_list (tabstring_events_));
86     }
87   SCM changes = get_property("chordChanges");
88   if (to_boolean (changes) && scm_is_pair(last_fret_notes_)
89       && ly_is_equal (last_fret_notes_, fret_notes))
90     fret_board_->set_property ("begin-of-line-visible", SCM_BOOL_T);
91   
92   last_fret_notes_ = fret_notes;
93 }
94
95 void
96 Fretboard_engraver::stop_translation_timestep ()
97 {
98   fret_board_ = 0;
99   note_events_.clear ();
100   tabstring_events_.clear ();
101 }
102
103 ADD_TRANSLATOR (Fretboard_engraver,
104                 /* doc */
105                 "Generate one or more tablature noteheads from event of type"
106                 " @code{NoteEvent}.",
107
108                 /* create */
109                 "FretBoard ",
110
111                 /* read */
112                 "chordChanges "
113                 "stringTunings "
114                 "minimumFret "
115                 "maximumFretStretch "
116                 "tablatureFormat "
117                 "highStringOne "
118                 "predefinedDiagramTable",
119
120                 /* write */
121                 ""
122                 );
123