From 6798fd9b3d52cbed28b24dbac067bff9af406230 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Tue, 12 Sep 2000 22:05:53 +0200 Subject: [PATCH] patch::: 1.3.85.jcn3 1.3.85.jcn3 =========== * Added get_music () and next () to music iterators. 1.3.85 ====== --- CHANGES | 7 + VERSION | 2 +- lily/include/music-iterator.hh | 3 + lily/include/music-wrapper-iterator.hh | 2 + lily/include/request-chord-iterator.hh | 6 +- lily/include/request-iterator.hh | 23 --- lily/include/sequential-music-iterator.hh | 2 + lily/include/simple-music-iterator.hh | 22 +++ lily/music-iterator.cc | 19 +- lily/music-wrapper-iterator.cc | 11 ++ lily/part-combine-music-iterator.cc | 204 +++++++++++++++++++++- lily/request-chord-iterator.cc | 16 +- lily/request-iterator.cc | 25 --- lily/sequential-music-iterator.cc | 79 ++++++--- lily/simple-music-iterator.cc | 27 +++ 15 files changed, 361 insertions(+), 87 deletions(-) create mode 100644 lily/include/simple-music-iterator.hh create mode 100644 lily/simple-music-iterator.cc diff --git a/CHANGES b/CHANGES index 8e64408e4e..78430277db 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,10 @@ +1.3.85.jcn3 +=========== + +* Added get_music () and next () to music iterators. + +1.3.85 +====== * Separated definition and implementation of contexts (moved definition out of Translator_group into Translator_def) diff --git a/VERSION b/VERSION index bb87c38926..87ad523c6f 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=3 PATCH_LEVEL=85 -MY_PATCH_LEVEL=jcn2 +MY_PATCH_LEVEL=jcn3 # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/lily/include/music-iterator.hh b/lily/include/music-iterator.hh index 561e9c11eb..bb6d36f80e 100644 --- a/lily/include/music-iterator.hh +++ b/lily/include/music-iterator.hh @@ -87,6 +87,9 @@ public: ///Are we finished with this piece of music? virtual bool ok() const; + virtual Music* get_music (); + virtual bool next (); + virtual ~Music_iterator(); diff --git a/lily/include/music-wrapper-iterator.hh b/lily/include/music-wrapper-iterator.hh index 8200709e52..1429f00be6 100644 --- a/lily/include/music-wrapper-iterator.hh +++ b/lily/include/music-wrapper-iterator.hh @@ -27,6 +27,8 @@ public: virtual void construct_children () ; virtual Moment next_moment () const; virtual bool ok () const; + virtual Music* get_music (); + virtual bool next (); protected: virtual void do_print () const; diff --git a/lily/include/request-chord-iterator.hh b/lily/include/request-chord-iterator.hh index bc09247992..ec88c28e32 100644 --- a/lily/include/request-chord-iterator.hh +++ b/lily/include/request-chord-iterator.hh @@ -15,7 +15,8 @@ /** Walk through a Request_chord */ -class Request_chord_iterator : public Music_iterator { +class Request_chord_iterator : public Music_iterator +{ Request_chord * elt_l () const; /** cache elt_l ()->length_mom (). @@ -26,12 +27,13 @@ class Request_chord_iterator : public Music_iterator { public: Request_chord_iterator (); + virtual bool next (); + virtual bool ok () const; protected: virtual void do_process_and_next (Moment); virtual Moment next_moment() const; virtual void construct_children(); - virtual bool ok() const; virtual void do_print() const; }; diff --git a/lily/include/request-iterator.hh b/lily/include/request-iterator.hh index ea2b07b026..e69de29bb2 100644 --- a/lily/include/request-iterator.hh +++ b/lily/include/request-iterator.hh @@ -1,23 +0,0 @@ -/* - request-iterator.hh -- declare Request_iterator - - source file of the GNU LilyPond music typesetter - - (c) 2000 Han-Wen Nienhuys - - */ - -#ifndef REQUEST_ITERATOR_HH -#define REQUEST_ITERATOR_HH - -#include "music-iterator.hh" - -class Simple_music_iterator : public Music_iterator -{ -public: -protected: - virtual void do_process_and_next (Moment ); -}; - -#endif /* REQUEST_ITERATOR_HH */ - diff --git a/lily/include/sequential-music-iterator.hh b/lily/include/sequential-music-iterator.hh index 79f493fa87..17e7aede8b 100644 --- a/lily/include/sequential-music-iterator.hh +++ b/lily/include/sequential-music-iterator.hh @@ -24,6 +24,8 @@ public: virtual void construct_children (); virtual Moment next_moment () const; virtual bool ok () const; + virtual Music* get_music (); + virtual bool next (); protected: virtual void do_print() const; diff --git a/lily/include/simple-music-iterator.hh b/lily/include/simple-music-iterator.hh new file mode 100644 index 0000000000..00e9f66d4f --- /dev/null +++ b/lily/include/simple-music-iterator.hh @@ -0,0 +1,22 @@ +/* + request-iterator.hh -- declare Request_iterator + + source file of the GNU LilyPond music typesetter + + (c) 2000 Han-Wen Nienhuys + + */ + +#ifndef REQUEST_ITERATOR_HH +#define REQUEST_ITERATOR_HH + +#include "music-iterator.hh" + +class Simple_music_iterator : public Music_iterator +{ +protected: + virtual void do_process_and_next (Moment ); +}; + +#endif /* REQUEST_ITERATOR_HH */ + diff --git a/lily/music-iterator.cc b/lily/music-iterator.cc index b1697e199e..3abd8cecb3 100644 --- a/lily/music-iterator.cc +++ b/lily/music-iterator.cc @@ -37,7 +37,7 @@ #include "part-combine-music.hh" #include "part-combine-music-iterator.hh" #include "request.hh" -#include "request-iterator.hh" +#include "simple-music-iterator.hh" #include "output-property.hh" #include "chord-tremolo-iterator.hh" @@ -118,11 +118,26 @@ Music_iterator::do_process_and_next (Moment) } bool -Music_iterator::ok() const +Music_iterator::ok () const { return first_b_; } +Music* +Music_iterator::get_music () +{ + if (ok ()) + return music_l_; + return 0; +} + +bool +Music_iterator::next () +{ + first_b_ = false; + return ok (); +} + Music_iterator* Music_iterator::static_get_iterator_p (Music *m) { diff --git a/lily/music-wrapper-iterator.cc b/lily/music-wrapper-iterator.cc index af658cf72a..43fe4b495c 100644 --- a/lily/music-wrapper-iterator.cc +++ b/lily/music-wrapper-iterator.cc @@ -50,6 +50,17 @@ Music_wrapper_iterator::do_process_and_next (Moment m) Music_iterator::do_process_and_next (m); } +Music* +Music_wrapper_iterator::get_music () +{ + return child_iter_p_->get_music (); +} + +bool +Music_wrapper_iterator::next () +{ + return child_iter_p_->next (); +} Moment Music_wrapper_iterator::next_moment () const diff --git a/lily/part-combine-music-iterator.cc b/lily/part-combine-music-iterator.cc index 3a72a587a9..9c924c1284 100644 --- a/lily/part-combine-music-iterator.cc +++ b/lily/part-combine-music-iterator.cc @@ -10,6 +10,7 @@ #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 () @@ -117,6 +118,7 @@ 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 ())); } +#if 0 Pitch_interrogate_req* first_spanish_inquisition; // nobody expects it Pitch_interrogate_req* second_spanish_inquisition; // won't strike twice @@ -132,7 +134,7 @@ Part_combine_music_iterator::do_process_and_next (Moment m) /* Hmm, shouldn't we check per iterator if next_moment < m? - */ + */ if (first_iter_p_->ok ()) first_iter_p_->process_and_next (m); @@ -154,16 +156,16 @@ Part_combine_music_iterator::do_process_and_next (Moment m) * Hymnals: - Rules for Hymnals/SATB (John Henckel ): + Rules for Hymnals/SATB (John Henckel ): - 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 + 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; @@ -296,6 +298,194 @@ Part_combine_music_iterator::do_process_and_next (Moment m) first_durations->clear (); second_durations->clear (); } +#else +void +Part_combine_music_iterator::do_process_and_next (Moment m) +{ + Part_combine_music const * p = dynamic_cast (music_l_); + + /* + Huh? + */ + // now_ = next_moment (); + + /* + 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 ): + + 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 1 + Music *first_music; + Music *second_music; + if (first_iter_p_->ok ()) + first_music = first_iter_p_->get_music (); + + if (second_iter_p_->ok ()) + second_music = second_iter_p_->get_music (); +#endif + + Array first_pitches; + Array first_durations; + if (Music_sequence* m = dynamic_cast (first_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 (u)) + first_pitches.push (r->pitch_); + if (Rhythmic_req *r = dynamic_cast (u)) + first_durations.push (r->duration_); + } + } + + Array second_pitches; + Array second_durations; + if (Music_sequence* m = dynamic_cast (second_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 (u)) + second_pitches.push (r->pitch_); + if (Rhythmic_req *r = dynamic_cast (u)) + second_durations.push (r->duration_); + } + } + + SCM interval = SCM_BOOL_F; + 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 ()); + } + if (first_durations.size ()) + { + 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 ()) + { + second_durations.sort (Duration::compare); + Moment new_until = now_ + second_durations.top ().length_mom (); + if (new_until > second_until_) + second_until_ = new_until; + } + + 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 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"); + + bool split_interval_b = false; + if (gh_number_p (interval)) + { + SCM s = fd->get_property (ly_symbol2scm ("splitInterval")); + int i = gh_scm2int (interval); + if (gh_pair_p (s) + && gh_number_p (gh_car (s)) + && gh_number_p (gh_cdr (s)) + && i >= gh_scm2int (gh_car (s)) + && i <= gh_scm2int (gh_cdr (s))) + split_interval_b = true; + } + + /* + URG, dememberme + */ + combined_b_ = first_iter_p_->report_to_l ()->daddy_trans_l_ + == second_iter_p_->report_to_l ()->daddy_trans_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_ = !combined_b_; + to_id = combined_b_ ? "one" : "two"; + change_to (second_iter_p_, p->what_str_, to_id); + } + + if (!combined_b_) + sir = second_iter_p_->report_to_l (); + + SCM b = unirhythm_b ? SCM_BOOL_T : SCM_BOOL_F; + fd->set_property ("unirhythm", b); + sd->set_property ("unirhythm", b); + + b = split_interval_b ? SCM_BOOL_T : SCM_BOOL_F; + fd->set_property ("split-interval", b); + sd->set_property ("split-interval", b); + + b = unisilence_b ? SCM_BOOL_T : SCM_BOOL_F; + fd->set_property ("unisilence", b); + sd->set_property ("unisilence", b); + + b = unison_b ? SCM_BOOL_T : SCM_BOOL_F; + fd->set_property ("unison", b); + sd->set_property ("unison", b); + + b = solo_b ? SCM_BOOL_T : SCM_BOOL_F; + if (first_pitches.size ()) + { + fd->set_property ("solo", b); + sd->set_property ("solo", SCM_BOOL_F); + } + + 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); + now_ = next_moment (); +} +#endif Music_iterator* Part_combine_music_iterator::try_music_in_children (Music *m) const diff --git a/lily/request-chord-iterator.cc b/lily/request-chord-iterator.cc index 7f0b00827f..a1d711ef9c 100644 --- a/lily/request-chord-iterator.cc +++ b/lily/request-chord-iterator.cc @@ -57,12 +57,22 @@ Request_chord_iterator::do_print() const #endif } +bool +Request_chord_iterator::next () +{ + first_b_ = false; + // last_b_ = true; + return ok (); +} + void Request_chord_iterator::do_process_and_next (Moment mom) { + // URG + // if (ok ()) if (first_b_) { - for (SCM s = dynamic_cast (music_l_)->music_list (); gh_pair_p (s); s = gh_cdr (s)) + for (SCM s = dynamic_cast (get_music ())->music_list (); gh_pair_p (s); s = gh_cdr (s)) { Music *mus = unsmob_music (gh_car (s)); if (Request * req_l = dynamic_cast (mus)) @@ -75,9 +85,11 @@ Request_chord_iterator::do_process_and_next (Moment mom) mus->origin ()->warning (_f ("Huh? Not a Request: `%s'", classname (mus))); } - first_b_ = false; } + next (); + // URG if (mom >= elt_length_mom_) last_b_ = true; + } diff --git a/lily/request-iterator.cc b/lily/request-iterator.cc index 51c7604281..e69de29bb2 100644 --- a/lily/request-iterator.cc +++ b/lily/request-iterator.cc @@ -1,25 +0,0 @@ -/* - request-iterator.cc -- implement Simple_music_iterator - - source file of the GNU LilyPond music typesetter - - (c) 2000 Han-Wen Nienhuys - - */ -#include "request-iterator.hh" -#include "music.hh" -#include "input.hh" - -void -Simple_music_iterator::do_process_and_next (Moment m) -{ - if (first_b_) - { - bool g= try_music (music_l_); - if (!g) - music_l_->origin ()->warning (_f ("Junking music: `%s'", classname(music_l_))); - - first_b_ = false; - } - Music_iterator::do_process_and_next (m); -} diff --git a/lily/sequential-music-iterator.cc b/lily/sequential-music-iterator.cc index d99381cf54..16cd0e5e59 100644 --- a/lily/sequential-music-iterator.cc +++ b/lily/sequential-music-iterator.cc @@ -86,39 +86,68 @@ Sequential_music_iterator::~Sequential_music_iterator() } } -void -Sequential_music_iterator::do_process_and_next (Moment until) +Music* +Sequential_music_iterator::get_music () { - if (!iter_p_) - return; - - while (1) + if (ok ()) + return unsmob_music (gh_car (cursor_)); + + return 0; +} + +bool +Sequential_music_iterator::next () +{ + if (ok ()) { - Moment local_until = until - here_mom_; - while (iter_p_->ok()) + bool b = false; + if (iter_p_->ok ()) + b = iter_p_->next (); + if (!b) { - Moment here = iter_p_->next_moment(); - if (here != local_until) - goto loopexit; - - iter_p_->process_and_next (local_until); + set_sequential_music_translator (); + leave_element (); + if (gh_pair_p (cursor_)) + start_next_element (); + b = ok (); } - - if (!iter_p_->ok()) + return b; + } + return false; +} + +/* + This should use get_music () and next () + */ +void +Sequential_music_iterator::do_process_and_next (Moment until) +{ + if (ok ()) + { + while (1) { - set_sequential_music_translator(); - leave_element(); + Moment local_until = until - here_mom_; + while (iter_p_->ok ()) + { + Moment here = iter_p_->next_moment (); + if (here != local_until) + return Music_iterator::do_process_and_next (until); + + iter_p_->process_and_next (local_until); + } - if (gh_pair_p (cursor_)) - start_next_element(); - else - goto loopexit; + if (!iter_p_->ok ()) + { + set_sequential_music_translator (); + leave_element (); + + if (gh_pair_p (cursor_)) + start_next_element (); + else + return Music_iterator::do_process_and_next (until); + } } } - -loopexit: - - Music_iterator::do_process_and_next (until); } Moment diff --git a/lily/simple-music-iterator.cc b/lily/simple-music-iterator.cc new file mode 100644 index 0000000000..4c925f3c91 --- /dev/null +++ b/lily/simple-music-iterator.cc @@ -0,0 +1,27 @@ +/* + simple-music-iterator.cc -- implement Simple_music_iterator + + source file of the GNU LilyPond music typesetter + + (c) 2000 Han-Wen Nienhuys + + */ + +#include "simple-music-iterator.hh" +#include "music.hh" +#include "input.hh" + + +void +Simple_music_iterator::do_process_and_next (Moment m) +{ + if (ok ()) + { + bool b = try_music (get_music ()); + if (!b) + music_l_->origin ()->warning (_f ("Junking music: `%s'", + classname (music_l_))); + + } + Music_iterator::do_process_and_next (m); +} -- 2.39.5