]> git.donarmstrong.com Git - lilypond.git/blob - lily/timing-translator.cc
Run `make grand-replace'.
[lilypond.git] / lily / timing-translator.cc
1 /*
2   timing-translator.cc -- implement Timing_translator
3
4
5   source file of the GNU LilyPond music typesetter
6
7   (c) 1997--2008 Han-Wen Nienhuys <hanwen@xs4all.nl>
8 */
9
10 #include "timing-translator.hh"
11
12 #include "warn.hh"
13 #include "translator-group.hh"
14 #include "global-context.hh"
15 #include "multi-measure-rest.hh"
16
17 void
18 Timing_translator::stop_translation_timestep ()
19 {
20   Global_context *global = get_global_context ();
21
22   if (to_boolean (get_property ("timing"))
23       && !to_boolean (get_property ("skipBars")))
24     {
25       Moment barleft = (measure_length () - measure_position (context ()));
26       Moment now = now_mom ();
27
28       if (barleft > Moment (0))
29         {
30           Moment nextmom = now + barleft;
31           nextmom.grace_part_ = Rational (0);
32           global->add_moment_to_process (nextmom);
33         }
34     }
35 }
36
37 void
38 Timing_translator::initialize ()
39 {
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));
43
44   context ()->set_property ("timeSignatureFraction",
45                             scm_cons (scm_from_int (4), scm_from_int (4)));
46   /*
47     Do not init measurePosition; this should be done from global
48     context.
49   */
50   context ()->set_property ("measureLength",
51                             Moment (Rational (1)).smobbed_copy ());
52   context ()->set_property ("beatLength",
53                             Moment (Rational (1, 4)).smobbed_copy ());
54 }
55
56 Rational
57 Timing_translator::measure_length () const
58 {
59   SCM l = get_property ("measureLength");
60   if (unsmob_moment (l))
61     return unsmob_moment (l)->main_part_;
62   else
63     return Rational (1);
64 }
65
66 Timing_translator::Timing_translator ()
67 {
68 }
69
70 void
71 Timing_translator::start_translation_timestep ()
72 {
73   Global_context *global = get_global_context ();
74
75   Moment now = global->now_mom ();
76   Moment dt = now - global->previous_moment ();
77   if (dt < Moment (0))
78     {
79       programming_error ("moving backwards in time");
80       dt = 0;
81     }
82   else if (dt.main_part_.is_infinity ())
83     {
84       programming_error ("moving infinitely to future");
85       dt = 0;
86     }
87
88   if (!dt.to_bool ())
89     return;
90
91   Moment measposp;
92
93   SCM s = get_property ("measurePosition");
94   if (unsmob_moment (s))
95     measposp = *unsmob_moment (s);
96   else
97     {
98       measposp = now;
99       context ()->set_property ("measurePosition",
100                                 measposp.smobbed_copy ());
101     }
102
103   measposp += dt;
104
105   int current_barnumber = robust_scm2int (get_property ("currentBarNumber"), 0);
106   int internal_barnumber = robust_scm2int (get_property ("internalBarNumber"), 0);
107
108   SCM cad = get_property ("timing");
109   bool c = to_boolean (cad);
110
111   Rational len = measure_length ();
112   while (c && measposp.main_part_ >= len)
113     {
114       measposp.main_part_ -= len;
115       current_barnumber ++;
116       internal_barnumber ++;
117     }
118
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 ());
122 }
123
124 #include "translator.icc"
125
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}.",
133
134                 /* create */
135                 "",
136
137                 /* read */
138                 "internalBarNumber "
139                 "currentBarNumber "
140                 "measureLength "
141                 "measurePosition ",
142
143                 /* write */
144                 "internalBarNumber "
145                 "currentBarNumber "
146                 "measurePosition "
147                 );