X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fnew-lyric-combine-music-iterator.cc;h=0144e9e5e1ed7426cb9882fbda687d5465fb7700;hb=f0b7ccb46df75c89e1f69dd4ef42ab370f1847fe;hp=1b3a14a84a5716b83999c74ccd37ce521cf171b2;hpb=ef8093ad63c7a00a169cf88d71368b204dd65655;p=lilypond.git diff --git a/lily/new-lyric-combine-music-iterator.cc b/lily/new-lyric-combine-music-iterator.cc index 1b3a14a84a..0144e9e5e1 100644 --- a/lily/new-lyric-combine-music-iterator.cc +++ b/lily/new-lyric-combine-music-iterator.cc @@ -1,56 +1,63 @@ -/* -new-lyric-combine-iterator.cc -- implement New_lyric_combine_music_iterator - -source file of the GNU LilyPond music typesetter +/* + new-lyric-combine-iterator.cc -- implement New_lyric_combine_music_iterator -(c) 2004 Han-Wen Nienhuys + source file of the GNU LilyPond music typesetter - */ + (c) 2004--2005 Han-Wen Nienhuys +*/ -#include "translator-group.hh" -#include "lyric-combine-music.hh" +#include "context.hh" #include "event.hh" #include "grob.hh" #include "music-iterator.hh" - class New_lyric_combine_music_iterator : public Music_iterator { public: New_lyric_combine_music_iterator (); - New_lyric_combine_music_iterator (New_lyric_combine_music_iterator const&src); - DECLARE_SCHEME_CALLBACK(constructor, ()); + New_lyric_combine_music_iterator (New_lyric_combine_music_iterator const &src); + DECLARE_SCHEME_CALLBACK (constructor, ()); protected: virtual void construct_children (); virtual Moment pending_moment () const; - virtual void do_quit(); + virtual void do_quit (); virtual void process (Moment); virtual Music_iterator *try_music_in_children (Music *) const; virtual bool run_always ()const; virtual bool ok () const; virtual void derived_mark () const; - virtual void derived_substitute (Translator_group*,Translator_group*); + virtual void derived_substitute (Context *, Context *); private: - bool start_new_syllable () ; - void find_thread (); - - Translator_group * lyrics_context_; - Translator_group* music_context_; - Music_iterator * lyric_iter_; + bool start_new_syllable (); + void find_voice (); + + bool music_found_; + bool made_association_; + Context *lyrics_context_; + Context *music_context_; + SCM lyricsto_voice_name_; + + Music_iterator *lyric_iter_; }; /* Ugh, why static? - */ +*/ static Music *busy_ev; static Music *start_ev; static Music *melisma_playing_ev; New_lyric_combine_music_iterator::New_lyric_combine_music_iterator () { - lyric_iter_ =0; - music_context_ =0; + music_found_ = false; + made_association_ = false; + lyric_iter_ = 0; + music_context_ = 0; lyrics_context_ = 0; + + /* + Ugh. out of place here. + */ if (!busy_ev) { busy_ev @@ -66,20 +73,20 @@ bool New_lyric_combine_music_iterator::start_new_syllable () { bool b = music_context_->try_music (busy_ev); - + if (!b) return false; if (!lyrics_context_) return false; - + if (!to_boolean (lyrics_context_->get_property ("ignoreMelismata"))) { bool m = music_context_->try_music (melisma_playing_ev); if (m) return false; } - + return true; } @@ -89,7 +96,7 @@ New_lyric_combine_music_iterator::pending_moment () const Moment m; m.set_infinite (1); - + return m; } @@ -106,7 +113,7 @@ New_lyric_combine_music_iterator::ok () const } void -New_lyric_combine_music_iterator::derived_mark()const +New_lyric_combine_music_iterator::derived_mark ()const { if (lyric_iter_) scm_gc_mark (lyric_iter_->self_scm ()); @@ -117,130 +124,131 @@ New_lyric_combine_music_iterator::derived_mark()const } void -New_lyric_combine_music_iterator::derived_substitute (Translator_group*f, Translator_group*t) +New_lyric_combine_music_iterator::derived_substitute (Context *f, Context *t) { if (lyric_iter_) - lyric_iter_->substitute_outlet (f,t); - if (lyrics_context_ && lyrics_context_==f) + lyric_iter_->substitute_outlet (f, t); + if (lyrics_context_ && lyrics_context_ == f) lyrics_context_ = t; if (music_context_ && music_context_ == f) - music_context_ = t; -} - -/* - ID == "" means accept any ID. - */ -Translator_group * -find_context_below (Translator_group * where, - String type, String id) -{ - if (where->is_alias (ly_symbol2scm (type.to_str0 ()))) - { - if (id == "" || where->id_string_ == id) - return where; - } - - Translator_group * found = 0; - for (SCM s = where->trans_group_list_; - !found && gh_pair_p (s); s = gh_cdr (s)) - { - Translator_group * tr = dynamic_cast (unsmob_translator (gh_car (s))); - - found = find_context_below (tr, type, id); - } - - return found; + music_context_ = t; } - - void New_lyric_combine_music_iterator::construct_children () { - Music *m = unsmob_music (get_music ()->get_mus_property ("element")); + Music *m = unsmob_music (get_music ()->get_property ("element")); lyric_iter_ = unsmob_iterator (get_iterator (m)); - find_thread (); - + lyricsto_voice_name_ = get_music ()->get_property ("associated-context"); + + find_voice (); + if (lyric_iter_) lyrics_context_ = find_context_below (lyric_iter_->get_outlet (), - "LyricsVoice", ""); + ly_symbol2scm ("Lyrics"), ""); /* - We do not create a LyricsVoice context, because the user might + 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. - */ + */ } void -New_lyric_combine_music_iterator::find_thread () +New_lyric_combine_music_iterator::find_voice () { - if (!music_context_) + 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 ())) + { + /* + (spaghettini). + + Need to set associatedVoiceContext again + */ + if (music_context_) + made_association_ = false; + + Context *t = get_outlet (); + while (t && t->get_parent_context ()) + t = t->get_parent_context (); + + String name = ly_scm2string (voice_name); + Context *voice = find_context_below (t, ly_symbol2scm ("Voice"), name); + + if (voice) + music_context_ = voice; + } + + if (lyrics_context_ && music_context_) { - SCM voice_name = get_music ()->get_mus_property ("associated-context"); - - if (gh_string_p (voice_name)) + if (!made_association_) { - Translator_group *t = get_outlet (); - while (t && t->daddy_trans_) - t = t->daddy_trans_; - - String name = ly_scm2string (voice_name); - Translator_group *voice = find_context_below (t, "Voice", name); - Translator_group *thread = 0; - if (voice) - thread = find_context_below (voice, "Thread", ""); - else - get_music ()->origin ()->warning (_f ("Cannot find Voice: %s\n", - name.to_str0 ())); - - if (thread) - music_context_ = thread; - - if (lyrics_context_ && voice) - lyrics_context_->set_property ("associatedVoiceContext", - voice->self_scm ()); + made_association_ = true; + lyrics_context_->set_property ("associatedVoiceContext", + music_context_->self_scm ()); } } } void -New_lyric_combine_music_iterator::process (Moment ) +New_lyric_combine_music_iterator::process (Moment) { - find_thread (); + find_voice (); if (!music_context_) - return ; - - if (!music_context_->daddy_trans_) + return; + + if (!music_context_->get_parent_context ()) { - music_context_ = 0; + /* + The melody has died. + We die too. + */ if (lyrics_context_) lyrics_context_->unset_property (ly_symbol2scm ("associatedVoiceContext")); + lyric_iter_ = 0; + music_context_ = 0; } - + if (music_context_ && start_new_syllable () && lyric_iter_->ok ()) { - Moment m= lyric_iter_->pending_moment (); + Moment m = lyric_iter_->pending_moment (); lyric_iter_->process (m); + + music_found_ = true; } } void New_lyric_combine_music_iterator::do_quit () { - if (lyric_iter_) - lyric_iter_->quit(); -} + if (!music_found_) + { + SCM voice_name = get_music ()->get_property ("associated-context"); + + String name; + if (scm_is_string (voice_name)) + name = ly_scm2string (voice_name); + get_music ()->origin ()->warning (_f ("cannot find Voice `%s'", + name.to_str0 ()) + "\n"); + } + if (lyric_iter_) + lyric_iter_->quit (); +} -Music_iterator* +Music_iterator * New_lyric_combine_music_iterator::try_music_in_children (Music *m) const { return lyric_iter_->try_music (m); } - IMPLEMENT_CTOR_CALLBACK (New_lyric_combine_music_iterator);