2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1999--2015 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"
25 Represents a stem belonging to a beam. Sometimes (for example, if the stem
26 belongs to a rest and stemlets aren't used) the stem will be invisible.
28 The rhythmic_importance_ of an element tells us the significance of the
29 moment at which this element occurs. For example, an element that occurs at
30 a beat is more significant than one that doesn't. Smaller number are
31 more important. The rhythmic_importance_ is decided and filled in by
32 Beaming_pattern. A rhythmic_importance_ smaller than zero has extra
33 significance: it represents the start of a beat and therefore beams may
34 need to be subdivided.
36 Beam_rhythmic_element::Beam_rhythmic_element ()
39 rhythmic_importance_ = 0;
40 beam_count_drul_[LEFT] = 0;
41 beam_count_drul_[RIGHT] = 0;
43 factor_ = Rational (1);
44 tuplet_start_ = false;
47 Beam_rhythmic_element::Beam_rhythmic_element (Moment m, int i, bool inv,
48 Rational factor, bool tuplet_start)
51 rhythmic_importance_ = 0;
52 beam_count_drul_[LEFT] = i;
53 beam_count_drul_[RIGHT] = i;
56 tuplet_start_ = tuplet_start;
60 Beam_rhythmic_element::de_grace ()
62 if (start_moment_.grace_part_)
64 start_moment_.main_part_ = start_moment_.grace_part_;
65 start_moment_.grace_part_ = 0;
70 Beam_rhythmic_element::count (Direction d) const
72 return beam_count_drul_[d];
76 Finds the appropriate direction for the flags at the given index that
77 hang below the neighbouring flags. If
78 the stem has no more flags than either of its neighbours, this returns
82 Beaming_pattern::flag_direction (Beaming_options const &options, vsize i) const
84 // The extremal stems shouldn't be messed with, so it's appropriate to
85 // return CENTER here also.
86 if (i == 0 || i == infos_.size () - 1)
89 int count = infos_[i].count (LEFT); // Both directions should still be the same
90 int left_count = infos_[i - 1].count (RIGHT);
91 int right_count = infos_[i + 1].count (LEFT);
93 // If we are told to subdivide beams and we are next to a beat, point the
94 // beamlet away from the beat.
95 if (options.subdivide_beams_)
97 if (infos_[i].rhythmic_importance_ < 0)
99 else if (infos_[i + 1].rhythmic_importance_ < 0)
103 if (count <= left_count && count <= right_count)
105 else if (!options.strict_beat_beaming_)
107 // Try to avoid sticking-out flags as much as possible by pointing
108 // my flags at the neighbor with the most flags.
109 if (right_count > left_count)
111 else if (left_count > right_count)
115 // If all else fails, point the beamlet away from the important moment.
116 return (infos_[i].rhythmic_importance_ < infos_[i + 1].rhythmic_importance_)
121 Beaming_pattern::de_grace ()
123 for (vsize i = 0; i < infos_.size (); i++)
125 infos_[i].de_grace ();
130 Beaming_pattern::beamify (Beaming_options const &options)
132 if (infos_.size () <= 1)
135 int subdivide_beam_count = intlog2(options.base_moment_.main_part_.den())-2;
137 unbeam_invisible_stems ();
139 if (infos_[0].start_moment_.grace_part_)
142 if (infos_[0].start_moment_ < Moment (0))
143 for (vsize i = 0; i < infos_.size (); i++)
144 infos_[i].start_moment_ += options.measure_length_;
146 find_rhythmic_importance (options);
148 vector <Direction> flag_directions;
149 // Get the initial flag directions
150 for (vsize i = 0; i < infos_.size (); i++)
151 flag_directions.push_back (flag_direction (options, i));
153 // Correct flag directions for subdivision
154 for (vsize i = 1; i < infos_.size () - 1; i++)
156 if ((flag_directions[i] == CENTER) && (flag_directions[i - 1] == LEFT))
157 flag_directions[i] = RIGHT;
158 if ((flag_directions[i] == CENTER) && (flag_directions[i + 1] == RIGHT))
159 flag_directions[i] = LEFT;
162 // Set the count on each side of the stem
163 // We need to run this code twice to make both the
164 // left and the right counts work properly
165 for (int i = 0; i < 2; i++)
166 for (vsize i = 1; i < infos_.size () - 1; i++)
168 Direction non_flag_dir = -flag_directions[i];
171 int importance = infos_[i + 1].rhythmic_importance_;
172 int count = (importance < 0 && options.subdivide_beams_)
173 ? subdivide_beam_count
174 : min (min (infos_[i].count (non_flag_dir),
175 infos_[i + non_flag_dir].count (-non_flag_dir)),
176 infos_[i - non_flag_dir].count (non_flag_dir));
178 infos_[i].beam_count_drul_[non_flag_dir] = max(count, 1);
184 Set the tuplet start moment as necessary
187 update_tuplet (Moment start_moment, Rational factor, Moment *tuplet_start_moment)
189 int tuplet_number = (int) factor.den ();
190 if ((tuplet_number > 1) && (tuplet_start_moment->num () < 0))
191 *tuplet_start_moment = start_moment;
192 else if (tuplet_number == 1)
193 *tuplet_start_moment = Moment (-1, 1);
197 Get the group start position, the next group starting position, and the
198 next beat starting position, given start_moment, base_moment,
202 find_location (SCM grouping, Moment base_moment, Moment start_moment,
203 Rational factor, Moment *group_pos, Moment *next_group_pos,
204 Moment *next_beat_pos)
206 *group_pos = Moment (0);
207 *next_group_pos = Moment (0);
208 *next_beat_pos = base_moment;
210 while (*next_beat_pos <= start_moment)
211 *next_beat_pos += base_moment;
213 while (*next_group_pos < *next_beat_pos)
215 I64 group_count = 1; //default -- 1 base moments in a beam
216 if (scm_is_pair (grouping))
218 group_count = scm_to_int (scm_car (grouping));
219 grouping = scm_cdr (grouping);
222 // If we have a tuplet, the count should be determined from
223 // the maximum tuplet size for beamed tuplets.
224 U64 tuplet_number = factor.den ();
225 if (tuplet_number > 1U)
227 // We use 1/8 as the base moment for the tuplet because it's
228 // the largest beamed value. If the tuplet is shorter, it's
229 // OK, the code still works
230 I64 test_count = ( Moment (Rational (1, 8) / factor) / base_moment).num ();
231 if (test_count > group_count) group_count = test_count;
233 *group_pos = *next_group_pos;
234 *next_group_pos = *group_pos + Rational(group_count) * base_moment;
239 Beaming_pattern::find_rhythmic_importance (Beaming_options const &options)
241 Moment group_pos (0); // 0 is the start of the first group
242 Moment next_group_pos (0);
243 Moment next_beat_pos (options.base_moment_);
244 Moment tuplet_start_moment (-1, 1);
245 I64 tuplet_number = 1;
247 SCM grouping = options.grouping_;
250 // Find where we are in the beat structure of the measure
252 find_location (grouping, options.base_moment_, infos_[i].start_moment_,
253 infos_[i].factor_, &group_pos, &next_group_pos, &next_beat_pos);
255 // Mark the importance of stems that start at a beat or a beat group.
256 while (i < infos_.size ())
258 if ((next_beat_pos > next_group_pos)
259 || (infos_[i].start_moment_ > next_beat_pos))
260 // Find the new group ending point
261 find_location (grouping, options.base_moment_, infos_[i].start_moment_,
262 infos_[i].factor_, &group_pos, &next_group_pos, &next_beat_pos);
263 // Mark the start of this beat group
264 if (infos_[i].start_moment_ == group_pos)
265 infos_[i].rhythmic_importance_ = -2;
266 // Work through the end of the beat group or the end of the beam
267 while (i < infos_.size () && infos_[i].start_moment_ < next_group_pos)
269 // Set the tuplet start as necessary
270 update_tuplet (infos_[i].start_moment_, infos_[i].factor_, &tuplet_start_moment);
271 Moment dt = infos_[i].start_moment_ - group_pos;
272 Rational tuplet = infos_[i].factor_;
273 Moment tuplet_moment (tuplet);
274 Moment tuplet_dt = infos_[i].start_moment_ - tuplet_start_moment;
275 tuplet_number = tuplet.den ();
276 // set the beat end and increment the next beat
277 if (infos_[i].start_moment_ == next_beat_pos)
279 infos_[i].rhythmic_importance_ = -1;
280 next_beat_pos += options.base_moment_;
282 // The rhythmic importance of a stem between beats depends on its fraction
283 // of a beat: those stems with a lower denominator are deemed more
284 // important. For tuplets, we need to make sure that we use
285 // the fraction of the tuplet, instead of the fraction of
287 Moment ratio = (tuplet_number == 1)
288 ? dt / options.base_moment_
289 : tuplet_dt / Moment (1, 8) / tuplet_moment;
290 if (infos_[i].rhythmic_importance_ >= 0)
291 infos_[i].rhythmic_importance_ = (int) ratio.den ();
296 if (i < infos_.size () && infos_[i].start_moment_ == next_beat_pos)
298 if (tuplet_number == 1)
299 infos_[i].rhythmic_importance_ = -1;
300 next_beat_pos += options.base_moment_;
301 if (infos_[i].start_moment_ == next_group_pos)
302 infos_[i].rhythmic_importance_ = -2;
308 Invisible stems should be treated as though they have the same number of
309 beams as their least-beamed neighbour. Here we go through the stems and
310 modify the invisible stems to satisfy this requirement.
313 Beaming_pattern::unbeam_invisible_stems ()
315 for (vsize i = 1; i < infos_.size (); i++)
316 if (infos_[i].invisible_)
318 int b = min (infos_[i].count (LEFT), infos_[i - 1].count (LEFT));
319 infos_[i].beam_count_drul_[LEFT] = b;
320 infos_[i].beam_count_drul_[RIGHT] = b;
323 if (infos_.size () > 1)
324 for (vsize i = infos_.size () - 1; i--;)
325 if (infos_[i].invisible_)
327 int b = min (infos_[i].count (LEFT), infos_[i + 1].count (LEFT));
328 infos_[i].beam_count_drul_[LEFT] = b;
329 infos_[i].beam_count_drul_[RIGHT] = b;
334 Beaming_pattern::add_stem (Moment m, int b, bool invisible, Rational factor, bool tuplet_start)
336 infos_.push_back (Beam_rhythmic_element (m, b, invisible, factor, tuplet_start));
339 Beaming_pattern::Beaming_pattern ()
344 Beaming_pattern::beamlet_count (int i, Direction d) const
346 return infos_.at (i).beam_count_drul_[d];
350 Beaming_pattern::start_moment (int i) const
352 return infos_.at (i).start_moment_;
356 Beaming_pattern::end_moment (int i) const
358 Duration dur (2 + max (beamlet_count (i, LEFT),
359 beamlet_count (i, RIGHT)),
362 return infos_.at (i).start_moment_
363 + infos_.at (i).factor_ * dur.get_length ();
367 Beaming_pattern::invisibility (int i) const
369 return infos_.at (i).invisible_;
373 Beaming_pattern::factor (int i) const
375 return infos_.at (i).factor_;
379 Beaming_pattern::tuplet_start (int i) const
381 return infos_.at (i).tuplet_start_;
385 Split a beaming pattern at index i and return a new
386 Beaming_pattern containing the removed elements
389 Beaming_pattern::split_pattern (int i)
391 Beaming_pattern *new_pattern = 0;
394 new_pattern = new Beaming_pattern ();
395 for (vsize j = i + 1; j < infos_.size (); j++)
397 count = max (beamlet_count (j, LEFT), beamlet_count (j, RIGHT));
398 new_pattern->add_stem (start_moment (j),
404 for (vsize j = i + 1; j < infos_.size ();)
406 return (new_pattern);
410 Beaming_options::from_context (Context *context)
412 grouping_ = context->get_property ("beatStructure");
413 subdivide_beams_ = to_boolean (context->get_property ("subdivideBeams"));
414 strict_beat_beaming_ = to_boolean (context->get_property ("strictBeatBeaming"));
415 base_moment_ = robust_scm2moment (context->get_property ("baseMoment"),
417 measure_length_ = robust_scm2moment (context->get_property ("measureLength"),
421 Beaming_options::Beaming_options ()
424 subdivide_beams_ = false;
425 strict_beat_beaming_ = false;