From 6a3360c40308285434e06a1de031efb073c015fa Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Fri, 5 Jan 2007 12:25:59 +0100 Subject: [PATCH] Fix #221. Listen to CreateContext in all cases, so we can respond to associatedVoice changes in time. --- .../regression/lyric-combine-switch-voice.ly | 44 ++++++++++++++++ lily/lyric-combine-music-iterator.cc | 50 +++++++++++-------- 2 files changed, 74 insertions(+), 20 deletions(-) create mode 100644 input/regression/lyric-combine-switch-voice.ly diff --git a/input/regression/lyric-combine-switch-voice.ly b/input/regression/lyric-combine-switch-voice.ly new file mode 100644 index 0000000000..b0b6d1952e --- /dev/null +++ b/input/regression/lyric-combine-switch-voice.ly @@ -0,0 +1,44 @@ +\header { + + texidoc = "Switching melody to a different voice works even +the switch occurs together with context instantiation." + +} + +\version "2.10.8" + +<< + \relative \new Voice = "lahlah" { + \set Staff.autoBeaming = ##f + c4 + << + \new Voice = "alternative" { + \voiceOne + \times 2/3 { + %% show associations clearly. + \override NoteColumn #'force-hshift = #-3 + r8 f g + } + } + { + \voiceTwo + f8.[ g16] + \oneVoice + } >> + a8( b) c + } + \new Lyrics \lyricsto "lahlah" { + %% Tricky: need to set associatedVoice + %% one syllable too soon! + + \set associatedVoice = alternative % applies to "ran" + Ty -- + ran -- + \set associatedVoice = lahlah % applies to "sau" + no -- + sau -- rus Rex + } +>> + + + diff --git a/lily/lyric-combine-music-iterator.cc b/lily/lyric-combine-music-iterator.cc index 61500e8af2..bb47a09f38 100644 --- a/lily/lyric-combine-music-iterator.cc +++ b/lily/lyric-combine-music-iterator.cc @@ -16,8 +16,19 @@ #include "music.hh" /* - Deprecated - junkme. - */ + This iterator is hairy. It tracks both lyric and melody contexts, + and has a complicated communication route, reading/writing + properties in both. + + In the future, this should rather be done with + + \interpretAsMelodyFor { MUSIC } { LYRICS LYRICS LYRICS } + + This can run an interpret step on MUSIC, generating a stream. Then + the stream can be perused at leisure to apply durations to all of + the LYRICS. +*/ + class Lyric_combine_music_iterator : public Music_iterator { public: @@ -35,7 +46,7 @@ protected: virtual void derived_substitute (Context *, Context *); void set_music_context (Context *to); private: - bool start_new_syllable (); + bool start_new_syllable () const; Context *find_voice (); DECLARE_LISTENER (set_busy); DECLARE_LISTENER (check_new_context); @@ -78,6 +89,7 @@ Lyric_combine_music_iterator::set_music_context (Context *to) music_context_->event_source()->remove_listener (GET_LISTENER (set_busy), ly_symbol2scm ("music-event")); lyrics_context_->unset_property (ly_symbol2scm ("associatedVoiceContext")); } + music_context_ = to; if (to) { @@ -88,13 +100,11 @@ Lyric_combine_music_iterator::set_music_context (Context *to) } bool -Lyric_combine_music_iterator::start_new_syllable () +Lyric_combine_music_iterator::start_new_syllable () const { if (!busy_) return false; - busy_ = false; - if (!lyrics_context_) return false; @@ -172,15 +182,13 @@ Lyric_combine_music_iterator::construct_children () Context *voice = find_voice (); if (voice) set_music_context (voice); - else - { - /* - Wait for a Create_context event. If this isn't done, lyrics can be - delayed when voices are created implicitly. - */ - Global_context *g = get_outlet ()->get_global_context (); - g->events_below ()->add_listener (GET_LISTENER (check_new_context), ly_symbol2scm ("CreateContext")); - } + + /* + Wait for a Create_context event. If this isn't done, lyrics can be + delayed when voices are created implicitly. + */ + Global_context *g = get_outlet ()->get_global_context (); + g->events_below ()->add_listener (GET_LISTENER (check_new_context), ly_symbol2scm ("CreateContext")); /* We do not create a Lyrics context, because the user might @@ -194,15 +202,15 @@ void Lyric_combine_music_iterator::check_new_context (SCM sev) { // TODO: Check first if type=Voice and if id matches - (void)sev; - + Stream_event * ev = unsmob_stream_event (sev); + if (ev->get_property ("type") != ly_symbol2scm ("Voice")) + return ; + Context *voice = find_voice (); + if (voice) { set_music_context (voice); - - Global_context *g = voice->get_global_context (); - g->events_below ()->remove_listener (GET_LISTENER (check_new_context), ly_symbol2scm ("CreateContext")); } } @@ -261,10 +269,12 @@ Lyric_combine_music_iterator::process (Moment) set_music_context (0); } + if (music_context_ && (start_new_syllable () || pending_grace_lyric_) && lyric_iter_->ok ()) { + busy_ = false; if (music_context_->now_mom ().grace_part_) { pending_grace_lyric_ = true; -- 2.39.5