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);
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);
194 Get the group start position, the next group starting position, and the
195 next beat starting position, given start_moment, base_moment,
199 find_location (SCM grouping, Moment base_moment, Moment start_moment,
200 Rational factor, Moment *group_pos, Moment *next_group_pos,
201 Moment *next_beat_pos)
203 *group_pos = Moment (0);
204 *next_group_pos = Moment (0);
205 *next_beat_pos = base_moment;
207 while (*next_beat_pos <= start_moment)
208 *next_beat_pos += base_moment;
210 while (*next_group_pos < *next_beat_pos)
212 int group_count = 1; //default -- 1 base moments in a beam
213 if (scm_is_pair (grouping))
215 group_count = scm_to_int (scm_car (grouping));
216 grouping = scm_cdr (grouping);
219 // If we have a tuplet, the count should be determined from
220 // the maximum tuplet size for beamed tuplets.
221 int tuplet_number = factor.den ();
222 if (tuplet_number > 1)
224 // We use 1/8 as the base moment for the tuplet because it's
225 // the largest beamed value. If the tuplet is shorter, it's
226 // OK, the code still works
227 int test_count = ( Moment (Rational (1, 8) / factor ) / base_moment).num ();
228 if (test_count > group_count) group_count = test_count;
230 *group_pos = *next_group_pos;
231 *next_group_pos = *group_pos + group_count * base_moment;
236 Beaming_pattern::find_rhythmic_importance (Beaming_options const &options)
238 Moment group_pos (0); // 0 is the start of the first group
239 Moment next_group_pos (0);
240 Moment next_beat_pos (options.base_moment_);
241 Moment tuplet_start_moment (-1, 1);
242 int tuplet_number = 1;
244 SCM grouping = options.grouping_;
247 // Find where we are in the beat structure of the measure
249 find_location (grouping, options.base_moment_, infos_[i].start_moment_,
250 infos_[i].factor_, &group_pos, &next_group_pos, &next_beat_pos);
252 // Mark the importance of stems that start at a beat or a beat group.
253 while (i < infos_.size ())
255 if ((next_beat_pos > next_group_pos)
256 || (infos_[i].start_moment_ > next_beat_pos))
257 // Find the new group ending point
258 find_location (grouping, options.base_moment_, infos_[i].start_moment_,
259 infos_[i].factor_, &group_pos, &next_group_pos, &next_beat_pos);
260 // Mark the start of this beat group
261 if (infos_[i].start_moment_ == group_pos)
262 infos_[i].rhythmic_importance_ = -2;
263 // Work through the end of the beat group or the end of the beam
264 while (i < infos_.size () && infos_[i].start_moment_ < next_group_pos)
266 // Set the tuplet start as necessary
267 update_tuplet (infos_[i].start_moment_, infos_[i].factor_, &tuplet_start_moment);
268 Moment dt = infos_[i].start_moment_ - group_pos;
269 Rational tuplet = infos_[i].factor_;
270 Moment tuplet_moment (tuplet);
271 Moment tuplet_dt = infos_[i].start_moment_ - tuplet_start_moment;
272 tuplet_number = tuplet.den ();
273 // set the beat end (if not in a tuplet) and increment the next beat
274 if (infos_[i].start_moment_ == next_beat_pos)
276 if (tuplet_number == 1)
278 infos_[i].rhythmic_importance_ = -1;
279 next_beat_pos += options.base_moment_;
281 if (infos_[i].tuplet_start_)
282 infos_[i].rhythmic_importance_ = -1;
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 = new Duration (2 + max (beamlet_count (i, LEFT),
361 beamlet_count (i, RIGHT)),
364 return infos_.at (i).start_moment_ + dur->get_length ();
368 Beaming_pattern::invisibility (int i) const
370 return infos_.at (i).invisible_;
374 Beaming_pattern::factor (int i) const
376 return infos_.at (i).factor_;
380 Beaming_pattern::tuplet_start (int i) const
382 return infos_.at (i).tuplet_start_;
386 Split a beaming pattern at index i and return a new
387 Beaming_pattern containing the removed elements
390 Beaming_pattern::split_pattern (int i)
392 Beaming_pattern *new_pattern = 0;
395 new_pattern = new Beaming_pattern ();
396 for (vsize j = i + 1; j < infos_.size (); j++)
398 count = max (beamlet_count (j, LEFT), beamlet_count (j, RIGHT));
399 new_pattern->add_stem (start_moment (j),
405 for (vsize j = i + 1; j < infos_.size ();)
407 return (new_pattern);
411 Beaming_options::from_context (Context *context)
413 grouping_ = context->get_property ("beatStructure");
414 subdivide_beams_ = to_boolean (context->get_property ("subdivideBeams"));
415 strict_beat_beaming_ = to_boolean (context->get_property ("strictBeatBeaming"));
416 base_moment_ = robust_scm2moment (context->get_property ("baseMoment"),
418 measure_length_ = robust_scm2moment (context->get_property ("measureLength"),
422 Beaming_options::Beaming_options ()
425 subdivide_beams_ = false;
426 strict_beat_beaming_ = false;