]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/percent-repeat-engraver.cc, lily/parser.yy,
authorErik Sandberg <mandolaerik@gmail.com>
Tue, 16 May 2006 11:19:50 +0000 (11:19 +0000)
committerErik Sandberg <mandolaerik@gmail.com>
Tue, 16 May 2006 11:19:50 +0000 (11:19 +0000)
lily/define-music-types.cc, lily/percent-repeat-iterator.cc,
lily/slash-repeat-engraver.cc,
lily/include/percent-repeat-iterator.hh: Rework percent repeats:
iterator sends PercentEvents

* lily/time-scaled-music-iterator.cc, lily/tuplet-engraver.cc:
rework tuplets: send start/stop events to engraver

13 files changed:
ChangeLog
lily/folded-repeat-iterator.cc
lily/include/percent-repeat-iterator.hh
lily/include/time-scaled-music-iterator.hh
lily/parser.yy
lily/percent-repeat-engraver.cc
lily/percent-repeat-iterator.cc
lily/slash-repeat-engraver.cc
lily/time-scaled-music-iterator.cc
lily/tuplet-engraver.cc
lily/volta-engraver.cc
scm/define-music-types.scm
scm/music-functions.scm

index 33969857f70be1012ebd7afcc9e88eecd78fa38f..4f9d2aa07c6810847dda33aee7bf499a12bc988d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2006-05-16  Erik Sandberg  <mandolaerik@gmail.com>
+       * lily/percent-repeat-engraver.cc, lily/parser.yy,
+       lily/define-music-types.cc, lily/percent-repeat-iterator.cc,
+       lily/slash-repeat-engraver.cc,
+       lily/include/percent-repeat-iterator.hh: Rework percent repeats:
+       iterator sends PercentEvents
+
+       * lily/time-scaled-music-iterator.cc, lily/tuplet-engraver.cc:
+       rework tuplets: send start/stop events to engraver
+
 2006-05-15  Graham Percival  <gpermus@gmail.com>
 
        * Documentation/user/README.txt: update info for doc writers.
