]> git.donarmstrong.com Git - lilypond.git/commitdiff
* scm/output-lib.scm (grace-spacing::calc-shortest-duration): new function.
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Fri, 21 Jul 2006 11:44:58 +0000 (11:44 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Fri, 21 Jul 2006 11:44:58 +0000 (11:44 +0000)
* scm/define-grob-properties.scm (all-user-grob-properties):
remove grace-space-factor.

* scm/define-grob-interfaces.scm (grace-spacing-interface): add grace-spacing-interface
(spacing-options-interface): add.

* ly/engraver-init.ly (AncientRemoveEmptyStaffContext): add Grace_spacing_engraver

* lily/spacing-options.cc (get_duration_space): move function from spacing-basic.cc

* lily/spacing-basic.cc (note_spacing): do init_from_grob on
GraceSpacing object.

* lily/note-spacing.cc: fix prop list formatting

* lily/beaming-pattern.cc (de_grace): new function. Sensible
beaming for grace notes too.

* input/regression/spacing-grace.ly: update.

* lily/grace-spacing-engraver.cc: new file.

* lily/spacing-spanner.cc: add strict-grace-spacing.

18 files changed:
ChangeLog
VERSION
input/regression/spacing-grace.ly
lily/beaming-pattern.cc
lily/grace-spacing-engraver.cc [new file with mode: 0644]
lily/include/beaming-pattern.hh
lily/include/spacing-spanner.hh
lily/note-spacing.cc
lily/paper-column.cc
lily/spacing-basic.cc
lily/spacing-loose-columns.cc
lily/spacing-options.cc
lily/spacing-spanner.cc
ly/engraver-init.ly
scm/define-grob-interfaces.scm
scm/define-grob-properties.scm
scm/define-grobs.scm
scm/output-lib.scm

index c2cd818c184094ba958c05b99711da46f4e2a10d..30708b6964cd08f85082c8d43d9a57e16c86d752 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2006-07-21  Han-Wen Nienhuys  <hanwen@lilypond.org>
+
+       * scm/output-lib.scm (grace-spacing::calc-shortest-duration): new function.
+
+       * scm/define-grob-properties.scm (all-user-grob-properties):
+       remove grace-space-factor.
+
+       * scm/define-grob-interfaces.scm (grace-spacing-interface): add grace-spacing-interface
+       (spacing-options-interface): add. 
+
+       * ly/engraver-init.ly (AncientRemoveEmptyStaffContext): add Grace_spacing_engraver
+
+       * lily/spacing-options.cc (get_duration_space): move function from spacing-basic.cc
+
+       * lily/spacing-basic.cc (note_spacing): do init_from_grob on
+       GraceSpacing object.
+
+       * lily/note-spacing.cc: fix prop list formatting
+
+       * lily/beaming-pattern.cc (de_grace): new function. Sensible
+       beaming for grace notes too.
+
+       * input/regression/spacing-grace.ly: update.
+
+       * lily/grace-spacing-engraver.cc: new file.
+
+       * lily/spacing-spanner.cc: add strict-grace-spacing.
+
 2006-07-20  Graham Percival  <gpermus@gmail.com>
 
        * lily/parser.yy: compile fix.
diff --git a/VERSION b/VERSION
index 76e2b35efeb37991a4c33c8767def6011baf281d..7d754a77ed2e7aac64d5bdab72785265d1312add 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1,6 +1,6 @@
 PACKAGE_NAME=LilyPond
 MAJOR_VERSION=2
 MINOR_VERSION=9
-PATCH_LEVEL=12
+PATCH_LEVEL=13
 MY_PATCH_LEVEL=
 
index aedc10df7d4b4c94ee01f0ee3f92c49fad36db8a..c4a1c466f8a63d5eab482afa177bd7ebffd778e1 100644 (file)
@@ -1,14 +1,27 @@
-
-\version "2.7.39"
-\header {
-  texidoc = "Grace note spacing.  "
+\header
+{
+  texidoc = "Grace note runs have their own spacing variables in
+  @code{Score.GraceSpacing}. So differing grace note lengths inside a
+  run are spaced accordingly. "
 }
 
-\layout { ragged-right = ##t}
-
-
-\context Voice \relative c'' { \grace {  c16[ d] } c4 }
-
-
-
-
+\version "2.9.13"
+
+\paper {  ragged-right = ##t }
+
+\relative c''
+{
+  c4
+  \grace { c16  }
+  c
+  \grace { c16  }
+  d
+  \grace { c16[ d e f] }
+  c
+  \grace { c8[ c16 d c8]  }
+  c
+  \override Score.GraceSpacing #'spacing-increment = #2.0
+
+  \grace { c4 c16 d16  }
+  c
+} 
index 87ff00dc63cb1d5b7cc5732201bac10f6a664d8c..8966657e4813f37b1e55343cf9efcb64ef0fd29f 100644 (file)
@@ -25,6 +25,17 @@ Beam_rhythmic_element::Beam_rhythmic_element (Moment m, int i)
 }
 
 
+void
+Beam_rhythmic_element::de_grace ()
+{
+  if (start_moment_.grace_part_)
+    {
+      start_moment_.main_part_ = 
+       start_moment_.grace_part_; 
+      start_moment_.grace_part_ = 0;
+    }
+}
+
 int
 count_factor_twos (int x)
 {
@@ -96,11 +107,23 @@ Beaming_pattern::beam_extend_count (Direction d) const
   return min (thisbeam.beam_count_drul_[-d], next.beam_count_drul_[d]);
 }
 
+void
+Beaming_pattern::de_grace ()
+{
+  for (vsize i = 0; i < infos_.size (); i ++)
+    {
+      infos_[i].de_grace ();
+    }
+}
+
 void
 Beaming_pattern::beamify (Context *context)
 {
   if (infos_.size () <= 1)
     return;
+
+  if (infos_[0].start_moment_.grace_part_)
+    de_grace ();
   
   bool subdivide_beams = to_boolean (context->get_property ("subdivideBeams"));
   Moment beat_length = robust_scm2moment (context->get_property ("beatLength"), Moment (1, 4));
diff --git a/lily/grace-spacing-engraver.cc b/lily/grace-spacing-engraver.cc
new file mode 100644 (file)
index 0000000..b784358
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+  grace-spacing-engraver.cc -- implement Grace_spacing_engraver
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 2006 Han-Wen <hanwen@lilypond.org>
+
+*/
+
+#include "engraver.hh"
+#include "spanner.hh"
+#include "pointer-group-interface.hh"
+
+#include "translator.icc"
+
+class Grace_spacing_engraver : public Engraver
+{
+  TRANSLATOR_DECLARATIONS (Grace_spacing_engraver);
+
+protected:
+
+  Moment last_moment_;
+  Spanner *grace_spacing_;
+  
+  void process_music ();
+  void stop_translation_timestep ();
+};
+
+
+Grace_spacing_engraver::Grace_spacing_engraver ()
+{
+  grace_spacing_ = 0;
+}
+
+void
+Grace_spacing_engraver::process_music ()
+{
+  Moment now = now_mom ();
+  if (!last_moment_.grace_part_ and now.grace_part_)
+    {
+      grace_spacing_ = make_spanner ("GraceSpacing", SCM_EOL);
+    }
+
+
+  if (grace_spacing_ && (now.grace_part_ || last_moment_.grace_part_))
+    {
+      Grob *column = unsmob_grob (get_property ("currentMusicalColumn"));
+      Pointer_group_interface::add_grob (grace_spacing_,
+                                        ly_symbol2scm ("columns"),
+                                        column);
+
+      column->set_object ("grace-spacing", grace_spacing_->self_scm ());
+    }
+}
+
+void
+Grace_spacing_engraver::stop_translation_timestep ()
+{
+  last_moment_ = now_mom ();
+
+  if (!last_moment_.grace_part_)
+    grace_spacing_ = 0;
+}
+
+
+ADD_TRANSLATOR (Grace_spacing_engraver,
+               "Bookkeeping of shortest starting and playing notes in grace note runs.",
+
+               /* create */
+               "GraceSpacing ",
+               
+               /* accept */
+               "",
+
+               /* read */
+               "currentMusicalColumn ",
+               
+               /* write */ "");
index 603321766881cd3ad0a2e7e867097c844f58b40d..5e0c7c30ecd98004b776fc7fc40603772dae6d67 100644 (file)
@@ -26,6 +26,7 @@ struct Beam_rhythmic_element
   Beam_rhythmic_element ();
 
   int count (Direction d);
+  void de_grace ();
 };
 
 /*
@@ -38,6 +39,7 @@ public:
   Beaming_pattern ();
   
   void beamify (Context*);
+  void de_grace ();
   void add_stem (Moment d, int beams);
   int beamlet_count (int idx, Direction d) const;
   
index d2259533c824a12452720dfab851ec920d158747..f39ea98bc30726fd2042cd670c1bf9e2f65f5bdb 100644 (file)
@@ -26,7 +26,7 @@ struct Spacing_options
 
   Spacing_options();
   void init_from_grob (Grob *me);
-  Real get_duration_space (Moment d, bool *) const;
+  Real get_duration_space (Rational d, bool *) const;
 };
 
 /*
index 619cda9b4eabcc50800a113a9841cbcb6534ce04..2700c12835a990362644667ddf8da5df43c903f2 100644 (file)
@@ -457,5 +457,13 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn,
 
 ADD_INTERFACE (Note_spacing, "note-spacing-interface",
               "This object calculates spacing wishes for individual voices.",
-              "left-items right-items stem-spacing-correction same-direction-correction knee-spacing-correction");
+
+              
+              "knee-spacing-correction "
+              "left-items "
+              "right-items "
+              "same-direction-correction "
+              "stem-spacing-correction "
+
+              );
 
index fccdba6e7f694d4549f0008438126e17fbc6ba0f..4da6ff3ef9351419387914458f6f7cc879ca0296 100644 (file)
@@ -206,6 +206,7 @@ ADD_INTERFACE (Paper_column,
               /* properties */
               "between-cols "
               "bounded-by-me "
+              "grace-spacing " 
               "line-break-system-details "
               "line-break-penalty "
               "line-break-permission "
index 86dd575d1ec9ea15c53d3b84473a1b748acc840a..4a11d75b48bf90f15af2d4662b3a47ff3927bb8c 100644 (file)
@@ -9,7 +9,6 @@
 #include "spacing-spanner.hh"
 #include "moment.hh"
 #include "paper-column.hh"
-#include "misc.hh"
 #include "warn.hh"
 
 /*
   adding subtle adjustments to that. This file does the simple-minded
   spacing routines.
 */
-
-/*
-  Get the measure wide ant for arithmetic spacing.
-*/
-Real
-Spacing_options::get_duration_space (Moment d,
-                                    bool *expand_only) const
-{
-  Real k = shortest_duration_space_;
-
-  if (d < global_shortest_)
-    {
-      /*
-       We don't space really short notes using the log of the
-       duration, since it would disproportionally stretches the long
-       notes in a piece. In stead, we use geometric spacing with constant 0.5
-       (i.e. linear.)
-
-       This should probably be tunable, to use other base numbers.
-
-       In Mozart hrn3 by EB., we have 8th note = 3.9 mm (total), 16th note =
-       3.6 mm (total).  head-width = 2.4, so we 1.2mm for 16th, 1.5
-       mm for 8th. (white space), suggesting that we use
-
-       (1.2 / 1.5)^{-log2(duration ratio)}
-
-
-      */
-      Rational ratio = d.main_part_ / global_shortest_;
-
-      return ((k - 1) + double (ratio)) * increment_;
-    }
-  else
-    {
-      /*
-       John S. Gourlay. ``Spacing a Line of Music, '' Technical
-       Report OSU-CISRC-10/87-TR35, Department of Computer and
-       Information Science, The Ohio State University, 1987.
-      */
-      Real log = log_2 (global_shortest_);
-      k -= log;
-      Rational compdur = d.main_part_ + d.grace_part_ / Rational (3);
-      *expand_only = false;
-
-      return (log_2 (compdur) + k) * increment_;
-    }
-}
-
 /*
   The one-size-fits all spacing. It doesn't take into account
   different spacing wishes from one to the next column.
@@ -119,7 +70,7 @@ Spacing_spanner::standard_breakable_column_spacing (Grob *me, Item *l, Item *r,
       else
        {
          bool dummy;
-         *space = *fixed + options->get_duration_space (dt, &dummy);
+         *space = *fixed + options->get_duration_space (dt.main_part_, &dummy);
        }
     }
 }
@@ -129,6 +80,8 @@ Spacing_spanner::note_spacing (Grob *me, Grob *lc, Grob *rc,
                               Spacing_options const *options,
                               bool *expand_only)
 {
+  (void) me;
+  
   Moment shortest_playing_len = 0;
   SCM s = lc->get_property ("shortest-playing-duration");
 
@@ -169,7 +122,7 @@ Spacing_spanner::note_spacing (Grob *me, Grob *lc, Grob *rc,
   Real dist = 0.0;
   if (delta_t.main_part_ && !lwhen.grace_part_)
     {
-      dist = options->get_duration_space (shortest_playing_len,
+      dist = options->get_duration_space (shortest_playing_len.main_part_,
                                          expand_only);
       dist *= double (delta_t.main_part_ / shortest_playing_len.main_part_);
     }
@@ -180,15 +133,20 @@ Spacing_spanner::note_spacing (Grob *me, Grob *lc, Grob *rc,
        available (namely the space for the global shortest note), and
        multiply that by grace-space-factor
       */
-      dist = options->get_duration_space (options->global_shortest_, expand_only);
+      dist = options->get_duration_space (options->global_shortest_, expand_only) / 2.0;
+      Grob *grace_spacing = unsmob_grob (lc->get_object ("grace-spacing"));
+      if (grace_spacing)
+       {
+         Spacing_options grace_opts;
+         grace_opts.init_from_grob (grace_spacing);
 
-      Real grace_fact
-       = robust_scm2double (me->get_property ("grace-space-factor"), 1);
 
-      dist *= grace_fact;
+         bool bla;
+         dist = grace_opts.get_duration_space (delta_t.grace_part_, &bla);
+       }
+      
     }
 
   return dist;
 }
 
-/****************************************************************/
index cc73fc138e01bc75d849825a82ce15b528aa4796..fdcc77f1b2797e34697fe892a541ca4974edbb96 100644 (file)
@@ -97,7 +97,8 @@ set_loose_columns (System *which, Column_x_positions const *posns)
 
                  Moment dt = Paper_column::when_mom (right) - Paper_column::when_mom (col);
                  bool expand = false;
-                 space = options.get_duration_space (dt, &expand);
+
+                 space = options.get_duration_space (dt.main_part_, &expand);
                  Note_spacing::get_spacing (spacing, right, space, options.increment_,
                                             &space, &fixed);
                }
