2 time-scaled-music-iterator.cc -- implement Time_scaled_music_iterator
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--2008 Han-Wen Nienhuys <hanwen@xs4all.nl>,
7 Erik Sandberg <mandolaerik@gmail.com>
12 #include "international.hh"
14 #include "music-wrapper-iterator.hh"
15 #include "stream-event.hh"
18 Iterates \times, by sending TupletSpanEvents at the start/end of each
19 tuplet bracket. Extra stop/start events are sent at regular
20 intervals if tupletSpannerDuration is set.
22 class Time_scaled_music_iterator
: public Music_wrapper_iterator
25 DECLARE_SCHEME_CALLBACK (constructor
, ());
27 DECLARE_CLASSNAME (Time_scaled_music_iterator
);
28 Time_scaled_music_iterator ();
30 virtual void process (Moment m
);
31 virtual void construct_children ();
32 virtual void derived_mark () const;
33 virtual Moment
pending_moment () const;
35 Music
*create_event (Direction d
);
39 /* tupletSpannerDuration */
40 Moment spanner_duration_
;
42 /* next time to add a stop/start pair */
43 Moment next_split_mom_
;
45 /* Recycle start/stop events if tupletSpannerDuration is set. */
46 SCM synthesized_events_
;
48 Context_handle tuplet_handler_
;
52 Time_scaled_music_iterator::create_event (Direction d
)
54 SCM ev_scm
= scm_call_2 (ly_lily_module_constant ("make-span-event"),
55 ly_symbol2scm ("TupletSpanEvent"),
58 Music
*mus
= get_music ();
60 Music
*ev
= unsmob_music (ev_scm
);
61 ev
->set_spot (*mus
->origin ());
64 ev
->set_property ("numerator", mus
->get_property ("numerator"));
65 ev
->set_property ("denominator", mus
->get_property ("denominator"));
66 ev
->set_property ("tweaks", mus
->get_property ("tweaks"));
67 ev
->set_property ("length", spanner_duration_
.smobbed_copy ());
70 synthesized_events_
= scm_cons (ev_scm
, synthesized_events_
);
75 Time_scaled_music_iterator::Time_scaled_music_iterator ()
77 spanner_duration_
= next_split_mom_
= 0;
78 synthesized_events_
= SCM_EOL
;
83 Time_scaled_music_iterator::pending_moment () const
85 Moment next_mom
= Music_wrapper_iterator::pending_moment ();
86 next_mom
= min (next_mom
, next_split_mom_
);
93 Time_scaled_music_iterator::process (Moment m
)
95 if (spanner_duration_
.to_bool () &&
96 m
.main_part_
== next_split_mom_
)
98 descend_to_bottom_context ();
99 if (tuplet_handler_
.get_outlet ())
100 create_event (STOP
)->send_to_context (tuplet_handler_
.get_outlet ());
102 if (m
.main_part_
< music_get_length ().main_part_
)
104 tuplet_handler_
.set_context (get_outlet ());
105 report_event (create_event (START
));
107 next_split_mom_
+= spanner_duration_
;
111 tuplet_handler_
.set_context (0);
114 Music_wrapper_iterator::process (m
);
115 if (child_iter_
&& child_iter_
->ok ())
116 descend_to_child (child_iter_
->get_outlet ());
121 Time_scaled_music_iterator::construct_children ()
123 spanner_duration_
= music_get_length ();
125 Moment
*mp
= unsmob_moment (get_outlet ()->get_property ("tupletSpannerDuration"));
127 spanner_duration_
= min (mp
->main_part_
, spanner_duration_
);
129 Music_wrapper_iterator::construct_children ();
131 if (child_iter_
&& child_iter_
->ok ())
132 descend_to_child (child_iter_
->get_outlet ());
136 Time_scaled_music_iterator::derived_mark () const
138 scm_gc_mark (synthesized_events_
);
139 Music_wrapper_iterator::derived_mark ();
142 IMPLEMENT_CTOR_CALLBACK (Time_scaled_music_iterator
);