X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ftime-scaled-music-iterator.cc;h=ccc93d031463d1d4ff1eebb48d90b0488531f2b9;hb=73b1239c26cd8f25d34ed9595967caa99932d784;hp=f422ddd8c62d6452622bc6d28aafabd8b0a85e9e;hpb=ea1b3696c02bb143fc7faf8b872a5c23c0725fef;p=lilypond.git diff --git a/lily/time-scaled-music-iterator.cc b/lily/time-scaled-music-iterator.cc index f422ddd8c6..ccc93d0314 100644 --- a/lily/time-scaled-music-iterator.cc +++ b/lily/time-scaled-music-iterator.cc @@ -1,29 +1,143 @@ -/* +/* time-scaled-music-iterator.cc -- implement Time_scaled_music_iterator - + source file of the GNU LilyPond music typesetter - - (c) 1998--2004 Han-Wen Nienhuys - - */ -#include "time-scaled-music-iterator.hh" + (c) 1998--2006 Han-Wen Nienhuys , + Erik Sandberg +*/ + #include "context.hh" #include "input.hh" +#include "international.hh" +#include "music.hh" +#include "sequential-iterator.hh" + +/* + Iterates \times, by sending TupletEvents 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 +{ +public: + DECLARE_SCHEME_CALLBACK (constructor, ()); + /* construction */ + 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; +private: + + /* tupletSpannerDuration */ + Moment spanner_duration_; + + /* next time to add a stop/start pair */ + Moment next_split_mom_; + + /* Recycle start/stop events if tupletSpannerDuration is set. */ + Music *start_; + Music *stop_; +}; + +Time_scaled_music_iterator::Time_scaled_music_iterator () +{ + spanner_duration_ = next_split_mom_ = 0; +} + + +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_; + } + + return next_mom; +} + void Time_scaled_music_iterator::process (Moment m) { - if (!m.to_bool ()) + if (spanner_duration_.to_bool () && + m.main_part_ == next_split_mom_) { - Music_iterator *yeah = try_music (get_music ()); - if (yeah) - set_context (yeah->get_outlet ()); - else - get_music ()->origin ()->warning (_ ("no one to print a tuplet start bracket")); + report_event (stop_); + report_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); } + Sequential_iterator::process(m); +} + +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 ("TupletEvent"); + 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); + + 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 (); +} - Music_wrapper_iterator::process (m); +SCM +Time_scaled_music_iterator::get_music_list () const +{ + Music *mus = get_music (); + SCM child = mus->get_property ("element"); + + return scm_list_3 (start_->self_scm (), child, stop_->self_scm ()); } - + +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 (); +} + IMPLEMENT_CTOR_CALLBACK (Time_scaled_music_iterator);