2 duration-convert.cc -- implement Duration_convert
4 source file of the LilyPond music typesetter
6 (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 Jan Nieuwenhuizen <jan@digicash.com>
10 #include "duration-convert.hh"
13 // statics Duration_convert
14 bool const Duration_convert::midi_as_plet_b_s
= true;
15 bool Duration_convert::no_quantify_b_s
= false;
16 bool Duration_convert::no_double_dots_b_s
= false;
17 bool Duration_convert::no_triplets_b_s
= false;
18 int Duration_convert::no_smaller_than_i_s
= 0;
19 Array
<Duration
> Duration_convert::dur_array_s
;
22 Duration_convert::dur2_str(Duration dur
)
25 return String("[") + String(dur
.ticks_i_
) + "]";
28 if (dur
.durlog_i_
>= 0)
29 str
= String( type2_i(dur
.durlog_i_
) );
30 else if (dur
.durlog_i_
== -1)
32 else if (dur
.durlog_i_
== -2)
34 str
+= String('.', dur
.dots_i_
);
36 str
+= String("*") + String(dur
.plet_
.iso_i_
)
37 + String("/") + String(dur
.plet_
.type_i_
);
43 Duration_convert::dur2_i(Duration dur
, int division_1_i
)
45 return dur2_mom(dur
) * Moment(division_1_i
);
50 Duration_convert::dur2ticks_i(Duration dur
)
54 return dur2_mom(dur
) * Moment(Duration::division_1_i_s
);
59 Duration_convert::i2_type(int i
)
70 Duration_convert::type2_i(int type
)
79 Duration_convert::dur2_mom(Duration dur
)
82 return Moment(dur
.ticks_i_
, Duration::division_1_i_s
);
85 if (dur
.durlog_i_
<-10)
89 mom
= Moment(type2_i(-dur
.durlog_i_
), 1);
91 mom
= Moment(1 , type2_i(dur
.durlog_i_
));
100 return mom
* plet_factor_mom(dur
);
105 Duration_convert::i2_mom(int time_i
, int division_1_i
)
110 if (division_1_i
> 0)
111 return Moment(time_i
, division_1_i
);
113 return Moment(-division_1_i
, time_i
);
118 Duration_convert::mom2_dur(Moment mom
)
128 Duration dur
= mom2standardised_dur(mom
);
129 // if (!dur.mom() || (dur.mom() == mom))
130 if (!dur
.length() || (dur
.length() == mom
))
132 assert(midi_as_plet_b_s
);
134 // dur.set_plet(type_mom, Duration::division_1_i_s / 4);
136 // Moment as_plet_mom = mom / dur.mom();
137 Moment as_plet_mom
= mom
/ dur
.length();
138 as_plet_mom
*= dur
.plet_
.mom();
139 long num
= as_plet_mom
.numerator().as_long();
140 long den
= as_plet_mom
.denominator().as_long();
141 dur
.set_plet(num
, den
);
146 Duration_convert::mom2standardised_dur(Moment mom
)
148 // if (!dur_array_s.length_i())
149 if (!dur_array_s
.size())
151 assert(dur_array_s
.size());
152 for (int i
= 0; i
< dur_array_s
.size() - 1; i
++)
154 Moment lower_mom
= dur2_mom(dur_array_s
[ i
]);
155 if (mom
<= lower_mom
)
157 // all arbitrary, but 3/4 will get rid of the noise...
159 if (i
|| (mom
/ lower_mom
> Moment(3, 4)))
160 return dur_array_s
[ i
];
168 Moment upper_mom
= dur2_mom(dur_array_s
[ i
+ 1 ]);
169 if ((mom
< upper_mom
)
170 && ((mom
- lower_mom
) / lower_mom
171 < (upper_mom
- mom
) / upper_mom
))
172 return dur_array_s
[ i
];
174 return dur_array_s
[ dur_array_s
.size() - 1 ];
178 Duration_convert::set_array()
182 Duration_iterator iter_dur
;
185 dur_array_s
.push(iter_dur
++);
190 Duration_convert::plet_factor_mom(Duration dur
)
192 return dur
.plet_
.mom();
196 Duration_convert::sync_f(Duration dur
, Moment mom
)
198 return mom
/ dur2_mom(dur
);
202 Duration_convert::ticks2_dur(int ticks_i
)
204 // Duration dur(4, 0);
205 // dur.set_plet(ticks_i, Duration::division_1_i_s / 4);
207 Moment
mom(ticks_i
, Duration::division_1_i_s
);
208 if (midi_as_plet_b_s
)
209 return mom2_dur(mom
);
211 Duration dur
= mom2standardised_dur(mom
);
213 // if (dur.mom() == mom)
214 if (dur
.length() == mom
)
219 dur
.durlog_i_
= -100;
221 dur
.set_ticks(ticks_i
);
224 return mom2_dur(mom
);
229 Duration_convert::ticks2standardised_dur(int ticks_i
)
231 Moment
mom(ticks_i
, Duration::division_1_i_s
);
232 Duration dur
= mom2standardised_dur(mom
);
236 Duration_iterator::Duration_iterator()
238 cursor_dur_
.durlog_i_
= 7;
239 if (Duration_convert::no_smaller_than_i_s
)
240 cursor_dur_
.durlog_i_
= Duration_convert::no_smaller_than_i_s
;
241 // cursor_dur_.set_plet(1, 1);
245 Duration_iterator::operator ++(int)
247 return forward_dur();
251 Duration_iterator::operator ()()
256 Duration_iterator::operator bool()
262 Duration_iterator::dur()
268 Duration_iterator::forward_dur()
270 /* should do smart table? guessing:
284 Duration dur
= cursor_dur_
;
286 if (!cursor_dur_
.dots_i_
&& !cursor_dur_
.plet_b())
288 cursor_dur_
.durlog_i_
+= 1;
289 cursor_dur_
.dots_i_
= 2;
291 else if (cursor_dur_
.dots_i_
== 2)
293 assert(!cursor_dur_
.plet_b());
294 cursor_dur_
.dots_i_
= 0;
295 cursor_dur_
.durlog_i_
-=2;
296 cursor_dur_
.set_plet(2, 3);
298 else if (cursor_dur_
.plet_b()
299 && (cursor_dur_
.plet_
.iso_i_
== 2)
300 && (cursor_dur_
.plet_
.type_i_
== 3))
302 assert(!cursor_dur_
.dots_i_
);
303 cursor_dur_
.set_plet(1, 1);
304 cursor_dur_
.durlog_i_
+= 1;
305 cursor_dur_
.dots_i_
= 1;
307 else if (cursor_dur_
.dots_i_
== 1)
309 assert(!cursor_dur_
.plet_b());
310 cursor_dur_
.dots_i_
= 0;
311 cursor_dur_
.durlog_i_
-= 1;
314 if (Duration_convert::no_triplets_b_s
315 && cursor_dur_
.plet_b() && ok())
317 if (Duration_convert::no_double_dots_b_s
318 && (cursor_dur_
.dots_i_
== 2) && ok())
320 if (Duration_convert::no_smaller_than_i_s
321 && (cursor_dur_
.durlog_i_
> Duration_convert::no_smaller_than_i_s
) && ok())
323 if (Duration_convert::no_smaller_than_i_s
324 && cursor_dur_
.dots_i_
325 && (cursor_dur_
.durlog_i_
>= Duration_convert::no_smaller_than_i_s
)
328 if (Duration_convert::no_smaller_than_i_s
329 && (cursor_dur_
.dots_i_
== 2)
330 && (cursor_dur_
.durlog_i_
>= Duration_convert::no_smaller_than_i_s
/ 2)
338 Duration_iterator::ok()
340 return (cursor_dur_
.durlog_i_
341 && !((cursor_dur_
.durlog_i_
== 0) && (cursor_dur_
.dots_i_
> 2)));