]> 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.
 
 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
 
 
 @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.
 
 @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
 @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 ());
   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)
        {
 
       if (h)
        {
@@ -190,7 +190,8 @@ ADD_TRANSLATOR (Extender_engraver,
                "LyricExtender ",
 
                /* read */
                "LyricExtender ",
 
                /* read */
-               "extendersOverRests ",
+               "extendersOverRests "
+               "includeGraceNotes ",
 
                /* write */
                ""
 
                /* 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);
 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);
 
 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);
     }
 
       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 (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);
        {
          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);
        }
        {
          pending_grace_moment_.set_infinite (1);
        }
-      
+
       Moment m = lyric_iter_->pending_moment ();
       lyrics_context_->set_property (ly_symbol2scm ("associatedVoiceContext"),
                                     music_context_->self_scm ());
       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 *
 }
 
 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");
 {
   Moment now = voice->now_mom ();
   for (SCM s = voice->get_property ("busyGrobs");
@@ -138,10 +138,13 @@ get_current_note_head (Context *voice)
          continue;
        }
 
          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;
     }
 
   return 0;
@@ -156,7 +159,8 @@ Lyric_engraver::stop_translation_timestep ()
 
       if (voice)
        {
 
       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)
            {
 
          if (head)
            {
@@ -188,6 +192,7 @@ ADD_TRANSLATOR (Lyric_engraver,
 
                /* read */
                "ignoreMelismata "
 
                /* read */
                "ignoreMelismata "
+               "includeGraceNotes "
                "lyricMelismaAlignment ",
 
                /* write */
                "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.")
 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
      (instrumentCueName ,markup? "The name to print if another
 instrument is to be taken.")
      (instrumentEqualizer ,procedure? "A function taking a string