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 unbeam_invisible_stems ();
137 if (infos_[0].start_moment_.grace_part_)
140 if (infos_[0].start_moment_ < Moment (0))
141 for (vsize i = 0; i < infos_.size (); i++)
142 infos_[i].start_moment_ += options.measure_length_;
144 find_rhythmic_importance (options);
146 vector <Direction> flag_directions;
147 // Get the initial flag directions
148 for (vsize i = 0; i < infos_.size (); i++)
149 flag_directions.push_back (flag_direction (options, i));
151 // Correct flag directions for subdivision
152 for (vsize i = 1; i < infos_.size () - 1; i++)
154 if ((flag_directions[i] == CENTER) && (flag_directions[i - 1] == LEFT))
155 flag_directions[i] = RIGHT;
156 if ((flag_directions[i] == CENTER) && (flag_directions[i + 1] == RIGHT))
157 flag_directions[i] = LEFT;
160 // Set the count on each side of the stem
161 // We need to run this code twice to make both the
162 // left and the right counts work properly
163 for (int i = 0; i < 2; i++)
164 for (vsize i = 1; i < infos_.size () - 1; i++)
166 Direction non_flag_dir = other_dir (flag_directions[i]);
169 int importance = infos_[i + 1].rhythmic_importance_;
170 int start_dur = intlog2(infos_[i+1].start_moment_.main_part_.den());
171 int count = (importance < 0 && options.subdivide_beams_)
172 ? max(start_dur,3)-2 // 1/8 note has one beam
173 : min (min (infos_[i].count (non_flag_dir),
174 infos_[i + non_flag_dir].count (-non_flag_dir)),
175 infos_[i - non_flag_dir].count (non_flag_dir));
177 infos_[i].beam_count_drul_[non_flag_dir] = count;
183 Set the tuplet start moment as necessary
186 update_tuplet (Moment start_moment, Rational factor, Moment *tuplet_start_moment)
188 int tuplet_number = (int) factor.den ();
189 if ((tuplet_number > 1) && (tuplet_start_moment->num () < 0))
190 *tuplet_start_moment = start_moment;
191 else if (tuplet_number == 1)
192 *tuplet_start_moment = Moment (-1, 1);
196 Get the group start position, the next group starting position, and the
197 next beat starting position, given start_moment, base_moment,
201 find_location (SCM grouping, Moment base_moment, Moment start_moment,
202 Rational factor, Moment *group_pos, Moment *next_group_pos,
203 Moment *next_beat_pos)
205 *group_pos = Moment (0);
206 *next_group_pos = Moment (0);
207 *next_beat_pos = base_moment;
209 while (*next_beat_pos <= start_moment)
210 *next_beat_pos += base_moment;
212 while (*next_group_pos < *next_beat_pos)
214 I64 group_count = 1; //default -- 1 base moments in a beam
215 if (scm_is_pair (grouping))
217 group_count = scm_to_int (scm_car (grouping));
218 grouping = scm_cdr (grouping);
221 // If we have a tuplet, the count should be determined from
222 // the maximum tuplet size for beamed tuplets.
223 U64 tuplet_number = factor.den ();
224 if (tuplet_number > 1U)
226 // We use 1/8 as the base moment for the tuplet because it's
227 // the largest beamed value. If the tuplet is shorter, it's
228 // OK, the code still works
229 I64 test_count = ( Moment (Rational (1, 8) / factor) / base_moment).num ();
230 if (test_count > group_count) group_count = test_count;
232 *group_pos = *next_group_pos;
233 *next_group_pos = *group_pos + Rational(group_count) * base_moment;
238 Beaming_pattern::find_rhythmic_importance (Beaming_options const &options)
240 Moment group_pos (0); // 0 is the start of the first group
241 Moment next_group_pos (0);
242 Moment next_beat_pos (options.base_moment_);
243 Moment tuplet_start_moment (-1, 1);
244 I64 tuplet_number = 1;
246 SCM grouping = options.grouping_;
249 // Find where we are in the beat structure of the measure
251 find_location (grouping, options.base_moment_, infos_[i].start_moment_,
252 infos_[i].factor_, &group_pos, &next_group_pos, &next_beat_pos);
254 // Mark the importance of stems that start at a beat or a beat group.
255 while (i < infos_.size ())
257 if ((next_beat_pos > next_group_pos)
258 || (infos_[i].start_moment_ > next_beat_pos))
259 // Find the new group ending point
260 find_location (grouping, options.base_moment_, infos_[i].start_moment_,
261 infos_[i].factor_, &group_pos, &next_group_pos, &next_beat_pos);
262 // Mark the start of this beat group
263 if (infos_[i].start_moment_ == group_pos)
264 infos_[i].rhythmic_importance_ = -2;
265 // Work through the end of the beat group or the end of the beam
266 while (i < infos_.size () && infos_[i].start_moment_ < next_group_pos)
268 // Set the tuplet start as necessary
269 update_tuplet (infos_[i].start_moment_, infos_[i].factor_, &tuplet_start_moment);
270 Moment dt = infos_[i].start_moment_ - group_pos;
271 Rational tuplet = infos_[i].factor_;
272 Moment tuplet_moment (tuplet);
273 Moment tuplet_dt = infos_[i].start_moment_ - tuplet_start_moment;
274 tuplet_number = tuplet.den ();
275 // set the beat end and increment the next beat
276 if (infos_[i].start_moment_ == next_beat_pos)
278 infos_[i].rhythmic_importance_ = -1;
279 next_beat_pos += options.base_moment_;
281 // The rhythmic importance of a stem between beats depends on its fraction
282 // of a beat: those stems with a lower denominator are deemed more
283 // important. For tuplets, we need to make sure that we use
284 // the fraction of the tuplet, instead of the fraction of
286 Moment ratio = (tuplet_number == 1)
287 ? dt / options.base_moment_
288 : tuplet_dt / Moment (1, 8) / tuplet_moment;
289 if (infos_[i].rhythmic_importance_ >= 0)
290 infos_[i].rhythmic_importance_ = (int) ratio.den ();
295 if (i < infos_.size () && infos_[i].start_moment_ == next_beat_pos)
297 if (tuplet_number == 1)
298 infos_[i].rhythmic_importance_ = -1;
299 next_beat_pos += options.base_moment_;
300 if (infos_[i].start_moment_ == next_group_pos)
301 infos_[i].rhythmic_importance_ = -2;
307 Invisible stems should be treated as though they have the same number of
308 beams as their least-beamed neighbour. Here we go through the stems and
309 modify the invisible stems to satisfy this requirement.
312 Beaming_pattern::unbeam_invisible_stems ()
314 for (vsize i = 1; i < infos_.size (); i++)
315 if (infos_[i].invisible_)
317 int b = min (infos_[i].count (LEFT), infos_[i - 1].count (LEFT));
318 infos_[i].beam_count_drul_[LEFT] = b;
319 infos_[i].beam_count_drul_[RIGHT] = b;
322 if (infos_.size () > 1)
323 for (vsize i = infos_.size () - 1; i--;)
324 if (infos_[i].invisible_)
326 int b = min (infos_[i].count (LEFT), infos_[i + 1].count (LEFT));
327 infos_[i].beam_count_drul_[LEFT] = b;
328 infos_[i].beam_count_drul_[RIGHT] = b;
333 Beaming_pattern::add_stem (Moment m, int b, bool invisible, Rational factor, bool tuplet_start)
335 infos_.push_back (Beam_rhythmic_element (m, b, invisible, factor, tuplet_start));
338 Beaming_pattern::Beaming_pattern ()
343 Beaming_pattern::beamlet_count (int i, Direction d) const
345 return infos_.at (i).beam_count_drul_[d];
349 Beaming_pattern::start_moment (int i) const
351 return infos_.at (i).start_moment_;
355 Beaming_pattern::end_moment (int i) const
357 Duration dur (2 + max (beamlet_count (i, LEFT),
358 beamlet_count (i, RIGHT)),
361 return infos_.at (i).start_moment_
362 + infos_.at (i).factor_ * dur.get_length ();
366 Beaming_pattern::invisibility (int i) const
368 return infos_.at (i).invisible_;
372 Beaming_pattern::factor (int i) const
374 return infos_.at (i).factor_;
378 Beaming_pattern::tuplet_start (int i) const
380 return infos_.at (i).tuplet_start_;
384 Split a beaming pattern at index i and return a new
385 Beaming_pattern containing the removed elements
388 Beaming_pattern::split_pattern (int i)
390 Beaming_pattern *new_pattern = 0;
393 new_pattern = new Beaming_pattern ();
394 for (vsize j = i + 1; j < infos_.size (); j++)
396 count = max (beamlet_count (j, LEFT), beamlet_count (j, RIGHT));
397 new_pattern->add_stem (start_moment (j),
403 for (vsize j = i + 1; j < infos_.size ();)
405 return (new_pattern);
409 Beaming_options::from_context (Context *context)
411 grouping_ = context->get_property ("beatStructure");
412 subdivide_beams_ = to_boolean (context->get_property ("subdivideBeams"));
413 strict_beat_beaming_ = to_boolean (context->get_property ("strictBeatBeaming"));
414 base_moment_ = robust_scm2moment (context->get_property ("baseMoment"),
416 measure_length_ = robust_scm2moment (context->get_property ("measureLength"),
420 Beaming_options::Beaming_options ()
423 subdivide_beams_ = false;
424 strict_beat_beaming_ = false;