index 917980f5f81baab78ab0840fd81c72789eae5f7c..916408aa7335af66d84c2d52ee15046a251b6ff9 100644 (file)
@@ -9,6 +9,8 @@
 
 #include "spacing-spanner.hh"
 #include "grob.hh"
+#include "misc.hh"
+#include "moment.hh"
 
 void
 Spacing_options::init_from_grob (Grob *me)
@@ -22,6 +24,16 @@ Spacing_options::init_from_grob (Grob *me)
   float_grace_columns_
     = to_boolean (me->get_property ("strict-grace-spacing"));
   shortest_duration_space_ = robust_scm2double (me->get_property ("shortest-duration-space"), 1);
+
+
+  Moment shortest_dur = robust_scm2moment (me->get_property ("common-shortest-duration"),
+                                          Moment (Rational (1,8), Rational (1,16)));
+
+  if (shortest_dur.main_part_)
+    global_shortest_ = shortest_dur.main_part_;
+  else
+    global_shortest_ = shortest_dur.grace_part_;
+
 }
 
 Spacing_options::Spacing_options ()
@@ -36,3 +48,52 @@ Spacing_options::Spacing_options ()
 
   global_shortest_ = Rational (1, 8);
 }
+
+
+
+/*
+  Get the measure wide ant for arithmetic spacing.
+*/
+Real
+Spacing_options::get_duration_space (Rational d,
+                                    bool *expand_only) const
+{
+  Real k = shortest_duration_space_;
+
+  if (d < global_shortest_)
+    {
+      /*
+       We don't space really short notes using the log of the
+       duration, since it would disproportionally stretches the long
+       notes in a piece. In stead, we use geometric spacing with constant 0.5
+       (i.e. linear.)
+
+       This should probably be tunable, to use other base numbers.
+
+       In Mozart hrn3 by EB., we have 8th note = 3.9 mm (total), 16th note =
+       3.6 mm (total).  head-width = 2.4, so we 1.2mm for 16th, 1.5
+       mm for 8th. (white space), suggesting that we use
+
+       (1.2 / 1.5)^{-log2(duration ratio)}
+
+
+      */
+      Rational ratio = d / global_shortest_;
+
+      return ((k - 1) + double (ratio)) * increment_;
+    }
+  else
+    {
+      /*
+       John S. Gourlay. ``Spacing a Line of Music, '' Technical
+       Report OSU-CISRC-10/87-TR35, Department of Computer and
+       Information Science, The Ohio State University, 1987.
+      */
+      Real log = log_2 (global_shortest_);
+      k -= log;
+      *expand_only = false;
+
+      return (log_2 (d) + k) * increment_;
+    }
+}
+
index 04ad54765e56754b9fbc0ed52a021ce634c5dcea..b21ce3d3ab7feac013832be6d105b7758ee98550 100644 (file)
@@ -54,8 +54,6 @@ Spacing_spanner::set_springs (SCM smob)
 
   Spacing_options options;
   options.init_from_grob (me);
