]> git.donarmstrong.com Git - lilypond.git/commitdiff
Fix #221.
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Fri, 5 Jan 2007 13:38:05 +0000 (14:38 +0100)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Fri, 5 Jan 2007 13:38:05 +0000 (14:38 +0100)
Listen to CreateContext in all cases, so we can respond to
associatedVoice changes in time.

Conflicts:

lily/lyric-combine-music-iterator.cc

input/regression/lyric-combine-switch-voice.ly [new file with mode: 0644]
lily/lyric-combine-music-iterator.cc

diff --git a/input/regression/lyric-combine-switch-voice.ly b/input/regression/lyric-combine-switch-voice.ly
new file mode 100644 (file)
index 0000000..b0b6d19
--- /dev/null
@@ -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
+  }
+>>
+
+
+
index ade6fbefe977625a62752932821a734c7bce597d..bd679e633cecaf8da6336200138a73af76b68fcb 100644 (file)
 #include "music-iterator.hh"
 #include "music.hh"
 
+/*
+  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:
@@ -33,7 +47,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);
@@ -76,6 +90,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)
     {
@@ -86,13 +101,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;
 
@@ -170,15 +183,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
@@ -192,15 +203,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"));
     }
 }
 
@@ -259,10 +270,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;