]> git.donarmstrong.com Git - lilypond.git/blob - lily/timing-translator.cc
d7929181716a635177523b7c657afd935dd33d05
[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--2006 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             Hmm. We insert the bar moment every time we process a
31             moment.  A waste of cpu?
32           */
33           && !now.grace_part_)
34         global->add_moment_to_process (now + barleft);
35     }
36 }
37
38 void
39 Timing_translator::initialize ()
40 {
41   context ()->add_alias (ly_symbol2scm ("Timing"));
42   context ()->set_property ("currentBarNumber", scm_from_int (1));
43   context ()->set_property ("internalBarNumber", scm_from_int (1));
44
45   context ()->set_property ("timeSignatureFraction",
46                             scm_cons (scm_from_int (4), scm_from_int (4)));
47   /*
48     Do not init measurePosition; this should be done from global
49     context.
50   */
51   context ()->set_property ("measureLength",
52                             Moment (Rational (1)).smobbed_copy ());
53   context ()->set_property ("beatLength",
54                             Moment (Rational (1, 4)).smobbed_copy ());
55 }
56
57 Rational
58 Timing_translator::measure_length () const
59 {
60   SCM l = get_property ("measureLength");
61   if (unsmob_moment (l))
62     return unsmob_moment (l)->main_part_;
63   else
64     return Rational (1);
65 }
66
67 Timing_translator::Timing_translator ()
68 {
69 }
70
71 void
72 Timing_translator::start_translation_timestep ()
73 {
74   Global_context *global = get_global_context ();
75
76   Moment now = global->now_mom ();
77   Moment dt = now - global->previous_moment ();
78   if (dt < Moment (0))
79     {
80       programming_error ("moving backwards in time");
81       dt = 0;
82     }
83   else if (dt.main_part_.is_infinity ())
84     {
85       programming_error ("moving infinitely to future");
86       dt = 0;
87     }
88
89   if (!dt.to_bool ())
90     return;
91
92   Moment measposp;
93
94   SCM s = get_property ("measurePosition");
95   if (unsmob_moment (s))
96     measposp = *unsmob_moment (s);
97   else
98     {
99       measposp = now;
100       context ()->set_property ("measurePosition",
101                                 measposp.smobbed_copy ());
102     }
103
104   measposp += dt;
105
106   int current_barnumber = robust_scm2int (get_property ("currentBarNumber"), 0);
107   int internal_barnumber = robust_scm2int (get_property ("internalBarNumber"), 0);
108
109   SCM cad = get_property ("timing");
110   bool c = to_boolean (cad);
111
112   Rational len = measure_length ();
113   while (c && measposp.main_part_ >= len)
114     {
115       measposp.main_part_ -= len;
116       current_barnumber ++;
117       internal_barnumber ++;
118     }
119
120   context ()->set_property ("currentBarNumber", scm_from_int (current_barnumber));
121   context ()->set_property ("internalBarNumber", scm_from_int (internal_barnumber));
122   context ()->set_property ("measurePosition", measposp.smobbed_copy ());
123 }
124
125 #include "translator.icc"
126
127 ADD_TRANSLATOR (Timing_translator,
128                 "This engraver adds the alias "
129                 "@code{Timing} to its containing context."
130                 "Responsible for synchronizing timing information from staves.  "
131                 "Normally in @code{Score}.  In order to create polyrhythmic music, "
132                 "this engraver should be removed from @code{Score} and placed in "
133                 "@code{Staff}. "
134                 "\n\nThis engraver adds the alias @code{Timing} to its containing context.",
135
136                 "", "",
137
138                 "internalBarNumber "
139                 "currentBarNumber "
140                 "measureLength "
141                 "measurePosition ",
142
143                 "internalBarNumber "
144                 "currentBarNumber "
145                 "measurePosition "
146                 );