2 duration.cc -- implement Duration
4 source file of the LilyPond music typesetter
6 (c) 1997--2003 Jan Nieuwenhuizen <janneke@gnu.org>
7 Han-Wen Nienhuys <hanwen@cs.uu.nl>
14 #include "lily-proto.hh"
17 #include "duration.hh"
18 #include "ly-smobs.icc"
23 Duration::compare (Duration
const &left
, Duration
const &right
)
25 return Rational::compare (left
.get_length (), right
.get_length ());
32 factor_
= Rational (1,1);
35 Duration::Duration (int l
, int d
)
39 factor_
= Rational (1,1);
43 Duration::compressed (Rational m
) const
51 Duration::get_length () const
53 Rational
mom (1 << abs (durlog_
));
56 mom
= Rational (1)/mom
;
60 for (int d
= dots_
; d
; d
--)
62 delta
/= Rational (2);
72 Duration::to_string () const
77 s
= "log = " + ::to_string (durlog_
);
79 s
= ::to_string (1 << durlog_
);
81 s
+= ::to_string ('.', dots_
);
82 if (factor_
!= Moment (Rational (1,1)))
84 s
+= "*" + factor_
.to_string ();
90 IMPLEMENT_TYPE_P (Duration
, "ly:duration?");
93 Duration::mark_smob (SCM
)
98 IMPLEMENT_SIMPLE_SMOBS (Duration
);
100 Duration::print_smob (SCM s
, SCM port
, scm_print_state
*)
102 Duration
*r
= (Duration
*) ly_cdr (s
);
104 scm_puts ("#<Duration ", port
);
105 scm_display (scm_makfrom0str (r
->to_string ().to_str0 ()), port
);
106 scm_puts (" >", port
);
112 Duration::equal_p (SCM a
, SCM b
)
114 Duration
*p
= (Duration
*) ly_cdr (a
);
115 Duration
*q
= (Duration
*) ly_cdr (b
);
117 bool eq
= p
->dots_
== q
->dots_
118 && p
->durlog_
== q
->durlog_
119 && p
->factor_
== q
->factor_
;
121 return eq
? SCM_BOOL_T
: SCM_BOOL_F
;
124 MAKE_SCHEME_CALLBACK (Duration
, less_p
, 2);
126 Duration::less_p (SCM p1
, SCM p2
)
128 Duration
*a
= unsmob_duration (p1
);
129 Duration
*b
= unsmob_duration (p2
);
131 if (compare (*a
, *b
) < 0)
137 LY_DEFINE(duration_less
, "ly:duration<?", 2,0,0, (SCM p1
, SCM p2
),
138 "Is @var{p1} shorter than @var{p2}?")
140 Duration
*a
= unsmob_duration (p1
);
141 Duration
*b
= unsmob_duration (p2
);
143 SCM_ASSERT_TYPE(a
, p1
, SCM_ARG1
, __FUNCTION__
, "Duration");
144 SCM_ASSERT_TYPE(b
, p2
, SCM_ARG2
, __FUNCTION__
, "Duration");
146 if (Duration::compare (*a
, *b
) < 0)
153 LY_DEFINE(make_duration
,
154 "ly:make-duration", 2, 2, 0, (SCM length
, SCM dotcount
,
157 "@var{length} is the negative logarithm (base 2) of the duration:\n"
158 "1 is a half note, 2 is a quarter note, 3 is an eighth\n"
159 "note, etc. The number of dots after the note is given by\n"
162 "The duration factor is optionally given by @var{num} and @var{den}.\n"
164 "A duration is a musical duration, i.e. a length of time described by a\n"
165 "power of two (whole, half, quarter, etc.) and a number of augmentation\n"
170 SCM_ASSERT_TYPE(gh_number_p (length
), length
, SCM_ARG1
, __FUNCTION__
, "integer");
171 SCM_ASSERT_TYPE(gh_number_p (dotcount
), dotcount
, SCM_ARG2
, __FUNCTION__
, "integer");
173 bool compress
= false;
174 if (num
!= SCM_UNDEFINED
)
176 SCM_ASSERT_TYPE(gh_number_p (num
), length
, SCM_ARG3
, __FUNCTION__
, "integer");
180 num
= gh_int2scm (1);
182 if (den
!= SCM_UNDEFINED
)
183 SCM_ASSERT_TYPE(gh_number_p (den
), length
, SCM_ARG4
, __FUNCTION__
, "integer");
185 den
= gh_int2scm (1);
187 Duration
p (gh_scm2int (length
), gh_scm2int (dotcount
));
189 p
= p
.compressed (Rational (gh_scm2int (num
), gh_scm2int (den
)));
191 return p
.smobbed_copy ();
196 LY_DEFINE(duration_log
,
197 "ly:duration-log", 1, 0, 0, (SCM dur
),
198 "Extract the duration log from @var{dur}"
201 SCM_ASSERT_TYPE(unsmob_duration(dur
), dur
, SCM_ARG1
, __FUNCTION__
, "duration");
203 return gh_int2scm (unsmob_duration (dur
)->duration_log ());
207 LY_DEFINE(dot_count_log
,
208 "ly:duration-dot-count", 1, 0, 0, (SCM dur
),
209 "Extract the dot count from @var{dur}"
212 SCM_ASSERT_TYPE(unsmob_duration(dur
), dur
, SCM_ARG1
, __FUNCTION__
, "duration");
214 return gh_int2scm (unsmob_duration (dur
)->dot_count ());
218 LY_DEFINE(ly_intlog2
,
219 "ly:intlog2", 1, 0, 0, (SCM d
),
220 "The 2-logarithm of 1/@var{d}."
223 SCM_ASSERT_TYPE(gh_number_p (d
), d
, SCM_ARG1
, __FUNCTION__
, "integer");
225 int l
= intlog2 (gh_scm2int (d
));
227 return gh_int2scm (l
);
230 LY_DEFINE(compression_factor
,
231 "ly:duration-factor", 1, 0, 0, (SCM dur
),
232 "Extract the compression factor from @var{dur}. Return as a pair."
235 SCM_ASSERT_TYPE(unsmob_duration(dur
), dur
, SCM_ARG1
, __FUNCTION__
, "duration");
236 Rational r
=unsmob_duration (dur
)->factor ();
238 return gh_cons(gh_int2scm (r
.num()),gh_int2scm (r
.den ()));
242 Duration::smobbed_copy ()const
244 Duration
* p
= new Duration (*this);
245 return p
->smobbed_self ();
249 Duration::duration_log () const
255 Duration::dot_count () const