lilypond-1.5.8
[lilypond.git] / midi2ly / duration-convert.cc
blobb915c87727df15a8e50787d09c77175af7dd2a9d
1 /*
2 duration-convert.cc -- implement Duration_convert
4 source file of the LilyPond music typesetter
6 (c) 1997--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 Jan Nieuwenhuizen <janneke@gnu.org>
8 */
9 #include <assert.h>
10 #include "duration-convert.hh"
11 #include "duration-iter.hh"
12 #include "warn.hh"
14 // statics Duration_convert
15 bool Duration_convert::no_quantify_b_s = false;
16 bool Duration_convert::no_double_dots_b_s = false;
17 bool Duration_convert::no_tuplets_b_s = false;
18 int Duration_convert::no_smaller_than_i_s = 0;
19 Array<Duration> Duration_convert::dur_array_s;
21 String
22 Duration_convert::dur2_str (Duration dur)
24 if (dur.ticks_i_)
25 return String ("[") + to_str (dur.ticks_i_) + "]";
27 String str;
28 if (dur.durlog_i_ >= 0)
29 str = to_str ( type2_i (dur.durlog_i_) );
30 else if (dur.durlog_i_ == -1)
31 str = "\\breve";
32 else if (dur.durlog_i_ <= -2)
34 str = "\\longa";
35 if (dur.durlog_i_ < -2)
37 dur.plet_.iso_i_ *= 1 << (-2 - dur.durlog_i_);
40 str += to_str ('.', dur.dots_i_);
41 if (dur.plet_b ())
42 str += String ("*") + to_str (dur.plet_.iso_i_)
43 + String ("/") + to_str (dur.plet_.type_i_);
44 return str;
47 int
48 Duration_convert::dur2ticks_i (Duration dur)
50 if (dur.ticks_i_)
51 return dur.ticks_i_;
52 return dur2_mom (dur) * Rational (Duration::division_1_i_s);
55 int
56 Duration_convert::i2_type (int i)
58 int t=0;
59 while (i && !(i & 1)) {
60 i >>= 1;
61 t++;
63 return t;
66 int
67 Duration_convert::type2_i (int type)
69 if (type<0)
70 return 0;
71 else
72 return 1 << type;
75 Rational
76 Duration_convert::dur2_mom (Duration dur)
78 if (dur.ticks_i_)
79 return Rational (dur.ticks_i_, Duration::division_1_i_s);
81 // or simply assert?
82 if (dur.durlog_i_<-10)
83 return Rational (0);
84 Rational mom;
85 if (dur.durlog_i_<0)
86 mom = Rational (type2_i (-dur.durlog_i_), 1);
87 else
88 mom = Rational (1 , type2_i (dur.durlog_i_));
90 Rational delta = mom;
91 while (dur.dots_i_--)
93 delta /= 2.0;
94 mom += delta;
97 return mom * plet_factor_mom (dur);
100 Duration
101 Duration_convert::mom2_dur (Rational mom)
103 if (!mom)
105 Duration dur;
106 dur.set_plet (0,1);
107 return dur;
110 return mom2standardised_dur (mom);
113 Duration
114 Duration_convert::mom2standardised_dur (Rational mom)
116 // if (!dur_array_s.length_i ())
117 if (!dur_array_s.size ())
118 set_array ();
119 assert (dur_array_s.size ());
120 for (int i = 0; i < dur_array_s.size () - 1; i++)
122 Rational lower_mom = dur2_mom (dur_array_s[ i ]);
123 if (mom <= lower_mom)
125 // all arbitrary, but 3/4 will get rid of the noise...
126 // kinda ok
127 if (i || (mom / lower_mom > Rational (3, 4)))
128 return dur_array_s[ i ];
129 else
131 Duration d;
132 d.durlog_i_ = -100;
133 return d;
136 Rational upper_mom = dur2_mom (dur_array_s[ i + 1 ]);
137 if ((mom < upper_mom)
138 && ((mom - lower_mom) / lower_mom
139 < (upper_mom - mom) / upper_mom))
140 return dur_array_s[ i ];
142 return dur_array_s[ dur_array_s.size () - 1 ];
145 void
146 Duration_convert::set_array ()
148 dur_array_s.clear ();
150 Duration_iterator i;
151 while (i.ok ())
152 dur_array_s.push (i.forward_dur ());
156 Rational
157 Duration_convert::plet_factor_mom (Duration dur)
159 return dur.plet_.mom ();
162 Real
163 Duration_convert::sync_f (Duration dur, Rational mom)
165 return mom / dur2_mom (dur);
168 Duration
169 Duration_convert::ticks2_dur (int ticks_i)
171 Rational mom (ticks_i, Duration::division_1_i_s);
172 return mom2standardised_dur (mom);
175 Duration
176 Duration_convert::ticks2standardised_dur (int ticks_i)
178 Rational mom (ticks_i, Duration::division_1_i_s);
179 Duration dur = mom2standardised_dur (mom);
180 return dur;