From: Han-Wen Nienhuys Date: Mon, 22 May 2006 17:45:40 +0000 (+0000) Subject: * lily/beaming-info.cc (beamify): new function: read beatLength X-Git-Tag: release/2.9.6~14 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=7693db10b018da89a3123cb4c9e21e3956638c56;p=lilypond.git * lily/beaming-info.cc (beamify): new function: read beatLength and beatGrouping from context. * lily/beam.cc (get_beam_segments): generate events for max_connect_ case too. (get_beam_segments): read Stem::max-beam-connect. * lily/stem.cc (set_beaming): use #f as signaling value for beamcount 0. * 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() --- diff --git a/Documentation/topdocs/NEWS.tely b/Documentation/topdocs/NEWS.tely index a53cff5e09..e7868f427e 100644 --- a/Documentation/topdocs/NEWS.tely +++ b/Documentation/topdocs/NEWS.tely @@ -66,6 +66,29 @@ which scares away people. @end ignore +@item +Beams may be put on isolated stems, and beamlets may be paired by +setting the @code{max-beam-connect} property, + +@lilypond[ragged-right,relative=2,fragment] + \override Stem #'max-beam-connect = #1 + c16[ c16] c32[] +@end lilypond + +This feature was sponsored by Trevor Bača. + +@item +Beaming patterns obey the @code{beatGrouping} property. + +@lilypond[ragged-right,relative=2,fragment] + \time 5/16 + \set beatGrouping = #'(2 3) + c8[^"(2+3)" c16 c8] + \set beatGrouping = #'(3 2) + c8[^"(3+2)" c16 c8] +@end lilypond + +This feature was sponsored by Trevor Bača. @item A new command @code{\transposedCueDuring} has been added which overrides diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc index 0b729bf03e..5ced1d2cfe 100644 --- a/lily/auto-beam-engraver.cc +++ b/lily/auto-beam-engraver.cc @@ -7,7 +7,7 @@ */ #include "engraver.hh" -#include "beaming.hh" +#include "beaming-pattern.hh" #include "beam.hh" #include "stem.hh" #include "warn.hh" @@ -71,10 +71,10 @@ private: Moment beat_length_; // We act as if beam were created, and start a grouping anyway. - Beaming_info_list *grouping_; + Beaming_pattern *grouping_; SCM beam_settings_; - Beaming_info_list *finished_grouping_; + Beaming_pattern *finished_grouping_; void check_bar_property (); }; @@ -211,7 +211,7 @@ Auto_beam_engraver::begin_beam () } stems_ = new vector; - grouping_ = new Beaming_info_list (); + grouping_ = new Beaming_pattern (); beam_settings_ = updated_grob_properties (context (), ly_symbol2scm ("Beam")); beam_start_moment_ = now_mom (); diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index 55920f032d..c8104d0bd0 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -7,7 +7,7 @@ */ #include "beam.hh" -#include "beaming.hh" +#include "beaming-pattern.hh" #include "context.hh" #include "drul-array.hh" #include "duration.hh" @@ -36,8 +36,8 @@ protected: Music *now_stop_ev_; - Beaming_info_list *beam_info_; - Beaming_info_list *finished_beam_info_; + Beaming_pattern *beam_info_; + Beaming_pattern *finished_beam_info_; /// location within measure where beam started. Moment beam_start_location_; @@ -145,7 +145,7 @@ Beam_engraver::process_music () beam_start_location_ = mp; beam_start_mom_ = now_mom (); - beam_info_ = new Beaming_info_list; + beam_info_ = new Beaming_pattern; /* urg, must copy to Auto_beam_engraver too */ } } diff --git a/lily/beam.cc b/lily/beam.cc index 01f66b435d..9dd66cef9a 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -26,7 +26,7 @@ #include "beam.hh" -#include "beaming.hh" +#include "beaming-pattern.hh" #include "directional-element-interface.hh" #include "main.hh" #include "international.hh" @@ -1191,7 +1191,7 @@ Beam::set_stem_lengths (SCM smob) } void -Beam::set_beaming (Grob *me, Beaming_info_list const *beaming) +Beam::set_beaming (Grob *me, Beaming_pattern const *beaming) { extract_grob_set (me, "stems", stems); diff --git a/lily/beaming-info.cc b/lily/beaming-info.cc deleted file mode 100644 index e8ba953bc7..0000000000 --- a/lily/beaming-info.cc +++ /dev/null @@ -1,184 +0,0 @@ -/* - beaming-info.cc -- implement Beaming_info, Beaming_info_list - - source file of the GNU LilyPond music typesetter - - (c) 1999--2006 Han-Wen Nienhuys -*/ - -#include "beaming.hh" -#include "context.hh" - -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) -{ - start_moment_ = m; - beam_count_drul_[LEFT] = i; - beam_count_drul_[RIGHT] = i; -} - -int -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++) - { - Moment dt = infos_[i].start_moment_ - infos_[i].beat_start_; - if (dt.den () < min_denominator) - { - min_denominator = dt.den (); - min_index = i; - } - } - - return min_index; -} - -int -Beaming_info_list::beam_extend_count (Direction d) const -{ - if (infos_.size () == 1) - return infos_[0].beam_count_drul_[d]; - - Beaming_info thisbeam = boundary (infos_, d, 0); - Beaming_info next = boundary (infos_, d, 1); - - return min (thisbeam.beam_count_drul_[-d], next.beam_count_drul_[d]); -} - -void -Beaming_info_list::beamify (Context *context) -{ - 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); - } - - 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++; - - infos_[i].beat_start_ = beat_starts[k]; - } - - beamify (subdivide_beams); -} - - -void -Beaming_info_list::beamify (bool subdivide_beams) -{ - if (infos_.size () <= 1) - return; - - Drul_array splits; - - bool at_boundary = false; - int m = best_splitpoint_index (&at_boundary); - - splits[LEFT].infos_ = vector (infos_.begin (), - infos_.begin () + m); - splits[RIGHT].infos_ = vector (infos_.begin () + m, - infos_.end ()); - - Direction d = LEFT; - - do - { - splits[d].beamify (subdivide_beams); - } - while (flip (&d) != LEFT); - - int middle_beams = ((at_boundary && subdivide_beams) - ? 1 - : min (splits[RIGHT].beam_extend_count (LEFT), - splits[LEFT].beam_extend_count (RIGHT))); - - do - { - if (splits[d].infos_.size () != 1) - boundary (splits[d].infos_, -d, 0).beam_count_drul_[-d] = middle_beams; - } - while (flip (&d) != LEFT); - - infos_ = splits[LEFT].infos_; - infos_.insert (infos_.end (), - splits[RIGHT].infos_.begin (), - splits[RIGHT].infos_.end ()); -} - - -void -Beaming_info_list::add_stem (Moment m, int b) -{ - infos_.push_back (Beaming_info (m, b)); -} - -Beaming_info_list::Beaming_info_list () -{ -} - -int -Beaming_info_list::beamlet_count (int i, Direction d) const -{ - return infos_.at (i).beam_count_drul_[d]; -} diff --git a/lily/beaming-pattern.cc b/lily/beaming-pattern.cc new file mode 100644 index 0000000000..c6fba3a5a5 --- /dev/null +++ b/lily/beaming-pattern.cc @@ -0,0 +1,184 @@ +/* + beaming-info.cc -- implement Beam_rhythmic_element, Beaming_pattern + + source file of the GNU LilyPond music typesetter + + (c) 1999--2006 Han-Wen Nienhuys +*/ + +#include "beaming-pattern.hh" +#include "context.hh" + +Beam_rhythmic_element::Beam_rhythmic_element () +{ + start_moment_ = 0; + beam_count_drul_[LEFT] = 0; + beam_count_drul_[RIGHT] = 0; + +} + +Beam_rhythmic_element::Beam_rhythmic_element (Moment m, int i) +{ + start_moment_ = m; + beam_count_drul_[LEFT] = i; + beam_count_drul_[RIGHT] = i; +} + +int +Beaming_pattern::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++) + { + Moment dt = infos_[i].start_moment_ - infos_[i].beat_start_; + if (dt.den () < min_denominator) + { + min_denominator = dt.den (); + min_index = i; + } + } + + return min_index; +} + +int +Beaming_pattern::beam_extend_count (Direction d) const +{ + if (infos_.size () == 1) + return infos_[0].beam_count_drul_[d]; + + Beam_rhythmic_element thisbeam = boundary (infos_, d, 0); + Beam_rhythmic_element next = boundary (infos_, d, 1); + + return min (thisbeam.beam_count_drul_[-d], next.beam_count_drul_[d]); +} + +void +Beaming_pattern::beamify (Context *context) +{ + 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); + } + + 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++; + + infos_[i].beat_start_ = beat_starts[k]; + } + + beamify (subdivide_beams); +} + + +void +Beaming_pattern::beamify (bool subdivide_beams) +{ + if (infos_.size () <= 1) + return; + + Drul_array splits; + + bool at_boundary = false; + int m = best_splitpoint_index (&at_boundary); + + splits[LEFT].infos_ = vector (infos_.begin (), + infos_.begin () + m); + splits[RIGHT].infos_ = vector (infos_.begin () + m, + infos_.end ()); + + Direction d = LEFT; + + do + { + splits[d].beamify (subdivide_beams); + } + while (flip (&d) != LEFT); + + int middle_beams = ((at_boundary && subdivide_beams) + ? 1 + : min (splits[RIGHT].beam_extend_count (LEFT), + splits[LEFT].beam_extend_count (RIGHT))); + + do + { + if (splits[d].infos_.size () != 1) + boundary (splits[d].infos_, -d, 0).beam_count_drul_[-d] = middle_beams; + } + while (flip (&d) != LEFT); + + infos_ = splits[LEFT].infos_; + infos_.insert (infos_.end (), + splits[RIGHT].infos_.begin (), + splits[RIGHT].infos_.end ()); +} + + +void +Beaming_pattern::add_stem (Moment m, int b) +{ + infos_.push_back (Beam_rhythmic_element (m, b)); +} + +Beaming_pattern::Beaming_pattern () +{ +} + +int +Beaming_pattern::beamlet_count (int i, Direction d) const +{ + return infos_.at (i).beam_count_drul_[d]; +} diff --git a/lily/include/beam.hh b/lily/include/beam.hh index f20556a696..71821f6629 100644 --- a/lily/include/beam.hh +++ b/lily/include/beam.hh @@ -74,7 +74,7 @@ public: static bool has_interface (Grob *); static void add_stem (Grob *, Grob *); static bool is_knee (Grob *); - static void set_beaming (Grob *, Beaming_info_list const *); + static void set_beaming (Grob *, Beaming_pattern const *); static void set_stemlens (Grob *); static int get_beam_count (Grob *me); static Real get_beam_translation (Grob *me); diff --git a/lily/include/beaming-pattern.hh b/lily/include/beaming-pattern.hh new file mode 100644 index 0000000000..9f2adb1940 --- /dev/null +++ b/lily/include/beaming-pattern.hh @@ -0,0 +1,50 @@ +/* + beaming-pattern.hh -- declare beaming-pattern.hh + + source file of the GNU LilyPond music typesetter + + (c) 1999--2006 Han-Wen Nienhuys +*/ + +#ifndef BEAMING_PATTERN_HH +#define BEAMING_PATTERN_HH + +#include "std-vector.hh" +#include "moment.hh" +#include "lily-proto.hh" + +struct Beam_rhythmic_element +{ + Moment start_moment_; + Drul_array beam_count_drul_; + + Moment beat_start_; + Moment group_start_; + + Beam_rhythmic_element (Moment, int); + Beam_rhythmic_element (); + + int count (Direction d); +}; + +/* + Generate beaming given durations of notes. Beam uses this to + set_beaming () for each of its stems. +*/ +class Beaming_pattern +{ +public: + Beaming_pattern (); + + 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; +}; + +#endif /* BEAMING_PATTERN_HH */ diff --git a/lily/include/beaming.hh b/lily/include/beaming.hh deleted file mode 100644 index a9848de196..0000000000 --- a/lily/include/beaming.hh +++ /dev/null @@ -1,52 +0,0 @@ -/* - beaming.hh -- declare beaming.hh - - source file of the GNU LilyPond music typesetter - - (c) 1999--2006 Han-Wen Nienhuys -*/ - -#ifndef BEAMING_HH -#define BEAMING_HH - -#include "std-vector.hh" -#include "moment.hh" -#include "lily-proto.hh" - -struct Beaming_info -{ - Moment start_moment_; - Drul_array beam_count_drul_; - - Moment beat_start_; - Moment group_start_; - - Beaming_info (Moment, int); - Beaming_info (); - - int count (Direction d); -}; - -/* - Generate beaming given durations of notes. Beam uses this to - set_beaming () for each of its stems. -*/ -class Beaming_info_list -{ -public: - Beaming_info_list (); - - 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 *); - -#endif /* BEAMING_HH */ diff --git a/lily/include/lily-proto.hh b/lily/include/lily-proto.hh index b2b12416c4..d0410c7ae2 100644 --- a/lily/include/lily-proto.hh +++ b/lily/include/lily-proto.hh @@ -30,7 +30,7 @@ class Auto_change_music; class Axis_group_engraver; class Bar_engraver; class Bar_req_collect_engraver; -class Beaming_info_list; +class Beaming_pattern; class Bezier; class Bezier_bow; class Book; diff --git a/lily/stem.cc b/lily/stem.cc index 3b00da28cf..a25c37f777 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -982,6 +982,7 @@ ADD_INTERFACE (Stem, "stem-interface", "french-beaming " "length " "length-fraction " + "max-beam-connect " "neutral-direction " "no-stem-extend " "note-heads "