X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ftime-scaled-music-iterator.cc;h=9ab2673eeb86a23a7694700e886f5b0a13242086;hb=c750e9b0ef41267a9b6be0300c880047f48b9353;hp=f68a4d7d88304d2e11e7548813b306b49ca88117;hpb=287611887cd612ac84dbf10c5fe4e1a44cc56596;p=lilypond.git diff --git a/lily/time-scaled-music-iterator.cc b/lily/time-scaled-music-iterator.cc index f68a4d7d88..9ab2673eeb 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--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 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 +{ +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_; - (c) 1998--2000 Han-Wen Nienhuys - - */ + /* 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; +} -#include "time-scaled-music-iterator.hh" -#include "time-scaled-music.hh" -#include "musical-request.hh" -#include "translator-group.hh" -#include "command-request.hh" void Time_scaled_music_iterator::process (Moment m) { - if (!m) + if (spanner_duration_.to_bool () && + m.main_part_ == next_split_mom_) + { + 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 ("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); + + Moment *mp = unsmob_moment (get_outlet ()->get_property ("tupletSpannerDuration")); + + if (mp) { - Music_iterator *yeah = try_music (music_l_); - if (yeah) - set_translator (yeah->report_to_l ()); - else - music_l_->origin ()->warning ( _("no one to print a tuplet start bracket")); + spanner_duration_ = mp->main_part_; + next_split_mom_ = spanner_duration_; } - Music_wrapper_iterator::process (m); + Sequential_iterator::construct_children (); } + +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);