]> git.donarmstrong.com Git - lilypond.git/commitdiff
''
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 1 Jul 2002 23:52:24 +0000 (23:52 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 1 Jul 2002 23:52:24 +0000 (23:52 +0000)
ChangeLog
input/template/satb.ly [new file with mode: 0644]
lily/ambitus-engraver.cc
lily/ambitus.cc

index a0c23596c09cd4a7bd9643b6d813a2d06beae6b5..6546837642b0753c951ba969822cd193d2c9a756 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2002-07-02  Juergen Reuter  <reuter@ipd.uka.de>
+
+       * lily/ambitus-engraver.cc, lily/ambitus.cc: Various bugfixes:
+       avoid segfault on undefined ambitus pitch; avoid wasteful creation
+       of pitch smobs; defer computation of centralCPosition beyond first
+       timestep to catch also clefs outside of the current voice context.
+
 2002-07-02  Han-Wen  <hanwen@cs.uu.nl>
 
        * input/template/satb.ly: new file
diff --git a/input/template/satb.ly b/input/template/satb.ly
new file mode 100644 (file)
index 0000000..3c23696
--- /dev/null
@@ -0,0 +1,51 @@
+
+%{
+
+ Example template for a SATB vocal  score.
+%}
+
+sopMusic = \notes  \relative c'' { c4 c [c8( )b] c4 }
+sopWords = \lyrics { hi4 hi hi hi  }
+
+altoMusic = \notes  \relative c' { e4 f d e }
+altoWords =\lyrics { ha4 ha ha ha }
+
+tenorMusic = \notes \relative c' { g4 a f g }
+tenorWords = \lyrics { hu4 hu hu hu }
+
+bassMusic = \notes \relative c { c4 c g c }
+bassWords = \lyrics { ho4 ho ho ho }
+
+\score { \notes
+         \context StaffGroup <
+             \property Score.automaticMelismata = ##t
+         \context Lyrics = sopLyrs { s1 }
+         \context Staff = women { s1 }
+         \context Lyrics = altoLyrs { s1 }
+         \context Lyrics = tenorLyrs { s1 }
+         \context Staff = men {\clef bass s1 }
+         \context Lyrics = bassLyrs { s1 }
+         \addlyrics
+               \context Staff = women \context Voice = VA { \voiceOne \sopMusic }
+               \context Lyrics = sopLyrs { \sopWords}
+         \addlyrics
+               \context Staff = women \context Voice = VB { \voiceTwo \altoMusic }
+               \context Lyrics = altoLyrs { \altoWords}
+         \addlyrics
+               \context Staff = men \context Voice = VA { \voiceOne \tenorMusic }
+               \context Lyrics = tenorLyrs { \tenorWords}
+         \addlyrics
+               \context Staff = men  \context Voice = VB { \voiceTwo \bassMusic }
+               \context Lyrics = bassLyrs { \bassWords}
+         
+         >
+  \paper {
+    \translator {
+
+       % a little smaller so lyrics can be closer to the staff. 
+       \StaffContext
+       minimumVerticalExtent = #'(-3 . 3) 
+    }
+  }
+}
index fb0af0286b813b1cf4b57b8f167a673759203c6d..85dbbd46b87f3b396dd01c5b350651ed946bd942 100644 (file)
@@ -64,10 +64,9 @@ class Ambitus_engraver : public Engraver
 {
 public:
 TRANSLATOR_DECLARATIONS(Ambitus_engraver);
-  virtual void start_translation_timestep ();
   virtual void acknowledge_grob (Grob_info);
-  virtual void create_grobs ();
   virtual void stop_translation_timestep ();
+  virtual void finalize ();
 
 private:
   void create_ambitus ();
@@ -90,6 +89,14 @@ void
 Ambitus_engraver::stop_translation_timestep ()
 {
   if (!ambitus_p_) {
+    // Create ambitus not before stopping timestep.  centralCPosition
+    // will then be the same as that for the first timestep.
+    //
+    // TODO: is this really a good idea?  At least, creating the
+    // ambitus in start_translation_timestep is a *bad* idea, since we
+    // may then oversee a clef that is defined in a staff context if
+    // we are in a voice context; centralCPosition would then be
+    // assumed to be 0.
     create_ambitus ();
   }
   if (ambitus_p_ && isActive)
@@ -97,27 +104,10 @@ Ambitus_engraver::stop_translation_timestep ()
       SCM key_signature = get_property ("keySignature");
       ambitus_p_->set_grob_property ("keySignature", key_signature);
       typeset_grob (ambitus_p_);
-      //ambitus_p_ = 0;
       isActive = 0;
     }
 }
 
-void
-Ambitus_engraver::start_translation_timestep ()
-{
-  if (!ambitus_p_) {
-    create_ambitus ();
-  }
-}
-
-void
-Ambitus_engraver::create_grobs ()
-{
-  if (!ambitus_p_) {
-    create_ambitus ();
-  }
-}
-
 void
 Ambitus_engraver::acknowledge_grob (Grob_info info)
 {
@@ -140,22 +130,14 @@ Ambitus_engraver::acknowledge_grob (Grob_info info)
                  // not yet init'd; use current pitch to init min/max
                  pitch_min = pitch;
                  pitch_max = pitch;
-                 ambitus_p_->set_grob_property ("pitch-min",
-                                                pitch_min.smobbed_copy ());
-                 ambitus_p_->set_grob_property ("pitch-max",
-                                                pitch_max.smobbed_copy ());
                }
              else if (Pitch::compare (pitch, pitch_max) > 0) // new max?
                {
                  pitch_max = pitch;
-                 ambitus_p_->set_grob_property ("pitch-max",
-                                                pitch_max.smobbed_copy ());
                }
              else if (Pitch::compare (pitch, pitch_min) < 0) // new min?
                {
                  pitch_min = pitch;
-                 ambitus_p_->set_grob_property ("pitch-min",
-                                                pitch_min.smobbed_copy ());
                }
            }
        }
