From 7dd74aea18fe3fc6107e2b287e96cf5236280534 Mon Sep 17 00:00:00 2001
From: Han-Wen Nienhuys <hanwen@xs4all.nl>
Date: Wed, 2 Jul 2003 16:25:16 +0000
Subject: [PATCH] * lily/duration.cc (var): backport SCM_ASSERT_TYPE sideeffect
 fix.

* lily/parser.yy (Repeated_music): backport tremolo fix.

* lily/chord-tremolo-engraver.cc: idem.
---
 ChangeLog                         |  8 +++++++
 input/regression/chord-tremolo.ly | 40 ++++++++++++++++++-------------
 lily/chord-tremolo-engraver.cc    | 30 +++++++++++++++++++----
 lily/duration.cc                  |  5 +++-
 lily/parser.yy                    | 37 ++++++++++++++++++----------
 5 files changed, 86 insertions(+), 34 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8a48838aaa..0b6a330334 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2003-07-02  Han-Wen Nienhuys  <hanwen@cs.uu.nl>
+
+	* lily/duration.cc (var): backport SCM_ASSERT_TYPE sideeffect fix. 
+
+	* lily/parser.yy (Repeated_music): backport tremolo fix.
+
+	* lily/chord-tremolo-engraver.cc: idem.
+
 2003-06-23  Han-Wen Nienhuys  <hanwen@cs.uu.nl>
 
 	* Documentation/topdocs/index.tely (Top): typo
diff --git a/input/regression/chord-tremolo.ly b/input/regression/chord-tremolo.ly
index 6ce983e12e..391443d5af 100644
--- a/input/regression/chord-tremolo.ly
+++ b/input/regression/chord-tremolo.ly
@@ -1,4 +1,4 @@
-\version "1.5.68"
+\version "1.7.18"
 
 \header{
 texidoc="
@@ -8,28 +8,36 @@ leave a gap.  Chord tremolo beams on half notes are not ambiguous,
 as half notes cannot appear in a regular beam, and should reach the 
 stems.
 
+In this example, each tremolo lasts exactly one measure.
+
 (To ensure that the spacing engine is not confused we add some regular notes as well.) 
 "
 }
-  
+
 \score { 
   \context Voice \notes\relative c' {
-        % huh -> one beam missing!
+	\time 4/4
+	\repeat "tremolo" 16 { d32 e }
 	\repeat "tremolo" 8 { d16 e }
-	\repeat "tremolo" 4 { d e }
-	\repeat "tremolo" 2 { d e }
-	c4
-	\break
-	\repeat "tremolo" 4 { f'8 e }
-	\repeat "tremolo" 2 { f e }
-	c4
-	c4 c4 c4 c4
-	c4 c4 c4 c4
-	c4 c4 c4 c4
+	\repeat "tremolo" 4 { d8 e }
+
+	\time 3/4
+	\repeat "tremolo" 12 { d32 e }
+	\repeat "tremolo" 6 { d16 e } 
+	\repeat "tremolo" 3 { d8 e } 
 
+	\time 2/4
+	\repeat "tremolo" 8 { d32 e }
+	\repeat "tremolo" 4 { d16 e }
+	\repeat "tremolo" 2 { d8 e }
+
+	\time 1/4
+	\repeat "tremolo" 4 { d32 e }
+	\repeat "tremolo" 2 { d16 e }
+
+	c4 c4 c4 c4 c4 
   }
-  \paper {
-    linewidth = 90*\staffspace
-  }  
+
   \midi { }
 }
+%% new-chords-done %%
diff --git a/lily/chord-tremolo-engraver.cc b/lily/chord-tremolo-engraver.cc
index e580e17716..f8365b5cc0 100644
--- a/lily/chord-tremolo-engraver.cc
+++ b/lily/chord-tremolo-engraver.cc
@@ -86,11 +86,33 @@ Chord_tremolo_engraver::try_music (Music * m)
       repeat_ = rp;
       start_mom_ = now_mom ();
       stop_mom_ = start_mom_ + l;
-      sequential_body_b_ = dynamic_cast<Sequential_music*> (rp->body ());
 
