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"
27 Represents a stem belonging to a beam. Sometimes (for example, if the stem
28 belongs to a rest and stemlets aren't used) the stem will be invisible.
30 The rhythmic_importance_ of an element tells us the significance of the
31 moment at which this element occurs. For example, an element that occurs at
32 a beat is more significant than one that doesn't. Smaller number are
33 more important. The rhythmic_importance_ is decided and filled in by
34 Beaming_pattern. A rhythmic_importance_ smaller than zero has extra
35 significance: it represents the start of a beat and therefore beams may
36 need to be subdivided.
38 Beam_rhythmic_element::Beam_rhythmic_element ()
41 rhythmic_importance_ = 0;
42 beam_count_drul_[LEFT] = 0;
43 beam_count_drul_[RIGHT] = 0;
45 factor_ = Rational (1);
46 tuplet_start_ = false;
49 Beam_rhythmic_element::Beam_rhythmic_element (Moment m, int i, bool inv,
50 Rational factor, bool tuplet_start)
53 rhythmic_importance_ = 0;
54 beam_count_drul_[LEFT] = i;
55 beam_count_drul_[RIGHT] = i;
58 tuplet_start_ = tuplet_start;
62 Beam_rhythmic_element::de_grace ()
64 if (start_moment_.grace_part_)
66 start_moment_.main_part_ = start_moment_.grace_part_;
67 start_moment_.grace_part_ = 0;
72 Beam_rhythmic_element::count (Direction d) const
74 return beam_count_drul_[d];
78 Finds the appropriate direction for the flags at the given index that
79 hang below the neighbouring flags. If
80 the stem has no more flags than either of its neighbours, this returns
84 Beaming_pattern::flag_direction (Beaming_options const &options, vsize i) const
86 // The extremal stems shouldn't be messed with, so it's appropriate to
87 // return CENTER here also.
88 if (i == 0 || i == infos_.size () - 1)
91 int count = infos_[i].count (LEFT); // Both directions should still be the same
92 int left_count = infos_[i - 1].count (RIGHT);
93 int right_count = infos_[i + 1].count (LEFT);
95 // If we are told to subdivide beams and we are next to a beat, point the
96 // beamlet away from the beat.
97 if (options.subdivide_beams_)
99 if (infos_[i].rhythmic_importance_ < 0)
101 else if (infos_[i + 1].rhythmic_importance_ < 0)
105 if (count <= left_count && count <= right_count)
107 else if (!options.strict_beat_beaming_)
109 // Try to avoid sticking-out flags as much as possible by pointing
110 // my flags at the neighbor with the most flags.
111 if (right_count > left_count)
113 else if (left_count > right_count)
117 // If all else fails, point the beamlet away from the important moment.
118 return (infos_[i].rhythmic_importance_ < infos_[i + 1].rhythmic_importance_)
123 Beaming_pattern::de_grace ()
125 for (vsize i = 0; i < infos_.size (); i++)
127 infos_[i].de_grace ();
132 Beaming_pattern::beamify (Beaming_options const &options)
134 if (infos_.size () <= 1)
137 int subdivide_beam_count = intlog2(options.base_moment_.main_part_.den())-2;
139 unbeam_invisible_stems ();
141 if (infos_[0].start_moment_.grace_part_)
144 if (infos_[0].start_moment_ < Moment (0))
145 for (vsize i = 0; i < infos_.size (); i++)
146 infos_[i].start_moment_ += options.measure_length_;
148 find_rhythmic_importance (options);
150 vector <Direction> flag_directions;
151 // Get the initial flag directions
152 for (vsize i = 0; i < infos_.size (); i++)
153 flag_directions.push_back (flag_direction (options, i));
155 // Correct flag directions for subdivision
156 for (vsize i = 1; i < infos_.size () - 1; i++)
158 if ((flag_directions[i] == CENTER) && (flag_directions[i - 1] == LEFT))
159 flag_directions[i] = RIGHT;
160 if ((flag_directions[i] == CENTER) && (flag_directions[i + 1] == RIGHT))
161 flag_directions[i] = LEFT;
164 // Set the count on each side of the stem
165 // We need to run this code twice to make both the
166 // left and the right counts work properly
167 for (int i = 0; i < 2; i++)
168 for (vsize i = 1; i < infos_.size () - 1; i++)
170 Direction non_flag_dir = -flag_directions[i];
173 int importance = infos_[i + 1].rhythmic_importance_;
174 int count = (importance < 0 && options.subdivide_beams_)
175 ? subdivide_beam_count
176 : min (min (infos_[i].count (non_flag_dir),
177 infos_[i + non_flag_dir].count (-non_flag_dir)),
178 infos_[i - non_flag_dir].count (non_flag_dir));
180 infos_[i].beam_count_drul_[non_flag_dir] = count;
186 Set the tuplet start moment as necessary
189 update_tuplet (Moment start_moment, Rational factor, Moment *tuplet_start_moment)
191 int tuplet_number = (int) factor.den ();
192 if ((tuplet_number > 1) && (tuplet_start_moment->num () < 0))
193 *tuplet_start_moment = start_moment;
194 else if (tuplet_number == 1)
195 *tuplet_start_moment = Moment (-1, 1);
199 Get the group start position, the next group starting position, and the
200 next beat starting position, given start_moment, base_moment,
204 find_location (SCM grouping, Moment base_moment, Moment start_moment,
205 Rational factor, Moment *group_pos, Moment *next_group_pos,
206 Moment *next_beat_pos)
208 *group_pos = Moment (0);
209 *next_group_pos = Moment (0);
210 *next_beat_pos = base_moment;
212 while (*next_beat_pos <= start_moment)
213 *next_beat_pos += base_moment;
215 while (*next_group_pos < *next_beat_pos)
217 I64 group_count = 1; //default -- 1 base moments in a beam
218 if (scm_is_pair (grouping))
220 group_count = scm_to_int (scm_car (grouping));
221 grouping = scm_cdr (grouping);
224 // If we have a tuplet, the count should be determined from
225 // the maximum tuplet size for beamed tuplets.
226 U64 tuplet_number = factor.den ();
227 if (tuplet_number > 1U)
229 // We use 1/8 as the base moment for the tuplet because it's
230 // the largest beamed value. If the tuplet is shorter, it's
231 // OK, the code still works
232 I64 test_count = ( Moment (Rational (1, 8) / factor) / base_moment).num ();
233 if (test_count > group_count) group_count = test_count;
235 *group_pos = *next_group_pos;
236 *next_group_pos = *group_pos + Rational(group_count) * base_moment;
241 Beaming_pattern::find_rhythmic_importance (Beaming_options const &options)
243 Moment group_pos (0); // 0 is the start of the first group
244 Moment next_group_pos (0);
245 Moment next_beat_pos (options.base_moment_);
246 Moment tuplet_start_moment (-1, 1);
247 I64 tuplet_number = 1;
249 SCM grouping = options.grouping_;
252 // Find where we are in the beat structure of the measure
254 find_location (grouping, options.base_moment_, infos_[i].start_moment_,
255 infos_[i].factor_, &group_pos, &next_group_pos, &next_beat_pos);
257 // Mark the importance of stems that start at a beat or a beat group.
258 while (i < infos_.size ())
260 if ((next_beat_pos > next_group_pos)
261 || (infos_[i].start_moment_ > next_beat_pos))
262 // Find the new group ending point
263 find_location (grouping, options.base_moment_, infos_[i].start_moment_,
264 infos_[i].factor_, &group_pos, &next_group_pos, &next_beat_pos);
265 // Mark the start of this beat group
266 if (infos_[i].start_moment_ == group_pos)
267 infos_[i].rhythmic_importance_ = -2;
268 // Work through the end of the beat group or the end of the beam
269 while (i < infos_.size () && infos_[i].start_moment_ < next_group_pos)
271 // Set the tuplet start as necessary
272 update_tuplet (infos_[i].start_moment_, infos_[i].factor_, &tuplet_start_moment);
273 Moment dt = infos_[i].start_moment_ - group_pos;
274 Rational tuplet = infos_[i].factor_;
275 Moment tuplet_moment (tuplet);
276 Moment tuplet_dt = infos_[i].start_moment_ - tuplet_start_moment;
277 tuplet_number = tuplet.den ();
278 // set the beat end and increment the next beat
279 if (infos_[i].start_moment_ == next_beat_pos)
281 infos_[i].rhythmic_importance_ = -1;
282 next_beat_pos += options.base_moment_;
284 // The rhythmic importance of a stem between beats depends on its fraction
285 // of a beat: those stems with a lower denominator are deemed more
286 // important. For tuplets, we need to make sure that we use
287 // the fraction of the tuplet, instead of the fraction of
289 Moment ratio = (tuplet_number == 1)
290 ? dt / options.base_moment_
291 : tuplet_dt / Moment (1, 8) / tuplet_moment;
292 if (infos_[i].rhythmic_importance_ >= 0)
293 infos_[i].rhythmic_importance_ = (int) ratio.den ();
298 if (i < infos_.size () && infos_[i].start_moment_ == next_beat_pos)
300 if (tuplet_number == 1)
301 infos_[i].rhythmic_importance_ = -1;
302 next_beat_pos += options.base_moment_;
303 if (infos_[i].start_moment_ == next_group_pos)
304 infos_[i].rhythmic_importance_ = -2;
310 Invisible stems should be treated as though they have the same number of
311 beams as their least-beamed neighbour. Here we go through the stems and
312 modify the invisible stems to satisfy this requirement.
315 Beaming_pattern::unbeam_invisible_stems ()
317 for (vsize i = 1; i < infos_.size (); i++)
318 if (infos_[i].invisible_)
320 int b = min (infos_[i].count (LEFT), infos_[i - 1].count (LEFT));
321 infos_[i].beam_count_drul_[LEFT] = b;
322 infos_[i].beam_count_drul_[RIGHT] = b;
325 if (infos_.size () > 1)
326 for (vsize i = infos_.size () - 1; i--;)
327 if (infos_[i].invisible_)
329 int b = min (infos_[i].count (LEFT), infos_[i + 1].count (LEFT));
330 infos_[i].beam_count_drul_[LEFT] = b;
331 infos_[i].beam_count_drul_[RIGHT] = b;
336 Beaming_pattern::add_stem (Moment m, int b, bool invisible, Rational factor, bool tuplet_start)
338 infos_.push_back (Beam_rhythmic_element (m, b, invisible, factor, tuplet_start));
341 Beaming_pattern::Beaming_pattern ()
346 Beaming_pattern::beamlet_count (int i, Direction d) const
348 return infos_.at (i).beam_count_drul_[d];
352 Beaming_pattern::start_moment (int i) const
354 return infos_.at (i).start_moment_;
358 Beaming_pattern::end_moment (int i) const
360 Duration dur (2 + max (beamlet_count (i, LEFT),
361 beamlet_count (i, RIGHT)),
364 return infos_.at (i).start_moment_
365 + infos_.at (i).factor_ * dur.get_length ();
369 Beaming_pattern::invisibility (int i) const
371 return infos_.at (i).invisible_;
375 Beaming_pattern::factor (int i) const
377 return infos_.at (i).factor_;
381 Beaming_pattern::tuplet_start (int i) const
383 return infos_.at (i).tuplet_start_;
387 Split a beaming pattern at index i and return a new
388 Beaming_pattern containing the removed elements
391 Beaming_pattern::split_pattern (int i)
393 Beaming_pattern *new_pattern = 0;
396 new_pattern = new Beaming_pattern ();
397 for (vsize j = i + 1; j < infos_.size (); j++)
399 count = max (beamlet_count (j, LEFT), beamlet_count (j, RIGHT));
400 new_pattern->add_stem (start_moment (j),
406 for (vsize j = i + 1; j < infos_.size ();)
408 return (new_pattern);
412 Beaming_options::from_context (Context *context)
414 grouping_ = context->get_property ("beatStructure");
415 subdivide_beams_ = to_boolean (context->get_property ("subdivideBeams"));
416 strict_beat_beaming_ = to_boolean (context->get_property ("strictBeatBeaming"));
417 base_moment_ = robust_scm2moment (context->get_property ("baseMoment"),
419 measure_length_ = robust_scm2moment (context->get_property ("measureLength"),
423 Beaming_options::Beaming_options ()
426 subdivide_beams_ = false;
427 strict_beat_beaming_ = false;