From: Jan Nieuwenhuizen Date: Wed, 20 Jan 1999 20:17:27 +0000 (+0100) Subject: patch::: 1.1.22.jcn5: autobiem X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=27633eb4721cc0150318b7f36f70309c61d83966;p=lilypond.git patch::: 1.1.22.jcn5: autobiem pl 22.jcn5 - auto-beaming v0: input/test/auto-beam.ly --- diff --git a/NEWS b/NEWS index 38fd7f6416..c4286c869d 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +pl 22.jcn5 + - auto-beaming v0: input/test/auto-beam.ly + pl 22.jcn4 - bf's: repeat-engraver; \bar "|:", ":|" now deprecated for repeats - bf: :|, |: diff --git a/TODO b/TODO index 2f33850f79..4a5d2ecba5 100644 --- a/TODO +++ b/TODO @@ -7,7 +7,6 @@ done, or is an idea that I want to think about Most of the items are marked in the code as well, with full explanation. grep for TODO and ugh/ugr/urg - * decimal point in \paper {} > I have changed Mark_engraver to use the G_... classes. @@ -42,6 +41,11 @@ grep for TODO and ugh/ugr/urg * update mi2mu for lilypond 1.1 BUGS: + + * AAARG: Rational::Rational (double x) is broken, try: + Rational x = (double)0.25; + see 'suck me gently...' + * collisions/voices \voiceone \voicetwo are broken; see input/praeludium-fuga-E.ly mutopia/J.S.Bach/wtk1-fugue2.ly diff --git a/VERSION b/VERSION index ebc2b4bdbb..2133ac66f4 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=1 PATCH_LEVEL=22 -MY_PATCH_LEVEL=jcn4 +MY_PATCH_LEVEL=jcn5 # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/input/test/auto-beam.ly b/input/test/auto-beam.ly new file mode 100644 index 0000000000..f325328909 --- /dev/null +++ b/input/test/auto-beam.ly @@ -0,0 +1,51 @@ +%{ + Currently (1.1.22.jcn5), the auto-beam engraver will only engrave + sensible beams (hopefully), which means that it will give up the + whole beam if: + * a rest is encountered + * another beam (entered manually) is encountered + * there's a 'gap' in the beam note's durations + + There's no smart algorithm, beginning a beam is considered when + + now / beamAutoBegin = 0 + + the beam will be ended when + + * now / beamAutoEnd = 0 +%} + +\score{ + \notes \relative c''{ + \time 2/4; + % one beam per measure + c8 c c c + % two beams per measure + \property Voice.beamAutoBegin = "0.25" + \property Voice.beamAutoEnd = "0.25" + c8 c c c + % manually override autobeam with weird beaming + c8 [c c] c + c8 c c r + c8 c c4 + r8 c c c + % no autobeaming + \property Voice.beamAuto = "0" + c8 c c c + } + \paper{ + \translator{ + \VoiceContext + % add experimental auto-beaming + \consists Auto_beam_engraver; + % switch it on (perhaps a bit double, but we want to be able + % to switch it off conveniently + beamAuto = 1.; + % consider starting beam at every 4 note + % would be nice if we could enter durations here, e.g.: + % what if we make 'dur (4)' a real_expression? + beamAutoBegin = 0.5; + beamAutoEnd = 0.5; + } + } +} diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc new file mode 100644 index 0000000000..cfc88a6f19 --- /dev/null +++ b/lily/auto-beam-engraver.cc @@ -0,0 +1,250 @@ +/* + auto-beam-engraver.cc -- implement Auto_beam_engraver + + source file of the GNU LilyPond music typesetter + + (c) 1999 Jan Nieuwenhuizen + + */ + +#include "auto-beam-engraver.hh" +#include "musical-request.hh" +#include "beam.hh" +#include "grouping.hh" +#include "rest.hh" +#include "stem.hh" +#include "debug.hh" +#include "time-description.hh" + +ADD_THIS_TRANSLATOR (Auto_beam_engraver); + +Auto_beam_engraver::Auto_beam_engraver () +{ + beam_p_ = 0; + finished_beam_p_ = 0; + finished_grouping_p_ = 0; + grouping_p_ = 0; +} + +void +Auto_beam_engraver::do_process_requests () +{ + Time_description const *time = get_staff_info().time_C_; + + //Moment begin_mom; + Real begin_f; + Scalar begin = get_property ("beamAutoBegin", 0); + if (begin.isnum_b ()) + // brrr. + // begin_mom = (Real)begin; + begin_f = (Real)begin; + else + return; + + Scalar end = get_property ("beamAutoEnd", 0); + //Moment end_mom; + Real end_f; + if (end.isnum_b ()) + // brrr. + // end_mom = (Real)end; + end_f = (Real)end; + else + return; + + Real epsilon_f = Moment (1, 512); + Real f; + if (beam_p_ && ((f=abs (fmod (time->whole_in_measure_, end_f))) < epsilon_f)) + { + DOUT << String ("ending autobeam at: ") + now_moment ().str (); + if (beam_p_->stems_.size () < 2) + { + DOUT << "junking autombeam: less than two stems"; + unbeam (); + } + else + { + finished_beam_p_ = beam_p_; + finished_grouping_p_ = grouping_p_; + beam_p_ = 0; + grouping_p_ = 0; + } + } + + /* + Allow already started autobeam to end + */ + Scalar on = get_property ("beamAuto", 0); + if (!on.to_bool ()) + return; + + if (!beam_p_ && ((f=abs (fmod (time->whole_in_measure_, begin_f))) < epsilon_f)) + { + DOUT << String ("starting autobeam at: ") + now_moment ().str (); + beam_p_ = new Beam; + grouping_p_ = new Rhythmic_grouping; + + /* urg, copied from Beam_engraver */ + Scalar prop = get_property ("beamslopedamping", 0); + if (prop.isnum_b ()) + beam_p_->damping_i_ = prop; + + prop = get_property ("beamquantisation", 0); + if (prop.isnum_b ()) + beam_p_->quantisation_ = (Beam::Quantisation)(int)prop; + + // must set minVerticalAlign = = maxVerticalAlign to get sane results + // see input/test/beam-interstaff.ly + prop = get_property ("minVerticalAlign", 0); + if (prop.isnum_b ()) + beam_p_->vertical_align_drul_[MIN] = prop; + + prop = get_property ("maxVerticalAlign", 0); + if (prop.isnum_b ()) + beam_p_->vertical_align_drul_[MAX] = prop; + + announce_element (Score_element_info (beam_p_, 0)); + } +} + +void +Auto_beam_engraver::typeset_beam () +{ + if (finished_beam_p_) + { + Rhythmic_grouping const * rg_C = get_staff_info().rhythmic_C_; + rg_C->extend (finished_grouping_p_->interval()); + finished_beam_p_->set_grouping (*rg_C, *finished_grouping_p_); + typeset_element (finished_beam_p_); + finished_beam_p_ = 0; + + delete finished_grouping_p_; + finished_grouping_p_= 0; + } +} + +void +Auto_beam_engraver::do_post_move_processing () +{ +} + +void +Auto_beam_engraver::do_pre_move_processing () +{ + typeset_beam (); +} + +void +Auto_beam_engraver::do_removal_processing () +{ + typeset_beam (); + if (beam_p_) + { + DOUT << "Unfinished beam"; + unbeam (); + } +} + +void +Auto_beam_engraver::acknowledge_element (Score_element_info info) +{ + if (Beam *b = dynamic_cast (info.elem_l_)) + { + if (beam_p_) + { + DOUT << "junking autobeam: beam encountered"; + unbeam (); + } + } + + if (beam_p_) + { + Rhythmic_req *rhythmic_req = dynamic_cast (info.req_l_); + if (!rhythmic_req) + return; + + if (dynamic_cast (info.elem_l_)) + { + DOUT << "junking autobeam: rest encountered"; + unbeam (); + return; + } + + Stem* stem_l = dynamic_cast (info.elem_l_); + if (!stem_l) + return; + + if (stem_l->beam_l_ && (stem_l->beam_l_ != beam_p_)) + { + DOUT << "junking autobeam: beamed stem encountered"; + unbeam (); + return; + } + + + /* + now that we have last_add_mom_, perhaps we can (should) do away + with these individual unbeams + */ + if (rhythmic_req->duration_.durlog_i_<= 2) + { + DOUT << "stem doesn't fit in beam"; + unbeam (); + return; + } + + Moment start = get_staff_info().time_C_->whole_in_measure_; + if (!grouping_p_->child_fit_b (start)) + { + unbeam (); + } + else + { + grouping_p_->add_child (start, rhythmic_req->duration ()); + stem_l->flag_i_ = rhythmic_req->duration_.durlog_i_; + beam_p_->add_stem (stem_l); + Moment now = now_moment (); + last_add_mom_ = now; + extend_mom_ = extend_mom_ >? now + rhythmic_req->duration (); + } + } +} + +void +Auto_beam_engraver::unbeam () +{ + assert (beam_p_); + for (int i=0; i < beam_p_->stems_.size (); i++) + { + Stem* s = beam_p_->stems_[i]; + s->beams_i_drul_[LEFT] = 0; + s->beams_i_drul_[RIGHT] = 0; + s->mult_i_ = 0; + s->beam_l_ = 0; + } + + beam_p_->unlink (); + beam_p_ = 0; + delete grouping_p_; + grouping_p_ = 0; +} + +void +Auto_beam_engraver::process_acknowledged () +{ + if (beam_p_) + { + Moment now = now_moment (); + if ((extend_mom_ < now) + || ((extend_mom_ == now) && (last_add_mom_ != now ))) + { + DOUT << String ("junking autobeam: no stem added since: ") + + last_add_mom_.str (); + unbeam (); + } + else if (!beam_p_->stems_.size ()) + { + DOUT << "junking started autobeam: no stems"; + unbeam (); + } + } +} diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index ebd09d3dff..ac7a02a26b 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -33,7 +33,7 @@ Beam_engraver::do_try_music (Music *m) if (d == STOP && !beam_p_) { - m->warning ("No Beam to end"); + m->warning (_ ("No Beam to end")); return false; } reqs_drul_[d ] = c; @@ -49,7 +49,7 @@ Beam_engraver::do_process_requests () if (reqs_drul_[STOP]) { if (!beam_p_) - reqs_drul_[STOP]->warning (_("No beam to stop")); + reqs_drul_[STOP]->warning (_("No beam to end")); finished_beam_p_ = beam_p_; finished_grouping_p_ = grouping_p_; @@ -61,7 +61,7 @@ Beam_engraver::do_process_requests () { if (beam_p_) { - reqs_drul_[START]->warning ("Already have a Beam"); + reqs_drul_[START]->warning (_ ("Already have a Beam")); return; } @@ -126,7 +126,7 @@ Beam_engraver::do_removal_processing () typeset_beam (); if (beam_p_) { - warning ("Unfinished beam"); + warning (_ ("Unfinished beam")); finished_beam_p_ = beam_p_; finished_grouping_p_ = grouping_p_; typeset_beam (); @@ -146,9 +146,9 @@ Beam_engraver::acknowledge_element (Score_element_info info) Rhythmic_req *rhythmic_req = dynamic_cast (info.req_l_); if (!rhythmic_req) { - String s=_("Stem must have Rhythmic structure."); + String s = _ ("Stem must have Rhythmic structure."); if (info.req_l_) - info.req_l_->warning(s); + info.req_l_->warning (s); else ::warning (s); @@ -159,7 +159,7 @@ Beam_engraver::acknowledge_element (Score_element_info info) if (rhythmic_req->duration_.durlog_i_<= 2) { rhythmic_req->warning (_ ("stem doesn't fit in beam")); - reqs_drul_[LEFT]->warning (_("beam was started here")); + reqs_drul_[LEFT]->warning (_ ("beam was started here")); return; } @@ -170,7 +170,7 @@ Beam_engraver::acknowledge_element (Score_element_info info) if (!grouping_p_->child_fit_b (start)) { - String s (_("please fix me") + ": " + String s (_ ("please fix me") + ": " + _f ("stem at %s doesn't fit in beam", now_moment ().str ())); if (info.req_l_) diff --git a/lily/include/auto-beam-engraver.hh b/lily/include/auto-beam-engraver.hh new file mode 100644 index 0000000000..b638ba4898 --- /dev/null +++ b/lily/include/auto-beam-engraver.hh @@ -0,0 +1,42 @@ +/* + auto-beam-engraver.hh -- declare Auto_beam_engraver + + source file of the GNU LilyPond music typesetter + + (c) 1999 Jan Nieuwenhuizen + + */ + +#ifndef AUTO_BEAM_ENGRAVER_HH +#define AUTO_BEAM_ENGRAVER_HH + +#include "engraver.hh" + +class Auto_beam_engraver : public Engraver +{ +public: + Auto_beam_engraver (); + VIRTUAL_COPY_CONS (Translator); + +protected: + virtual void do_pre_move_processing (); + virtual void do_post_move_processing (); + virtual void do_removal_processing (); + virtual void acknowledge_element (Score_element_info); + virtual void do_process_requests (); + virtual void process_acknowledged (); + +private: + void typeset_beam (); + void unbeam (); + + Beam *finished_beam_p_; + Beam *beam_p_; + Moment last_add_mom_; + Moment extend_mom_; + Rhythmic_grouping*grouping_p_; + Rhythmic_grouping*finished_grouping_p_; +}; + +#endif /* AUTO_BEAM_ENGRAVER_HH */ + diff --git a/lily/include/beam-engraver.hh b/lily/include/beam-engraver.hh index 834467858f..898e8b048d 100644 --- a/lily/include/beam-engraver.hh +++ b/lily/include/beam-engraver.hh @@ -1,5 +1,5 @@ /* - cbeam-engraver.hh -- declare Beam_engraver + beam-engraver.hh -- declare Beam_engraver source file of the GNU LilyPond music typesetter @@ -7,8 +7,8 @@ */ -#ifndef CBEAM_ENGRAVER_HH -#define CBEAM_ENGRAVER_HH +#ifndef BEAM_ENGRAVER_HH +#define BEAM_ENGRAVER_HH #include "engraver.hh" #include "drul-array.hh" @@ -35,5 +35,5 @@ public: VIRTUAL_COPY_CONS (Translator); }; -#endif /* CBEAM_ENGRAVER_HH */ +#endif /* BEAM_ENGRAVER_HH */ diff --git a/lily/include/lily-proto.hh b/lily/include/lily-proto.hh index b44dab4223..2554f271e4 100644 --- a/lily/include/lily-proto.hh +++ b/lily/include/lily-proto.hh @@ -15,8 +15,6 @@ struct Abbreviation; struct Abbreviation_beam; struct Abbreviation_beam_req; struct Abbreviation_beam_engraver; -struct G_staff_side_item; -struct G_text_item; struct Abbreviation_req; struct Adobe_font_metric; struct Adobe_font_char_metric; @@ -31,6 +29,7 @@ struct Audio_note; struct Audio_note_off; struct Audio_staff; struct Audio_tempo; +struct Auto_beam_engraver; struct Axis_group_element; struct Axis_group; struct Bar; @@ -81,6 +80,8 @@ struct Engraver; struct Engraver_group_engraver; struct Extender; struct Extender_req; +struct G_staff_side_item; +struct G_text_item; struct General_script_def; struct Graphical_element;