]> git.donarmstrong.com Git - lilypond.git/blob - lily/timing-translator.cc
Fix some bugs in the dynamic engraver and PostScript backend
[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
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   SCM barn = get_property ("currentBarNumber");
106   int b = 0;
107   if (scm_is_number (barn))
108     b = scm_to_int (barn);
109
110   SCM cad = get_property ("timing");
111   bool c = to_boolean (cad);
112
113   Rational len = measure_length ();
114   while (c && measposp.main_part_ >= len)
115     {
116       measposp.main_part_ -= len;
117       b++;
118     }
119
120   context ()->set_property ("currentBarNumber", scm_from_int (b));
121   context ()->set_property ("measurePosition", measposp.smobbed_copy ());
122 }
123
124 #include "translator.icc"
125
126 ADD_TRANSLATOR (Timing_translator,
127                 "This engraver adds the alias "
128                 "@code{Timing} to its containing context."
129                 "Responsible for synchronizing timing information from staves.  "
130                 "Normally in @code{Score}.  In order to create polyrhythmic music, "
131                 "this engraver should be removed from @code{Score} and placed in "
132                 "@code{Staff}. "
133                 "\n\nThis engraver adds the alias @code{Timing} to its containing context.",
134
135                 "", "", "", "");