2 duration.cc -- implement Duration
4 source file of the LilyPond music typesetter
6 (c) 1997--2007 Jan Nieuwenhuizen <janneke@gnu.org>
7 Han-Wen Nienhuys <hanwen@xs4all.nl>
10 #include "duration.hh"
13 #include "lily-proto.hh"
15 #include "ly-smobs.icc"
18 Duration::compare (Duration
const &left
, Duration
const &right
)
20 return Rational::compare (left
.get_length (), right
.get_length ());
27 factor_
= Rational (1, 1);
30 Duration::Duration (int log
, int d
)
34 factor_
= Rational (1, 1);
37 Duration::Duration (Rational r
, bool scale
)
39 factor_
= Rational (1, 1);
48 /* we want to find the integer k for which 2q/p > 2^k >= q/p.
49 It's simple to check that k' = \floor \log q - \floor \log p
50 satisfies the left inequality and is within a factor of 2 of
51 satistying the right one. Therefore either k = k' or k = k'+1 */
55 int k
= intlog2 (q
) - intlog2 (p
);
59 assert ((p
<< k
) >= q
&& (p
<< (k
-1)) < q
);
61 /* If we were to write out log (p/q) in base 2, then the position of the
62 first non-zero bit (ie. k in our notation) would be the durlog
63 and the number of consecutive 1s after that bit would be the number of
73 /* we only go up to 64th notes */
83 factor_
= r
/ get_length ();
88 Duration::compressed (Rational m
) const
96 Duration::get_length () const
98 Rational
mom (1 << abs (durlog_
));
101 mom
= Rational (1) / mom
;
103 Rational delta
= mom
;
104 for (int i
= 0; i
< dots_
; i
++)
106 delta
/= Rational (2);
110 return mom
* factor_
;
114 Duration::to_string () const
119 s
= "log = " + ::to_string (durlog_
);
121 s
= ::to_string (1 << durlog_
);
123 s
+= ::to_string ('.', dots_
);
124 if (factor_
!= Moment (Rational (1, 1)))
125 s
+= "*" + factor_
.to_string ();
129 IMPLEMENT_TYPE_P (Duration
, "ly:duration?");
132 Duration::mark_smob (SCM
)
137 IMPLEMENT_SIMPLE_SMOBS (Duration
);
139 Duration::print_smob (SCM s
, SCM port
, scm_print_state
*)
141 Duration
*r
= (Duration
*) SCM_CELL_WORD_1 (s
);
143 scm_puts ("#<Duration ", port
);
144 scm_display (ly_string2scm (r
->to_string ()), port
);
145 scm_puts (" >", port
);
151 Duration::equal_p (SCM a
, SCM b
)
153 Duration
*p
= (Duration
*) SCM_CELL_WORD_1 (a
);
154 Duration
*q
= (Duration
*) SCM_CELL_WORD_1 (b
);
156 bool eq
= p
->dots_
== q
->dots_
157 && p
->durlog_
== q
->durlog_
158 && p
->factor_
== q
->factor_
;
160 return eq
? SCM_BOOL_T
: SCM_BOOL_F
;
164 Duration::duration_log () const
170 Duration::dot_count () const