]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/part-combine-music-iterator.cc
release: 1.3.86
[lilypond.git] / lily / part-combine-music-iterator.cc
index b5c3780961c2b341664119d2b501d10ba938341b..3a72a587a959865256883b60abb0acd86d56ad94 100644 (file)
 #include "part-combine-music-iterator.hh"
 #include "translator-group.hh"
 #include "musical-request.hh"
-#include "music-sequence.hh"
 #include "warn.hh"
 
 Part_combine_music_iterator::Part_combine_music_iterator ()
 {
+  combined_b_ = true;
+
+  now_ = 0;
   first_iter_p_ = 0;
   second_iter_p_ = 0;
   first_until_ = 0;
@@ -115,118 +117,110 @@ Part_combine_music_iterator::change_to (Music_iterator *it, String to_type,
     error (_f ("none of these in my family: `%s'", to_id.ch_C ()));
 }
 
+Pitch_interrogate_req* first_spanish_inquisition; // nobody expects it
+Pitch_interrogate_req* second_spanish_inquisition; // won't strike twice
+
+Rhythm_interrogate_req* first_rhythmic_inquisition;
+Rhythm_interrogate_req* second_rhythmic_inquisition;
+
 void
 Part_combine_music_iterator::do_process_and_next (Moment m)
 {
   Part_combine_music const * p = dynamic_cast<Part_combine_music const* > (music_l_);
 
-  Moment now = next_moment ();
+  now_ = next_moment ();
 
-  Array<Musical_pitch> first_pitches;
-  Array<Duration> first_durations;
+  /*
+    Hmm, shouldn't we check per iterator if next_moment < m?
+   */
   if (first_iter_p_->ok ())
-    {
-      Music_iterator* i = first_iter_p_->clone ();
-      Moment until = i->next_moment ();
-
-      /* Urg, silly first_b_ stuff */
-      if (now && i->next ())
-       until = i->next_moment ();
-
-      /* How about a 'now_moment ()' for iterators? */
-      for (; i->ok () && i->next_moment () == until; i->next ())
-       {
-         if (Music_sequence* m = dynamic_cast<Music_sequence *> (i->get_music ()))
-           {
-             for (SCM s = m->music_list (); gh_pair_p (s);  s = gh_cdr (s))
-               {
-                 Music *u = unsmob_music (gh_car (s));
-                 if (Melodic_req *r = dynamic_cast<Melodic_req *> (u))
-                   first_pitches.push (r->pitch_);
-                 if (Rhythmic_req *r = dynamic_cast<Rhythmic_req *> (u))
-                   first_durations.push (r->duration_);
-               }
-           }
-       }
-    }
-
-  Array<Musical_pitch> second_pitches;
-  Array<Duration> second_durations;
+    first_iter_p_->process_and_next (m);
+  
   if (second_iter_p_->ok ())
-    {
-      Music_iterator* i = second_iter_p_->clone ();
-      Moment until = i->next_moment ();
-
-      /* Urg, silly second_b_ stuff */
-      if (now && i->next ())
-       until = i->next_moment ();
-
-      /* How about a 'now_moment ()' for iterators? */
-      for (; i->ok () && i->next_moment () == until; i->next ())
-       {
-         if (Music_sequence* m = dynamic_cast<Music_sequence *> (i->get_music ()))
-           {
-             for (SCM s = m->music_list (); gh_pair_p (s);  s = gh_cdr (s))
-               {
-                 Music *u = unsmob_music (gh_car (s));
-                 if (Melodic_req *r = dynamic_cast<Melodic_req *> (u))
-                   second_pitches.push (r->pitch_);
-                 if (Rhythmic_req *r = dynamic_cast<Rhythmic_req *> (u))
-                   second_durations.push (r->duration_);
-               }
-           }
-       }
-    }
+    second_iter_p_->process_and_next (m);
+
+  Music_iterator::do_process_and_next (m);
+
+  /*
+    TODO:
+
+    * Maybe we need a Skip_engraver?
+
+    (check): can this all be handled now?
+    
+    Maybe different modes exist?
+
+    * Wind instruments (Flute I/II)
+    * Hymnals:  
+
+
+      Rules for Hymnals/SATB (John Henckel <henckel@iname.com>):
+
+      1. if S and A differ by less than a third, the stems should be up/down.
+      2. else if S and A have different values, the stems should be up/down.
+      3. else if A sings "la" or higher, both S and A stems should be down.
+      4. else both stems should be up
+
+    * This may get really tricky: combining voices/staffs: string instruments
+
+   */
+  
+  if (!first_spanish_inquisition)
+    first_spanish_inquisition = new Pitch_interrogate_req;
+  first_iter_p_->try_music (first_spanish_inquisition);
   
+  if (!second_spanish_inquisition)
+    second_spanish_inquisition = new Pitch_interrogate_req;
+  second_iter_p_->try_music (second_spanish_inquisition);
+
+  Array<Musical_pitch>* first_pitches = &first_spanish_inquisition->pitch_arr_;
+  Array<Musical_pitch>* second_pitches = &second_spanish_inquisition->pitch_arr_;
+
+  if (!first_rhythmic_inquisition)
+    first_rhythmic_inquisition = new Rhythm_interrogate_req;
+  first_iter_p_->try_music (first_rhythmic_inquisition);
+
+  if (!second_rhythmic_inquisition)
+    second_rhythmic_inquisition = new Rhythm_interrogate_req;
+  second_iter_p_->try_music (second_rhythmic_inquisition);
+
+  Array<Duration>* first_durations = &first_rhythmic_inquisition->duration_arr_;
+  Array<Duration>* second_durations = &second_rhythmic_inquisition->duration_arr_;
+
   SCM interval = SCM_BOOL_F;
-  if (first_pitches.size () && second_pitches.size ())
+  if (first_pitches->size () && second_pitches->size ())
     {
-      first_pitches.sort (Musical_pitch::compare);
-      second_pitches.sort (Musical_pitch::compare);
-      interval = gh_int2scm (first_pitches.top ().steps ()
-                            - second_pitches[0].steps ());
+      first_pitches->sort (Musical_pitch::compare);
+      second_pitches->sort (Musical_pitch::compare);
+      interval = gh_int2scm (first_pitches->top ().steps ()
+                            - (*second_pitches)[0].steps ());
     }
-  if (first_durations.size ())
+  if (first_durations->size ())
     {
-      first_durations.sort (Duration::compare);
-      Moment new_until = now + first_durations.top ().length_mom ();
+      first_durations->sort (Duration::compare);
+      Moment new_until = now_ + first_durations->top ().length_mom ();
       if (new_until > first_until_)
        first_until_ = new_until;
     }
 
-    if (second_durations.size ())
+    if (second_durations->size ())
     {
-      second_durations.sort (Duration::compare);
-      Moment new_until = now + second_durations.top ().length_mom ();
+      second_durations->sort (Duration::compare);
+      Moment new_until = now_ + second_durations->top ().length_mom ();
       if (new_until > second_until_)
        second_until_ = new_until;
     }
 
-#if 0 /* DEBUG */
-  printf ("now: %s\n", now.str ().ch_C ());
-  printf ("first: ");
-  for (int i = 0; i < first_pitches.size (); i++)
-    {
-      printf ("%s, ", first_pitches[i].str ().ch_C ());
-    }
-  printf ("\nsecond: ");
-  for (int i = 0; i < second_pitches.size (); i++)
-    {
-      printf ("%s, ", second_pitches[i].str ().ch_C ());
-    }
-  printf ("\n");
-#endif
-
   Translator_group * fir = first_iter_p_->report_to_l ();
   Translator_group * sir = second_iter_p_->report_to_l ();
 
-  bool solo_b = (first_pitches.empty () != second_pitches.empty ())
-    && !(first_until_ > now && second_until_ > now);
+  bool solo_b = (first_pitches->empty () != second_pitches->empty ())
+    && !(first_until_ > now_ && second_until_ > now_);
 
-  bool unirhythm_b = !solo_b && !compare (&first_durations, &second_durations);
-  bool unison_b = unirhythm_b && !first_pitches.empty ()
-    &&!compare (&first_pitches, &second_pitches);
-  bool unisilence_b = unirhythm_b && first_pitches.empty ();
+  bool unirhythm_b = !solo_b && !compare (first_durations, second_durations);
+  bool unison_b = unirhythm_b && !first_pitches->empty ()
+    &&!compare (first_pitches, second_pitches);
+  bool unisilence_b = unirhythm_b && first_pitches->empty ();
 
   Translator_group * fd = fir->find_create_translator_l (p->what_str_, "one");
   Translator_group * sd = sir->find_create_translator_l (p->what_str_, "two");
@@ -244,23 +238,28 @@ Part_combine_music_iterator::do_process_and_next (Moment m)
        split_interval_b = true;
     }
 
-  bool combined_b = first_iter_p_->report_to_l ()->daddy_trans_l_
-    == second_iter_p_->report_to_l ()->daddy_trans_l_;
+  /*
+    Hmm, maybe we should set/check combined_b_ against
 
-  String to_id =  combined_b ? "one" : "two";
-  if ((!unirhythm_b && combined_b)
-      || (split_interval_b && combined_b)
-      || (solo_b && combined_b)
-      /*|| (unisilence_b && combined_b) */
+       first_iter_p_->report_to_l () == second_iter_p_->report_to_l ()
+
+   ? 
+   */
+
+  String to_id =  combined_b_ ? "one" : "two";
+  if ((!unirhythm_b && combined_b_)
+      || (split_interval_b && combined_b_)
+      || (solo_b && combined_b_)
+      /*|| (unisilence_b && combined_b_) */
       || ((unirhythm_b || unison_b || unisilence_b)
-         && !combined_b && !split_interval_b && !solo_b))
+         && !combined_b_ && !split_interval_b && !solo_b))
     {
-      combined_b = !combined_b;
-      to_id =  combined_b ? "one" : "two";
+      combined_b_ = !combined_b_;
+      to_id =  combined_b_ ? "one" : "two";
       change_to (second_iter_p_, p->what_str_, to_id);
     }
 
