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"
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);
43 tuplet_start_ = false;
46 Beam_rhythmic_element::Beam_rhythmic_element (Moment m, int i, bool inv,
47 Rational factor, bool tuplet_start)
50 rhythmic_importance_ = 0;
51 beam_count_drul_[LEFT] = i;
52 beam_count_drul_[RIGHT] = i;
55 tuplet_start_ = tuplet_start;
59 Beam_rhythmic_element::de_grace ()
61 if (start_moment_.grace_part_)
63 start_moment_.main_part_ = start_moment_.grace_part_;
64 start_moment_.grace_part_ = 0;
69 Beam_rhythmic_element::count (Direction d) const
71 return beam_count_drul_[d];
75 Finds the appropriate direction for the flags at the given index that
76 hang below the neighbouring flags. If
77 the stem has no more flags than either of its neighbours, this returns
81 Beaming_pattern::flag_direction (Beaming_options const &options, vsize i) const
83 // The extremal stems shouldn't be messed with, so it's appropriate to
84 // return CENTER here also.
85 if (i == 0 || i == infos_.size () - 1)
88 int count = infos_[i].count (LEFT); // Both directions should still be the same
89 int left_count = infos_[i - 1].count (RIGHT);
90 int right_count = infos_[i + 1].count (LEFT);
92 // If we are told to subdivide beams and we are next to a beat, point the
93 // beamlet away from the beat.
94 if (options.subdivide_beams_)
96 if (infos_[i].rhythmic_importance_ < 0)
98 else if (infos_[i + 1].rhythmic_importance_ < 0)
102 if (count <= left_count && count <= right_count)
104 else if (!options.strict_beat_beaming_)
106 // Try to avoid sticking-out flags as much as possible by pointing
107 // my flags at the neighbor with the most flags.
108 if (right_count > left_count)
110 else if (left_count > right_count)
114 // If all else fails, point the beamlet away from the important moment.
115 return (infos_[i].rhythmic_importance_ < infos_[i + 1].rhythmic_importance_)
120 Beaming_pattern::de_grace ()
122 for (vsize i = 0; i < infos_.size (); i++)
124 infos_[i].de_grace ();
129 Beaming_pattern::beamify (Beaming_options const &options)
131 if (infos_.size () <= 1)
134 unbeam_invisible_stems ();
136 if (infos_[0].start_moment_.grace_part_)
139 if (infos_[0].start_moment_ < Moment (0))
140 for (vsize i = 0; i < infos_.size (); i++)
141 infos_[i].start_moment_ += options.measure_length_;
143 find_rhythmic_importance (options);
145 vector <Direction> flag_directions;
146 // Get the initial flag directions
147 for (vsize i = 0; i < infos_.size (); i++)
148 flag_directions.push_back (flag_direction (options, i));
150 // Correct flag directions for subdivision
151 for (vsize i = 1; i < infos_.size () - 1; i++)
153 if ((flag_directions[i] == CENTER) && (flag_directions[i - 1] == LEFT))
154 flag_directions[i] = RIGHT;
155 if ((flag_directions[i] == CENTER) && (flag_directions[i + 1] == RIGHT))
156 flag_directions[i] = LEFT;
159 // Set the count on each side of the stem
160 // We need to run this code twice to make both the
161 // left and the right counts work properly
162 for (int i = 0; i < 2; i++)
163 for (vsize i = 1; i < infos_.size () - 1; i++)
165 Direction non_flag_dir = other_dir (flag_directions[i]);
168 int importance = infos_[i + 1].rhythmic_importance_;
169 int count = (importance < 0 && options.subdivide_beams_)
170 ? 1 : min (min (infos_[i].count (non_flag_dir),
171 infos_[i + non_flag_dir].count (-non_flag_dir)),
172 infos_[i - non_flag_dir].count (non_flag_dir));
174 infos_[i].beam_count_drul_[non_flag_dir] = count;
180 Set the tuplet start moment as necessary
183 update_tuplet (Moment start_moment, Rational factor, Moment *tuplet_start_moment)
185 int tuplet_number = (int) factor.den ();
186 if ((tuplet_number > 1) && (tuplet_start_moment->num () < 0))
187 *tuplet_start_moment = start_moment;
188 else if (tuplet_number == 1)
189 *tuplet_start_moment = Moment (-1, 1);
193 Get the group start position, the next group starting position, and the
194 next beat starting position, given start_moment, base_moment,
198 find_location (SCM grouping, Moment base_moment, Moment start_moment,
199 Rational factor, Moment *group_pos, Moment *next_group_pos,
200 Moment *next_beat_pos)
202 *group_pos = Moment (0);
203 *next_group_pos = Moment (0);
204 *next_beat_pos = base_moment;
206 while (*next_beat_pos <= start_moment)
207 *next_beat_pos += base_moment;
209 while (*next_group_pos < *next_beat_pos)
211 I64 group_count = 1; //default -- 1 base moments in a beam
212 if (scm_is_pair (grouping))
214 group_count = scm_to_int (scm_car (grouping));
215 grouping = scm_cdr (grouping);
218 // If we have a tuplet, the count should be determined from
219 // the maximum tuplet size for beamed tuplets.
220 U64 tuplet_number = factor.den ();
221 if (tuplet_number > 1U)
223 // We use 1/8 as the base moment for the tuplet because it's
224 // the largest beamed value. If the tuplet is shorter, it's
225 // OK, the code still works
226 I64 test_count = ( Moment (Rational (1, 8) / factor) / base_moment).num ();
227 if (test_count > group_count) group_count = test_count;
229 *group_pos = *next_group_pos;
230 *next_group_pos = *group_pos + Rational(group_count) * base_moment;
235 Beaming_pattern::find_rhythmic_importance (Beaming_options const &options)
237 Moment group_pos (0); // 0 is the start of the first group
238 Moment next_group_pos (0);
239 Moment next_beat_pos (options.base_moment_);
240 Moment tuplet_start_moment (-1, 1);
241 I64 tuplet_number = 1;
243 SCM grouping = options.grouping_;
246 // Find where we are in the beat structure of the measure
248 find_location (grouping, options.base_moment_, infos_[i].start_moment_,
249 infos_[i].factor_, &group_pos, &next_group_pos, &next_beat_pos);
251 // Mark the importance of stems that start at a beat or a beat group.
252 while (i < infos_.size ())
254 if ((next_beat_pos > next_group_pos)
255 || (infos_[i].start_moment_ > next_beat_pos))
256 // Find the new group ending point
257 find_location (grouping, options.base_moment_, infos_[i].start_moment_,
258 infos_[i].factor_, &group_pos, &next_group_pos, &next_beat_pos);
259 // Mark the start of this beat group
260 if (infos_[i].start_moment_ == group_pos)
261 infos_[i].rhythmic_importance_ = -2;
262 // Work through the end of the beat group or the end of the beam
263 while (i < infos_.size () && infos_[i].start_moment_ < next_group_pos)
265 // Set the tuplet start as necessary
266 update_tuplet (infos_[i].start_moment_, infos_[i].factor_, &tuplet_start_moment);
267 Moment dt = infos_[i].start_moment_ - group_pos;
268 Rational tuplet = infos_[i].factor_;
269 Moment tuplet_moment (tuplet);
270 Moment tuplet_dt = infos_[i].start_moment_ - tuplet_start_moment;
271 tuplet_number = tuplet.den ();
272 // set the beat end and increment the next beat
273 if (infos_[i].start_moment_ == next_beat_pos)
275 infos_[i].rhythmic_importance_ = -1;
276 next_beat_pos += options.base_moment_;
278 // The rhythmic importance of a stem between beats depends on its fraction
279 // of a beat: those stems with a lower denominator are deemed more
280 // important. For tuplets, we need to make sure that we use
281 // the fraction of the tuplet, instead of the fraction of
283 Moment ratio = (tuplet_number == 1)
284 ? dt / options.base_moment_
285 : tuplet_dt / Moment (1, 8) / tuplet_moment;
286 if (infos_[i].rhythmic_importance_ >= 0)
287 infos_[i].rhythmic_importance_ = (int) ratio.den ();
292 if (i < infos_.size () && infos_[i].start_moment_ == next_beat_pos)
294 if (tuplet_number == 1)
295 infos_[i].rhythmic_importance_ = -1;
296 next_beat_pos += options.base_moment_;
297 if (infos_[i].start_moment_ == next_group_pos)
298 infos_[i].rhythmic_importance_ = -2;
304 Invisible stems should be treated as though they have the same number of
305 beams as their least-beamed neighbour. Here we go through the stems and
306 modify the invisible stems to satisfy this requirement.
309 Beaming_pattern::unbeam_invisible_stems ()
311 for (vsize i = 1; i < infos_.size (); i++)
312 if (infos_[i].invisible_)
314 int b = min (infos_[i].count (LEFT), infos_[i - 1].count (LEFT));
315 infos_[i].beam_count_drul_[LEFT] = b;
316 infos_[i].beam_count_drul_[RIGHT] = b;
319 if (infos_.size () > 1)
320 for (vsize i = infos_.size () - 1; i--;)
321 if (infos_[i].invisible_)
323 int b = min (infos_[i].count (LEFT), infos_[i + 1].count (LEFT));
324 infos_[i].beam_count_drul_[LEFT] = b;
325 infos_[i].beam_count_drul_[RIGHT] = b;
330 Beaming_pattern::add_stem (Moment m, int b, bool invisible, Rational factor, bool tuplet_start)
332 infos_.push_back (Beam_rhythmic_element (m, b, invisible, factor, tuplet_start));
335 Beaming_pattern::Beaming_pattern ()
340 Beaming_pattern::beamlet_count (int i, Direction d) const
342 return infos_.at (i).beam_count_drul_[d];
346 Beaming_pattern::start_moment (int i) const
348 return infos_.at (i).start_moment_;
352 Beaming_pattern::end_moment (int i) const
354 Duration dur (2 + max (beamlet_count (i, LEFT),
355 beamlet_count (i, RIGHT)),
358 return infos_.at (i).start_moment_
359 + infos_.at (i).factor_ * dur.get_length ();
363 Beaming_pattern::invisibility (int i) const
365 return infos_.at (i).invisible_;
369 Beaming_pattern::factor (int i) const
371 return infos_.at (i).factor_;
375 Beaming_pattern::tuplet_start (int i) const
377 return infos_.at (i).tuplet_start_;
381 Split a beaming pattern at index i and return a new
382 Beaming_pattern containing the removed elements
385 Beaming_pattern::split_pattern (int i)
387 Beaming_pattern *new_pattern = 0;
390 new_pattern = new Beaming_pattern ();
391 for (vsize j = i + 1; j < infos_.size (); j++)
393 count = max (beamlet_count (j, LEFT), beamlet_count (j, RIGHT));
394 new_pattern->add_stem (start_moment (j),
400 for (vsize j = i + 1; j < infos_.size ();)
402 return (new_pattern);
406 Beaming_options::from_context (Context *context)
408 grouping_ = context->get_property ("beatStructure");
409 subdivide_beams_ = to_boolean (context->get_property ("subdivideBeams"));
410 strict_beat_beaming_ = to_boolean (context->get_property ("strictBeatBeaming"));
411 base_moment_ = robust_scm2moment (context->get_property ("baseMoment"),
413 measure_length_ = robust_scm2moment (context->get_property ("measureLength"),
417 Beaming_options::Beaming_options ()
420 subdivide_beams_ = false;
421 strict_beat_beaming_ = false;