X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fpart-combine-iterator.cc;h=9d2a520f7c0e0fbf6bec90547d3b3daf8d4a17a5;hb=75eebcb49e52d296b1da3e1074e0825d2c780db4;hp=39e3ea2ecffc40a8230cf7dcf92e9457178d9660;hpb=304b5f3aa7eee7b0ff8d4ba7526a1410735f6e74;p=lilypond.git diff --git a/lily/part-combine-iterator.cc b/lily/part-combine-iterator.cc index 39e3ea2ecf..9d2a520f7c 100644 --- a/lily/part-combine-iterator.cc +++ b/lily/part-combine-iterator.cc @@ -1,33 +1,32 @@ -/* - new-part-combine-music-iterator.cc -- implement Part_combine_iterator +/* + new-part-combine-music-iterator.cc -- implement Part_combine_iterator - source file of the GNU LilyPond music typesetter - - (c) 2004 Han-Wen Nienhuys + source file of the GNU LilyPond music typesetter + + (c) 2004--2006 Han-Wen Nienhuys */ #include "context.hh" -#include "event.hh" +#include "music.hh" #include "music-sequence.hh" #include "lily-guile.hh" #include "warn.hh" #include "music-iterator.hh" -#include "interpretation-context-handle.hh" class Part_combine_iterator : public Music_iterator { public: Part_combine_iterator (); - DECLARE_SCHEME_CALLBACK (constructor, ()); + DECLARE_SCHEME_CALLBACK (constructor, ()); protected: - virtual void derived_substitute (Context *f, Context *t) ; + virtual void derived_substitute (Context *f, Context *t); virtual void derived_mark () const; Part_combine_iterator (Part_combine_iterator const &); 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; @@ -35,30 +34,40 @@ protected: virtual bool ok () const; private: - Music_iterator * first_iter_; - Music_iterator * second_iter_; - + Music_iterator *first_iter_; + Music_iterator *second_iter_; + Moment start_moment_; + SCM split_list_; - enum Status { - APART, TOGETHER, - SOLO1, SOLO2, - UNISONO, UNISILENCE, - }; + enum Status + { + APART, + TOGETHER, + SOLO1, + SOLO2, + UNISONO, + UNISILENCE, + }; Status state_; Status playing_state_; /* - TODO: this is getting of hand... - */ - Interpretation_context_handle one_; - Interpretation_context_handle two_; - Interpretation_context_handle null_; - Interpretation_context_handle shared_; - Interpretation_context_handle solo_; - - void substitute_both (Context * to1, - Context * to2); + Should be SOLO1 or SOLO2 + */ + Status last_playing_; + + /* + TODO: this is getting of hand... + */ + Context_handle one_; + Context_handle two_; + Context_handle null_; + Context_handle shared_; + Context_handle solo_; + + void substitute_both (Context *to1, + Context *to2); void kill_mmrest (Context *); void chords_together (); @@ -68,6 +77,22 @@ private: void unisono (bool silent); }; +static Music *busy_playing_event; + +void +Part_combine_iterator::do_quit () +{ + if (first_iter_) + first_iter_->quit (); + if (second_iter_) + second_iter_->quit (); + + null_.set_context (0); + one_.set_context (0); + two_.set_context (0); + shared_.set_context (0); + solo_.set_context (0); +} Part_combine_iterator::Part_combine_iterator () { @@ -76,6 +101,12 @@ Part_combine_iterator::Part_combine_iterator () split_list_ = SCM_EOL; state_ = APART; playing_state_ = APART; + + if (!busy_playing_event) + { + busy_playing_event + = make_music_by_name (ly_symbol2scm ("BusyPlayingEvent")); + } } void @@ -89,27 +120,10 @@ Part_combine_iterator::derived_mark () const void Part_combine_iterator::derived_substitute (Context *f, - Context *t) + Context *t) { if (first_iter_) - first_iter_->substitute_outlet (f,t); - if (second_iter_) - second_iter_->substitute_outlet (f,t); -} - -void -Part_combine_iterator::do_quit () -{ - if (first_iter_) - first_iter_->quit (); - if (second_iter_) - second_iter_->quit (); - - null_.set_translator (0); - one_ .set_translator (0); - two_.set_translator (0); - shared_.set_translator (0); - solo_.set_translator (0); + first_iter_->substitute_outlet (f, t); } Moment @@ -118,10 +132,10 @@ Part_combine_iterator::pending_moment () const Moment p; p.set_infinite (1); if (first_iter_->ok ()) - p = p pending_moment (); + p = min (p, first_iter_->pending_moment ()); if (second_iter_->ok ()) - p = p pending_moment (); + p = min (p, second_iter_->pending_moment ()); return p; } @@ -145,11 +159,10 @@ Part_combine_iterator::chords_together () } } - void -Part_combine_iterator::kill_mmrest (Context * tg) +Part_combine_iterator::kill_mmrest (Context *tg) { - static Music * mmrest; + static Music *mmrest; if (!mmrest) { mmrest = make_music_by_name (ly_symbol2scm ("MultiMeasureRestEvent")); @@ -169,73 +182,81 @@ Part_combine_iterator::solo1 () state_ = SOLO1; substitute_both (solo_.get_outlet (), null_.get_outlet ()); - + kill_mmrest (two_.get_outlet ()); kill_mmrest (shared_.get_outlet ()); if (playing_state_ != SOLO1) { - static Music* event; + static Music *event; if (!event) event = make_music_by_name (ly_symbol2scm ("SoloOneEvent")); - first_iter_-> try_music_in_children (event); + first_iter_->try_music_in_children (event); } playing_state_ = SOLO1; } } void -Part_combine_iterator::substitute_both (Context * to1, - Context * to2) +Part_combine_iterator::substitute_both (Context *to1, + Context *to2) { - Context *tos[] = {to1,to2}; - Music_iterator *mis[] = {first_iter_, second_iter_}; - Interpretation_context_handle *hs[] = { + Context *tos[] = {to1, to2}; + Music_iterator *mis[] = {first_iter_, second_iter_}; + Context_handle *hs[] + = { &null_, &one_, &two_, - &shared_, &solo_, + &shared_, &solo_, 0 }; - - for (int i = 0; i < 2 ; i++) + + for (int i = 0; i < 2; i++) { - for (int j = 0; hs[j]; j++) + for (int j = 0; hs[j]; j++) if (hs[j]->get_outlet () != tos[i]) - mis[i]->substitute_outlet (hs[j]->get_outlet (), tos[i]); + mis[i]->substitute_outlet (hs[j]->get_outlet (), tos[i]); } - for (int j = 0; hs[j]; j++) + for (int j = 0; hs[j]; j++) { - Context * t = hs[j]->get_outlet (); + Context *t = hs[j]->get_outlet (); if (t != to1 && t != to2) kill_mmrest (t); } } - void Part_combine_iterator::unisono (bool silent) { Status newstate = (silent) ? UNISILENCE : UNISONO; - + if (newstate == state_) - return; + return; else { - substitute_both (shared_.get_outlet (), null_.get_outlet ()); - - kill_mmrest (two_.get_outlet ()); + /* + If we're coming from SOLO2 state, we might have kill mmrests + in the 1st voice, so in that case, we use the second voice + as a basis for events. + */ + Context *c1 = (last_playing_ == SOLO2) ? null_.get_outlet () : shared_.get_outlet (); + Context *c2 = (last_playing_ == SOLO2) ? shared_.get_outlet () : null_.get_outlet (); + substitute_both (c1, c2); + kill_mmrest ((last_playing_ == SOLO2) + ? one_.get_outlet () : two_.get_outlet ()); kill_mmrest (shared_.get_outlet ()); if (playing_state_ != UNISONO && newstate == UNISONO) { - static Music* event; + static Music *event; if (!event) event = make_music_by_name (ly_symbol2scm ("UnisonoEvent")); - first_iter_-> try_music_in_children (event); + (last_playing_ == SOLO2 ? second_iter_ : first_iter_) + ->try_music_in_children (event); playing_state_ = UNISONO; } state_ = newstate; @@ -250,16 +271,16 @@ Part_combine_iterator::solo2 () else { state_ = SOLO2; - + substitute_both (null_.get_outlet (), solo_.get_outlet ()); - + if (playing_state_ != SOLO2) { - static Music* event; + static Music *event; if (!event) event = make_music_by_name (ly_symbol2scm ("SoloTwoEvent")); - second_iter_-> try_music_in_children (event); + second_iter_->try_music_in_children (event); playing_state_ = SOLO2; } } @@ -280,65 +301,63 @@ Part_combine_iterator::apart (bool silent) } } - void Part_combine_iterator::construct_children () { - split_list_ = get_music ()->get_property ("split-list"); - SCM lst = get_music ()->get_property ("elements"); + start_moment_ = get_outlet ()->now_mom (); + split_list_ = get_music ()->get_property ("split-list"); + SCM lst = get_music ()->get_property ("elements"); SCM props = scm_list_n (/* used to have tweaks here. - */ - + */ + SCM_UNDEFINED); Context *tr - = get_outlet ()->find_create_context (ly_symbol2scm ("Voice"), - "shared",props); + = get_outlet ()->find_create_context (ly_symbol2scm ("Voice"), + "shared", props); - shared_.set_translator (tr); + shared_.set_context (tr); /* If we don't, we get a new staff for every Voice. - */ - set_translator (tr); + */ + set_context (tr); Context *solo_tr - = get_outlet ()->find_create_context (ly_symbol2scm ("Voice"), - "solo",props); + = get_outlet ()->find_create_context (ly_symbol2scm ("Voice"), + "solo", props); - solo_ .set_translator (solo_tr); + solo_.set_context (solo_tr); Context *null - = get_outlet ()->find_create_context (ly_symbol2scm ("Devnull"), - "", SCM_EOL); + = get_outlet ()->find_create_context (ly_symbol2scm ("Devnull"), + "", SCM_EOL); if (!null) - programming_error ("No Devnull found?"); - - null_.set_translator (null); + programming_error ("no Devnull found"); - Context *one = tr->find_create_context (ly_symbol2scm ("Voice"), - "one", props); + null_.set_context (null); - one_.set_translator (one); + Context *one = tr->find_create_context (ly_symbol2scm ("Voice"), + "one", props); - set_translator (one); - first_iter_ = unsmob_iterator (get_iterator (unsmob_music (gh_car (lst)))); + one_.set_context (one); + set_context (one); + first_iter_ = unsmob_iterator (get_iterator (unsmob_music (scm_car (lst)))); Context *two = tr->find_create_context (ly_symbol2scm ("Voice"), - "two", props); - two_.set_translator (two); - set_translator (two); - second_iter_ = unsmob_iterator (get_iterator (unsmob_music (gh_cadr (lst)))); - - - set_translator (tr); + "two", props); + two_.set_context (two); + set_context (two); + second_iter_ = unsmob_iterator (get_iterator (unsmob_music (scm_cadr (lst)))); + set_context (tr); - char const * syms[] = { + char const *syms[] + = { "Stem", "DynamicLineSpanner", "Tie", @@ -349,17 +368,16 @@ Part_combine_iterator::construct_children () "Script", 0 }; - - for (char const**p = syms; *p; p++) + + for (char const **p = syms; *p; p++) { SCM sym = ly_symbol2scm (*p); execute_pushpop_property (one, sym, - ly_symbol2scm ("direction"), gh_int2scm (1)); + ly_symbol2scm ("direction"), scm_from_int (1)); execute_pushpop_property (two, sym, - ly_symbol2scm ("direction"), gh_int2scm (-1)); + ly_symbol2scm ("direction"), scm_from_int (-1)); } - } void @@ -367,15 +385,15 @@ Part_combine_iterator::process (Moment m) { Moment now = get_outlet ()->now_mom (); Moment *splitm = 0; - - for (; gh_pair_p (split_list_); split_list_ = gh_cdr (split_list_)) + + for (; scm_is_pair (split_list_); split_list_ = scm_cdr (split_list_)) { - splitm = unsmob_moment (gh_caar (split_list_)); - if (*splitm > now) - break ; + splitm = unsmob_moment (scm_caar (split_list_)); + if (splitm && *splitm + start_moment_ > now) + break; + + SCM tag = scm_cdar (split_list_); - SCM tag = gh_cdar (split_list_); - if (tag == ly_symbol2scm ("chords")) chords_together (); else if (tag == ly_symbol2scm ("apart") @@ -390,25 +408,33 @@ Part_combine_iterator::process (Moment m) solo1 (); else if (tag == ly_symbol2scm ("solo2")) solo2 (); - else if (gh_symbol_p (tag)) + else if (scm_is_symbol (tag)) { - String s = "Unknown split directive: " - + (gh_symbol_p (tag) ? ly_symbol2string (tag) : String ("not a symbol")); + String s = "Unknown split directive: " + + (scm_is_symbol (tag) ? ly_symbol2string (tag) : String ("not a symbol")); programming_error (s); } } - + if (first_iter_->ok ()) - first_iter_->process (m); - + { + first_iter_->process (m); + if (first_iter_->try_music_in_children (busy_playing_event)) + last_playing_ = SOLO1; + } + if (second_iter_->ok ()) - second_iter_->process (m); + { + second_iter_->process (m); + if (second_iter_->try_music_in_children (busy_playing_event)) + last_playing_ = SOLO2; + } } -Music_iterator* +Music_iterator * Part_combine_iterator::try_music_in_children (Music *m) const { - Music_iterator * i = first_iter_->try_music (m); + Music_iterator *i = first_iter_->try_music (m); if (i) return i; else