]> git.donarmstrong.com Git - lilypond.git/commitdiff
patch::: 1.1.22.jcn5: autobiem
authorJan Nieuwenhuizen <janneke@gnu.org>
Wed, 20 Jan 1999 20:17:27 +0000 (21:17 +0100)
committerJan Nieuwenhuizen <janneke@gnu.org>
Wed, 20 Jan 1999 20:17:27 +0000 (21:17 +0100)
pl 22.jcn5
- auto-beaming v0: input/test/auto-beam.ly

NEWS
TODO
VERSION
input/test/auto-beam.ly [new file with mode: 0644]
lily/auto-beam-engraver.cc [new file with mode: 0644]
lily/beam-engraver.cc
lily/include/auto-beam-engraver.hh [new file with mode: 0644]
lily/include/beam-engraver.hh
lily/include/lily-proto.hh

diff --git a/NEWS b/NEWS
index 38fd7f641607c3dbfdad03c08cd5d76696b2c39f..c4286c869d694c9bb21a0a4cbec93dbb8cdfafef 100644 (file)
--- 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 2f33850f79c5aae82b5f05acaa4280f7c82bee42..4a5d2ecba5a429a0758c9b765f56cd76718d17e1 100644 (file)
--- 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 ebc2b4bdbb8332eadd78e35fd2fc1075404f0fff..2133ac66f4fb2e78fc09c8a74b992b68ba3ff40c 100644 (file)
--- 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 (file)
index 0000000..f325328
--- /dev/null
@@ -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 (file)
index 0000000..cfc88a6
--- /dev/null
@@ -0,0 +1,250 @@
+/*   
+  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 ();
+       }
+    }
+}
index ebd09d3dffd8705e91373ad97d5623c14060b92d..ac7a02a26b2dbc1ef504bcbd977675c8ae3b187c 100644 (file)
@@ -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 <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);
          
@@ -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 (file)
index 0000000..b638ba4
--- /dev/null
@@ -0,0 +1,42 @@
+/*   
+  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 */
+
index 834467858f9ec4c90d0e2202da7b1df08ecae357..898e8b048d778a8d3d1fa1d6b548513eace63d11 100644 (file)
@@ -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 */
 
index b44dab422342896ccb8aac43a6a438ce9bee5e02..2554f271e419e44b6442c4fbeef783f580eeaecf 100644 (file)
@@ -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;