]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/part-combine-iterator.cc
* scm/titling.scm (default-score-title): remove caps for piece.
[lilypond.git] / lily / part-combine-iterator.cc
index a40151ee1566d1fed6200b866485230a704f1a36..3e70e5b55c010c276c8bd3f5cee4300de42df04d 100644 (file)
@@ -42,13 +42,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 +78,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_translator (0);
+  one_ .set_translator (0);
+  two_.set_translator (0);
+  shared_.set_translator (0);
+  solo_.set_translator (0);
+
+}
+
 Part_combine_iterator::Part_combine_iterator ()
 {
   first_iter_ = 0;
@@ -77,6 +103,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 +126,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 +204,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 +240,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 +259,8 @@ Part_combine_iterator::unisono (bool silent)
          if (!event)
            event = make_music_by_name (ly_symbol2scm ("UnisonoEvent"));
 
-         first_iter_-> try_music_in_children (event);      
+         (state_ == SOLO2 ? second_iter_ : first_iter_)
+           ->try_music_in_children (event);      
          playing_state_ = UNISONO;
        }
       state_ = newstate;
@@ -327,14 +351,14 @@ Part_combine_iterator::construct_children ()
   one_.set_translator (one);
 
   set_translator (one);
-  first_iter_ = unsmob_iterator (get_iterator (unsmob_music (ly_car (lst))));
+  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))));
+  second_iter_ = unsmob_iterator (get_iterator (unsmob_music (scm_cadr (lst))));
 
 
   set_translator (tr);
@@ -370,13 +394,13 @@ Part_combine_iterator::process (Moment m)
   Moment now = get_outlet ()->now_mom ();
   Moment *splitm = 0;
   
-  for (; is_pair (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 +416,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*