]> git.donarmstrong.com Git - lilypond.git/blob - midi2ly/duration-convert.cc
release: 1.3.140
[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 "duration-iter.hh"
12 #include "warn.hh"
13
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;
20         
21 String 
22 Duration_convert::dur2_str (Duration dur)
23 {
24   if (dur.ticks_i_)
25     return String ("[") + to_str (dur.ticks_i_) + "]";
26   
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)
33     {
34       str = "\\longa";
35       if (dur.durlog_i_ < -2)
36         {
37           dur.plet_.iso_i_ *= 1 << (-2 - dur.durlog_i_);
38         }
39      }
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;
45 }
46
47 int
48 Duration_convert::dur2ticks_i (Duration dur)
49 {
50   if (dur.ticks_i_)
51     return dur.ticks_i_;
52   return dur2_mom (dur) * Rational (Duration::division_1_i_s);
53 }
54
55 int
56 Duration_convert::i2_type (int i)
57 {
58   int t=0;
59   while (i && !(i & 1)) {
60     i >>= 1;
61     t++;
62   }
63   return t;
64 }
65
66 int
67 Duration_convert::type2_i (int type)
68 {
69   if (type<0)
70     return 0; 
71   else
72     return 1 << type;
73 }
74
75 Rational
76 Duration_convert::dur2_mom (Duration dur)
77 {
78   if (dur.ticks_i_)
79     return Rational (dur.ticks_i_, Duration::division_1_i_s);   
80
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_));
89
90   Rational delta = mom;
91   while (dur.dots_i_--) 
92     {
93       delta /= 2.0;
94       mom += delta;
95     }
96
97   return mom * plet_factor_mom (dur);    
98 }
99
100 Duration
101 Duration_convert::mom2_dur (Rational mom)
102 {
103   if (!mom) 
104     {
105       Duration dur;
106       dur.set_plet (0,1);
107       return dur;
108     }
109
110   return mom2standardised_dur (mom);
111 }
112
113 Duration
114 Duration_convert::mom2standardised_dur (Rational mom)
115 {
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++) 
121     {
122       Rational lower_mom = dur2_mom (dur_array_s[ i ]);
123       if (mom <= lower_mom) 
124         {
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 
130             {
131               Duration d;
132               d.durlog_i_ = -100;
133               return d;
134             }
135         }
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 ];
141     }
142   return dur_array_s[ dur_array_s.size () - 1 ];
143 }
144
145 void
146 Duration_convert::set_array ()
147 {
148   dur_array_s.clear ();
149
150   Duration_iterator i;
151   while (i.ok ())
152     dur_array_s.push (i.forward_dur ());
153 }
154
155
156 Rational
157 Duration_convert::plet_factor_mom (Duration dur)
158 {
159   return dur.plet_.mom ();
160 }
161
162 Real
163 Duration_convert::sync_f (Duration dur, Rational mom)
164 {
165   return mom / dur2_mom (dur);
166 }
167
168 Duration
169 Duration_convert::ticks2_dur (int ticks_i)
170 {
171   Rational mom (ticks_i, Duration::division_1_i_s);
172   return mom2standardised_dur (mom);
173 }
174
175 Duration
176 Duration_convert::ticks2standardised_dur (int ticks_i)
177 {
178   Rational mom (ticks_i, Duration::division_1_i_s);
179   Duration dur = mom2standardised_dur (mom);
180   return dur;
181 }