-  options.global_shortest_ = robust_scm2moment (me->get_property ("common-shortest-duration"),
-                                               Moment (Rational (1,8))).main_part_;
 
   prune_loose_columns (me, &all, &options);
   set_implicit_neighbor_columns (all);
@@ -266,7 +264,6 @@ Spacing_spanner::musical_column_spacing (Grob *me,
          if (!lext.is_empty ())
            compound_note_space += -lext[LEFT];
        }
-      
     }
   else
     {
@@ -500,10 +497,10 @@ ADD_INTERFACE (Spacing_spanner, "spacing-spanner-interface",
               "average-spacing-wishes "
               "base-shortest-duration "
               "common-shortest-duration "
-              "grace-space-factor "
               "packed-spacing "
               "shortest-duration-space "
               "spacing-increment "
+              "strict-grace-spacing "
               "strict-note-spacing "
               "uniform-stretching "
               
@@ -512,5 +509,6 @@ ADD_INTERFACE (Spacing_spanner, "spacing-spanner-interface",
 ADD_INTERFACE (Spacing_interface, "spacing-interface",
               "Something to do with line breaking and spacing. "
               "Kill this one after determining line breaks.",
+              
               "");
 
index efc14e9a352619560443fb837df60a44e968e6d1..7798bc31458bc473bd4a5fae2ff7f27c386304c4 100644 (file)
@@ -459,6 +459,7 @@ AncientRemoveEmptyStaffContext = \context {
   \consists "Metronome_mark_engraver"  
   \consists "Break_align_engraver"
   \consists "Spacing_engraver"
+  \consists "Grace_spacing_engraver"
   \consists "Vertical_align_engraver"
   \consists "Stanza_number_align_engraver"
   \consists "Bar_number_engraver"
index 2251fb47809b3a289f45841ababd83c125f93876..6ab1b55cce9efdbaa82182e06b518ba8369a1b64 100644 (file)
  "A fingering instruction"
  '())
 
-(ly:add-interface
- 'string-number-interface
- "A string number instruction"
- '())
-
 (ly:add-interface
  'fret-diagram-interface
  "A fret diagram"
  '(align-dir barre-type dot-color dot-radius finger-code fret-count
   label-dir number-type size string-count thickness))
 
+(ly:add-interface
+ 'grace-spacing-interface
+ "Keep track of durations in a run of grace notes."
+ '(columns common-shortest-duration))
+
 (ly:add-interface
  'ligature-interface
  "A ligature"
 are interesting enough to maintain a hara-kiri staff."
  '())
 
+
+(ly:add-interface
+ 'spacing-options-interface
+ "Supports setting of spacing variables"
+ '(spacing-increment shortest-duration-space))
+
 (ly:add-interface
  'stanza-number-interface
  "A stanza number, to be put in from of a lyrics line"
  '())
 
+(ly:add-interface
+ 'string-number-interface
+ "A string number instruction"
+ '())
+
 (ly:add-interface
  'system-start-text-interface
  "A text at the beginning of a system."
index 2633e6db70ad5e50dc8c5e64b61a38ef3acf69f2..9d59719a8a4fe70fab5f51769c259dee27b2ff88 100644 (file)
@@ -225,9 +225,6 @@ typeset. Valid choices depend on the function that is reading this
 property.")
      (gap ,ly:dimension? "Size of a gap in a variable symbol.")
      (gap-count ,integer? "Number of gapped beams for tremolo.")
-     (grace-space-factor ,number? "Space grace notes at this fraction
-of the @code{spacing-increment}.")
-
      (grow-direction ,ly:dir? "Crescendo or decrescendo?")
      (hair-thickness ,number? "Thickness of the thin line in a bar line.")
      (head-direction ,ly:dir? "Are the note heads left or right in a semitie?")
@@ -529,6 +526,7 @@ paper-columns or note-column objects.")
 in addition to notes and stems.")
      (elements ,ly:grob-array? "list of grobs, type depending on the Grob
 where this is set in.")
+     (grace-spacing ,ly:grob-array? "a run of grace notes.")
      (heads ,ly:grob-array? "List of note heads.")
      (items-worth-living ,ly:grob-array? "A list of interesting items. If
 empty in a particular staff, then that staff is erased.")
index 8f554a2fa49cfe44255ee7f0abe6e938832d19b9..61edbf6b4a30f9b0a8a60db63350a3f5500bb42a 100644 (file)
                 (interfaces . (line-interface
                                line-spanner-interface))))))
 
+    (GraceSpacing
+     . (
+       (common-shortest-duration . ,grace-spacing::calc-shortest-duration)
+       (spacing-increment . 0.8)
+       (shortest-duration-space . 1.6)
+       (meta . ((class . Spanner)
+                (interfaces . (grace-spacing-interface
+                               spacing-interface
+                               spacing-options-interface
+                               spanner-interface))))))
     (GridPoint
      . (
        (X-extent . (0 . 0))
        (grace-space-factor . 0.6)
        (shortest-duration-space . 2.0)
        (spacing-increment . 1.2)
+       
        (base-shortest-duration . ,(ly:make-moment 3 16))
        (meta . ((class . Spanner)
                 (interfaces . (spacing-interface
+                               spacing-options-interface                               
                                spacing-spanner-interface))))))
 
     (SpanBar
index 561184cbe9f69337d6662d777d462334b29f8f24..dd456be80c026322f5bf1b6cfd47904ee97f8072 100644 (file)
@@ -377,3 +377,28 @@ centered, X==1 is at the right, X == -1 is at the left."
      (cons 0 dx)
      (cons (min 0 delta)
           (max 0 delta)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; grace spacing
+
+
+(define-public (grace-spacing::calc-shortest-duration grob)
+  (let*
+     ((cols (ly:grob-object grob 'columns))
+      (get-difference
+       (lambda (idx)
+        (ly:moment-sub (ly:grob-property (ly:grob-array-ref cols (1+ idx)) 'when)
+                       (ly:grob-property (ly:grob-array-ref cols idx) 'when))))
+      
+      (moment-min (lambda (x y)
+                   (cond
+                    ((and x y)
+                     (if (ly:moment<? x y)
+                           x
+                           y))
+                    (x x)
+                    (y y)))))
+                    
+        
+    (fold moment-min #f (map get-difference (iota (1- (ly:grob-array-length cols)))))))
+