2 // duration.cc -- implement Duration, Plet, Duration_convert, Duration_iterator
4 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
8 #include "proto.hh" // ugh, these all for midi-main.hh
11 #include "source-file.hh"
13 #include "midi-main.hh" // *tors
17 #include "duration.hh"
19 Duration::Duration( int type_i
, int dots_i
= 0, Plet
* plet_l
)
27 Duration::Duration( Duration
const& dur_c_r
)
41 Duration::operator =( Duration
const& dur_c_r
)
43 if ( &dur_c_r
== this )
46 type_i_
= dur_c_r
.type_i_
;
47 dots_i_
= dur_c_r
.dots_i_
;
48 set_plet( dur_c_r
.plet_p_
);
54 Duration::set_plet( Plet
* plet_l
)
59 plet_p_
= new Plet( *plet_l
);
62 Plet::Plet( int iso_i
, int type_i
)
68 Plet::Plet( Plet
const& plet_c_r
)
70 iso_i_
= plet_c_r
.iso_i_
;
71 type_i_
= plet_c_r
.type_i_
;
75 Duration_convert::dur2_str( Duration dur
)
77 String
str( dur
.type_i_
);
78 str
+= String( '.', dur
.dots_i_
);
80 str
+= String( "*" ) + String( dur
.plet_p_
->iso_i_
)
81 + String( "/" ) + String( dur
.plet_p_
->type_i_
);
86 Duration_convert::dur2_i( Duration dur
, int division_1_i
)
88 return dur2_mom( dur
) * Moment( division_1_i
);
92 Duration_convert::dur2_mom( Duration dur
)
97 Moment mom
= Moment( 1 , dur
.type_i_
);
100 while ( dur
.dots_i_
-- ) {
105 return mom
* plet_factor_mom( dur
);
109 Duration_convert::mom2_dur( Moment mom
)
112 but filling an array using Duration_iterator
113 might speed things up, a little
115 Duration_iterator iter_dur
;
118 Duration lower_dur
= iter_dur
++;
119 Duration
upper_dur( 0 );
121 upper_dur
= iter_dur();
122 Moment lower_mom
= dur2_mom( lower_dur
);
123 Moment upper_mom
= dur2_mom( upper_dur
);
124 if ( mom
== lower_mom
)
126 if ( mom
== upper_mom
) // don-t miss last (sic)
128 if ( ( mom
>= lower_mom
) && ( mom
<= upper_mom
) ) {
129 warning( String( "duration not exact: " ) + String( (Real
)mom
) , 0 );
130 if ( abs( mom
- lower_mom
) < abs( mom
- upper_mom
) )
135 lower_dur
= upper_dur
;
137 return Duration( 0 );
141 Duration_convert::plet_factor_mom( Duration dur
)
145 return Moment( dur
.plet_p_
->iso_i_
, dur
.plet_p_
->type_i_
);
149 Duration_convert::sync_f( Duration dur
, Moment mom
)
151 return mom
/ dur2_mom( dur
);
155 Duration_convert::i2_mom( int time_i
, int division_1_i
)
160 if ( division_1_i
> 0 )
161 return Moment( time_i
, division_1_i
);
163 return Moment( -division_1_i
, time_i
);
166 Duration_iterator::Duration_iterator()
168 cursor_dur_
.type_i_
= 128;
169 cursor_dur_
.set_plet( 0 );
173 Duration_iterator::operator ++(int)
175 return forward_dur();
179 Duration_iterator::operator ()()
184 Duration_iterator::operator bool()
190 Duration_iterator::dur()
196 Duration_iterator::forward_dur()
198 // should do smart table? guessing:
211 Duration dur
= cursor_dur_
;
213 if ( !cursor_dur_
.dots_i_
&& !cursor_dur_
.plet_p_
) {
214 cursor_dur_
.type_i_
*= 2;
215 cursor_dur_
.dots_i_
= 2;
217 else if ( cursor_dur_
.dots_i_
== 2 ) {
218 assert( !cursor_dur_
.plet_p_
);
219 cursor_dur_
.dots_i_
= 0;
220 cursor_dur_
.type_i_
/= 4;
221 cursor_dur_
.set_plet( &Plet( 2, 3 ) );
223 else if ( cursor_dur_
.plet_p_
224 && ( cursor_dur_
.plet_p_
->iso_i_
== 2 )
225 && ( cursor_dur_
.plet_p_
->type_i_
== 3 ) ) {
226 assert( !cursor_dur_
.dots_i_
);
227 cursor_dur_
.set_plet( 0 );
228 cursor_dur_
.type_i_
*= 2;
229 cursor_dur_
.dots_i_
= 1;
231 else if ( cursor_dur_
.dots_i_
== 1 ) {
232 assert( !cursor_dur_
.plet_p_
);
233 cursor_dur_
.dots_i_
= 0;
234 cursor_dur_
.type_i_
/= 2;
238 if ( no_triplets_bo_g
&& cursor_dur_
.plet_p_
&& ok() )
245 Duration_iterator::ok()
247 return ( cursor_dur_
.type_i_
248 && !( ( cursor_dur_
.type_i_
== 1 ) && ( cursor_dur_
.dots_i_
> 2 ) ) );