#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;
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");
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;
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*