]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/part-combine-iterator.cc
*** empty log message ***
[lilypond.git] / lily / part-combine-iterator.cc
index ecc89ba0a60ae090930ff497cf5eecf69cf2cd62..521e2c458dac22a5571d4f1c1d2fb63342ec9d78 100644 (file)
@@ -12,7 +12,6 @@
 #include "lily-guile.hh"
 #include "warn.hh"
 #include "music-iterator.hh"
-#include "interpretation-context-handle.hh"
 
 class Part_combine_iterator : public Music_iterator
 {
@@ -42,13 +41,21 @@ private:
   SCM split_list_;
 
   enum Status  {
-    APART, TOGETHER,
-    SOLO1, SOLO2,
-    UNISONO, UNISILENCE,
+    APART,
+    TOGETHER,
+    SOLO1,
+    SOLO2,
+    UNISONO,
+    UNISILENCE,
   };
   Status state_;
   Status playing_state_;
 
+  /*
+    Should be SOLO1 or SOLO2
+   */
+  Status last_playing_;
+
   /*
     TODO: this is getting of hand... 
    */
@@ -70,6 +77,24 @@ private:
 };
 
 
+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 ()
 {
   first_iter_ = 0;
@@ -77,6 +102,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
@@ -94,23 +125,7 @@ Part_combine_iterator::derived_substitute (Context *f,
 {
   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);
 }
 
 Moment
@@ -188,7 +203,7 @@ Part_combine_iterator::solo1 ()
 
 void
 Part_combine_iterator::substitute_both (Context * to1,
-                                 Context * to2)
+                                       Context * to2)
 {
   Context *tos[]  = {to1,to2};
   Music_iterator *mis[] = {first_iter_, second_iter_}; 
@@ -224,9 +239,16 @@ Part_combine_iterator::unisono (bool silent)
     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
@@ -236,7 +258,8 @@ Part_combine_iterator::unisono (bool silent)
          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;
@@ -299,18 +322,18 @@ Part_combine_iterator::construct_children ()
     =  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);
 
-  solo_ .set_translator (solo_tr);
+  solo_ .set_context (solo_tr);
 
   Context *null
     =  get_outlet ()->find_create_context (ly_symbol2scm ("Devnull"),
@@ -319,25 +342,25 @@ Part_combine_iterator::construct_children ()
   if (!null)
     programming_error ("No Devnull found?");
   
-  null_.set_translator (null);
+  null_.set_context (null);
 
   Context *one = tr->find_create_context (ly_symbol2scm ("Voice"),
                                                      "one", props);
 
-  one_.set_translator (one);
+  one_.set_context (one);
 
-  set_translator (one);
-  first_iter_ = unsmob_iterator (get_iterator (unsmob_music (ly_car (lst))));
+  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 (ly_cadr (lst))));
+  two_.set_context (two);
+  set_context (two);
+  second_iter_ = unsmob_iterator (get_iterator (unsmob_music (scm_cadr (lst))));
 
 
-  set_translator (tr);
+  set_context (tr);
 
 
   char const * syms[] = {
@@ -370,13 +393,13 @@ Part_combine_iterator::process (Moment m)
   Moment now = get_outlet ()->now_mom ();
   Moment *splitm = 0;
   
-  for (; ly_c_pair_p (split_list_); split_list_ = ly_cdr (split_list_))
+  for (; scm_is_pair (split_list_); split_list_ = scm_cdr (split_list_))
     {
-      splitm = unsmob_moment (ly_caar (split_list_));
+      splitm = unsmob_moment (scm_caar (split_list_));
       if (splitm && *splitm + start_moment_ > now)
        break ;
 
-      SCM tag = ly_cdar (split_list_);
+      SCM tag = scm_cdar (split_list_);
       
       if (tag == ly_symbol2scm ("chords"))
        chords_together ();
@@ -392,19 +415,27 @@ Part_combine_iterator::process (Moment m)
        solo1 ();
       else if (tag == ly_symbol2scm ("solo2"))
        solo2 ();
-      else if (is_symbol (tag))
+      else if (scm_is_symbol (tag))
        {
          String s =  "Unknown split directive: "
-           + (is_symbol (tag) ? ly_symbol2string (tag) : String ("not a symbol")); 
+           + (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 (first_iter_->try_music_in_children (busy_playing_event))
+       last_playing_ = SOLO2;
+    }
 }
 
 Music_iterator*