X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ftime-scaled-music-iterator.cc;h=e70c44a4854a3dfabf5d0709bd5b4e3782d0fd2a;hb=9a2ec61184ccd4598312ce81cf9638ac1784d1f5;hp=9ab2673eeb86a23a7694700e886f5b0a13242086;hpb=cc676c5aadd45985251b5d60fa23eed1ed98f6e6;p=lilypond.git diff --git a/lily/time-scaled-music-iterator.cc b/lily/time-scaled-music-iterator.cc index 9ab2673eeb..e70c44a485 100644 --- a/lily/time-scaled-music-iterator.cc +++ b/lily/time-scaled-music-iterator.cc @@ -3,7 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 1998--2006 Han-Wen Nienhuys , + (c) 1998--2009 Han-Wen Nienhuys , Erik Sandberg */ @@ -11,26 +11,29 @@ #include "input.hh" #include "international.hh" #include "music.hh" -#include "sequential-iterator.hh" +#include "music-wrapper-iterator.hh" +#include "stream-event.hh" /* Iterates \times, by sending TupletSpanEvents at the start/end of each tuplet bracket. Extra stop/start events are sent at regular intervals if tupletSpannerDuration is set. */ -class Time_scaled_music_iterator : public Sequential_iterator +class Time_scaled_music_iterator : public Music_wrapper_iterator { public: DECLARE_SCHEME_CALLBACK (constructor, ()); /* construction */ - DECLARE_CLASSNAME(Time_scaled_music_iterator); + DECLARE_CLASSNAME (Time_scaled_music_iterator); Time_scaled_music_iterator (); protected: - virtual SCM get_music_list () const; virtual void process (Moment m); virtual void construct_children (); virtual void derived_mark () const; virtual Moment pending_moment () const; + + Music *create_event (Direction d); + private: /* tupletSpannerDuration */ @@ -40,26 +43,47 @@ private: Moment next_split_mom_; /* Recycle start/stop events if tupletSpannerDuration is set. */ - Music *start_; - Music *stop_; + SCM synthesized_events_; + + Context_handle tuplet_handler_; }; +Music* +Time_scaled_music_iterator::create_event (Direction d) +{ + SCM ev_scm = scm_call_2 (ly_lily_module_constant ("make-span-event"), + ly_symbol2scm ("TupletSpanEvent"), + scm_from_int (d)); + + Music *mus = get_music (); + + Music *ev = unsmob_music (ev_scm); + ev->set_spot (*mus->origin ()); + if (d == START) + { + ev->set_property ("numerator", mus->get_property ("numerator")); + ev->set_property ("denominator", mus->get_property ("denominator")); + ev->set_property ("tweaks", mus->get_property ("tweaks")); + ev->set_property ("length", spanner_duration_.smobbed_copy ()); + } + + synthesized_events_ = scm_cons (ev_scm, synthesized_events_); + return ev; +} + + Time_scaled_music_iterator::Time_scaled_music_iterator () { spanner_duration_ = next_split_mom_ = 0; + synthesized_events_ = SCM_EOL; } Moment Time_scaled_music_iterator::pending_moment () const { - Moment next_mom = Sequential_iterator::pending_moment (); - - if (spanner_duration_.to_bool () && - next_mom.main_part_ > next_split_mom_) - { - next_mom = next_split_mom_; - } + Moment next_mom = Music_wrapper_iterator::pending_moment (); + next_mom = min (next_mom, next_split_mom_); return next_mom; } @@ -71,73 +95,48 @@ Time_scaled_music_iterator::process (Moment m) if (spanner_duration_.to_bool () && m.main_part_ == next_split_mom_) { - report_event (stop_); - report_event (start_); + descend_to_bottom_context (); + if (tuplet_handler_.get_outlet ()) + create_event (STOP)->send_to_context (tuplet_handler_.get_outlet ()); + + if (m.main_part_ < music_get_length ().main_part_) + { + tuplet_handler_.set_context (get_outlet ()); + report_event (create_event (START)); - next_split_mom_ += spanner_duration_; - /* avoid sending events twice at the end */ - if (next_split_mom_ == get_music ()->get_length ().main_part_) - next_split_mom_.set_infinite (1); + next_split_mom_ += spanner_duration_; + } + else + { + tuplet_handler_.set_context (0); + } } - Sequential_iterator::process(m); + Music_wrapper_iterator::process (m); + if (child_iter_ && child_iter_->ok ()) + descend_to_child (child_iter_->get_outlet ()); + } void Time_scaled_music_iterator::construct_children () { - /* - Inheritance trickery: - Time_scaled_music_iterator::construct_children initialises start_ - and stop_, and calls Sequential_music::construct_children, which - in turn calls Time_scaled_music_iterator::get_music which reads - start_ and stop_. - */ - - Music *mus = get_music (); - Input *origin = mus->origin (); - - SCM tuplet_symbol = ly_symbol2scm ("TupletSpanEvent"); - SCM start_scm = scm_call_2 (ly_lily_module_constant ("make-span-event"), tuplet_symbol, scm_from_int (START)); - start_ = unsmob_music (start_scm); - start_->set_spot (*origin); - start_->set_property ("numerator", mus->get_property ("numerator")); - start_->set_property ("denominator", mus->get_property ("denominator")); - start_->set_property ("tweaks", mus->get_property ("tweaks")); - - - SCM stop_scm = scm_call_2 (ly_lily_module_constant ("make-span-event"), tuplet_symbol, scm_from_int (STOP)); - stop_ = unsmob_music (stop_scm); - stop_->set_spot (*origin); + spanner_duration_ = music_get_length (); Moment *mp = unsmob_moment (get_outlet ()->get_property ("tupletSpannerDuration")); - if (mp) - { - spanner_duration_ = mp->main_part_; - next_split_mom_ = spanner_duration_; - } - - Sequential_iterator::construct_children (); -} - -SCM -Time_scaled_music_iterator::get_music_list () const -{ - Music *mus = get_music (); - SCM child = mus->get_property ("element"); + spanner_duration_ = min (mp->main_part_, spanner_duration_); + + Music_wrapper_iterator::construct_children (); - return scm_list_3 (start_->self_scm (), child, stop_->self_scm ()); + if (child_iter_ && child_iter_->ok ()) + descend_to_child (child_iter_->get_outlet ()); } void Time_scaled_music_iterator::derived_mark () const { - if (start_) - scm_gc_mark (start_->self_scm ()); - if (stop_) - scm_gc_mark (stop_->self_scm ()); - - Sequential_iterator::derived_mark (); + scm_gc_mark (synthesized_events_); + Music_wrapper_iterator::derived_mark (); } IMPLEMENT_CTOR_CALLBACK (Time_scaled_music_iterator);