/*
- beaming-info.cc -- implement Beam_rhythmic_element, Beaming_pattern
+ This file is part of LilyPond, the GNU music typesetter.
- A Beaming_pattern object takes a set of stems at given moments and calculates
- the pattern of their beam. That is, it works out, for each stem, how many
- beams should be connected to the right and left sides of that stem. In
- calculating this, Beaming_pattern takes into account
- - the rhythmic position of the stems
- - the options that are defined in Beaming_options
+ Copyright (C) 1999--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
- source file of the GNU LilyPond music typesetter
+ LilyPond is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- (c) 1999--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ LilyPond is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "beaming-pattern.hh"
#include "context.hh"
+#include "beaming-pattern.hh"
/*
Represents a stem belonging to a beam. Sometimes (for example, if the stem
{
if (start_moment_.grace_part_)
{
- start_moment_.main_part_ = start_moment_.grace_part_;
+ start_moment_.main_part_ = start_moment_.grace_part_;
start_moment_.grace_part_ = 0;
}
}
CENTER.
*/
Direction
-Beaming_pattern::flag_direction (vsize i) const
+Beaming_pattern::flag_direction (Beaming_options const &options, vsize i) const
{
// The extremal stems shouldn't be messed with, so it's appropriate to
// return CENTER here also.
int left_count = infos_[i-1].count (RIGHT);
int right_count = infos_[i+1].count (LEFT);
+ // If we are told to subdivide beams and we are next to a beat, point the
+ // beamlet away from the beat.
+ if (options.subdivide_beams_)
+ {
+ if (infos_[i].rhythmic_importance_ < 0)
+ return RIGHT;
+ else if (infos_[i+1].rhythmic_importance_ < 0)
+ return LEFT;
+ }
+
if (count <= left_count && count <= right_count)
return CENTER;
for (vsize i = 1; i < infos_.size () - 1; i++)
{
- Direction non_flag_dir = other_dir (flag_direction (i));
+ Direction non_flag_dir = other_dir (flag_direction (options, i));
if (non_flag_dir)
{
int importance = (non_flag_dir == LEFT)
? infos_[i].rhythmic_importance_ : infos_[i+1].rhythmic_importance_;
- int count = (importance < 0)
+ int count = (importance < 0 && options.subdivide_beams_)
? 1 : min (infos_[i].count (non_flag_dir),
infos_[i+non_flag_dir].count (-non_flag_dir));
void
Beaming_pattern::find_rhythmic_importance (Beaming_options const &options)
{
- Moment measure_pos (0);
+ Moment measure_pos (0);
SCM grouping = options.grouping_;
vsize i = 0;
if (infos_[i].start_moment_ == measure_pos)
infos_[i].rhythmic_importance_ = -2;
- // Mark the start of each beat up to the end of this beat group.
- for (int beat = 1; beat <= count; beat++)
+ // Mark the start of each unit up to the end of this beat group.
+ for (int unit = 1; unit <= count; unit++)
{
- Moment next_measure_pos = measure_pos + options.beat_length_;
+ Moment next_measure_pos = measure_pos + options.base_moment_;
while (i < infos_.size () && infos_[i].start_moment_ < next_measure_pos)
{
// in an 8th-note triplet with a quarter-note beat, 1/3 of a beat should be
// more important than 1/2.
if (infos_[i].rhythmic_importance_ >= 0)
- infos_[i].rhythmic_importance_ = (dt / options.beat_length_).den ();
+ infos_[i].rhythmic_importance_ = (int) (dt / options.base_moment_).den ();
i++;
}
return infos_.at (i).beam_count_drul_[d];
}
+Moment
+Beaming_pattern::start_moment (int i) const
+{
+ return infos_.at (i).start_moment_;
+}
+
+Moment
+Beaming_pattern::end_moment (int i) const
+{
+ Duration *dur = new Duration (2 + max (beamlet_count (i, LEFT),
+ beamlet_count (i, RIGHT)),
+ 0);
+
+ return infos_.at (i).start_moment_ + dur->get_length();
+}
+
+bool
+Beaming_pattern::invisibility (int i) const
+{
+ return infos_.at (i).invisible_;
+}
+
+/*
+ Split a beamin pattern at index i and return a new
+ Beaming_pattern containing the removed elements
+*/
+Beaming_pattern *
+Beaming_pattern::split_pattern (int i)
+{
+ Beaming_pattern* new_pattern=0;
+ int count;
+
+ new_pattern = new Beaming_pattern ();
+ for (vsize j=i+1; j<infos_.size (); j++)
+ {
+ count = max(beamlet_count (j, LEFT), beamlet_count(j, RIGHT));
+ new_pattern->add_stem (start_moment (j),
+ count,
+ invisibility (j));
+ }
+ for (vsize j=i+1; j<infos_.size (); )
+ infos_.pop_back ();
+ return (new_pattern);
+}
+
void
Beaming_options::from_context (Context *context)
{
- grouping_ = context->get_property ("beatGrouping");
+ grouping_ = context->get_property ("beatStructure");
subdivide_beams_ = to_boolean (context->get_property ("subdivideBeams"));
- beat_length_ = robust_scm2moment (context->get_property ("beatLength"), Moment (1, 4));
- measure_length_ = robust_scm2moment (context->get_property ("measureLength"), Moment (1, 4));
+ base_moment_ = robust_scm2moment (context->get_property ("baseMoment"),
+ Moment (1, 4));
+ measure_length_ = robust_scm2moment (context->get_property ("measureLength"),
+ Moment (4, 4));
}
Beaming_options::Beaming_options ()