]> git.donarmstrong.com Git - lilypond.git/commitdiff
includeGraceNotes: lyrics syllables of grace notes
authorRichard Gay <richard.gay@t-online.de>
Fri, 16 Apr 2010 22:19:48 +0000 (00:19 +0200)
committerNeil Puttock <n.puttock@gmail.com>
Sun, 18 Apr 2010 23:32:13 +0000 (00:32 +0100)
 * adds 'includeGraceNotes' property to the lyrics context; it allows
   for choosing between ignoring grace notes for lyrics ("old" behavior)
   and attaching lyrics syllables to grace notes
 * includes English and German documentation (vocal.itely)
 * includes regression tests (for feature itself and extenders)

Documentation/de/notation/vocal.itely
Documentation/notation/vocal.itely
input/regression/lyric-extender-includegraces.ly [new file with mode: 0644]
input/regression/lyrics-includegraces.ly [new file with mode: 0644]
lily/extender-engraver.cc
lily/include/context.hh
lily/lyric-combine-music-iterator.cc
lily/lyric-engraver.cc
scm/define-context-properties.scm

index 9393cc6706db2ddac34a8e4898f5a3a042197e82..0bceca343fbe9f63da9586eeef2ddf7e42980cb3 100644 (file)
@@ -1194,6 +1194,51 @@ Es ist notwendig, explizit @code{\set} und @code{\unset} zu
 verwenden, um den Text einzugrenzen, für den Melismen ignoriert
 werden sollen.
 