index b927653e0c1dfa02fed41e1a9fedfb0f6b6df287..6465f3399ad1982e876f13bef392411dc470d915 100644 (file)
@@ -56,13 +56,6 @@ Folded_repeat_iterator::construct_children ()
 void
 Folded_repeat_iterator::process (Moment m)
 {
-  if (!m.to_bool ())
-    {
-      bool success = try_music (get_music ());
-      if (!success)
-       get_music ()->origin ()->warning (_ ("no one to print a repeat brace"));
-    }
-
   if (main_iter_)
     {
       main_iter_->process (m);
index 6234b6773a03a305207b5c4c7de1539322a9e10b..7c510cd7ad3532425c334322fa84d57db5ee2b5f 100644 (file)
@@ -9,28 +9,20 @@
 #ifndef PERCENT_REPEAT_ITERATOR_HH
 #define PERCENT_REPEAT_ITERATOR_HH
 
-#include "music-iterator.hh"
+#include "sequential-iterator.hh"
 
-class Percent_repeat_iterator : public Music_iterator
+class Percent_repeat_iterator : public Sequential_iterator
 {
 public:
   DECLARE_CLASSNAME(Percent_repeat_iterator);
   DECLARE_SCHEME_CALLBACK (constructor, ());
   Percent_repeat_iterator ();
 protected:
-  virtual void derived_substitute (Context *f, Context *t);
-
+  virtual SCM get_music_list () const;
   virtual void derived_mark () const;
-  virtual Moment pending_moment () const;
-  virtual void do_quit ();
   virtual void construct_children ();
-  virtual bool ok () const;
-  virtual void process (Moment);
-  virtual Music_iterator *try_music_in_children (Music *) const;
-
 private:
-  Music_iterator *child_iter_;
-  Moment finish_mom_;
+  SCM child_list_;
 };
 
 #endif /* PERCENT_REPEAT_ITERATOR_HH */
index e8e9ee186fa96c4ac225f66d920b2ce4d15776ef..34bd50cf6f54e20a1d6b12ce93dee7c3907cacff 100644 (file)
@@ -3,23 +3,28 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  (c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>,
+                 Erik Sandberg <mandolaerik@gmail.com>
 */
 
-#ifndef Time_scaled_music_ITERATOR_HH
-#define Time_scaled_music_ITERATOR_HH
+#ifndef TIME_SCALED_MUSIC_ITERATOR_HH
+#define TIME_SCALED_MUSIC_ITERATOR_HH
 
-#include "music-wrapper-iterator.hh"
+#include "sequential-iterator.hh"
 
-class Time_scaled_music_iterator : public Music_wrapper_iterator
+class Time_scaled_music_iterator : public Sequential_iterator
 {
 public:
   DECLARE_SCHEME_CALLBACK (constructor, ());
   /* construction */
   DECLARE_CLASSNAME(Time_scaled_music_iterator);
+  Time_scaled_music_iterator ();
 protected:
-  virtual void process (Moment);
+  virtual SCM get_music_list () const;
+  virtual void derived_mark () const;
+  virtual void construct_children ();
+private:
+  SCM child_list_;
 };
 
-#endif /* Time_scaled_music_ITERATOR_HH */
-
+#endif /* TIME_SCALED_MUSIC_ITERATOR_HH */
index e2bbcd7d4d45796518338eeb7ffcb78a6cf4b4db..9266860f378155d4e1487753fe5aad460bc3f980 100644 (file)
@@ -872,57 +872,14 @@ Alternative_music:
 Repeated_music:
        REPEAT simple_string bare_unsigned Music Alternative_music
        {
-               /*TODO: move to Scheme.*/
-               Music *beg = $4;
-               int times = $3;
+               SCM proc = ly_lily_module_constant ("make-repeat");
                SCM alts = scm_is_pair ($5) ? scm_car ($5) : SCM_EOL;
-               if (times < scm_ilength (alts)) {
-                 unsmob_music (scm_car (alts))
-                   ->origin ()->warning (
-                   _ ("more alternatives than repeats"));
-                   warning ("junking excess alternatives");
-                 alts = ly_truncate_list (times, alts);
-               }
-
-
-               SCM proc = ly_lily_module_constant ("make-repeated-music");
-
-               SCM mus = scm_call_1 (proc, $2);
+               assert ($4);
+               SCM mus = scm_call_4 (proc, $2, scm_int2num ($3), $4->self_scm (), alts);
                Music *r = unsmob_music (mus);
-               r->protect ();
-               if (beg)
-                       {
-                       r-> set_property ("element", beg->self_scm ());
-                       beg->unprotect ();
-                       }
-               r->set_property ("repeat-count", scm_from_int (max (times, 1)));
-
-               r-> set_property ("elements",alts);
-               if (ly_is_equal ($2, scm_makfrom0str ("tremolo"))) {
-                       /*
-                       TODO: move this code to Scheme.
-                       */
-
-                       /* we cannot get durations and other stuff
-                          correct down the line,
-                          so we have to add to the duration log here. */
-                       SCM func = ly_lily_module_constant ("shift-duration-log");
-
-                       int dots = ($3 % 3) ? 0 : 1;
-                       int shift = -intlog2 ((dots) ? ($3*2/3) : $3);
 
-                       
-                       if ($4->is_mus_type ("sequential-music"))
-                       {
-                               int list_len = scm_ilength ($4->get_property ("elements"));
-                               if (list_len != 2)
-                                       $4->origin ()->warning (_f ("expect 2 elements for Chord tremolo, found %d", list_len));
-                               shift -= 1;
-                               r->compress (Moment (Rational (1, list_len)));
-                       }
-                       scm_call_3 (func, r->self_scm (), scm_from_int (shift), scm_from_int (dots));
-
-               }
+               r->protect ();
+               $4->unprotect ();
                r->set_spot (*$4->origin ());
 
                $$ = r;
@@ -1065,19 +1022,18 @@ Prefix_composite_music:
 
        | TIMES fraction Music  
        {
-               int n = scm_to_int (scm_car ($2));
-               int d = scm_to_int (scm_cdr ($2));
-               Music *mp = $3;
-
-               $$= MY_MAKE_MUSIC ("TimeScaledMusic");
-               $$->set_spot (@$);
-
-               $$->set_property ("element", mp->self_scm ());
-               mp->unprotect();
-               $$->set_property ("numerator", scm_from_int (n));
-               $$->set_property ("denominator", scm_from_int (d));
-               $$->compress (Moment (Rational (n,d)));
-
+                int n = scm_to_int (scm_car ($2));
+                int d = scm_to_int (scm_cdr ($2));
+                Music *mp = $3;
+
+                $$= MY_MAKE_MUSIC ("TimeScaledMusic");
+                $$->set_spot (@$);
+
+                $$->set_property ("element", mp->self_scm ());
+                mp->unprotect();
+                $$->set_property ("numerator", scm_from_int (n));
+                $$->set_property ("denominator", scm_from_int (d));
+                $$->compress (Moment (Rational (n,d)));
        }
        | Repeated_music                { $$ = $1; }
        | TRANSPOSE pitch_also_in_chords pitch_also_in_chords Music {
index dab7129e5ef4deb957434a14f8462097e50a7aa8..a979a2e743914f91bed6371c3fd3319e420ab102 100644 (file)
@@ -3,7 +3,7 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>, Erik Sandberg <mandolaerik@gmail.com>
 */
 
 
 
 #include "translator.icc"
 
+/*
+* TODO: Create separate Double_percent_repeat_engraver? 
+* Or, at least move double percent handling to Slash_repeat_engraver
+*/
+
 class Percent_repeat_engraver : public Engraver
 {
   void typeset_perc ();
@@ -30,16 +35,11 @@ public:
   TRANSLATOR_DECLARATIONS (Percent_repeat_engraver);
   
 protected:
-  Music *repeat_;
+  Music *percent_event_;
 
-  /// moment (global time) where beam started.
-  Moment start_mom_;
+  /// moment (global time) where percent started.
   Moment stop_mom_;
-
-  /// location within measure where beam started.
-  Moment beam_start_location_;
-  Moment next_moment_;
-  Moment body_length_;
+  Moment start_mom_;
 
   enum Repeat_sign_type
     {
@@ -49,16 +49,9 @@ protected:
     };
   Repeat_sign_type repeat_sign_type_;
 
-  Item *double_percent_;
-  Item *double_percent_counter_;
-  
   Spanner *percent_;
   Spanner *percent_counter_;
-  Spanner *finished_percent_;
-  Spanner *finished_percent_counter_;
 
-  int count_;
-  int total_count_; 
 protected:
   virtual void finalize ();
   virtual bool try_music (Music *);
@@ -73,62 +66,38 @@ Percent_repeat_engraver::Percent_repeat_engraver ()
   percent_ = 0;
   percent_counter_ = 0;
 
-  finished_percent_ = 0;
-  finished_percent_counter_ = 0;
-
-  double_percent_ = 0;
-  double_percent_counter_ = 0;
-
-  repeat_ = 0;
-  count_ = 0;
-  total_count_ = 0;
+  percent_event_ = 0;
 }
 
 bool
 Percent_repeat_engraver::try_music (Music *m)
 {
-  if (m->is_mus_type ("repeated-music")
-      && m->get_property ("iterator-ctor")
-      == Percent_repeat_iterator::constructor_proc
-      && !repeat_)
+  if (m->is_mus_type ("percent-event")
+      && !percent_event_)
     {
-      body_length_ = Repeated_music::body_get_length (m);
-      total_count_ = Repeated_music::repeat_count (m);
-      
-      Moment now = now_mom ();
-      start_mom_ = now;
-      stop_mom_ = start_mom_ + Moment (total_count_) * body_length_;
-      next_moment_ = start_mom_;
-      next_moment_ += body_length_;
-
+      Moment body_length = m->get_length ();
       Moment meas_len (robust_scm2moment (get_property ("measureLength"),
                                          Moment (1)));
-      
-      if (meas_len == body_length_)
+
+      if (meas_len == body_length)
+      {
        repeat_sign_type_ = MEASURE;
-      else if (Moment (2) * meas_len == body_length_)
+       start_mom_ = now_mom ();
+       stop_mom_ = now_mom () + body_length;
+       get_global_context ()->add_moment_to_process (stop_mom_);
+      }
+      else if (Moment (2) * meas_len == body_length)
+      {
        repeat_sign_type_ = DOUBLE_MEASURE;
+       start_mom_ = now_mom () + meas_len;
+       stop_mom_ = now_mom () + body_length; /* never used */
+       get_global_context ()->add_moment_to_process (start_mom_);
+      }
       else
        return false;
-    
-
-      repeat_ = m;
-
-      Global_context *global = get_global_context ();
-      for (int i = 1; i < total_count_; i++)
-       {
-         Moment m = next_moment_ + Moment (i) * body_length_;
-         global->add_moment_to_process (m);
-
-         /* bars between % too.  */
-         if (repeat_sign_type_ == DOUBLE_MEASURE)
-           global->add_moment_to_process (m - meas_len);
-       }
 
-      if (repeat_sign_type_ == DOUBLE_MEASURE)
-       next_moment_ += meas_len;
+      percent_event_ = m;
 
-      count_ = 1;
       return true;
     }
 
@@ -138,71 +107,69 @@ Percent_repeat_engraver::try_music (Music *m)
 void
 Percent_repeat_engraver::process_music ()
 {
-  if (repeat_ && now_mom ().main_part_ == next_moment_.main_part_)
+  if (percent_event_ && now_mom ().main_part_ == start_mom_.main_part_)
     {
-      count_ ++; 
       if (repeat_sign_type_ == MEASURE)
        {
-         finished_percent_ = percent_;
-         finished_percent_counter_ = percent_counter_;
-         
-         typeset_perc ();
-         percent_ = make_spanner ("PercentRepeat", repeat_->self_scm ());
+         if (percent_)
+           typeset_perc ();
+         percent_ = make_spanner ("PercentRepeat", percent_event_->self_scm ());
 
          Grob *col = unsmob_grob (get_property ("currentCommandColumn"));
          percent_->set_bound (LEFT, col);
 
-         if (total_count_ > 2
-             && to_boolean (get_property ("countPercentRepeats")))
+         SCM count = percent_event_->get_property ("repeat-count");
+          if (count != SCM_EOL && to_boolean (get_property ("countPercentRepeats")))
            {
              percent_counter_
-               = make_spanner ("PercentRepeatCounter", repeat_->self_scm ());
+               = make_spanner ("PercentRepeatCounter", percent_event_->self_scm ());
 
-             SCM text = scm_number_to_string (scm_from_int (count_),
-                                              scm_from_int (10));
+             SCM text = scm_number_to_string (count, scm_from_int (10));
              percent_counter_->set_property ("text", text);
              percent_counter_->set_bound (LEFT, col);
              Side_position_interface::add_support (percent_counter_,
                                                    percent_);
              percent_counter_->set_parent (percent_, Y_AXIS);
-           }     
+           }
+         else
+           percent_counter_ = 0;
        }
       else if (repeat_sign_type_ == DOUBLE_MEASURE)
        {
-         double_percent_ = make_item ("DoublePercentRepeat", repeat_->self_scm ());
+         Item *double_percent = make_item ("DoublePercentRepeat", percent_event_->self_scm ());
 
-         if (total_count_ > 2
+         SCM count = percent_event_->get_property ("repeat-count");
+         if (count != SCM_EOL
              && to_boolean (get_property ("countPercentRepeats")))
            {
-             double_percent_counter_
-               = make_item ("DoublePercentRepeatCounter",
-                            repeat_->self_scm());
+             Item *double_percent_counter = make_item ("DoublePercentRepeatCounter",
+                                                       percent_event_->self_scm());
 
-             SCM text = scm_number_to_string (scm_from_int (count_),
+             SCM text = scm_number_to_string (count,
                                               scm_from_int (10));
-             double_percent_counter_->set_property ("text", text);
+             double_percent_counter->set_property ("text", text);
 
-             Side_position_interface::add_support (double_percent_counter_,
-                                                   double_percent_);
-             double_percent_counter_->set_parent (double_percent_, Y_AXIS);
-             double_percent_counter_->set_parent (double_percent_, X_AXIS);
+             Side_position_interface::add_support (double_percent_counter,
+                                                   double_percent);
+             double_percent_counter->set_parent (double_percent, Y_AXIS);
+             double_percent_counter->set_parent (double_percent, X_AXIS);
            }
          
          /* forbid breaks on a % line. Should forbid all breaks, really. */
          context ()->get_score_context ()->set_property ("forbidBreak", SCM_BOOL_T);
+
+         /* No more processing needed. */
+         repeat_sign_type_ = UNKNOWN;
        }
-      next_moment_ = next_moment_ + body_length_;
-      next_moment_.grace_part_ = Rational (0);
     }
 }
 
 void
 Percent_repeat_engraver::finalize ()
 {
-  typeset_perc ();
   if (percent_)
     {
-      repeat_->origin ()->warning (_ ("unterminated percent repeat"));
+      percent_event_->origin ()->warning (_ ("unterminated percent repeat"));
       percent_->suicide ();
       percent_counter_->suicide();
     }
@@ -211,21 +178,17 @@ Percent_repeat_engraver::finalize ()
 void
 Percent_repeat_engraver::typeset_perc ()
 {
-  if (finished_percent_)
+  if (percent_)
     {
       Grob *col = unsmob_grob (get_property ("currentCommandColumn"));
 
-      finished_percent_->set_bound (RIGHT, col);
-      finished_percent_ = 0;
+      percent_->set_bound (RIGHT, col);
+      percent_ = 0;
 
-      if (finished_percent_counter_)
-       finished_percent_counter_->set_bound (RIGHT, col);
-    
-      finished_percent_counter_ = 0;
+      if (percent_counter_)
+       percent_counter_->set_bound (RIGHT, col);
+      percent_counter_ = 0;
     }
-
-  double_percent_ = 0;
-  double_percent_counter_ = 0;
 }
 
 void
@@ -234,16 +197,8 @@ Percent_repeat_engraver::start_translation_timestep ()
   if (stop_mom_.main_part_ == now_mom ().main_part_)
     {
       if (percent_)
-       {
-         finished_percent_ = percent_;
-         finished_percent_counter_ = percent_counter_;
-
-         typeset_perc ();
-       }
-      repeat_ = 0;
-      percent_ = 0;
-      
-      percent_counter_ = 0;
+       typeset_perc ();
+      percent_event_ = 0;
       repeat_sign_type_ = UNKNOWN;
     }
 }
@@ -251,7 +206,6 @@ Percent_repeat_engraver::start_translation_timestep ()
 void
 Percent_repeat_engraver::stop_translation_timestep ()
 {
-  typeset_perc ();
 }
 
 ADD_TRANSLATOR (Percent_repeat_engraver,
@@ -259,18 +213,18 @@ ADD_TRANSLATOR (Percent_repeat_engraver,
                "Make whole bar and double bar repeats.",
                
                /* create */
-               "PercentRepeat "
                "DoublePercentRepeat "
-               "PercentRepeatCounter "
-               "DoublePercentRepeatCounter",
+               "DoublePercentRepeatCounter "
+               "PercentRepeat "
+               "PercentRepeatCounter ",
                
                /* accept */
-               "repeated-music",
+               "percent-event ",
 
                /* read */
-               "measureLength "
+               "countPercentRepeats "
                "currentCommandColumn "
-               "countPercentRepeats",
+               "measureLength ",
 
                /* write */
                "forbidBreak "
index 79fd496daaa5df0daca6ebce0cc8ed460ec3aae4..29021ee3964e7350a982f2b910b266ed37605281 100644 (file)
@@ -3,90 +3,61 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 2001--2006  Han-Wen Nienhuys <hanwen@xs4all.nl>
+  (c) 2001--2006  Han-Wen Nienhuys <hanwen@xs4all.nl>, Erik Sandberg <mandolaerik@gmail.com>
 */
 
 #include "percent-repeat-iterator.hh"
 
 #include "input.hh"
 #include "international.hh"
+#include "music.hh"
 #include "repeated-music.hh"
 
 IMPLEMENT_CTOR_CALLBACK (Percent_repeat_iterator);
 
 Percent_repeat_iterator::Percent_repeat_iterator ()
 {
-  child_iter_ = 0;
-}
-
-void
-Percent_repeat_iterator::do_quit ()
-{
-  if (child_iter_)
-    child_iter_->quit ();
-}
-
-bool
-Percent_repeat_iterator::ok () const
-{
-  return child_iter_;
+  child_list_ = SCM_EOL;
 }
 
 void
 Percent_repeat_iterator::construct_children ()
 {
+  /* TODO: Distinction between percent and slash */
   Music *mus = get_music ();
-  finish_mom_ = mus->get_length ();
-  child_iter_ = unsmob_iterator (get_iterator (Repeated_music::body (mus)));
-}
-
-void
-Percent_repeat_iterator::process (Moment m)
-{
-  if (!m.to_bool ())
-    {
-      Music_iterator *yeah = try_music (get_music ());
-      if (yeah)
-       set_context (yeah->get_outlet ());
-      else
-       get_music ()->origin ()->warning (_ ("no one to print a percent"));
-    }
-
-  if (child_iter_->ok ())
-    child_iter_->process (m);
-
-  if (finish_mom_ <= m)
-    {
-      child_iter_->quit ();
-      child_iter_ = 0;
-    }
-}
-
-Moment
-Percent_repeat_iterator::pending_moment ()const
-{
-  if (child_iter_->ok ())
-    return child_iter_->pending_moment ();
-  else
-    return finish_mom_;
-}
-
-Music_iterator *
-Percent_repeat_iterator::try_music_in_children (Music *m) const
-{
-  return child_iter_->try_music (m);
-}
-
-void
-Percent_repeat_iterator::derived_mark ()const
-{
-  if (child_iter_)
-    scm_gc_mark (child_iter_->self_scm ());
+  Music *child = Repeated_music::body (mus);
+  SCM length = child->get_length ().smobbed_copy ();
+  child_list_ = SCM_EOL;
+
+  int repeats = scm_to_int (mus->get_property ("repeat-count"));
+  for (int i = repeats; i > 1; i--)
+  {
+    Music *percent = make_music_by_name (ly_symbol2scm ("PercentEvent"));
+    percent->set_spot (*mus->origin ());
+    percent->set_property ("length", length);
+    if (repeats > 1)
+      percent->set_property ("repeat-count", scm_int2num (i - 1));
+    Music *percent_chord = make_music_by_name (ly_symbol2scm ("EventChord"));
+    percent_chord->set_spot (*mus->origin ());
+    percent_chord->set_property ("elements", scm_list_1 (percent->self_scm ()));
+    child_list_ = scm_cons (percent_chord->self_scm (), child_list_);
+    percent->unprotect ();
+    percent_chord->unprotect ();
+  }
+  child_list_ = scm_cons (child->self_scm (), child_list_);
+  
+  Sequential_iterator::construct_children ();
+}
+
+SCM
+Percent_repeat_iterator::get_music_list () const
+{
+  return child_list_;
 }
 
 void
-Percent_repeat_iterator::derived_substitute (Context *f, Context *t)
+Percent_repeat_iterator::derived_mark () const
 {
-  if (child_iter_)
-    child_iter_->substitute_outlet (f, t);
+  scm_gc_mark (child_list_);
+  Sequential_iterator::derived_mark ();
 }
index 9949e9f227ca62bb7d2c6d057be811639c5d5be7..aa5b52c405ccc72ec952aa9fed23a580711b59fd 100644 (file)
@@ -3,7 +3,7 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>, Erik Sandberg <mandolaerik@gmail.com>
 */
 
 #include "repeated-music.hh"
 
 /**
    This acknowledges repeated music with "percent" style.  It typesets
-   a % sign.
-
-   TODO:
-
-   - BEAT case: Create items for single beat repeats, i.e. c4 / / /
-
-   - DOUBLE_MEASURE case: attach a % to an appropriate barline.
+   a slash sign.
 */
 class Slash_repeat_engraver : public Engraver
 {
 public:
   TRANSLATOR_DECLARATIONS (Slash_repeat_engraver);
 protected:
-  Music *repeat_;
-
-  /// moment (global time) where beam started.
-  Moment start_mom_;
-  Moment stop_mom_;
-
-  /// location  within measure where beam started.
-  Moment beam_start_location_;
-  Moment next_moment_;
-  Moment body_length_;
-
-  Item *beat_slash_;
-  Item *double_percent_;
+  Music *slash_;
 protected:
   virtual bool try_music (Music *);
-  void start_translation_timestep ();
   void process_music ();
 };
 
 Slash_repeat_engraver::Slash_repeat_engraver ()
 {
-  repeat_ = 0;
-  beat_slash_ = 0;
+  slash_ = 0;
 }
 
 bool
 Slash_repeat_engraver::try_music (Music *m)
 {
-  if (m->is_mus_type ("repeated-music")
-      && !repeat_
-      && m->get_property ("iterator-ctor")
-      == Percent_repeat_iterator::constructor_proc)
+  /*todo: separate events for percent and slash */
+  if (m->is_mus_type ("percent-event"))
     {
-      body_length_ = Repeated_music::body_get_length (m);
-      int count = Repeated_music::repeat_count (m);
-
-      Moment now = now_mom ();
-      start_mom_ = now;
-      stop_mom_ = start_mom_ + Moment (count) * body_length_;
-      next_moment_ = start_mom_ + body_length_;
-
       Moment meas_length
-       = robust_scm2moment (get_property ("measureLength"), Moment (0));
-      if (body_length_ < meas_length)
-       repeat_ = m;
+        = robust_scm2moment (get_property ("measureLength"), Moment (0));
+
+      if (m->get_length () < meas_length)
+       slash_ = m;
       else
        return false;
 
-      Global_context *global = get_global_context ();
-      for (int i = 0; i < count; i++)
-       global->add_moment_to_process (next_moment_ + Moment (i) * body_length_);
-
       return true;
     }
 
@@ -92,28 +59,18 @@ Slash_repeat_engraver::try_music (Music *m)
 void
 Slash_repeat_engraver::process_music ()
 {
-  if (repeat_ && now_mom () == next_moment_)
+  if (slash_)
     {
-      beat_slash_ = make_item ("RepeatSlash", repeat_->self_scm ());
-      next_moment_ = next_moment_ + body_length_;
-
-      get_global_context ()->add_moment_to_process (next_moment_);
+      make_item ("RepeatSlash", slash_->self_scm ());
+      slash_ = 0;
     }
 }
 
-void
-Slash_repeat_engraver::start_translation_timestep ()
-{
-  if (stop_mom_ == now_mom ())
-    repeat_ = 0;
-  beat_slash_ = 0;
-}
-
 #include "translator.icc"
 
 ADD_TRANSLATOR (Slash_repeat_engraver,
                /* doc */ "Make beat repeats.",
                /* create */ "RepeatSlash",
-               /* accept */ "repeated-music",
+               /* accept */ "percent-event",
                /* read */ "measureLength",
                /* write */ "");
index e1385ce2cc3f93bf86812b3ab772ad4d81df1a6a..db4c616274da4b09ec97e13ccfe5094d93a00c2c 100644 (file)
@@ -3,7 +3,8 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  (c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>,
+                 Erik Sandberg <mandolaerik@gmail.com>
 */
 
 #include "time-scaled-music-iterator.hh"
 #include "context.hh"
 #include "input.hh"
 #include "international.hh"
+#include "music.hh"
+
+Time_scaled_music_iterator::Time_scaled_music_iterator ()
+{
+  child_list_ = SCM_EOL;
+}
+
+void
+Time_scaled_music_iterator::construct_children ()
+{
+  Music *mus = get_music ();
+  Input *origin = mus->origin ();
+  Music *child = unsmob_music (mus->get_property ("element"));
+
+  /* Create tuplet start/stop span events before/after the music */
+  SCM tuplet_symbol = ly_symbol2scm ("TupletEvent");
+  SCM start_event = scm_call_2 (ly_lily_module_constant ("make-span-event"), tuplet_symbol, scm_from_int (START));
+  Music *start = unsmob_music (start_event);
+  start->set_spot (*origin);
+  start->set_property ("numerator", mus->get_property ("numerator"));
+  start->set_property ("denominator", mus->get_property ("denominator"));
+  start_event = scm_call_1 (ly_lily_module_constant ("make-event-chord"), scm_list_1 (start_event));
+  unsmob_music (start_event)->set_spot (*origin);
+
+  SCM stop_event = scm_call_2 (ly_lily_module_constant ("make-span-event"), tuplet_symbol, scm_from_int (STOP));
+  unsmob_music (stop_event)->set_spot (*origin);
+  stop_event = scm_call_1 (ly_lily_module_constant ("make-event-chord"), scm_list_1 (stop_event));
+  unsmob_music (stop_event)->set_spot (*origin);
+
+  child_list_ = scm_list_3 (start_event, child->self_scm (), stop_event);
+
+  Sequential_iterator::construct_children ();
+}
+
+SCM
+Time_scaled_music_iterator::get_music_list () const
+{
+  return child_list_;
+}
 
 void
-Time_scaled_music_iterator::process (Moment m)
+Time_scaled_music_iterator::derived_mark () const
 {
-  if (!m.to_bool ())
-    {
-      Music_iterator *yeah = try_music (get_music ());
-      if (yeah)
-       set_context (yeah->get_outlet ());
-      else
-       get_music ()->origin ()->warning (_ ("no one to print a tuplet start bracket"));
-    }
-
-  Music_wrapper_iterator::process (m);
+  scm_gc_mark (child_list_);
+  Sequential_iterator::derived_mark ();
 }
 
 IMPLEMENT_CTOR_CALLBACK (Time_scaled_music_iterator);
index 0d0966899cf138f1348cf42684a83cf5f7d04287..ac38db14e33218ef41de12137135051240056933 100644 (file)
@@ -17,9 +17,6 @@
 struct Tuplet_description
 {
   Music *music_;
-  Rational stop_;
-  Rational span_stop_;
-  Rational length_;
   Spanner *bracket_;
   Spanner *number_;
   Tuplet_description ()
@@ -28,10 +25,6 @@ struct Tuplet_description
     bracket_ = 0;
     number_ = 0;
   }
-  static int compare (Tuplet_description const &a, Tuplet_description const &b)
-  {
-    return ::compare (a.length_, b.length_);
-  }
 };
 
 class Tuplet_engraver : public Engraver
@@ -41,6 +34,7 @@ public:
 
 protected:
   vector<Tuplet_description> tuplets_;
+  vector<Tuplet_description> stopped_tuplets_;
   vector<Spanner*> last_tuplets_;
   DECLARE_ACKNOWLEDGER (note_column);
   virtual bool try_music (Music *r);
@@ -52,23 +46,20 @@ protected:
 bool
 Tuplet_engraver::try_music (Music *music)
 {
-  if (music->is_mus_type ("time-scaled-music"))
+  if (music->is_mus_type ("tuplet-spanner-event"))
     {
-      Music *el = unsmob_music (music->get_property ("element"));
-      if (el && !el->is_mus_type ("event-chord"))
+      Direction dir = to_dir (music->get_property ("span-direction"));
+      if (dir == START)
        {
          Tuplet_description d;
          d.music_ = music;
-         d.length_ = music->get_length ().main_part_;
-         d.stop_ = now_mom ().main_part_ + d.length_;
-         d.span_stop_ = d.stop_;
-
-         SCM s = get_property ("tupletSpannerDuration");
-         if (unsmob_moment (s))
-           d.span_stop_ = min (d.span_stop_, (now_mom () + *unsmob_moment (s)).main_part_);
-
          tuplets_.push_back (d);
        }
+      if (dir == STOP)
+       {
+         stopped_tuplets_.push_back (tuplets_.back ());
+         tuplets_.pop_back ();
+       }
       return true;
     }
   return false;
@@ -77,10 +68,36 @@ Tuplet_engraver::try_music (Music *music)
 void
 Tuplet_engraver::process_music ()
 {
+  for (vsize i = 0; i < stopped_tuplets_.size (); i++)
+    {
+      bool full_length = to_boolean (get_property ("tupletFullLength"));
+      if (stopped_tuplets_[i].bracket_)
+       {
+         if (full_length)
+           {
+             Item *col = unsmob_item (get_property ("currentMusicalColumn"));
+             
+             stopped_tuplets_[i].bracket_->set_bound (RIGHT, col);
+             stopped_tuplets_[i].number_->set_bound (RIGHT, col);
+           }
+         else if (!stopped_tuplets_[i].bracket_->get_bound (RIGHT))
+           {
+             stopped_tuplets_[i].bracket_->set_bound (RIGHT,
+                                                      stopped_tuplets_[i].bracket_->get_bound (LEFT));
+             stopped_tuplets_[i].number_->set_bound (RIGHT,
+                                                     stopped_tuplets_[i].bracket_->get_bound (LEFT));
+           }
+         // todo: scrap last_tuplets_, use stopped_tuplets_ only.
+         // clear stopped_tuplets_ at start_translation_timestep
+         last_tuplets_.push_back (tuplets_[i].bracket_);
+         last_tuplets_.push_back (tuplets_[i].number_);
+       }
+    }
+  stopped_tuplets_.clear ();
+
   if (!tuplets_.size ())
     return;
 
-  vector_sort (tuplets_, Tuplet_description::compare);
   for (vsize i = 0; i < tuplets_.size (); i++)
     {
       if (tuplets_[i].bracket_)
@@ -123,51 +140,7 @@ Tuplet_engraver::acknowledge_note_column (Grob_info inf)
 void
 Tuplet_engraver::start_translation_timestep ()
 {
-  Moment now = now_mom ();
-
   last_tuplets_.clear ();
-  if (tuplets_.empty ())
-    return;
-
-  Moment tsdmom = robust_scm2moment (get_property ("tupletSpannerDuration"), Moment (0));
-  bool full_length = to_boolean (get_property ("tupletFullLength"));
-
-  for (vsize i = tuplets_.size (); i--;)
-    {
-      Rational tsd = tsdmom.main_part_;
-
-      if (now.main_part_ >= tuplets_[i].span_stop_)
-       {
-         if (tuplets_[i].bracket_)
-           {
-             if (full_length)
-               {
-                 Item *col = unsmob_item (get_property ("currentMusicalColumn"));
-
-                 tuplets_[i].bracket_->set_bound (RIGHT, col);
-                 tuplets_[i].number_->set_bound (RIGHT, col);
-               }
-             else if (!tuplets_[i].bracket_->get_bound (RIGHT))
-               {
-                 tuplets_[i].bracket_->set_bound (RIGHT,
-                                                  tuplets_[i].bracket_->get_bound (LEFT));
-                 tuplets_[i].number_->set_bound (RIGHT,
-                                                 tuplets_[i].bracket_->get_bound (LEFT));
-               }
-             last_tuplets_.push_back (tuplets_[i].bracket_);
-             last_tuplets_.push_back (tuplets_[i].number_);
-             
-             tuplets_[i].bracket_ = 0;
-             tuplets_[i].number_ = 0;
-           }
-
-         if (tsd)
-           tuplets_[i].span_stop_ += tsd;
-       }
-
-      if (now.main_part_ >= tuplets_[i].stop_)
-       tuplets_.erase (tuplets_.begin () + i);
-    }
 }
 
 void
@@ -189,8 +162,8 @@ Tuplet_engraver::Tuplet_engraver ()
 
 ADD_ACKNOWLEDGER (Tuplet_engraver, note_column);
 ADD_TRANSLATOR (Tuplet_engraver,
-               /* doc */ "Catch Time_scaled_music and generate appropriate bracket  ",
-               /* create */ "TupletBracket TupletNumber",
-               /* accept */ "time-scaled-music",
-               /* read */ "tupletNumberFormatFunction tupletSpannerDuration tupletFullLength",
+               /* doc */ "Catch TupletSpannerEvent and generate appropriate bracket  ",
+               /* create */ "TupletBracket TupletNumber ",
+               /* accept */ "tuplet-spanner-event",
+               /* read */ "tupletNumberFormatFunction tupletSpannerDuration tupletFullLength ",
                /* write */ "");
index 1f64defa4a533b066acc1ce9ae25c021584c2367..fefc68e7f3ef460887c5cb7aa21e2fa0e083ae32 100644 (file)
@@ -22,7 +22,7 @@
 
 /*
   Create Volta spanners, by reading repeatCommands  property, usually
-  set by Unfolded_repeat_iterator.
+  set by Volta_repeat_iterator.
 */
 class Volta_engraver : public Engraver
 {
index 2192dc33663e77170b606c63514c40559e7107c5..41d4609d493d1a0efef4c55a820b11a971d5b36c 100644 (file)
@@ -397,7 +397,13 @@ Syntax: @code{\\property @var{context}.@var{prop} = @var{scheme-val}}.")
        (types . (layout-instruction general-music))
        (iterator-ctor . ,ly:property-unset-iterator::constructor)
        ))
-    
+
+    (PercentEvent
+     . (
+       (description .  "Used internally to signal percent repeats.")
+       (types . (general-music event percent-event))
+       ))
+
     (PesOrFlexaEvent
      . (
        (description .  "Within a ligature, mark the previous and the
@@ -534,6 +540,16 @@ Syntax NOTE(        and NOTE) ")
        (types . (general-music span-event event trill-span-event))
        ))
     
+    (TransposedMusic
+     . (
+       (description .  "Music that has been transposed.")
+       (iterator-ctor . ,ly:music-wrapper-iterator::constructor)
+       (start-callback . ,ly:music-wrapper::start-callback)
+       (length-callback . ,ly:music-wrapper::length-callback)
+       (to-relative-callback . ,ly:relative-octave-music::no-relative-callback)
+       (types . (music-wrapper-music general-music transposed-music))
+       ))
+
     (TimeScaledMusic
      . (
        (description .  "Multiply durations, as in tuplets. 
@@ -546,16 +562,12 @@ Syntax @code{\\times @var{fraction} @var{music}}, e.g.
        (iterator-ctor . ,ly:time-scaled-music-iterator::constructor)
        (types . (time-scaled-music music-wrapper-music general-music))
        ))
-    
-    (TransposedMusic
+
+    (TupletEvent
      . (
-       (description .  "Music that has been transposed.")
-       (iterator-ctor . ,ly:music-wrapper-iterator::constructor)
-       (start-callback . ,ly:music-wrapper::start-callback)
-       (length-callback . ,ly:music-wrapper::length-callback)
-       (to-relative-callback . ,ly:relative-octave-music::no-relative-callback)
-       (types . (music-wrapper-music general-music transposed-music))
-       ))
+       (description .  "Used internally to signal where tuplet brackets start and stop.")
+       (types . (tuplet-spanner-event span-event event general-music))
+       ))
 
     (UnrelativableMusic
      . (
index 3aa4de0dac1286005c9f1d6c095af36c9812498c..bc8dad2e448c5d5517725b485e196d8976b13a1d 100644 (file)
@@ -202,6 +202,36 @@ Returns `obj'.
   (music-map (lambda (x) (shift-one-duration-log x shift dot))
             music))
 
+(define-public (make-repeat name times main alts)
+  "create a repeat music expression, with all properties initialized properly"
+  (let ((talts (if (< times (length alts))
+                  (begin
+                    (ly:warning (_ "More alternatives than repeats. Junking excess alternatives"))
+                    (take alts times))
+                  alts))
+       (r (make-repeated-music name)))
+    (set! (ly:music-property r 'element) main)
+    (set! (ly:music-property r 'repeat-count) (max times 1))
+    (set! (ly:music-property r 'elements) talts)
+    (if (equal? name "tremolo")
+       (let* ((dot? (zero? (modulo times 3)))
+              (dots (if dot? 1 0))
+              (mult (if dot?
+                        (quotient (* times 2) 3)
+                        times))
+              (shift (- (ly:intlog2 mult))))
+         
+         (if (memq 'sequential-music (ly:music-property main 'types))
+             ;; \repeat "tremolo" { c4 d4 }
+             (let ((children (length (ly:music-property main 'elements))))
+               (if (not (= children 2))
+                   (ly:warning (_ "expecting 2 elements for chord tremolo, found ~a") children))
+               (ly:music-compress r (ly:make-moment 1 children))
+               (shift-duration-log r (1- shift) dots))
+             ;; \repeat "tremolo" c4
+             (shift-duration-log r shift dots)))
+       r)))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; clusters.