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>
10 #include "auto-beam-engraver.hh"
11 #include "musical-request.hh"
13 #include "grouping.hh"
17 #include "time-description.hh"
19 ADD_THIS_TRANSLATOR (Auto_beam_engraver);
21 Auto_beam_engraver::Auto_beam_engraver ()
25 finished_grouping_p_ = 0;
30 Auto_beam_engraver::do_process_requests ()
32 Time_description const *time = get_staff_info().time_C_;
36 Scalar begin = get_property ("beamAutoBegin", 0);
39 // begin_mom = (Real)begin;
40 begin_f = (Real)begin;
44 Scalar end = get_property ("beamAutoEnd", 0);
49 // end_mom = (Real)end;
54 Real epsilon_f = Moment (1, 512);
56 if (beam_p_ && ((f=abs (fmod (time->whole_in_measure_, end_f))) < epsilon_f))
58 DOUT << String ("ending autobeam at: ") + now_moment ().str ();
59 if (beam_p_->stems_.size () < 2)
61 DOUT << "junking autombeam: less than two stems";
66 finished_beam_p_ = beam_p_;
67 finished_grouping_p_ = grouping_p_;
74 Allow already started autobeam to end
76 Scalar on = get_property ("beamAuto", 0);
80 if (!beam_p_ && ((f=abs (fmod (time->whole_in_measure_, begin_f))) < epsilon_f))
82 DOUT << String ("starting autobeam at: ") + now_moment ().str ();
84 grouping_p_ = new Rhythmic_grouping;
86 /* urg, copied from Beam_engraver */
87 Scalar prop = get_property ("beamslopedamping", 0);
89 beam_p_->damping_i_ = prop;
91 prop = get_property ("beamquantisation", 0);
93 beam_p_->quantisation_ = (Beam::Quantisation)(int)prop;
95 // must set minVerticalAlign = = maxVerticalAlign to get sane results
96 // see input/test/beam-interstaff.ly
97 prop = get_property ("minVerticalAlign", 0);
99 beam_p_->vertical_align_drul_[MIN] = prop;
101 prop = get_property ("maxVerticalAlign", 0);
103 beam_p_->vertical_align_drul_[MAX] = prop;
105 announce_element (Score_element_info (beam_p_, 0));
110 Auto_beam_engraver::typeset_beam ()
112 if (finished_beam_p_)
114 Rhythmic_grouping const * rg_C = get_staff_info().rhythmic_C_;
115 rg_C->extend (finished_grouping_p_->interval());
116 finished_beam_p_->set_grouping (*rg_C, *finished_grouping_p_);
117 typeset_element (finished_beam_p_);
118 finished_beam_p_ = 0;
120 delete finished_grouping_p_;
121 finished_grouping_p_= 0;
126 Auto_beam_engraver::do_post_move_processing ()
131 Auto_beam_engraver::do_pre_move_processing ()
137 Auto_beam_engraver::do_removal_processing ()
142 DOUT << "Unfinished beam";
148 Auto_beam_engraver::acknowledge_element (Score_element_info info)
150 if (Beam *b = dynamic_cast<Beam *> (info.elem_l_))
154 DOUT << "junking autobeam: beam encountered";
161 Rhythmic_req *rhythmic_req = dynamic_cast <Rhythmic_req *> (info.req_l_);
165 if (dynamic_cast<Rest *> (info.elem_l_))
167 DOUT << "junking autobeam: rest encountered";
172 Stem* stem_l = dynamic_cast<Stem *> (info.elem_l_);
176 if (stem_l->beam_l_ && (stem_l->beam_l_ != beam_p_))
178 DOUT << "junking autobeam: beamed stem encountered";
185 now that we have last_add_mom_, perhaps we can (should) do away
186 with these individual unbeams
188 if (rhythmic_req->duration_.durlog_i_<= 2)
190 DOUT << "stem doesn't fit in beam";
195 Moment start = get_staff_info().time_C_->whole_in_measure_;
196 if (!grouping_p_->child_fit_b (start))
202 grouping_p_->add_child (start, rhythmic_req->duration ());
203 stem_l->flag_i_ = rhythmic_req->duration_.durlog_i_;
204 beam_p_->add_stem (stem_l);
205 Moment now = now_moment ();
207 extend_mom_ = extend_mom_ >? now + rhythmic_req->duration ();
213 Auto_beam_engraver::unbeam ()
216 for (int i=0; i < beam_p_->stems_.size (); i++)
218 Stem* s = beam_p_->stems_[i];
219 s->beams_i_drul_[LEFT] = 0;
220 s->beams_i_drul_[RIGHT] = 0;
232 Auto_beam_engraver::process_acknowledged ()
236 Moment now = now_moment ();
237 if ((extend_mom_ < now)
238 || ((extend_mom_ == now) && (last_add_mom_ != now )))
240 DOUT << String ("junking autobeam: no stem added since: ")
241 + last_add_mom_.str ();
244 else if (!beam_p_->stems_.size ())
246 DOUT << "junking started autobeam: no stems";