2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1999--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
6 LilyPond is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 LilyPond is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
21 #include "beaming-pattern.hh"
24 Represents a stem belonging to a beam. Sometimes (for example, if the stem
25 belongs to a rest and stemlets aren't used) the stem will be invisible.
27 The rhythmic_importance_ of an element tells us the significance of the
28 moment at which this element occurs. For example, an element that occurs at
29 a beat is more significant than one that doesn't. Smaller number are
30 more important. The rhythmic_importance_ is decided and filled in by
31 Beaming_pattern. A rhythmic_importance_ smaller than zero has extra
32 significance: it represents the start of a beat and therefore beams may
33 need to be subdivided.
35 Beam_rhythmic_element::Beam_rhythmic_element ()
38 rhythmic_importance_ = 0;
39 beam_count_drul_[LEFT] = 0;
40 beam_count_drul_[RIGHT] = 0;
42 factor_ = Rational (1);
46 Beam_rhythmic_element::Beam_rhythmic_element (Moment m, int i, bool inv, Rational factor)
49 rhythmic_importance_ = 0;
50 beam_count_drul_[LEFT] = i;
51 beam_count_drul_[RIGHT] = i;
57 Beam_rhythmic_element::de_grace ()
59 if (start_moment_.grace_part_)
61 start_moment_.main_part_ = start_moment_.grace_part_;
62 start_moment_.grace_part_ = 0;
67 Beam_rhythmic_element::count (Direction d) const
69 return beam_count_drul_[d];
73 Finds the appropriate direction for the flags at the given index that
74 hang below the neighbouring flags. If
75 the stem has no more flags than either of its neighbours, this returns
79 Beaming_pattern::flag_direction (Beaming_options const &options, vsize i) const
81 // The extremal stems shouldn't be messed with, so it's appropriate to
82 // return CENTER here also.
83 if (i == 0 || i == infos_.size () - 1)
86 int count = infos_[i].count (LEFT); // Both directions should still be the same
87 int left_count = infos_[i - 1].count (RIGHT);
88 int right_count = infos_[i + 1].count (LEFT);
90 // If we are told to subdivide beams and we are next to a beat, point the
91 // beamlet away from the beat.
92 if (options.subdivide_beams_)
94 if (infos_[i].rhythmic_importance_ < 0)
96 else if (infos_[i + 1].rhythmic_importance_ < 0)
100 if (count <= left_count && count <= right_count)
103 // If all else fails, point the beamlet away from the important moment.
104 return (infos_[i].rhythmic_importance_ < infos_[i + 1].rhythmic_importance_)
109 Beaming_pattern::de_grace ()
111 for (vsize i = 0; i < infos_.size (); i++)
113 infos_[i].de_grace ();
118 Beaming_pattern::beamify (Beaming_options const &options)
120 if (infos_.size () <= 1)
123 unbeam_invisible_stems ();
125 if (infos_[0].start_moment_.grace_part_)
128 if (infos_[0].start_moment_ < Moment (0))
129 for (vsize i = 0; i < infos_.size (); i++)
130 infos_[i].start_moment_ += options.measure_length_;
132 find_rhythmic_importance (options);
134 vector <Direction> flag_directions;
135 // Get the initial flag directions
136 for (vsize i = 0; i < infos_.size (); i++)
137 flag_directions.push_back (flag_direction (options, i));
139 // Correct flag directions for subdivision
140 for (vsize i = 1; i < infos_.size () - 1; i++)
142 if ((flag_directions[i] == CENTER) && (flag_directions[i - 1] == LEFT))
143 flag_directions[i] = RIGHT;
144 if ((flag_directions[i] == CENTER) && (flag_directions[i + 1] == RIGHT))
145 flag_directions[i] = LEFT;
148 // Set the count on each side of the stem
149 // We need to run this code twice to make both the
150 // left and the right counts work properly
151 for (int i = 0; i < 2; i++)
152 for (vsize i = 1; i < infos_.size () - 1; i++)
154 Direction non_flag_dir = other_dir (flag_directions[i]);
157 int importance = infos_[i + 1].rhythmic_importance_;
158 int count = (importance < 0 && options.subdivide_beams_)
159 ? 1 : min (min (infos_[i].count (non_flag_dir),
160 infos_[i + non_flag_dir].count (-non_flag_dir)),
161 infos_[i - non_flag_dir].count (non_flag_dir));
163 infos_[i].beam_count_drul_[non_flag_dir] = count;
169 Set the tuplet start moment as necessary
172 update_tuplet (Moment start_moment, Rational factor, Moment *tuplet_start_moment)
174 int tuplet_number = (int) factor.den ();
175 if ((tuplet_number > 1) && (tuplet_start_moment->num () < 0))
176 *tuplet_start_moment = start_moment;
177 else if (tuplet_number == 1)
178 *tuplet_start_moment = Moment (-1, 1);
183 Get the group start position, the next group starting position, and the
184 next beat starting position, given start_moment, base_moment,
188 find_location (SCM grouping, Moment base_moment, Moment start_moment,
189 Rational factor, Moment *group_pos, Moment *next_group_pos,
190 Moment *next_beat_pos)
192 *group_pos = Moment (0);
193 *next_group_pos = Moment (0);
194 *next_beat_pos = base_moment;
196 while (*next_beat_pos <= start_moment)
197 *next_beat_pos += base_moment;
199 while (*next_group_pos < *next_beat_pos)
201 int group_count = 1; //default -- 1 base moments in a beam
202 if (scm_is_pair (grouping))
204 group_count = scm_to_int (scm_car (grouping));
205 grouping = scm_cdr (grouping);
208 // If we have a tuplet, the count should be determined from
209 // the maximum tuplet size for beamed tuplets.
210 int tuplet_number = factor.den ();
211 if (tuplet_number > 1)
213 // We use 1/8 as the base moment for the tuplet because it's
214 // the largest beamed value. If the tuplet is shorter, it's
215 // OK, the code still works
216 int test_count = ( Moment (Rational (1, 8) / factor ) / base_moment).num ();
217 if (test_count > group_count) group_count = test_count;
219 *group_pos = *next_group_pos;
220 *next_group_pos = *group_pos + group_count * base_moment;
225 Beaming_pattern::find_rhythmic_importance (Beaming_options const &options)
227 Moment group_pos (0); // 0 is the start of the first group
228 Moment next_group_pos (0);
229 Moment next_beat_pos (options.base_moment_);
230 Moment tuplet_start_moment (-1, 1);
231 int tuplet_number = 1;
233 SCM grouping = options.grouping_;
236 // Find where we are in the beat structure of the measure
238 find_location (grouping, options.base_moment_, infos_[i].start_moment_,
239 infos_[i].factor_, &group_pos, &next_group_pos, &next_beat_pos);
241 // Mark the importance of stems that start at a beat or a beat group.
242 while (i < infos_.size ())
244 if ((next_beat_pos > next_group_pos)
245 || (infos_[i].start_moment_ > next_beat_pos))
246 // Find the new group ending point
247 find_location (grouping, options.base_moment_, infos_[i].start_moment_,
248 infos_[i].factor_, &group_pos, &next_group_pos, &next_beat_pos);
249 // Mark the start of this beat group
250 if (infos_[i].start_moment_ == group_pos)
251 infos_[i].rhythmic_importance_ = -2;
252 // Work through the end of the beat group or the end of the beam
253 while (i < infos_.size () && infos_[i].start_moment_ < next_group_pos)
255 // Set the tuplet start as necessary
256 update_tuplet (infos_[i].start_moment_, infos_[i].factor_, &tuplet_start_moment);
257 Moment dt = infos_[i].start_moment_ - group_pos;
258 Rational tuplet = infos_[i].factor_;
259 Moment tuplet_moment (tuplet);
260 Moment tuplet_dt = infos_[i].start_moment_ - tuplet_start_moment;
261 tuplet_number = tuplet.den ();
262 // set the beat end (if not in a tuplet) and increment the next beat
263 if (tuplet_number == 1 && infos_[i].start_moment_ == next_beat_pos)
265 infos_[i].rhythmic_importance_ = -1;
266 next_beat_pos += options.base_moment_;
268 // The rhythmic importance of a stem between beats depends on its fraction
269 // of a beat: those stems with a lower denominator are deemed more
270 // important. For tuplets, we need to make sure that we use
271 // the fraction of the tuplet, instead of the fraction of
273 Moment ratio = (tuplet_number == 1)
274 ? dt / options.base_moment_
275 : tuplet_dt / Moment (1, 8) / tuplet_moment;
276 if (infos_[i].rhythmic_importance_ >= 0)
277 infos_[i].rhythmic_importance_ = (int) ratio.den ();
282 if (i < infos_.size () && infos_[i].start_moment_ == next_beat_pos)
284 if (tuplet_number == 1)
285 infos_[i].rhythmic_importance_ = -1;
286 next_beat_pos += options.base_moment_;
287 if (infos_[i].start_moment_ == next_group_pos)
288 infos_[i].rhythmic_importance_ = -2;
294 Invisible stems should be treated as though they have the same number of
295 beams as their least-beamed neighbour. Here we go through the stems and
296 modify the invisible stems to satisfy this requirement.
299 Beaming_pattern::unbeam_invisible_stems ()
301 for (vsize i = 1; i < infos_.size (); i++)
302 if (infos_[i].invisible_)
304 int b = min (infos_[i].count (LEFT), infos_[i - 1].count (LEFT));
305 infos_[i].beam_count_drul_[LEFT] = b;
306 infos_[i].beam_count_drul_[RIGHT] = b;
309 if (infos_.size () > 1)
310 for (vsize i = infos_.size () - 1; i--;)
311 if (infos_[i].invisible_)
313 int b = min (infos_[i].count (LEFT), infos_[i + 1].count (LEFT));
314 infos_[i].beam_count_drul_[LEFT] = b;
315 infos_[i].beam_count_drul_[RIGHT] = b;
320 Beaming_pattern::add_stem (Moment m, int b, bool invisible, Rational factor)
322 infos_.push_back (Beam_rhythmic_element (m, b, invisible, factor));
325 Beaming_pattern::Beaming_pattern ()
330 Beaming_pattern::beamlet_count (int i, Direction d) const
332 return infos_.at (i).beam_count_drul_[d];
336 Beaming_pattern::start_moment (int i) const
338 return infos_.at (i).start_moment_;
342 Beaming_pattern::end_moment (int i) const
344 Duration *dur = new Duration (2 + max (beamlet_count (i, LEFT),
345 beamlet_count (i, RIGHT)),
348 return infos_.at (i).start_moment_ + dur->get_length ();
352 Beaming_pattern::invisibility (int i) const
354 return infos_.at (i).invisible_;
358 Beaming_pattern::factor (int i) const
360 return infos_.at (i).factor_;
364 Split a beaming pattern at index i and return a new
365 Beaming_pattern containing the removed elements
368 Beaming_pattern::split_pattern (int i)
370 Beaming_pattern *new_pattern = 0;
373 new_pattern = new Beaming_pattern ();
374 for (vsize j = i + 1; j < infos_.size (); j++)
376 count = max (beamlet_count (j, LEFT), beamlet_count (j, RIGHT));
377 new_pattern->add_stem (start_moment (j),
382 for (vsize j = i + 1; j < infos_.size ();)
384 return (new_pattern);
388 Beaming_options::from_context (Context *context)
390 grouping_ = context->get_property ("beatStructure");
391 subdivide_beams_ = to_boolean (context->get_property ("subdivideBeams"));
392 base_moment_ = robust_scm2moment (context->get_property ("baseMoment"),
394 measure_length_ = robust_scm2moment (context->get_property ("measureLength"),
398 Beaming_options::Beaming_options ()
401 subdivide_beams_ = false;