From db0bce29959deca64a1a3b9f98ee9b28e6dae10d Mon Sep 17 00:00:00 2001 From: Richard Gay Date: Sat, 17 Apr 2010 00:19:48 +0200 Subject: [PATCH] includeGraceNotes: lyrics syllables of grace notes * 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 | 45 +++++++++++++++++++++ Documentation/notation/vocal.itely | 46 ++++++++++++++++++++++ input/regression/lyric-extender-includegraces.ly | 17 ++++++++ input/regression/lyrics-includegraces.ly | 26 ++++++++++++ lily/extender-engraver.cc | 5 +- lily/include/context.hh | 2 +- lily/lyric-combine-music-iterator.cc | 5 +- lily/lyric-engraver.cc | 17 +++++--- scm/define-context-properties.scm | 2 + 9 files changed, 153 insertions(+), 12 deletions(-) create mode 100644 input/regression/lyric-extender-includegraces.ly create mode 100644 input/regression/lyrics-includegraces.ly diff --git a/Documentation/de/notation/vocal.itely b/Documentation/de/notation/vocal.itely index 9393cc6..dfab7ca 100644 --- a/Documentation/de/notation/vocal.itely +++ b/Documentation/de/notation/vocal.itely @@ -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. address@hidden Silben zu Verzierungsnoten hinzufügen + +Normalerweise werden Verzierungsnoten (z.B. durch @code{\grace}) bei address@hidden keine Silben zugeordnet. Dieses Verhalten kann +geändert werden, wie das folgende Beispiel zeigt. + address@hidden,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. +} address@hidden lilypond + address@hidden +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 address@hidden verwendet werden: + address@hidden,ragged-right,quote] +<< + \new Voice = melody \relative c' { + \grace { c16[( d e f] } + g1) f + } + \new Lyrics \with { includeGraceNotes = ##t } + \lyricsto melody { + Ah __ fa + } +>> address@hidden lilypond @subsubheading Zu einer alternativen Melodie umschalten diff --git a/Documentation/notation/vocal.itely b/Documentation/notation/vocal.itely index 34f6cc4..47a6cb2 100644 --- a/Documentation/notation/vocal.itely +++ b/Documentation/notation/vocal.itely @@ -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. address@hidden 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: + address@hidden,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. +} address@hidden lilypond + address@hidden +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: + address@hidden,ragged-right,quote] +<< + \new Voice = melody \relative c' { + \grace { c16[( d e f] } + g1) f + } + \new Lyrics \with { includeGraceNotes = ##t } + \lyricsto melody { + Ah __ fa + } +>> address@hidden 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 index 0000000..c8a175b --- /dev/null +++ b/input/regression/lyric-extender-includegraces.ly @@ -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 index 0000000..a70e643 --- /dev/null +++ b/input/regression/lyrics-includegraces.ly @@ -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. +} diff --git a/lily/extender-engraver.cc b/lily/extender-engraver.cc index 250430b..d38adce 100644 --- a/lily/extender-engraver.cc +++ b/lily/extender-engraver.cc @@ -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 */ "" diff --git a/lily/include/context.hh b/lily/include/context.hh index 45e94ab..4aa6c55 100644 --- a/lily/include/context.hh +++ b/lily/include/context.hh @@ -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); diff --git a/lily/lyric-combine-music-iterator.cc b/lily/lyric-combine-music-iterator.cc index 7b304cf..7b4732e 100644 --- a/lily/lyric-combine-music-iterator.cc +++ b/lily/lyric-combine-music-iterator.cc @@ -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 ()); diff --git a/lily/lyric-engraver.cc b/lily/lyric-engraver.cc index 0e18fbe..0d4392d 100644 --- a/lily/lyric-engraver.cc +++ b/lily/lyric-engraver.cc @@ -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 (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 (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 */ diff --git a/scm/define-context-properties.scm b/scm/define-context-properties.scm index 16b2538..5f937f6 100644 --- a/scm/define-context-properties.scm +++ b/scm/define-context-properties.scm @@ -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 address@hidden") (instrumentCueName ,markup? "The name to print if another instrument is to be taken.") (instrumentEqualizer ,procedure? "A function taking a string -- 1.6.4.4