+      Sequential_music * seq = dynamic_cast<Sequential_music*> (rp->body ());
+      sequential_body_b_ = seq;
+
+      int elt_count = seq ? scm_ilength (seq-> music_list ()) : 1;
+
+      if (elt_count != 2)
+	{
+	  rp->origin ()->warning (_f ("Chord tremolo with %d elements. Must have two elements.", elt_count));
+	}
+
+      if (elt_count <= 0)
+	elt_count = 1;
+	  
       Rational total_dur = l.main_part_;
-      Rational note_dur = (total_dur / Rational (repeat_->repeat_count ()));
-       flags_ = intlog2 ((total_dur / note_dur).num ());
+      Rational note_dur = total_dur / Rational (elt_count * repeat_->repeat_count ());
+
+      if (total_dur < Rational (1,4))
+	{
+	  /*
+	    This would require beams between flagged (8th) notes.
+	  */
+	  rp->origin ()->warning ("Chord tremolo is too short to denote properly.");
+	}
+      
+      Rational written_note_dur = total_dur / Rational (elt_count);
+      flags_ = intlog2 (note_dur.den ()) -2 ;
       
       return true;
     }
@@ -116,14 +138,12 @@ Chord_tremolo_engraver::process_music ()
 	}
       else if (!sequential_body_b_ && !stem_tremolo_)
 	{
-
 	  if (flags_)
 	    {
 	      stem_tremolo_ = new Item (get_property ("StemTremolo"));
 	      announce_grob(stem_tremolo_, repeat_->self_scm());
 	      stem_tremolo_->set_grob_property ("flag-count",
 						scm_int2num (flags_));
-
 	    }
 	}
     }
diff --git a/lily/duration.cc b/lily/duration.cc
index a036c55f52..5c6330ca23 100644
--- a/lily/duration.cc
+++ b/lily/duration.cc
@@ -164,7 +164,10 @@ dots.
     num = gh_int2scm (1);
   
   if (den != SCM_UNDEFINED)
-    SCM_ASSERT_TYPE(gh_number_p (den), length, SCM_ARG4, __FUNCTION__, "integer");
+    {
+      SCM_ASSERT_TYPE(gh_number_p (den), length, SCM_ARG4, __FUNCTION__, "integer");
+      compress = true;
+    }
   else
     den = gh_int2scm (1);
   
diff --git a/lily/parser.yy b/lily/parser.yy
index 44cc51660e..cf1a82254d 100644
--- a/lily/parser.yy
+++ b/lily/parser.yy
@@ -744,18 +744,31 @@ Repeated_music:
 		SCM func = scm_primitive_eval (ly_symbol2scm ("repeat-name-to-ctor"));
 		SCM result = gh_call1 (func, $2);
 
-		if (gh_equal_p ($2, scm_makfrom0str ("tremolo")))
-		{
-		/*
-		we can not get durations and other stuff correct down the line, so we have to
-		add to the duration log here.
-		*/
-			SCM func = scm_primitive_eval (ly_symbol2scm ("shift-duration-log"));
-			if (($3 % 3) == 0)
-			  gh_call3 (func, r->self_scm (), gh_int2scm(-intlog2 ($3*2/3)),gh_int2scm(1));
-			else
-			  gh_call3 (func, r->self_scm (), gh_int2scm(-intlog2 ($3)), gh_int2scm(0));
-		}
+ 		if (gh_equal_p ($2, scm_makfrom0str ("tremolo"))) {
+ 			/*
+ 			we can not get durations and other stuff correct down the line, so we have to
+ 			add to the duration log here.
+ 			*/
+ 			static SCM func;
+ 
+ 			if (!func)
+ 				func = scm_primitive_eval (ly_symbol2scm ("shift-duration-log"));
+ 
+ 			int dots = ($3 % 3) ? 0 : 1;
+ 			int shift = -intlog2 ((dots) ? ($3*2/3) : $3);
+ 
+ 			Sequential_music * seq = dynamic_cast<Sequential_music*> ($4);
+ 			
+ 			if (seq) {
+ 				int list_len =scm_ilength (seq->music_list ());
+ 				if (list_len != 2)
+ 					seq->origin ()->warning ("Chord tremolo must have 2 elements.");
+ 				shift -= 1;
+ 				r->compress (Moment (Rational (1,list_len)));
+ 				}
+ 			gh_call3 (func, r->self_scm (), gh_int2scm(shift),gh_int2scm(dots));
+ 
+  		}
 
 		set_music_properties (r, result);
 
-- 
2.39.5