summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Sorensen <c_sorensen@byu.edu>2009-08-29 10:28:04 -0600
committerCarl Sorensen <c_sorensen@byu.edu>2009-12-24 11:20:01 -0700
commit6dd8c00b4f33a5eb95a2aed2484e96347558fe05 (patch)
treec63b5e45117829628277b70ea83dedc2c06c82b0
parent6ec6f663f74bfc2c8bd93642962db820ff982cae (diff)
Fix 638: Fix autobeaming in 4 4 time.
Add rechecking for auto-beams when shortest duration changes. Add argument for test_moment to calls checking for beam start and end points. Create split procedures for stems_ and Beaming_pattern
-rw-r--r--input/regression/auto-beam-recheck.ly15
-rw-r--r--lily/auto-beam-engraver.cc142
-rw-r--r--lily/beam.cc102
-rw-r--r--lily/beaming-pattern.cc45
-rw-r--r--lily/include/beaming-pattern.hh12
-rw-r--r--scm/auto-beam.scm3
6 files changed, 234 insertions, 85 deletions
diff --git a/input/regression/auto-beam-recheck.ly b/input/regression/auto-beam-recheck.ly
new file mode 100644
index 0000000000..54f3614cbd
--- /dev/null
+++ b/input/regression/auto-beam-recheck.ly
@@ -0,0 +1,15 @@
+\version "2.13.10"
+\header {
+
+ texidoc = "In 4/4 time, the first and second and third and fourth
+beats should be beamed together if only eighth notes are involved.
+If any shorter notes are included, each beat should be beamed separately."
+
+}
+\layout { ragged-right = ##t }
+
+\relative c'' {
+ \repeat unfold 8 { a8} |
+ a8 a a a16 a a8 a a16 a a8 |
+ r16 a8. a8 a16 a r8. a16 a8 a16 a |
+}
diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc
index c4635ed62b..a3d38af5b3 100644
--- a/lily/auto-beam-engraver.cc
+++ b/lily/auto-beam-engraver.cc
@@ -51,19 +51,21 @@ protected:
void process_acknowledged ();
private:
- bool test_moment (Direction, Moment);
- void consider_begin (Moment);
- void consider_end (Moment);
+ bool test_moment (Direction, Moment, Moment);
+ void consider_begin (Moment, Moment);
+ void consider_end (Moment, Moment);
Spanner *create_beam ();
void begin_beam ();
void end_beam ();
void junk_beam ();
bool is_same_grace_state (Grob *e);
+ void recheck_beam ();
void typeset_beam ();
+ vector<Item*> *remove_end_stems (vsize);
Stream_event *forbid_;
/*
- shortest_mom is the shortest note in the beam.
+ shortest_mom_ is the shortest note in the beam.
*/
Moment shortest_mom_;
Spanner *finished_beam_;
@@ -87,8 +89,8 @@ private:
Beaming_options beaming_options_;
Beaming_options finished_beaming_options_;
-
-
+
+
void check_bar_property ();
};
@@ -108,7 +110,7 @@ Auto_beam_engraver::check_bar_property ()
if (scm_is_string (get_property ("whichBar"))
&& beam_start_moment_ < now)
{
- consider_end (shortest_mom_);
+ consider_end (measure_position (context ()), shortest_mom_);
junk_beam ();
}
}
@@ -116,25 +118,25 @@ Auto_beam_engraver::check_bar_property ()
void
Auto_beam_engraver::process_music ()
{
+ Moment now = now_mom ();
/*
don't beam over skips
*/
if (stems_)
{
- Moment now = now_mom ();
if (extend_mom_ < now)
end_beam ();
}
if (scm_is_string (get_property ("whichBar")))
{
- consider_end (shortest_mom_);
+ consider_end (measure_position (context ()), shortest_mom_);
junk_beam ();
}
if (forbid_)
{
- consider_end (shortest_mom_);
+ consider_end (measure_position (context ()), shortest_mom_);
junk_beam ();
}
}
@@ -159,36 +161,37 @@ Auto_beam_engraver::listen_beam_forbid (Stream_event *ev)
}
bool
-Auto_beam_engraver::test_moment (Direction dir, Moment test)
+Auto_beam_engraver::test_moment (Direction dir, Moment test_mom, Moment dur)
{
- return scm_call_3 (get_property ("autoBeamCheck"),
+ return scm_call_4 (get_property ("autoBeamCheck"),
context ()->self_scm (),
scm_from_int (dir),
- test.smobbed_copy ())
+ test_mom.smobbed_copy(),
+ dur.smobbed_copy ())
!= SCM_BOOL_F;
}
void
-Auto_beam_engraver::consider_begin (Moment test_mom)
+Auto_beam_engraver::consider_begin (Moment test_mom, Moment dur)
{
bool on = to_boolean (get_property ("autoBeaming"));
if (!stems_ && on
&& !forbid_)
{
- bool b = test_moment (START, test_mom);
+ bool b = test_moment (START, test_mom, dur);
if (b)
begin_beam ();
}
}
void
-Auto_beam_engraver::consider_end (Moment test_mom)
+Auto_beam_engraver::consider_end (Moment test_mom, Moment dur)
{
if (stems_)
{
/* Allow already started autobeam to end:
don't check for autoBeaming */
- bool b = test_moment (STOP, test_mom);
+ bool b = test_moment (STOP, test_mom, dur);
if (b)
end_beam ();
}
@@ -260,7 +263,7 @@ Auto_beam_engraver::end_beam ()
else
{
finished_beam_ = create_beam ();
-
+
if (finished_beam_)
{
announce_end_grob (finished_beam_, SCM_EOL);
@@ -283,7 +286,7 @@ Auto_beam_engraver::typeset_beam ()
{
if (!finished_beam_->get_bound (RIGHT))
finished_beam_->set_bound (RIGHT, finished_beam_->get_bound (LEFT));
-
+
finished_grouping_->beamify (finished_beaming_options_);
Beam::set_beaming (finished_beam_, finished_grouping_);
finished_beam_ = 0;
@@ -381,13 +384,22 @@ Auto_beam_engraver::acknowledge_stem (Grob_info info)
if (bool (beam_start_location_.grace_part_) != bool (now.grace_part_))
return;
- Moment dur = unsmob_duration (ev->get_property ("duration"))->get_length ();
-
- consider_end (dur);
- consider_begin (dur);
+ Moment ev_dur = unsmob_duration (ev->get_property ("duration"))->get_length ();
+ Moment dur = Rational (1, ev_dur.den ());
+ Moment measure_now = measure_position (context ());
+ bool recheck_needed = 0;
if (dur < shortest_mom_)
+ {
+ /* new shortest moment, so store it and set recheck_needed */
shortest_mom_ = dur;
+ recheck_needed = 1;
+ }
+
+ /* end should be based on shortest_mom_, begin should be
+ based on current duration */
+ consider_end (measure_now, shortest_mom_);
+ consider_begin (measure_now, dur);
if (!stems_)
return;
@@ -398,24 +410,98 @@ Auto_beam_engraver::acknowledge_stem (Grob_info info)
stems_->push_back (stem);
last_add_mom_ = now;
extend_mom_ = max (extend_mom_, now) + get_event_length (ev, now);
+ if (recheck_needed) recheck_beam ();
+}
+
+void
+Auto_beam_engraver::recheck_beam ()
+{
+ /*
+ Recheck the beam after the shortest duration has changed
+ If shorter duration has created a new break, typeset the
+ first part of the beam and reset the current beam to just
+ the last part of the beam
+ */
+ Beaming_pattern *new_grouping_ = 0;
+ vector<Item*> *new_stems_ = 0;
+ Moment temporary_shortest_mom;
+ SCM temporary_beam_settings;
+
+ bool found_end;
+
+
+ for (vsize i = 0; i < stems_->size () - 1; )
+ {
+ found_end = test_moment (STOP,
+ grouping_->end_moment (i),
+ shortest_mom_);
+ if (!found_end)
+ i++;
+ else
+ {
+ /*
+ Save the current beam settings and shortest_mom_
+ Necessary because end_beam destroys them
+ */
+ temporary_shortest_mom = shortest_mom_;
+ temporary_beam_settings = beam_settings_;
+
+ /* Eliminate (and save) the items no longer part of the first beam */
+
+ new_grouping_ = grouping_->split_pattern (i);
+ new_stems_ = remove_end_stems (i);
+
+ end_beam ();
+ typeset_beam ();
+
+ /* now recreate the unbeamed data structures */
+ stems_ = new_stems_;
+ grouping_ = new_grouping_;
+ shortest_mom_ = temporary_shortest_mom;
+ beam_settings_ = temporary_beam_settings;
+
+ i = 0;
+ }
+
+ }
+
+}
+
+/*
+ Remove all stems with an index greater than split_index
+ from stems_, and return a vector containing all of the
+ removed stems
+*/
+vector <Item*> *
+Auto_beam_engraver::remove_end_stems (vsize split_index)
+{
+ vector <Item*> *removed_stems = 0;
+ removed_stems = new vector <Item*>;
+
+ for (vsize j=split_index + 1; j < stems_->size (); j++)
+ removed_stems->push_back ((*stems_).at (j));
+ for (vsize j=split_index + 1; j < stems_->size (); )
+ stems_->pop_back ();
+ return (removed_stems);
}
void
Auto_beam_engraver::process_acknowledged ()
{
- if (extend_mom_ > now_mom ())
+ Moment now = now_mom();
+ if (extend_mom_ > now)
return;
if (!process_acknowledged_count_)
{
- consider_end (shortest_mom_);
- consider_begin (shortest_mom_);
+ Moment measure_now = measure_position (context ());
+ consider_end (measure_now, shortest_mom_);
+ consider_begin (measure_now, shortest_mom_);
}
else if (process_acknowledged_count_ > 1)
{
if (stems_)
{
- Moment now = now_mom ();
if ((extend_mom_ < now)
|| ((extend_mom_ == now) && (last_add_mom_ != now)))
end_beam ();
@@ -448,7 +534,7 @@ ADD_TRANSLATOR (Auto_beam_engraver,
"beamSettings "
"beatLength "
"subdivideBeams ",
-
+
/* write */
""
);
diff --git a/lily/beam.cc b/lily/beam.cc
index 5e26628fc0..4c71860664 100644
--- a/lily/beam.cc
+++ b/lily/beam.cc
@@ -108,7 +108,7 @@ Beam::get_beam_translation (Grob *me)
Real line = Staff_symbol_referencer::line_thickness (me);
Real beam_thickness = get_beam_thickness (me);
Real fract = robust_scm2double (me->get_property ("length-fraction"), 1.0);
-
+
Real beam_translation = beam_count < 4
? (2 * staff_space + line - beam_thickness) / 2.0
: (3 * staff_space + line - beam_thickness) / 3.0;
@@ -136,15 +136,15 @@ SCM
Beam::calc_normal_stems (SCM smob)
{
Grob *me = unsmob_grob (smob);
-
+
extract_grob_set (me, "stems", stems);
SCM val = Grob_array::make_array ();
Grob_array *ga = unsmob_grob_array (val);
for (vsize i = 0; i < stems.size (); i++)
if (Stem::is_normal_stem (stems[i]))
ga->add (stems[i]);
-
- return val;
+
+ return val;
}
MAKE_SCHEME_CALLBACK (Beam, calc_direction, 1);
@@ -173,7 +173,7 @@ Beam::calc_direction (SCM smob)
return SCM_UNSPECIFIED;
}
- else
+ else
{
Grob *stem = first_normal_stem (me);
@@ -182,8 +182,8 @@ Beam::calc_direction (SCM smob)
*/
if (!stem)
stem = stems[0];
-
- if (is_direction (stem->get_property_data ("direction")))
+
+ if (is_direction (stem->get_property_data ("direction")))
dir = to_dir (stem->get_property_data ("direction"));
else
dir = to_dir (stem->get_property ("default-direction"));
@@ -194,7 +194,7 @@ Beam::calc_direction (SCM smob)
{
if (!dir)
dir = get_default_dir (me);
-
+
consider_auto_knees (me);
}
@@ -202,7 +202,7 @@ Beam::calc_direction (SCM smob)
{
set_stem_directions (me, dir);
}
-
+
return scm_from_int (dir);
}
@@ -255,12 +255,12 @@ SCM
Beam::calc_beaming (SCM smob)
{
Grob *me = unsmob_grob (smob);
-
+
extract_grob_set (me, "stems", stems);
Slice last_int;
last_int.set_empty ();
-
+
SCM last_beaming = scm_cons (SCM_EOL, scm_list_1 (scm_from_int (0)));
Direction last_dir = CENTER;
for (vsize i = 0; i < stems.size (); i++)
@@ -299,7 +299,7 @@ Beam::calc_beaming (SCM smob)
else
{
/*
- FIXME: what's this for?
+ FIXME: what's this for?
*/
SCM s = scm_cdr (this_beaming);
for (; scm_is_pair (s); s = scm_cdr (s))
@@ -309,7 +309,7 @@ Beam::calc_beaming (SCM smob)
last_int.add_point (np);
}
}
-
+
if (scm_ilength (scm_cdr (this_beaming)) > 0)
{
last_beaming = this_beaming;
@@ -327,7 +327,7 @@ operator <(Beam_stem_segment const &a,
return a.rank_ < b.rank_;
}
-typedef map<int, vector<Beam_stem_segment> > Position_stem_segments_map;
+typedef map<int, vector<Beam_stem_segment> > Position_stem_segments_map;
vector<Beam_segment>
Beam::get_beam_segments (Grob *me_grob, Grob **common)
@@ -345,7 +345,7 @@ Beam::get_beam_segments (Grob *me_grob, Grob **common)
commonx = me->get_bound (RIGHT)->common_refpoint (commonx, X_AXIS);
*common = commonx;
-
+
int gap_count = robust_scm2int (me->get_property ("gap-count"), 0);
Real gap_length = robust_scm2double (me->get_property ("gap"), 0.0);
@@ -381,13 +381,13 @@ Beam::get_beam_segments (Grob *me_grob, Grob **common)
int beam_rank = scm_to_int (scm_car (s));
ranks.add_point (beam_rank);
}
-
+
for (SCM s = index_get_cell (beaming, d);
scm_is_pair (s); s = scm_cdr (s))
{
if (!scm_is_integer (scm_car (s)))
continue;
-
+
int beam_rank = scm_to_int (scm_car (s));
Beam_stem_segment seg;
seg.stem_ = stem;
@@ -397,9 +397,9 @@ Beam::get_beam_segments (Grob *me_grob, Grob **common)
seg.stem_index_ = i;
seg.dir_ = d;
seg.max_connect_ = robust_scm2int (stem->get_property ("max-beam-connect"), 1000);
-
+
Direction stem_dir = get_grob_direction (stem);
-
+
seg.gapped_
= (stem_dir * beam_rank < (stem_dir * ranks[-stem_dir] + gap_count));
stem_segments[beam_rank].push_back (seg);
@@ -450,12 +450,12 @@ Beam::get_beam_segments (Grob *me_grob, Grob **common)
bool inside_stem = (event_dir == LEFT)
? seg.stem_index_ > 0
: seg.stem_index_ + 1 < stems.size () ;
-
+
bool event = on_beam_bound
|| abs (seg.rank_ - neighbor_seg.rank_) > 1
|| (abs (vertical_count) >= seg.max_connect_
|| abs (vertical_count) >= neighbor_seg.max_connect_);
-
+
if (!event)
// Then this edge of the current segment is irrelevent because it will
// be connected with the next segment in the event_dir direction.
@@ -531,7 +531,7 @@ Beam::get_beam_segments (Grob *me_grob, Grob **common)
}
while (flip (&event_dir) != LEFT);
}
-
+
}
return segments;
@@ -553,7 +553,7 @@ Beam::print (SCM grob)
}
else
{
- extract_grob_set (me, "stems", stems);
+ extract_grob_set (me, "stems", stems);
span[LEFT] = stems[0]->relative_coordinate (commonx, X_AXIS);
span[RIGHT] = stems.back ()->relative_coordinate (commonx, X_AXIS);
}
@@ -579,7 +579,7 @@ Beam::print (SCM grob)
Real beam_dy = get_beam_translation (me);
Direction feather_dir = to_dir (me->get_property ("grow-direction"));
-
+
Stencil the_beam;
for (vsize i = 0; i < segments.size (); i ++)
{
@@ -588,18 +588,18 @@ Beam::print (SCM grob)
{
local_slope += feather_dir * segments[i].vertical_count_ * beam_dy / span.length ();
}
-
+
Stencil b = Lookup::beam (local_slope, segments[i].horizontal_.length (), beam_thickness, blot);
b.translate_axis (segments[i].horizontal_[LEFT], X_AXIS);
-
+
b.translate_axis (local_slope
* (segments[i].horizontal_[LEFT] - span.linear_combination (feather_dir))
+ pos.linear_combination (feather_dir)
+ beam_dy * segments[i].vertical_count_, Y_AXIS);
- the_beam.add_stencil (b);
+ the_beam.add_stencil (b);
}
-
+
#if (DEBUG_BEAM_SCORING)
SCM annotation = me->get_property ("annotation");
if (!scm_is_string (annotation))
@@ -608,10 +608,10 @@ Beam::print (SCM grob)
if (to_boolean (debug))
annotation = me->get_property ("quant-score");
}
-
+
if (scm_is_string (annotation))
{
- extract_grob_set (me, "stems", stems);
+ extract_grob_set (me, "stems", stems);
/*
This code prints the demerits for each beam. Perhaps this
@@ -637,7 +637,7 @@ Beam::print (SCM grob)
the_beam.translate_axis (-me->relative_coordinate (commonx, X_AXIS), X_AXIS);
return the_beam.smobbed_copy ();
}
-
+
Direction
Beam::get_default_dir (Grob *me)
{
@@ -691,7 +691,7 @@ Beam::get_default_dir (Grob *me)
else if (extremes[UP] < -extremes[DOWN])
return UP;
}
-
+
Direction dir = CENTER;
Direction d = CENTER;
if ((d = (Direction) sign (count[UP] - count[DOWN])))
@@ -704,7 +704,7 @@ Beam::get_default_dir (Grob *me)
dir = d;
else
dir = to_dir (me->get_property ("neutral-direction"));
-
+
return dir;
}
@@ -864,14 +864,14 @@ set_minimum_dy (Grob *me, Real *dy)
}
}
-
+
MAKE_SCHEME_CALLBACK (Beam, calc_stem_shorten, 1)
SCM
Beam::calc_stem_shorten (SCM smob)
{
Grob *me = unsmob_grob (smob);
-
+
/*
shortening looks silly for x staff beams
*/
@@ -895,7 +895,7 @@ Beam::calc_stem_shorten (SCM smob)
shorten *= forced_fraction;
-
+
if (shorten)
return scm_from_double (shorten);
@@ -909,7 +909,7 @@ Beam::no_visible_stem_positions (Grob *me, Interval default_value)
extract_grob_set (me, "stems", stems);
if (stems.empty ())
return default_value;
-
+
Interval head_positions;
Slice multiplicity;
for (vsize i = 0; i < stems.size(); i++)
@@ -1144,7 +1144,7 @@ Beam::slope_damping (SCM smob, SCM posns)
if (normal_stem_count (me) <= 1)
return posns;
-
+
SCM s = me->get_property ("damping");
Real damping = scm_to_double (s);
Real concaveness = robust_scm2double (me->get_property ("concaveness"), 0.0);
@@ -1154,7 +1154,7 @@ Beam::slope_damping (SCM smob, SCM posns)
me->set_property ("least-squares-dy", scm_from_double (0));
damping = 0;
}
-
+
if (damping)
{
scale_drul (&pos, Staff_symbol_referencer::staff_space (me));
@@ -1209,7 +1209,7 @@ where_are_the_whole_beams (SCM beaming)
in POS for stem S. This Y position is relative to S. */
Real
Beam::calc_stem_y (Grob *me, Grob *stem, Grob **common,
- Real xl, Real xr, Direction feather_dir,
+ Real xl, Real xr, Direction feather_dir,
Drul_array<Real> pos, bool french)
{
Real beam_translation = get_beam_translation (me);
@@ -1233,15 +1233,15 @@ Beam::calc_stem_y (Grob *me, Grob *stem, Grob **common,
/*
feather dir = 1 , relx 0->1 : factor 0 -> 1
- feather dir = 0 , relx 0->1 : factor 1 -> 1
- feather dir = -1, relx 0->1 : factor 1 -> 0
+ feather dir = 0 , relx 0->1 : factor 1 -> 1
+ feather dir = -1, relx 0->1 : factor 1 -> 0
*/
Real feather_factor = 1;
if (feather_dir > 0)
feather_factor = relx;
else if (feather_dir < 0)
feather_factor = 1 - relx;
-
+
stem_y += feather_factor * beam_translation
* beam_multiplicity[Direction(((french) ? DOWN : UP)*stem_dir)];
Real id = me->relative_coordinate (common[Y_AXIS], Y_AXIS)
@@ -1254,7 +1254,7 @@ Beam::calc_stem_y (Grob *me, Grob *stem, Grob **common,
Hmm. At this time, beam position and slope are determined. Maybe,
stem directions and length should set to relative to the chord's
position of the beam. */
-MAKE_SCHEME_CALLBACK (Beam, set_stem_lengths, 1);
+MAKE_SCHEME_CALLBACK (Beam, set_stem_lengths, 1);
SCM
Beam::set_stem_lengths (SCM smob)
{
@@ -1265,7 +1265,7 @@ Beam::set_stem_lengths (SCM smob)
(void) me->get_property ("beaming");
SCM posns = me->get_property ("positions");
-
+
extract_grob_set (me, "stems", stems);
if (!stems.size ())
return posns;
@@ -1370,7 +1370,7 @@ Beam::forced_stem_count (Grob *me)
/* I can imagine counting those boundaries as a half forced stem,
but let's count them full for now. */
Direction defdir = to_dir (s->get_property ("default-direction"));
-
+
if (abs (Stem::chord_start_y (s)) > 0.1
&& defdir
&& get_grob_direction (s) != defdir)
@@ -1419,7 +1419,7 @@ Beam::rest_collision_callback (SCM smob, SCM prev_offset)
return scm_from_int (0);
Real offset = robust_scm2double (prev_offset, 0.0);
-
+
Grob *st = unsmob_grob (rest->get_object ("stem"));
Grob *stem = st;
if (!stem)
@@ -1442,9 +1442,9 @@ Beam::rest_collision_callback (SCM smob, SCM prev_offset)
Drul_array<Grob*> visible_stems (first_normal_stem (beam),
last_normal_stem (beam));
extract_grob_set (beam, "stems", stems);
-
+
Grob *common = common_refpoint_of_array (stems, beam, X_AXIS);
-
+
Real x0 = visible_stems[LEFT]->relative_coordinate (common, X_AXIS);
Real dx = visible_stems[RIGHT]->relative_coordinate (common, X_AXIS) - x0;
Real slope = dy && dx ? dy / dx : 0;
@@ -1474,7 +1474,7 @@ Beam::rest_collision_callback (SCM smob, SCM prev_offset)
*/
Interval rest_extent = rest->extent (common_y, Y_AXIS);
rest_extent.translate (offset);
-
+
Real rest_dim = rest_extent[d];
Real minimum_distance
= staff_space * (robust_scm2double (stem->get_property ("stemlet-length"), 0.0)
@@ -1601,7 +1601,7 @@ ADD_INTERFACE (Beam,
"Damping slope which is considered zero for purposes of"
" calculating direction penalties.\n"
"@end table\n",
-
+
/* properties */
"annotation "
"auto-knee-gap "
diff --git a/lily/beaming-pattern.cc b/lily/beaming-pattern.cc
index ab89bc386e..56623d99a6 100644
--- a/lily/beaming-pattern.cc
+++ b/lily/beaming-pattern.cc
@@ -245,6 +245,51 @@ Beaming_pattern::beamlet_count (int i, Direction d) const
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)
{
diff --git a/lily/include/beaming-pattern.hh b/lily/include/beaming-pattern.hh
index eb813da275..bf56739d8e 100644
--- a/lily/include/beaming-pattern.hh
+++ b/lily/include/beaming-pattern.hh
@@ -32,7 +32,7 @@ struct Beaming_options
Moment measure_length_;
Beaming_options ();
- void from_context (Context*);
+ void from_context (Context*);
};
struct Beam_rhythmic_element
@@ -42,7 +42,7 @@ struct Beam_rhythmic_element
int rhythmic_importance_;
bool invisible_;
-
+
Beam_rhythmic_element (Moment, int, bool);
Beam_rhythmic_element ();
@@ -58,12 +58,16 @@ class Beaming_pattern
{
public:
Beaming_pattern ();
-
+
void beamify (Beaming_options const&);
void de_grace ();
void add_stem (Moment d, int beams, bool invisible);
int beamlet_count (int idx, Direction d) const;
-
+ bool invisibility (int idx) const;
+ Moment start_moment (int idx) const;
+ Moment end_moment (int idx) const;
+ Beaming_pattern* split_pattern(int idx);
+
private:
vector<Beam_rhythmic_element> infos_;
Direction flag_direction (Beaming_options const&, vsize) const;
diff --git a/scm/auto-beam.scm b/scm/auto-beam.scm
index df31f36990..c5ec73266d 100644
--- a/scm/auto-beam.scm
+++ b/scm/auto-beam.scm
@@ -34,7 +34,7 @@
;; 2. exceptions for specific time signature, for specific duration type
-(define-public (default-auto-beam-check context dir test-beam)
+(define-public (default-auto-beam-check context dir measure-pos test-beam)
(define (get name default)
(let ((value (ly:context-property context name)))
(if (not (null? value)) value default)))
@@ -60,7 +60,6 @@
(measure-length (get 'measureLength (ly:make-moment 1 1)))
(time-signature-fraction
(get 'timeSignatureFraction '(4 . 4)))
- (measure-pos (get 'measurePosition ZERO-MOMENT))
(settings (get 'beamSettings '()))
(function (if (= dir START) 'begin 'end))
(type (cons (ly:moment-main-numerator test-beam)