2 auto-beam-engraver.cc -- implement Auto_beam_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
9 #include "new-beaming.hh"
10 #include "auto-beam-engraver.hh"
11 #include "musical-request.hh"
17 #include "timing-engraver.hh"
18 #include "engraver-group-engraver.hh"
20 ADD_THIS_TRANSLATOR (Auto_beam_engraver);
22 Auto_beam_engraver::Auto_beam_engraver ()
25 shortest_mom_ = Moment (1, 8);
27 finished_grouping_p_ = 0;
33 Auto_beam_engraver::do_creation_processing ()
35 Translator * t = daddy_grav_l ()->get_simple_translator ("Timing_engraver");
36 timer_l_ = dynamic_cast<Timing_engraver*> (t);
40 Auto_beam_engraver::do_try_music (Music* m)
43 Mag dit? Nu word-i toch maar geswallowed, en
44 komt er dus ook geen announce...
46 if (Skip_req* s = dynamic_cast <Skip_req*> (m))
56 Auto_beam_engraver::do_process_requests ()
58 consider_end_and_begin (shortest_mom_);
62 Auto_beam_engraver::consider_end_and_begin (Moment test_mom)
67 Time_description const *time = &timer_l_->time_;
68 int num = time->whole_per_measure_ / time->one_beat_;
69 int den = time->one_beat_.den_i ();
70 String time_str = String ("time") + to_str (num) + "_" + to_str (den);
73 if (test_mom.num () != 1)
74 type_str = to_str (test_mom.num ());
75 if (test_mom.den () != 1)
76 type_str = type_str + "_" + to_str (test_mom.den ());
79 Determine end moment for auto beaming (and begin, mostly 0==anywhere)
80 In order of increasing priority:
83 ii. time<num>_<den>beamAutoEnd
84 iii. time<num>_<den>beamAutoEnd<type>
91 [to be defined in config file]
92 i. easy catch-all rule
93 ii. exceptions for time signature
94 iii. exceptions for time signature, for specific duration type
98 v. override for specific duration type
100 The user overrides should be required for common cases.
104 first guess: begin beam at any position
106 Moment begin_mom (0);
108 first guess: end beam at end of beat
110 Moment end_mom = time->one_beat_;
113 second guess: property generic time exception
115 Scalar begin = get_property (time_str + "beamAutoBegin", 0);
116 if (begin.length_i ())
117 begin_mom = begin.to_rat ();
119 Scalar end = get_property (time_str + "beamAutoEnd", 0);
121 end_mom = end.to_rat ();
124 third guess: property time exception, specific for duration type
126 if (type_str.length_i ())
128 Scalar end_mult = get_property (time_str + "beamAutoEnd" + type_str, 0);
129 if (end_mult.length_i ())
130 end_mom = end_mult.to_rat ();
131 Scalar begin_mult = get_property (time_str + "beamAutoBegin" + type_str, 0);
132 if (begin_mult.length_i ())
133 begin_mom = begin_mult.to_rat ();
137 fourth guess [user override]: property plain generic
139 begin = get_property ("beamAutoBegin", 0);
140 if (begin.length_i ())
141 begin_mom = begin.to_rat ();
143 end = get_property ("beamAutoEnd", 0);
145 end_mom = end.to_rat ();
148 fifth guess [user override]: property plain, specific for duration type
150 if (type_str.length_i ())
152 Scalar end_mult = get_property (String ("beamAutoEnd") + type_str, 0);
153 if (end_mult.length_i ())
154 end_mom = end_mult.to_rat ();
155 Scalar begin_mult = get_property (String ("beamAutoBegin") + type_str, 0);
156 if (begin_mult.length_i ())
157 begin_mom = begin_mult.to_rat ();
162 r = time->whole_in_measure_.mod_rat (end_mom);
166 if (stem_l_arr_p_ && !r)
170 Allow already started autobeam to end
172 Scalar on = get_property ("beamAuto", 0);
177 r = time->whole_in_measure_.mod_rat (begin_mom);
178 if (!stem_l_arr_p_ && (!begin_mom || !r))
184 Auto_beam_engraver::begin_beam ()
186 assert (!stem_l_arr_p_);
187 stem_l_arr_p_ = new Array<Stem*>;
188 assert (!grouping_p_);
189 grouping_p_ = new Beaming_info_list;
190 beam_start_moment_ = now_mom ();
191 beam_start_location_ = timer_l_->time_.whole_in_measure_;
195 Auto_beam_engraver::create_beam_p ()
197 Beam* beam_p = new Beam;
199 for (int i = 0; i < stem_l_arr_p_->size (); i++)
200 beam_p->add_stem ((*stem_l_arr_p_)[i]);
202 /* urg, copied from Beam_engraver */
203 Scalar prop = get_property ("beamslopedamping", 0);
205 beam_p->set_elt_property (damping_scm_sym, gh_int2scm( prop));
207 prop = get_property ("beamquantisation", 0);
209 beam_p->quantisation_ = (Beam::Quantisation)(int)prop;
211 announce_element (Score_element_info (beam_p, 0));
216 Auto_beam_engraver::end_beam ()
218 if (stem_l_arr_p_->size () < 2)
224 finished_beam_p_ = create_beam_p ();
225 finished_grouping_p_ = grouping_p_;
226 delete stem_l_arr_p_;
229 shortest_mom_ = Moment (1, 8);
234 Auto_beam_engraver::typeset_beam ()
236 if (finished_beam_p_)
238 finished_grouping_p_->beamify ();
239 finished_beam_p_->set_beaming (finished_grouping_p_);
240 typeset_element (finished_beam_p_);
241 finished_beam_p_ = 0;
243 delete finished_grouping_p_;
244 finished_grouping_p_= 0;
249 Auto_beam_engraver::do_post_move_processing ()
254 Auto_beam_engraver::do_pre_move_processing ()
260 Auto_beam_engraver::do_removal_processing ()
268 Auto_beam_engraver::same_grace_state_b (Score_element* e)
270 bool gr = (e->get_elt_property (grace_scm_sym) != SCM_BOOL_F) ;
272 return gr == get_property ("weAreGraceContext",0).to_bool ();
276 Auto_beam_engraver::acknowledge_element (Score_element_info info)
278 if (!same_grace_state_b (info.elem_l_) || !timer_l_)
283 if (Beam *b = dynamic_cast<Beam *> (info.elem_l_))
287 else if (Bar *b = dynamic_cast<Bar *> (info.elem_l_))
291 else if (Rest* rest_l = dynamic_cast<Rest *> (info.elem_l_))
295 else if (Stem* stem_l = dynamic_cast<Stem *> (info.elem_l_))
297 Rhythmic_req *rhythmic_req = dynamic_cast <Rhythmic_req *> (info.req_l_);
300 programming_error ("Stem must have rhythmic structure");
311 now that we have last_add_mom_, perhaps we can (should) do away
312 with these individual junk_beams
315 int durlog =rhythmic_req->duration_.durlog_i_;
321 if shortest duration would change
322 reconsider ending/starting beam first.
324 Moment mom = rhythmic_req->duration_.length_mom ();
325 consider_end_and_begin (mom);
328 if (mom < shortest_mom_)
330 if (stem_l_arr_p_->size ())
333 consider_end_and_begin (shortest_mom_);
339 Moment now = now_mom ();
341 grouping_p_->add_stem (now - beam_start_moment_ + beam_start_location_, durlog - 2);
342 stem_l_arr_p_->push (stem_l);
344 extend_mom_ = extend_mom_ >? now + rhythmic_req->length_mom ();
351 Auto_beam_engraver::junk_beam ()
353 assert (stem_l_arr_p_);
355 delete stem_l_arr_p_;
359 shortest_mom_ = Moment (1, 8);
363 Auto_beam_engraver::process_acknowledged ()
367 Moment now = now_mom ();
368 if ((extend_mom_ < now)
369 || ((extend_mom_ == now) && (last_add_mom_ != now )))
373 else if (!stem_l_arr_p_->size ())