+@subsubheading Silben zu Verzierungsnoten hinzufügen
+
+Normalerweise werden Verzierungsnoten (z.B. durch @code{\grace}) bei
+@code{\lyricsto} keine Silben zugeordnet.  Dieses Verhalten kann
+geändert werden, wie das folgende Beispiel zeigt.
+
+@lilypond[verbatim,ragged-right,quote]
+\relative c' {
+  f4 \appoggiatura a32 b4
+  \grace { f16[ a16] } b2
+  \afterGrace b2 { f16[ a16] }
+  \appoggiatura a32 b4
+  \acciaccatura a8 b4
+}
+\addlyrics {
+  normal
+  \set includeGraceNotes = ##t
+  case,
+  gra -- ce case,
+  after -- grace case,
+  \set ignoreMelismata = ##t
+  app. case,
+  acc. case.
+}
+@end lilypond
+
+@knownissues
+Wie bei @code{associatedVoice} muss @code{includeGraceNotes}
+spätestens eine Silbe vor derjenigen gesetzt werden, die unter einer
+Verzierungsnote stehen soll.  Im Fall, dass eine Verzierungsnote
+die erste des Musikstückes ist, kann ein @code{\with}- oder
+@code{\context}-Block verwendet werden:
+
+@lilypond[verbatim,ragged-right,quote]
+<<
+  \new Voice = melody \relative c' {
+    \grace { c16[( d e f] }
+    g1) f
+  }
+  \new Lyrics \with { includeGraceNotes = ##t }
+  \lyricsto melody {
+    Ah __ fa
+  }
+>>
+@end lilypond
 
 @subsubheading Zu einer alternativen Melodie umschalten
 
index 34f6cc4938227d2a3b6d3eee3a612688b9de6430..974de3bdbccc0f658f4049386efa52ee050cc56c 100644 (file)
@@ -1152,6 +1152,52 @@ not work if prefixed with @code{\once}.  It is necessary to use
 @code{\set} and @code{\unset} to bracket the lyrics where melismata
 are to be ignored.
 
+@subsubheading Adding syllables to grace notes
+
+By default, grace notes (e.g. via @code{\grace}) do not get assigned
+syllables when using @code{\lyricsto}, but this behavior can be
+changed:
+
+@lilypond[verbatim,ragged-right,quote]
+\relative c' {
+  f4 \appoggiatura a32 b4
+  \grace { f16[ a16] } b2
+  \afterGrace b2 { f16[ a16] }
+  \appoggiatura a32 b4
+  \acciaccatura a8 b4
+}
+\addlyrics {
+  normal
+  \set includeGraceNotes = ##t
+  case,
+  gra -- ce case,
+  after -- grace case,
+  \set ignoreMelismata = ##t
+  app. case,
+  acc. case.
+}
+@end lilypond
+
+@knownissues
+Like for @code{associatedVoice}, @code{includeGraceNotes} needs to be
+set at latest one syllable before the one which is to be put under a
+grace note.  For the case of a grace note at the very beginning of a
+piece of music, consider using a @code{\with} or @code{\context}
+block:
+
+@lilypond[verbatim,ragged-right,quote]
+<<
+  \new Voice = melody \relative c' {
+    \grace { c16[( d e f] }
+    g1) f
+  }
+  \new Lyrics \with { includeGraceNotes = ##t }
+  \lyricsto melody {
+    Ah __ fa
+  }
+>>
+@end lilypond
+
 @subsubheading Switching to an alternative melody
 
 More complex variations in text underlay are possible.  It is possible
diff --git a/input/regression/lyric-extender-includegraces.ly b/input/regression/lyric-extender-includegraces.ly
new file mode 100644 (file)
index 0000000..c8a175b
--- /dev/null
@@ -0,0 +1,17 @@
+\version "2.13.19"
+
+\header {
+  texidoc="
+If @code{includeGraceNotes} is enabled, lyric extenders work as
+expected also for syllables starting under grace notes.
+"
+}
+
+\relative c' {
+  c2 \grace { c16([ d e f] } g2)
+  f1
+}
+\addlyrics {
+  \set includeGraceNotes = ##t
+  _ Ah __ fa
+}
diff --git a/input/regression/lyrics-includegraces.ly b/input/regression/lyrics-includegraces.ly
new file mode 100644 (file)
index 0000000..a70e643
--- /dev/null
@@ -0,0 +1,26 @@
+\version "2.13.19"
+
+\header {
+  texidoc="
+Setting @code{includeGraceNotes} enables lyrics syllables to be
+assigned to grace notes.
+"
+}
+
+\relative c' {
+  f4 \appoggiatura a32 b4
+  \grace { f16[ a16] } b2
+  \afterGrace b2 { f16[ a16] }
+  \appoggiatura a32 b4
+  \acciaccatura a8 b4
+}
+\addlyrics {
+  normal
+  \set includeGraceNotes = ##t
+  case,
+  gra -- ce case,
+  after -- grace case,
+  \set ignoreMelismata = ##t
+  app. case,
+  acc. case.
+}
index 250430ba3f636c8ae31e429a8b4d85f916f69678..d38adce683034f520361c508eb3df16648608f19 100644 (file)
@@ -113,7 +113,7 @@ Extender_engraver::stop_translation_timestep ()
   if (extender_ || pending_extender_)
     {
       Context *voice = get_voice_to_lyrics (context ());
-      Grob *h = voice ? get_current_note_head (voice) : 0;
+      Grob *h = voice ? get_current_note_head (voice, to_boolean (get_property ("includeGraceNotes"))) : 0;
 
       if (h)
        {
@@ -190,7 +190,8 @@ ADD_TRANSLATOR (Extender_engraver,
                "LyricExtender ",
 
                /* read */
-               "extendersOverRests ",
+               "extendersOverRests "
+               "includeGraceNotes ",
 
                /* write */
                ""
index 45e94ab9e5593f78861dff6dc48e27080eceab63..4aa6c5580ece95f714a953a6e216c2095ecfc450 100644 (file)
@@ -146,7 +146,7 @@ Context *find_context_below (Context *where,
 bool melisma_busy (Context *);
 
 Context *get_voice_to_lyrics (Context *lyrics);
-Grob *get_current_note_head (Context *voice);
+Grob *get_current_note_head (Context *voice, bool include_grace_notes);
 Grob *get_current_rest (Context *voice);
 DECLARE_UNSMOB (Context, context);
 
index 7b304cf67efa1c4ae1ba6c2cafae57ce12918cf4..7b4732ebf57c9acbbbc1430aaada69b16ebc458b 100644 (file)
@@ -293,14 +293,13 @@ Lyric_combine_music_iterator::process (Moment /* when */)
       set_music_context (0);
     }
 
-
   if (music_context_
       && (start_new_syllable () ||
          (busy_moment_ >= pending_grace_moment_))
       && lyric_iter_->ok ())
     {
       Moment now = music_context_->now_mom ();
-      if (now.grace_part_)
+      if (now.grace_part_ && !to_boolean (lyrics_context_->get_property ("includeGraceNotes")))
        {
          pending_grace_moment_ = now;
          pending_grace_moment_.grace_part_ = Rational (0);
@@ -310,7 +309,7 @@ Lyric_combine_music_iterator::process (Moment /* when */)
        {
          pending_grace_moment_.set_infinite (1);
        }
-      
+
       Moment m = lyric_iter_->pending_moment ();
       lyrics_context_->set_property (ly_symbol2scm ("associatedVoiceContext"),
                                     music_context_->self_scm ());
index 0e18fbef229842c5ca49279979de61f81228f285..0d4392d48639b152148ec441633be16c7f49f514 100644 (file)
@@ -124,7 +124,7 @@ get_voice_to_lyrics (Context *lyrics)
 }
 
 Grob *
-get_current_note_head (Context *voice)
+get_current_note_head (Context *voice, bool include_grace_notes)
 {
   Moment now = voice->now_mom ();
   for (SCM s = voice->get_property ("busyGrobs");
@@ -138,10 +138,13 @@ get_current_note_head (Context *voice)
          continue;
        }
 
-      if (end_mom->main_part_ > now.main_part_
-         && dynamic_cast<Item *> (g)
-         && Note_head::has_interface (g))
-       return g;
+      if (((end_mom->main_part_ > now.main_part_) ||
+           (include_grace_notes && end_mom->grace_part_ > now.grace_part_))
+          && dynamic_cast<Item *> (g)
+          && Note_head::has_interface (g))
+        {
+         return g;
+        }
     }
 
   return 0;
@@ -156,7 +159,8 @@ Lyric_engraver::stop_translation_timestep ()
 
       if (voice)
        {
-         Grob *head = get_current_note_head (voice);
+         bool include_grace_notes = to_boolean (get_property ("includeGraceNotes"));
+         Grob *head = get_current_note_head (voice, include_grace_notes);
 
          if (head)
            {
@@ -188,6 +192,7 @@ ADD_TRANSLATOR (Lyric_engraver,
 
                /* read */
                "ignoreMelismata "
+               "includeGraceNotes "
                "lyricMelismaAlignment ",
 
                /* write */
index 16b2538ed36c6b054a7bac76f863923b4976daee..5f937f6a31170607599e78f928df621f94381112 100644 (file)
@@ -267,6 +267,8 @@ string selector for tablature notation.")
 printed as numbers, but only as extender lines.")
      (implicitTimeSignatureVisibility ,vector? "break visibility for
 the default time signature.")
+     (includeGraceNotes ,boolean? "Do not ignore grace notes for
+@rinternals{Lyrics}.")
      (instrumentCueName ,markup? "The name to print if another
 instrument is to be taken.")
      (instrumentEqualizer ,procedure? "A function taking a string