]> git.donarmstrong.com Git - lilypond.git/blob - midi2ly/duration-convert.cc
ee53cf47c4392d93bd31fe5fc8a7958f99939e94
[lilypond.git] / midi2ly / duration-convert.cc
1 /*
2   duration-convert.cc -- implement Duration_convert
3
4   source file of the LilyPond music typesetter
5
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 "warn.hh"
12
13 // statics Duration_convert
14 bool Duration_convert::no_quantify_b_s = false;
15 bool Duration_convert::no_double_dots_b_s = false;
16 bool Duration_convert::no_tuplets_b_s = false;
17 int Duration_convert::no_smaller_than_i_s = 0;
18 Array<Duration> Duration_convert::dur_array_s;
19         
20 String 
21 Duration_convert::dur2_str (Duration dur)
22 {
23   if (dur.ticks_i_)
24     return String ("[") + to_str (dur.ticks_i_) + "]";
25   
26   String str;
27   if (dur.durlog_i_ >= 0)
28     str = to_str ( type2_i (dur.durlog_i_) );
29   else if (dur.durlog_i_ == -1)
30     str = "\\breve";
31   else if (dur.durlog_i_ <= -2)
32     {
33       str = "\\longa";
34       if (dur.durlog_i_ < -2)
35         {
36           dur.plet_.iso_i_ *= 1 << (-2 - dur.durlog_i_);
37         }
38      }
39   str += to_str ('.', dur.dots_i_);
40   if (dur.plet_b ())
41     {
42       str += String ("*") + to_str (dur.plet_.iso_i_);
43       if (dur.plet_.type_i_ != 1)
44         str += String ("/") + to_str (dur.plet_.type_i_);
45     }
46   return str;
47 }
48
49 int
50 Duration_convert::dur2ticks_i (Duration dur)
51 {
52   if (dur.ticks_i_)
53     return dur.ticks_i_;
54   return dur2_mom (dur) * Rational (Duration::division_1_i_s);
55 }
56
57 int
58 Duration_convert::i2_type (int i)
59 {
60   int t=0;
61   while (i && !(i & 1)) {
62     i >>= 1;
63     t++;
64   }
65   return t;
66 }
67
68 int
69 Duration_convert::type2_i (int type)
70 {
71   if (type<0)
72     return 0; 
73   else
74     return 1 << type;
75 }
76
77 Rational
78 Duration_convert::dur2_mom (Duration dur)
79 {
80   if (dur.ticks_i_)
81     return Rational (dur.ticks_i_, Duration::division_1_i_s);   
82
83   // or simply assert?
84   if (dur.durlog_i_<-10)
85     return Rational (0);
86   Rational mom;
87   if (dur.durlog_i_<0)
88     mom = Rational (type2_i (-dur.durlog_i_), 1);
89   else
90     mom = Rational (1 , type2_i (dur.durlog_i_));
91
92   Rational delta = mom;
93   while (dur.dots_i_--) 
94     {
95       delta /= 2.0;
96       mom += delta;
97     }
98
99   return mom * plet_factor_mom (dur);    
100 }
101
102 Duration
103 Duration_convert::mom2_dur (Rational mom)
104 {
105   if (!mom) 
106     {
107       Duration dur;
108       dur.set_plet (0,1);
109       return dur;
110     }
111
112   return mom2standardised_dur (mom);
113 }
114
115
116 Duration
117 Duration_convert::mom2standardised_dur (Rational mom)
118 {
119   Duration dur;
120
121   if (mom == Rational (0))
122     return dur;
123
124   int d = no_smaller_than_i_s ? no_smaller_than_i_s : 7;
125   int i = type2_i (d);
126   int n = (mom / Rational (1, i)).to_int ();
127   
128   int tuplet = 1;
129   if (!no_tuplets_b_s)
130     {
131       // ugh: 8
132       int m = n;
133       int tup = 1;
134       while (tup < 8 && 
135              mom != Rational (m, i * tup))
136         {
137           tup += 2;
138           m = (mom / Rational (1, i * tup)).to_int ();
139         }
140
141       if (tuplet < 8)
142         {
143           n = m;
144           tuplet = tup;
145         }
146     }
147       
148   if (!n)
149     return dur;
150   
151   if (mom - Rational (n, i)
152       > Rational (1, i * 2 * tuplet))
153     n++;
154   
155   while (!(n & 1))
156     {
157       n >>= 1;
158       d--;
159     }
160   
161   dur.durlog_i_ = d;
162   dur.plet_.iso_i_ = n;
163   dur.plet_.type_i_ = tuplet;
164   return dur;
165 }
166
167 Rational
168 Duration_convert::plet_factor_mom (Duration dur)
169 {
170   return dur.plet_.mom ();
171 }
172
173 Real
174 Duration_convert::sync_f (Duration dur, Rational mom)
175 {
176   return mom / dur2_mom (dur);
177 }
178
179 Duration
180 Duration_convert::ticks2_dur (int ticks_i)
181 {
182   Rational mom (ticks_i, Duration::division_1_i_s);
183   return mom2standardised_dur (mom);
184 }
185
186 Duration
187 Duration_convert::ticks2standardised_dur (int ticks_i)
188 {
189   Rational mom (ticks_i, Duration::division_1_i_s);
190   Duration dur = mom2standardised_dur (mom);
191   return dur;
192 }