]> git.donarmstrong.com Git - lilypond.git/commitdiff
''
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 1 Apr 2002 14:57:56 +0000 (14:57 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 1 Apr 2002 14:57:56 +0000 (14:57 +0000)
ChangeLog
Documentation/regression-test.tely
input/regression/spacing-short-notes.ly [new file with mode: 0644]
input/regression/tup.ly
lily/multi-measure-rest.cc
lily/spacing-spanner.cc
lily/tuplet-bracket.cc
scm/grob-description.scm
scm/grob-property-description.scm

index 764e93139006efd03deba33b27f8f062160cf0f2..056ee9a85fa69faafd46a22ff3e2df48c157b458 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2002-04-01  Han-Wen  <hanwen@cs.uu.nl>
 
+       * lily/multi-measure-rest.cc (set_spacing_rods): tune rods to the
+       extent of the mm rest. 
+
+       * lily/spacing-spanner.cc (get_duration_space): better spacing for
+       really short notes.
+
        * lily/tuplet-bracket.cc (make_bracket): new function
        (get_x_offset): new function; make tuplet brackets align on stems
        if stem has same direction.
index 588ea303b68460eb72d3a8a961005045d30c5b85..5ff30ffc4355e0573ed2f87652c3293e411c3c2e 100644 (file)
@@ -260,6 +260,8 @@ Grace note do weird things with timing. Fragile.
 
 @lilypondfile[printfilename]{spacing-rest.ly}
 
+@lilypondfile[printfilename]{spacing-short-notes.ly}
+
 @lilypondfile[printfilename]{lyrics-bar.ly}
 
 @lilypondfile[printfilename]{spacing-knee.ly}
diff --git a/input/regression/spacing-short-notes.ly b/input/regression/spacing-short-notes.ly
new file mode 100644 (file)
index 0000000..1abde19
--- /dev/null
@@ -0,0 +1,22 @@
+\header {
+    
+texidoc = "Notes that are shorter than the common shortest note, Get a
+space (i.e. without the space needed for the note) proportional to
+their duration. So 16th notes get 1/2 of the space of an eigth note.
+The total distance for a 16th is (including note head) is 3/4 of the
+eighth note. "
+
+}
+
+\score { \notes \relative c''
+{
+    \time 2/4 
+    c16 c c c c4 c4
+    c8 c8 c8 c8
+    c8 c8 c4
+    c8 c8 c4
+
+}
+
+        \paper { linewidth = -1. }
+}
index 970f0e80c26587c13dbd948da94df653af152f0a..675da01a394cfaa59ca1e1815c075535dc608a05 100644 (file)
@@ -18,7 +18,12 @@ direction as the
 \score{
        \notes \context Voice \relative c'' {
                 \times 2/3 { \times 2/3 { a8 b c}  c }
-                \times 3/4 { c4 c4 c4 c4 }
+                \times 2/3 { r8 [b f] }
+                \times 2/3 { r8 b r8 }
+                c4 |
+                
+                \times 3/4 { c4 c4 c4 c4 } c4 | 
+                
                 \time 6/8
                 \times 6/9 { c8 c c c c c c c c }
 
index 6a52280949843e6985716b4400d15f0aa544969d..0d0c3d6d2ee4d181900a2bc5416e9b661f838266 100644 (file)
@@ -257,10 +257,15 @@ Multi_measure_rest::church_rest (Grob*me, Font_metric *musfont, int measures,
       count ++;
     }
 
+  
 
   Real outer_padding_factor = 1.5; //     make outer padding this much bigger.
   Real inner_padding = (space - symbols_width) / (2 * outer_padding_factor + (count-1)); 
-
+  if (inner_padding < 0)
+    {
+      inner_padding = 1.0;
+    }
+  
   Molecule mol; 
   for (SCM  s = mols; gh_pair_p (s); s = gh_cdr(s))
     {
@@ -302,6 +307,8 @@ Multi_measure_rest::set_spacing_rods (SCM smob)
   
   Item* combinations[4][2]={{l,r}, {lb,r}, {l,rb},{lb,rb}};
 
+  Real sym_width = symbol_molecule (me, 0.0).extent (X_AXIS).length ();
+  
   for (int i=0; i < 4; i++)
     {
       Item * l =  combinations[i][0];
@@ -313,8 +320,10 @@ Multi_measure_rest::set_spacing_rods (SCM smob)
       Rod rod;
       rod.item_l_drul_[LEFT] = l;
       rod.item_l_drul_[RIGHT] = r;
+
+      
       rod.distance_f_ = l->extent (l, X_AXIS)[BIGGER] - r->extent (r, X_AXIS)[SMALLER]
-       + 5.0;                  // magic!
+       + sym_width  + 2.0;                     // 2.0 = magic!
   
       rod.add_to_cols ();
     }
index fbad90b0ed666b7351eec1e7f6258b3def709bab..b087ffde981c597e6adb7ca6f7d4e0fb4bdb4b6c 100644 (file)
@@ -441,7 +441,7 @@ Spacing_spanner::find_shortest (Link_array<Grob> const &cols)
          max_count = counts[i];
        }
 
-      //      printf ("Den %d/%d, c %d\n", durations[i].num (), durations[i].den (), counts[i]);
+      printf ("duration %d/%d, count %d\n", durations[i].num (), durations[i].den (), counts[i]);
     }
 
   /*
@@ -546,7 +546,6 @@ Spacing_spanner::musical_column_spacing (Grob *me, Item * lc, Item *rc, Real inc
          max_note_space = max_note_space >? space;
          max_fixed_note_space = max_fixed_note_space >? fixed;
        }
-
     }
 
   if (max_note_space < 0)
@@ -667,28 +666,44 @@ Real
 Spacing_spanner::get_duration_space (Grob*me, Moment d, Rational shortest, bool * expand_only) 
 {
   Real k = gh_scm2double (me->get_grob_property ("shortest-duration-space"));
-    
+  Real incr = gh_scm2double (me->get_grob_property ("spacing-increment"));
+  
   if (d < 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_ / shortest;
       
       *expand_only = true;
-      return (0.5 + 0.5 * double (ratio)) * k ;
+      return ((k-1) + double (ratio)) * incr;
     }
   else
     {
       /*
-         @see
-  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.
+         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 (shortest);
       k -= log;
       Rational compdur = d.main_part_ + d.grace_part_ /Rational (3);
       *expand_only = false;      
    
-      return (log_2 (compdur) + k) * gh_scm2double (me->get_grob_property ("spacing-increment"));
+      return (log_2 (compdur) + k) * incr;
     }
 }
 
@@ -741,47 +756,17 @@ Spacing_spanner::note_spacing (Grob*me, Grob *lc, Grob *rc,
 
 
 ADD_INTERFACE (Spacing_spanner,"spacing-spanner-interface",
-  " SPACE = arithmetic_multiplier * ( C + log2 (TIME) ))
-The space taken by a note is determined by the formula 
-
-
-
-where TIME is the amount of time a note occupies.  The value of C is
-chosen such that the smallest space within a measure is
-arithmetic_basicspace:
-
-C = arithmetic_basicspace - log2 (mininum (SHORTEST, 1/8)) 
-
-The smallest space is the one following the shortest note in the
-measure, or the space following a hypothetical 1/8 note.  Typically
-arithmetic_basicspace is set to a value so that the shortest note
-takes about two noteheads of space (ie, is followed by a notehead of
-space):
-
-@example
-2*quartwidth = arithmetic_multiplier * ( C + log2 (SHORTEST) ))
-
-@{ using: C = arithmetic_basicspace - log2 (mininum (SHORTEST, 1/8)) @}
-@{ assuming: SHORTEST <= 1/8 @}
-
-= arithmetic_multiplier *
-( arithmetic_basicspace - log2 (SHORTEST) + log2 (SHORTEST) )
-
-= arithmetic_multiplier * arithmetic_basicspace
-
-@{ choose: arithmetic_multiplier = 1.0*quartwidth (why?) @}
-
-= quartwidth * arithmetic_basicspace
-
-=>            
-
-arithmetic_basicspace = 2/1 = 2
-
-
-If you want to space your music wider, use something like:
-
-arithmetic_basicspace = 4.;
-
-@end example",
+  "
+The space taken by a note is dependent on its duration. Doubling a
+duration adds spacing-increment to the space. The most common shortest
+note gets shortest-duration-space. Notes that are even shorter are
+spaced proportonial to their duration.
+
+Typically, the increment is the width of a black note head.  In a
+piece with lots of 8th notes, and some 16th notes, the eighth note
+gets 2 note heads width (i.e. the space following a note is 1 note
+head width) A 16th note is followed by 0.5 note head width. The
+quarter note is followed by  3 NHW, the half by 4 NHW, etc.
+",
   "spacing-increment shortest-duration-space");
 
index bfcc48bfdb3e160938ba1c05b5db9e4babe600a0..bb397a27fa34cec23ade1098f6fcd23ac67a90c7 100644 (file)
 #include "lookup.hh"
 
 
-static Real
-get_x_offset (Grob *g, Grob *common, Direction my_dir)
+static Grob*
+get_x_bound_grob (Grob *g, Direction my_dir)
 {
   if (Note_column::stem_l (g)
       && Note_column::dir (g) == my_dir)
     {
       g = Note_column::stem_l (g);
     }
-  return g->relative_coordinate (common, X_AXIS);
+  return g;
 }
 
 
@@ -129,9 +129,12 @@ Tuplet_bracket::brew_molecule (SCM smob)
        
   Grob * commonx = column_arr[0]->common_refpoint (column_arr.top (),X_AXIS);
   Direction dir = Directional_element_interface::get (me);
-      
-  Real x0 = get_x_offset (column_arr[0], commonx, dir);
-  Real x1 = get_x_offset (column_arr.top(), commonx, dir);
+
+  Grob * lgr = get_x_bound_grob (column_arr[0], dir);
+  Grob * rgr = get_x_bound_grob (column_arr.top(), dir);  
+  Real x0 = lgr->extent (commonx,X_AXIS)[LEFT];
+  Real x1 = rgr->extent (commonx,X_AXIS)[RIGHT];
+
   Real w = x1 -x0;
 
   Real ly = gh_scm2double (me->get_grob_property ("left-position"));
@@ -230,7 +233,7 @@ Tuplet_bracket::calc_position_and_height (Grob*me,Real *offset, Real * dy)
   Grob * commony = me->common_refpoint (me->get_grob_property ("note-columns"), Y_AXIS);
   Grob * commonx = me->common_refpoint (me->get_grob_property ("note-columns"), X_AXIS);  
   
-  Direction d = Directional_element_interface::get (me);
+  Direction dir = Directional_element_interface::get (me);
 
   /*
     Use outer non-rest columns to determine slope
@@ -245,22 +248,25 @@ Tuplet_bracket::calc_position_and_height (Grob*me,Real *offset, Real * dy)
   
   if (l < r)
     {
-      *dy = column_arr[r]->extent (commony, Y_AXIS) [d]
-       - column_arr[l]->extent (commony, Y_AXIS) [d] ;
+      *dy = column_arr[r]->extent (commony, Y_AXIS) [dir]
+       - column_arr[l]->extent (commony, Y_AXIS) [dir] ;
     }
   else
     * dy = 0;
 
 
-  *offset = - d * infinity_f;
+  *offset = - dir * infinity_f;
 
   if (!column_arr.size ())
     return;
 
 
   
-  Real x0 = get_x_offset (column_arr[0], commonx, d);
-  Real x1 = get_x_offset (column_arr.top(), commonx, d);
+  Grob * lgr = get_x_bound_grob (column_arr[0], dir);
+  Grob * rgr = get_x_bound_grob (column_arr.top(), dir);  
+  Real x0 = lgr->extent (commonx,X_AXIS)[LEFT];
+  Real x1 = rgr->extent (commonx,X_AXIS)[RIGHT];
+
 
     /*
       Slope.
@@ -269,18 +275,18 @@ Tuplet_bracket::calc_position_and_height (Grob*me,Real *offset, Real * dy)
   
   for (int i = 0; i < column_arr.size ();  i++)
     {
-      Real notey = column_arr[i]->extent (commony, Y_AXIS)[d] 
+      Real notey = column_arr[i]->extent (commony, Y_AXIS)[dir
        - me->relative_coordinate (commony, Y_AXIS);
 
       Real x = column_arr[i]->relative_coordinate (commonx, X_AXIS) - x0;
       Real tuplety =  *dy * x * factor;
 
-      if (notey * d > (*offset + tuplety) * d)
+      if (notey * dir > (*offset + tuplety) * dir)
        *offset = notey - tuplety; 
     }
 
   // padding
-  *offset +=  gh_scm2double (me->get_grob_property ("padding")) *d;
+  *offset +=  gh_scm2double (me->get_grob_property ("padding")) *dir;
 
   
   /*
@@ -294,7 +300,7 @@ Tuplet_bracket::calc_position_and_height (Grob*me,Real *offset, Real * dy)
       
       *offset = rint (*offset);
       if (Staff_symbol_referencer::on_staffline (me, (int) rint (*offset)))
-       *offset += d;
+       *offset += dir;
 
       *offset *= 0.5 * ss;
     }
index d5e27b3546da9a21cf2fa74a6a12dc37a322cf92..f319e97de8d1efdfb913fbf308cc761c684d7cb5 100644 (file)
     (SpacingSpanner
      . (
        (spacing-procedure .  ,Spacing_spanner::set_springs)
-       (grace-space-factor . 0.5)
-
+       (grace-space-factor . 0.6)
        (shortest-duration-space . 2.0)
        (spacing-increment . 1.2)
-       
-
        (meta . ((interfaces . (spacing-spanner-interface))))
        ))
 
index f2f98584f075709c9dd1d8b1def1550b345cb7b6..3d64f306ffb8ff575504b730efe9fd40e7ae1574 100644 (file)
@@ -112,8 +112,6 @@ square of the inner notes involved.")
 
 (grob-property-description 'neutral-direction dir? "Where to go if we're on the neutral position of the staff (by default, the middle of the staff; see also grob-property neutral-position).  [Ross] has the following to say about this: Some engravers consider the middle line neutral, and take the option of using either up- or down-stems for notes that fall on it. However, more up-to-date engraving no longer permits an option; now a down-stem is always appropriate.")
 (grob-property-description 'neutral-position number? "Position (in half staff spaces) where to flip the direction of stems: by default, custodes above this position get their stems downwards; custodes below this position get their stems upwards.  A value of 0 designates the center of the staff.  Use property neutral-direction to control the behaviour of stems on the neutral position itself.  (Note: currently, neutral-position is supported only for custodes; for stems of note heads, neutral-position is currently fixed to 0, i.e. the middle of the staff.)")
-
-(grob-property-description 'delta-y number? "amount of ascension.")
 (grob-property-description 'dependencies list? "list of score-grob pointers that indicate who to compute first for certain global passes.")
 (grob-property-description 'details list? "alist of parameters for detailed grob behavior.")
 (grob-property-description 'dir-forced boolean? "set if direction has been forced; read by Beam.")