2 tab-note-heads-engraver.cc -- part of GNU LilyPond
4 (c) 2002--2009 Han-Wen Nienhuys, Jean-Baptiste Lamy <jiba@tuxfamily.org>,
10 #include "engraver.hh"
14 #include "duration.hh"
16 #include "output-def.hh"
18 #include "rhythmic-head.hh"
19 #include "stream-event.hh"
23 #include "translator.icc"
26 make (guitar-like) tablature note
28 class Tab_note_heads_engraver
: public Engraver
32 vector
<Stream_event
*> note_events_
;
33 vector
<Stream_event
*> tabstring_events_
;
35 TRANSLATOR_DECLARATIONS (Tab_note_heads_engraver
);
38 DECLARE_TRANSLATOR_LISTENER (note
);
39 DECLARE_TRANSLATOR_LISTENER (string_number
);
40 void process_music ();
42 void stop_translation_timestep ();
45 Tab_note_heads_engraver::Tab_note_heads_engraver ()
49 IMPLEMENT_TRANSLATOR_LISTENER (Tab_note_heads_engraver
, note
);
51 Tab_note_heads_engraver::listen_note (Stream_event
*ev
)
53 note_events_
.push_back (ev
);
56 IMPLEMENT_TRANSLATOR_LISTENER (Tab_note_heads_engraver
, string_number
);
58 Tab_note_heads_engraver::listen_string_number (Stream_event
*ev
)
60 tabstring_events_
.push_back (ev
);
64 Tab_note_heads_engraver::process_music ()
67 for (vsize i
= 0; i
< note_events_
.size (); i
++)
69 SCM string_tunings
= get_property ("stringTunings");
70 int string_count
= scm_ilength (string_tunings
);
71 bool high_string_one
= to_boolean (get_property ("highStringOne"));
73 Stream_event
*event
= note_events_
[i
];
75 Stream_event
*tabstring_event
= 0;
77 for (SCM s
= event
->get_property ("articulations");
78 !tabstring_event
&& scm_is_pair (s
); s
= scm_cdr (s
))
80 Stream_event
*art
= unsmob_stream_event (scm_car (s
));
82 if (art
->in_event_class ("string-number-event"))
83 tabstring_event
= art
;
86 if (!tabstring_event
&& j
< tabstring_events_
.size ())
88 tabstring_event
= tabstring_events_
[j
];
89 if (j
+ 1 < tabstring_events_
.size ())
93 int string_number
= 0;
95 string_number
= scm_to_int (tabstring_event
->get_property ("string-number"));
99 SCM scm_pitch
= event
->get_property ("pitch");
100 int min_fret
= robust_scm2int (get_property ("minimumFret"), 0);
101 int start
= (high_string_one
) ? 1 : string_count
;
102 int end
= (high_string_one
) ? string_count
+1 : 0;
107 int fret
= unsmob_pitch (scm_pitch
)->rounded_semitone_pitch ()
108 - scm_to_int (robust_list_ref (i
- 1, string_tunings
));
110 if (fret
>= min_fret
)
115 i
+= high_string_one
? 1 : -1;
122 SCM proc
= get_property ("tablatureFormat");
123 SCM text
= scm_call_3 (proc
, scm_from_int (string_number
),
124 context ()->self_scm (),
126 Item
*note
= make_item ("TabNoteHead", event
->self_scm ());
127 note
->set_property ("text", text
);
130 int pos
= 2 * string_number
- string_count
- 1; // No tab-note between the string !!!
131 if (to_boolean (get_property ("stringOneTopmost")))
134 note
->set_property ("staff-position", scm_from_int (pos
));
136 notes_
.push_back (note
);
139 event
->origin ()->warning ("could not calculate a string number.");
143 Tab_note_heads_engraver::stop_translation_timestep ()
146 note_events_
.clear ();
147 tabstring_events_
.clear ();
150 ADD_TRANSLATOR (Tab_note_heads_engraver
,
152 "Generate one or more tablature noteheads from event of type"
153 " @code{NoteEvent}.",