From 7440997e6cb838533b460d45db89108b331c165d Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 22 May 2006 17:21:25 +0000 Subject: [PATCH] * lily/beaming-info.cc (beamify): new function: read beatLength and beatGrouping from context. * input/regression/beam-beat-grouping.ly (Module): new file. * lily/beam.cc (get_beam_segments): generate events for max_connect_ case too. (get_beam_segments): read Stem::max-beam-connect. * lily/beam-engraver.cc (typeset_beam): set right bound if unset. * lily/beam.cc (set_beaming): read clip-edges property. (calc_direction): don't suicide for single stem. * lily/beaming-info.cc (best_splitpoint_index): take bool* argument, remove 1<<15 hack. Remove clip_edges() --- ChangeLog | 5 ++ VERSION | 2 +- input/regression/beam-beat-grouping.ly | 18 ++++ lily/auto-beam-engraver.cc | 4 +- lily/beam-engraver.cc | 4 +- lily/beam.cc | 4 +- lily/beaming-info.cc | 118 +++++++++++++++++-------- lily/include/beaming.hh | 21 +++-- 8 files changed, 122 insertions(+), 54 deletions(-) create mode 100644 input/regression/beam-beat-grouping.ly diff --git a/ChangeLog b/ChangeLog index e82fb007e8..dde1af11e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2006-05-22 Han-Wen Nienhuys + * lily/beaming-info.cc (beamify): new function: read beatLength + and beatGrouping from context. + + * input/regression/beam-beat-grouping.ly (Module): new file. + * input/regression/beam-unconnected-beamlets.ly (Module): new file. * lily/beam.cc (get_beam_segments): generate events for diff --git a/VERSION b/VERSION index 9c3e3cb61c..eeddea6bb5 100644 --- a/VERSION +++ b/VERSION @@ -1,6 +1,6 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=2 MINOR_VERSION=9 -PATCH_LEVEL=5 +PATCH_LEVEL=6 MY_PATCH_LEVEL= diff --git a/input/regression/beam-beat-grouping.ly b/input/regression/beam-beat-grouping.ly new file mode 100644 index 0000000000..720f772906 --- /dev/null +++ b/input/regression/beam-beat-grouping.ly @@ -0,0 +1,18 @@ +\header { + + texidoc = "Beaming patterns obey the @code{beatGrouping} property. " + } + +\layout { + ragged-right = ##t + } +\version "2.9.6" + + +\relative c'' { + \time 5/16 + \set beatGrouping = #'(2 3) + c8[^"(2+3)" c16 c8] + \set beatGrouping = #'(3 2) + c8[^"(3+2)" c16 c8] +} diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc index 03795dc9a0..0b729bf03e 100644 --- a/lily/auto-beam-engraver.cc +++ b/lily/auto-beam-engraver.cc @@ -211,7 +211,7 @@ Auto_beam_engraver::begin_beam () } stems_ = new vector; - grouping_ = make_beaming_info_list (context ()); + grouping_ = new Beaming_info_list (); beam_settings_ = updated_grob_properties (context (), ly_symbol2scm ("Beam")); beam_start_moment_ = now_mom (); @@ -261,7 +261,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_grouping_->beamify (context ()); Beam::set_beaming (finished_beam_, finished_grouping_); finished_beam_ = 0; diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index 7f89b9ed98..55920f032d 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -145,7 +145,7 @@ Beam_engraver::process_music () beam_start_location_ = mp; beam_start_mom_ = now_mom (); - beam_info_ = make_beaming_info_list (context ()); + beam_info_ = new Beaming_info_list; /* urg, must copy to Auto_beam_engraver too */ } } @@ -158,7 +158,7 @@ Beam_engraver::typeset_beam () if (!finished_beam_->get_bound (RIGHT)) finished_beam_->set_bound (RIGHT, finished_beam_->get_bound (LEFT)); - finished_beam_info_->beamify (); + finished_beam_info_->beamify (context ()); Beam::set_beaming (finished_beam_, finished_beam_info_); delete finished_beam_info_; diff --git a/lily/beam.cc b/lily/beam.cc index cf5e7c296c..01f66b435d 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -1208,11 +1208,11 @@ Beam::set_beaming (Grob *me, Beaming_info_list const *beaming) if (beaming_prop == SCM_EOL || index_get_cell (beaming_prop, d) == SCM_EOL) { - int count = beaming->infos_.at (i).beam_count_drul_[d]; + int count = beaming->beamlet_count (i, d); if (i > 0 && i < stems.size () -1 && Stem::is_invisible (stem)) - count = min (count, beaming->infos_.at (i).beam_count_drul_[-d]); + count = min (count, beaming->beamlet_count (i,-d)); if ( ((i == 0 && d == LEFT) || (i == stems.size ()-1 && d == RIGHT)) diff --git a/lily/beaming-info.cc b/lily/beaming-info.cc index 0e66b2b681..e8ba953bc7 100644 --- a/lily/beaming-info.cc +++ b/lily/beaming-info.cc @@ -14,6 +14,7 @@ Beaming_info::Beaming_info () start_moment_ = 0; beam_count_drul_[LEFT] = 0; beam_count_drul_[RIGHT] = 0; + } Beaming_info::Beaming_info (Moment m, int i) @@ -24,31 +25,37 @@ Beaming_info::Beaming_info (Moment m, int i) } int -Beaming_info_list::best_splitpoint_index (Moment beat_length, - bool subdivide_beams, - bool *at_beat_subdivide) const +Beaming_info_list::best_splitpoint_index (bool *at_boundary) const { + *at_boundary = true; + for (vsize i = 1; i < infos_.size (); i++) + { + if (infos_[i].group_start_ == infos_[i].start_moment_) + return i; + } + + for (vsize i = 1; i < infos_.size (); i++) + { + if (infos_[i].beat_start_ == infos_[i].start_moment_) + return i; + } + + *at_boundary = false; + int min_denominator = INT_MAX; int min_index = -1; + Moment beat_pos; - - for (vsize i = 1; i < infos_.size (); i++) + for (vsize i = 1; i < infos_.size (); i++) { - beat_pos = infos_[i].start_moment_ / beat_length; - int den = beat_pos.den (); - if (infos_[i].beam_count_drul_[LEFT] == infos_[i - 1].beam_count_drul_[RIGHT] - && !subdivide_beams) - den *= 2; - - if (den < min_denominator) + Moment dt = infos_[i].start_moment_ - infos_[i].beat_start_; + if (dt.den () < min_denominator) { + min_denominator = dt.den (); min_index = i; - min_denominator = den; } } - *at_beat_subdivide = (min_denominator == 1 && subdivide_beams); - return min_index; } @@ -65,37 +72,68 @@ Beaming_info_list::beam_extend_count (Direction d) const } void -Beaming_info_list::beamify () +Beaming_info_list::beamify (Context *context) { - bool subdivide_beams = to_boolean (context_->get_property ("subdivideBeams")); - Moment beat_length = robust_scm2moment (context_->get_property ("beatLength"), Moment (1, 4)); + if (infos_.size () <= 1) + return; + + bool subdivide_beams = to_boolean (context->get_property ("subdivideBeams")); + Moment beat_length = robust_scm2moment (context->get_property ("beatLength"), Moment (1, 4)); + + SCM grouping = context->get_property ("beatGrouping"); + Moment measure_pos (0); + + vector group_starts; + vector beat_starts; + + while (measure_pos <= infos_.back().start_moment_) + { + int count = 2; + if (scm_is_pair (grouping)) + { + count = scm_to_int (scm_car (grouping)); + grouping = scm_cdr (grouping); + } - beamify (beat_length, subdivide_beams); -} + group_starts.push_back (measure_pos); + for (int i = 0; i < count; i++) + { + beat_starts.push_back (measure_pos + beat_length * i); + } + measure_pos += beat_length * count; + } + + vsize j = 0; + vsize k = 0; + for (vsize i = 0; i < infos_.size(); i++) + { + while (j < group_starts.size()-1 + && group_starts[j+1] <= infos_[i].start_moment_) + j++; + infos_[i].group_start_ = group_starts[j]; + while (k < beat_starts.size()-1 + && beat_starts[k+1] <= infos_[i].start_moment_) + k++; -Beaming_info_list * -make_beaming_info_list (Context *context) -{ - Beaming_info_list *l = new Beaming_info_list; - l->context_ = context; - return l; -} + infos_[i].beat_start_ = beat_starts[k]; + } + + beamify (subdivide_beams); +} void -Beaming_info_list::beamify (Moment beat_length, - bool subdivide_beams) +Beaming_info_list::beamify (bool subdivide_beams) { if (infos_.size () <= 1) return; - - Drul_array splits (*this, *this); + Drul_array splits; - bool split = false; - int m = best_splitpoint_index (beat_length, subdivide_beams, &split); + bool at_boundary = false; + int m = best_splitpoint_index (&at_boundary); splits[LEFT].infos_ = vector (infos_.begin (), infos_.begin () + m); @@ -106,11 +144,12 @@ Beaming_info_list::beamify (Moment beat_length, do { - splits[d].beamify (beat_length, subdivide_beams); + splits[d].beamify (subdivide_beams); } while (flip (&d) != LEFT); - int middle_beams = (split ? 1 + int middle_beams = ((at_boundary && subdivide_beams) + ? 1 : min (splits[RIGHT].beam_extend_count (LEFT), splits[LEFT].beam_extend_count (RIGHT))); @@ -128,17 +167,18 @@ Beaming_info_list::beamify (Moment beat_length, } - void Beaming_info_list::add_stem (Moment m, int b) { infos_.push_back (Beaming_info (m, b)); } - Beaming_info_list::Beaming_info_list () { - context_ = 0; } - +int +Beaming_info_list::beamlet_count (int i, Direction d) const +{ + return infos_.at (i).beam_count_drul_[d]; +} diff --git a/lily/include/beaming.hh b/lily/include/beaming.hh index bb4bc7e1c0..a9848de196 100644 --- a/lily/include/beaming.hh +++ b/lily/include/beaming.hh @@ -18,6 +18,9 @@ struct Beaming_info Moment start_moment_; Drul_array beam_count_drul_; + Moment beat_start_; + Moment group_start_; + Beaming_info (Moment, int); Beaming_info (); @@ -28,18 +31,20 @@ struct Beaming_info Generate beaming given durations of notes. Beam uses this to set_beaming () for each of its stems. */ -struct Beaming_info_list +class Beaming_info_list { - vector infos_; - Context *context_; - +public: Beaming_info_list (); - int beam_extend_count (Direction) const; - int best_splitpoint_index (Moment, bool, bool *split) const; - void beamify (); - void beamify (Moment, bool); + void beamify (Context*); void add_stem (Moment d, int beams); + int beamlet_count (int idx, Direction d) const; + +private: + vector infos_; + void beamify (bool); + int beam_extend_count (Direction) const; + int best_splitpoint_index (bool *split) const; }; Beaming_info_list *make_beaming_info_list (Context *); -- 2.39.2