+ Music *m = unsmob_music (get_music ()->get_property ("element"));
+ lyric_iter_ = unsmob_iterator (get_iterator (m));
+ if (!lyric_iter_)
+ return;
+ lyrics_context_ = find_context_below (lyric_iter_->get_outlet (),
+ ly_symbol2scm ("Lyrics"), "");
+
+ lyricsto_voice_name_ = get_music ()->get_property ("associated-context");
+
+ 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 = lyrics_context_->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
+ create one with a different name, and then we will not find that
+ one.
+ */
+}
+
+IMPLEMENT_LISTENER (Lyric_combine_music_iterator, check_new_context)
+void
+Lyric_combine_music_iterator::check_new_context (SCM sev)
+{
+ // TODO: Check first if type=Voice and if id matches
+ (void)sev;
+
+ 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"));
+ }
+}
+
+/*
+ Look for a suitable voice to align lyrics to.
+
+ Returns 0 if nothing should change; i.e., if we already listen to the
+ right voice, or if we don't yet listen to a voice but no appropriate
+ voice could be found.
+*/
+Context *
+Lyric_combine_music_iterator::find_voice ()
+{
+ SCM voice_name = lyricsto_voice_name_;
+ SCM running = lyrics_context_
+ ? lyrics_context_->get_property ("associatedVoice")
+ : SCM_EOL;
+
+ if (scm_is_string (running))
+ voice_name = running;
+
+ if (scm_is_string (voice_name)
+ && (!music_context_ || ly_scm2string (voice_name) != music_context_->id_string ()))
+ {
+ Context *t = get_outlet ();
+ while (t && t->get_parent_context ())
+ t = t->get_parent_context ();
+
+ string name = ly_scm2string (voice_name);
+ return find_context_below (t, ly_symbol2scm ("Voice"), name);
+ }
+
+ return 0;