Workaround for broken MusicXML files (percussion clef in MuseScore)
[lilypond.git] / lily / timing-translator.cc
blob57998ace963d654a45cb598a5b8e6933556d3f24
1 /*
2 timing-translator.cc -- implement Timing_translator
5 source file of the GNU LilyPond music typesetter
7 (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
8 */
10 #include "timing-translator.hh"
12 #include "warn.hh"
13 #include "translator-group.hh"
14 #include "global-context.hh"
15 #include "multi-measure-rest.hh"
17 void
18 Timing_translator::stop_translation_timestep ()
20 Global_context *global = get_global_context ();
22 if (to_boolean (get_property ("timing"))
23 && !to_boolean (get_property ("skipBars")))
25 Moment barleft = (measure_length () - measure_position (context ()));
26 Moment now = now_mom ();
28 if (barleft > Moment (0))
30 Moment nextmom = now + barleft;
31 nextmom.grace_part_ = Rational (0);
32 global->add_moment_to_process (nextmom);
37 void
38 Timing_translator::initialize ()
40 context ()->add_alias (ly_symbol2scm ("Timing"));
41 context ()->set_property ("currentBarNumber", scm_from_int (1));
42 context ()->set_property ("internalBarNumber", scm_from_int (1));
44 context ()->set_property ("timeSignatureFraction",
45 scm_cons (scm_from_int (4), scm_from_int (4)));
47 Do not init measurePosition; this should be done from global
48 context.
50 context ()->set_property ("measureLength",
51 Moment (Rational (1)).smobbed_copy ());
52 context ()->set_property ("beatLength",
53 Moment (Rational (1, 4)).smobbed_copy ());
56 Rational
57 Timing_translator::measure_length () const
59 SCM l = get_property ("measureLength");
60 if (unsmob_moment (l))
61 return unsmob_moment (l)->main_part_;
62 else
63 return Rational (1);
66 Timing_translator::Timing_translator ()
70 void
71 Timing_translator::start_translation_timestep ()
73 Global_context *global = get_global_context ();
75 Moment now = global->now_mom ();
76 Moment dt = now - global->previous_moment ();
77 if (dt < Moment (0))
79 programming_error ("moving backwards in time");
80 dt = 0;
82 else if (dt.main_part_.is_infinity ())
84 programming_error ("moving infinitely to future");
85 dt = 0;
88 if (!dt.to_bool ())
89 return;
91 Moment measposp;
93 SCM s = get_property ("measurePosition");
94 if (unsmob_moment (s))
95 measposp = *unsmob_moment (s);
96 else
98 measposp = now;
99 context ()->set_property ("measurePosition",
100 measposp.smobbed_copy ());
103 measposp += dt;
105 int current_barnumber = robust_scm2int (get_property ("currentBarNumber"), 0);
106 int internal_barnumber = robust_scm2int (get_property ("internalBarNumber"), 0);
108 SCM cad = get_property ("timing");
109 bool c = to_boolean (cad);
111 Rational len = measure_length ();
112 while (c && measposp.main_part_ >= len)
114 measposp.main_part_ -= len;
115 current_barnumber ++;
116 internal_barnumber ++;
119 context ()->set_property ("currentBarNumber", scm_from_int (current_barnumber));
120 context ()->set_property ("internalBarNumber", scm_from_int (internal_barnumber));
121 context ()->set_property ("measurePosition", measposp.smobbed_copy ());
124 #include "translator.icc"
126 ADD_TRANSLATOR (Timing_translator,
127 /* doc */
128 "This engraver adds the alias @code{Timing} to its containing"
129 " context. Responsible for synchronizing timing information"
130 " from staves. Normally in @code{Score}. In order to create"
131 " polyrhythmic music, this engraver should be removed from"
132 " @code{Score} and placed in @code{Staff}.",
134 /* create */
137 /* read */
138 "internalBarNumber "
139 "currentBarNumber "
140 "measureLength "
141 "measurePosition ",
143 /* write */
144 "internalBarNumber "
145 "currentBarNumber "
146 "measurePosition "