]> git.donarmstrong.com Git - lilypond.git/blob - lily/timing-translator.cc
Update mailmap.
[lilypond.git] / lily / timing-translator.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "timing-translator.hh"
21
22 #include "warn.hh"
23 #include "translator-group.hh"
24 #include "global-context.hh"
25 #include "multi-measure-rest.hh"
26
27 void
28 Timing_translator::stop_translation_timestep ()
29 {
30   Global_context *global = get_global_context ();
31
32   if (to_boolean (get_property ("timing"))
33       && !to_boolean (get_property ("skipBars")))
34     {
35       Moment barleft = (measure_length () - measure_position (context ()));
36       Moment now = now_mom ();
37
38       if (barleft > Moment (0))
39         {
40           Moment nextmom = now + barleft;
41           nextmom.grace_part_ = Rational (0);
42           global->add_moment_to_process (nextmom);
43         }
44     }
45 }
46
47 void
48 Timing_translator::initialize ()
49 {
50   context ()->add_alias (ly_symbol2scm ("Timing"));
51   context ()->set_property ("currentBarNumber", scm_from_int (1));
52   context ()->set_property ("internalBarNumber", scm_from_int (1));
53
54   context ()->set_property ("timeSignatureFraction",
55                             scm_cons (scm_from_int (4), scm_from_int (4)));
56   /*
57     Do not init measurePosition; this should be done from global
58     context.
59   */
60   context ()->set_property ("measureLength",
61                             Moment (Rational (1)).smobbed_copy ());
62   context ()->set_property ("beatLength",
63                             Moment (Rational (1, 4)).smobbed_copy ());
64 }
65
66 Rational
67 Timing_translator::measure_length () const
68 {
69   SCM l = get_property ("measureLength");
70   if (unsmob_moment (l))
71     return unsmob_moment (l)->main_part_;
72   else
73     return Rational (1);
74 }
75
76 Timing_translator::Timing_translator ()
77 {
78 }
79
80 void
81 Timing_translator::start_translation_timestep ()
82 {
83   Global_context *global = get_global_context ();
84
85   Moment now = global->now_mom ();
86   Moment dt = now - global->previous_moment ();
87   if (dt < Moment (0))
88     {
89       programming_error ("moving backwards in time");
90       dt = 0;
91     }
92   else if (dt.main_part_.is_infinity ())
93     {
94       programming_error ("moving infinitely to future");
95       dt = 0;
96     }
97
98   if (!dt.to_bool ())
99     return;
100
101   Moment measposp;
102
103   SCM s = get_property ("measurePosition");
104   if (unsmob_moment (s))
105     measposp = *unsmob_moment (s);
106   else
107     {
108       measposp = now;
109       context ()->set_property ("measurePosition",
110                                 measposp.smobbed_copy ());
111     }
112
113   measposp += dt;
114
115   int current_barnumber = robust_scm2int (get_property ("currentBarNumber"), 0);
116   int internal_barnumber = robust_scm2int (get_property ("internalBarNumber"), 0);
117
118   SCM cad = get_property ("timing");
119   bool c = to_boolean (cad);
120
121   Rational len = measure_length ();
122   while (c && measposp.main_part_ >= len)
123     {
124       measposp.main_part_ -= len;
125       current_barnumber ++;
126       internal_barnumber ++;
127     }
128
129   context ()->set_property ("currentBarNumber", scm_from_int (current_barnumber));
130   context ()->set_property ("internalBarNumber", scm_from_int (internal_barnumber));
131   context ()->set_property ("measurePosition", measposp.smobbed_copy ());
132 }
133
134 #include "translator.icc"
135
136 ADD_TRANSLATOR (Timing_translator,
137                 /* doc */
138                 "This engraver adds the alias @code{Timing} to its containing"
139                 " context.  Responsible for synchronizing timing information"
140                 " from staves.  Normally in @code{Score}.  In order to create"
141                 " polyrhythmic music, this engraver should be removed from"
142                 " @code{Score} and placed in @code{Staff}.",
143
144                 /* create */
145                 "",
146
147                 /* read */
148                 "internalBarNumber "
149                 "currentBarNumber "
150                 "measureLength "
151                 "measurePosition ",
152
153                 /* write */
154                 "internalBarNumber "
155                 "currentBarNumber "
156                 "measurePosition "
157                 );