-  if (!combined_b)
+  if (!combined_b_)
     sir = second_iter_p_->report_to_l ();
 
   SCM b = unirhythm_b ? SCM_BOOL_T : SCM_BOOL_F;
@@ -280,28 +279,22 @@ Part_combine_music_iterator::do_process_and_next (Moment m)
   sd->set_property ("unison", b);
 
   b = solo_b  ? SCM_BOOL_T : SCM_BOOL_F;
-  if (first_pitches.size ())
+  if (first_pitches->size ())
     {
       fd->set_property ("solo", b);
       sd->set_property ("solo", SCM_BOOL_F);
     }
 
-  if (second_pitches.size ())
+  if (second_pitches->size ())
     {
       fd->set_property ("solo", SCM_BOOL_F);
       sd->set_property ("solo", b);
     }
 
-  /*
-    Hmm, shouldn't we check per iterator if next_moment < m?
-  */
-  if (first_iter_p_->ok ())
-    first_iter_p_->process_and_next (m);
-  
-  if (second_iter_p_->ok ())
-    second_iter_p_->process_and_next (m);
-
-  Music_iterator::do_process_and_next (m);
+  first_pitches->clear ();
+  second_pitches->clear ();
+  first_durations->clear ();
+  second_durations->clear ();
 }
 
 Music_iterator*