@@ -172,6 +154,31 @@ Ambitus_engraver::create_ambitus ()
   announce_grob (ambitus_p_, SCM_EOL);
 }
 
+void
+Ambitus_engraver::finalize ()
+{
+  if (ambitus_p_)
+    {
+      if (Pitch::compare (pitch_min, pitch_max) <= 0)
+       {
+         ambitus_p_->set_grob_property ("pitch-min",
+                                        pitch_min.smobbed_copy ());
+         ambitus_p_->set_grob_property ("pitch-max",
+                                        pitch_max.smobbed_copy ());
+       }
+      else // have not seen any pitch, so forget about the ambitus
+       {
+         // Do not print a warning on empty ambitus range, since this
+         // most probably arises from an empty voice, such as shared
+         // global timesig/clef definitions.
+#if 0
+         ambitus_p_->warning("empty ambitus range [ignored]");
+#endif
+         ambitus_p_->suicide();
+       }
+    }
+}
+
 ENTER_DESCRIPTION(Ambitus_engraver,
 /* descr */       "",
 /* creats*/       "Ambitus",
index ccc7ba3318c455a6818f3f2358807eff12fb7866..c09f557f1b78b3d94ed5d983e62649cc9ff0768f 100644 (file)
@@ -146,15 +146,30 @@ Ambitus::brew_molecule (SCM smob)
       return SCM_EOL;
     }
 
+  int p_min, p_max;
   Pitch *pitch_min = unsmob_pitch (me->get_grob_property ("pitch-min"));
-  int p_min = pitch_min->steps ();
+  if (!pitch_min)
+    {
+      me->programming_error("Ambitus: pitch_min undefined; assuming 0");
+      p_min = 0;
+    }
+  else
+    {
+      p_min = pitch_min->steps ();
+    }
   Pitch *pitch_max = unsmob_pitch (me->get_grob_property ("pitch-max"));
-  int p_max = pitch_max->steps ();
+  if (!pitch_max)
+    {
+      me->programming_error("Ambitus: pitch_max undefined; assuming 0");
+      p_max = 0;
+    }
+  else
+    {
+      p_max = pitch_max->steps ();
+    }
   if (p_min > p_max)
     {
-      String message = "Ambitus: no range to output";
-      me->warning (_ (message.ch_C ()));
-      return SCM_EOL;
+      me->programming_error ("Ambitus: reverse range");
     }
 
   SCM c0 = me->get_grob_property ("centralCPosition");