+pl 22.jcn5
+ - auto-beaming v0: input/test/auto-beam.ly
+
pl 22.jcn4
- bf's: repeat-engraver; \bar "|:", ":|" now deprecated for repeats
- bf: :|, |:
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.
* 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
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.
--- /dev/null
+%{
+ 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;
+ }
+ }
+}
--- /dev/null
+/*
+ auto-beam-engraver.cc -- implement Auto_beam_engraver
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
+
+ */
+
+#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<Beam *> (info.elem_l_))
+ {
+ if (beam_p_)
+ {
+ DOUT << "junking autobeam: beam encountered";
+ unbeam ();
+ }
+ }
+
+ if (beam_p_)
+ {
+ Rhythmic_req *rhythmic_req = dynamic_cast <Rhythmic_req *> (info.req_l_);
+ if (!rhythmic_req)
+ return;
+
+ if (dynamic_cast<Rest *> (info.elem_l_))
+ {
+ DOUT << "junking autobeam: rest encountered";
+ unbeam ();
+ return;
+ }
+
+ Stem* stem_l = dynamic_cast<Stem *> (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 ();
+ }
+ }
+}
if (d == STOP && !beam_p_)
{
- m->warning ("No Beam to end");
+ m->warning (_ ("No Beam to end"));
return false;
}
reqs_drul_[d ] = c;
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_;
{
if (beam_p_)
{
- reqs_drul_[START]->warning ("Already have a Beam");
+ reqs_drul_[START]->warning (_ ("Already have a Beam"));
return;
}
typeset_beam ();
if (beam_p_)
{
- warning ("Unfinished beam");
+ warning (_ ("Unfinished beam"));
finished_beam_p_ = beam_p_;
finished_grouping_p_ = grouping_p_;
typeset_beam ();
Rhythmic_req *rhythmic_req = dynamic_cast <Rhythmic_req *> (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);
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;
}
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_)
--- /dev/null
+/*
+ auto-beam-engraver.hh -- declare Auto_beam_engraver
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
+
+ */
+
+#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 */
+
/*
- cbeam-engraver.hh -- declare Beam_engraver
+ beam-engraver.hh -- declare Beam_engraver
source file of the GNU LilyPond music typesetter
*/
-#ifndef CBEAM_ENGRAVER_HH
-#define CBEAM_ENGRAVER_HH
+#ifndef BEAM_ENGRAVER_HH
+#define BEAM_ENGRAVER_HH
#include "engraver.hh"
#include "drul-array.hh"
VIRTUAL_COPY_CONS (Translator);
};
-#endif /* CBEAM_ENGRAVER_HH */
+#endif /* BEAM_ENGRAVER_HH */
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;
struct Audio_note_off;
struct Audio_staff;
struct Audio_tempo;
+struct Auto_beam_engraver;
struct Axis_group_element;
struct Axis_group;
struct Bar;
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;