2 // mudela-staff.cc -- implement Mudela_staff
4 // copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
9 #include "duration-convert.hh"
10 #include "string-convert.hh"
11 #include "mi2mu-proto.hh"
12 #include "mi2mu-global.hh"
13 #include "mudela-column.hh"
14 #include "mudela-item.hh"
15 #include "mudela-staff.hh"
16 #include "mudela-stream.hh"
17 #include "mudela-voice.hh"
18 #include "mudela-score.hh"
20 #include "killing-cons.tcc"
22 extern Mudela_score
* mudela_score_l_g
;
24 Mudela_staff::Mudela_staff (int number_i
, String copyright_str
, String track_name_str
, String instrument_str
)
27 copyright_str_
= copyright_str
;
28 instrument_str_
= instrument_str
;
29 name_str_
= track_name_str
;
31 mudela_time_signature_l_
= 0;
36 Mudela_staff::add_item (Mudela_item
* mudela_item_p
)
38 mudela_item_p_list_
.append (new Killing_cons
<Mudela_item
> (mudela_item_p
, 0));
39 if (mudela_item_p
->mudela_column_l_
)
40 mudela_item_p
->mudela_column_l_
->add_item (mudela_item_p
);
44 Mudela_staff::eat_voice (Cons_list
<Mudela_item
>& items
)
46 Mudela_voice
* voice_p
= new Mudela_voice (this);
47 mudela_voice_p_list_
.append (new Killing_cons
<Mudela_voice
> (voice_p
, 0));
49 // Moment mom = items.top ()->at_mom ();
52 for (Cons
<Mudela_item
>** pp
= &items
.head_
; *pp
;)
54 Cons
<Mudela_item
>* i
= *pp
;
55 LOGOUT (DEBUG_ver
) << "At: " << i
->car_
->at_mom ().str () << "; ";
56 LOGOUT (DEBUG_ver
) << "dur: " << i
->car_
->duration_mom ().str () << "; ";
57 LOGOUT (DEBUG_ver
) << "mom: " << mom
.str () << " -> ";
58 if (i
->car_
->at_mom () > mom
)
60 Moment dur
= i
->car_
->at_mom () - mom
;
62 Mudela_column
* start
= mudela_score_l_g
->find_column_l (mom
);
63 voice_p
->add_item (new Mudela_skip (start
, dur
));
64 mom
= i
->car_
->at_mom ();
66 if (i
->car_
->at_mom () == mom
)
68 mom
= i
->car_
->at_mom () + i
->car_
->duration_mom ();
69 Cons
<Mudela_item
>* c
= items
.remove_cons (pp
);
70 voice_p
->add_item (c
->car_
);
75 LOGOUT (DEBUG_ver
) << "mom: " << mom
.str () << '\n';
80 Mudela_staff::id_str ()
82 String
id (name_str ());
83 char *cp
= id
.ch_l ();
84 char *end
= cp
+ id
.length_i ();
96 Mudela_staff::name_str ()
98 if (name_str_
.length_i ())
100 return String ("track") + to_str (char ('A' - 1 + number_i_
));
106 Mudela_staff::output (Mudela_stream
& mudela_stream_r
)
108 mudela_stream_r
<< id_str () << " = \\notes";
109 mudela_stream_r
<< (mudela_voice_p_list_
.size_i () > 1 ? "<" : "{");
110 mudela_stream_r
<< '\n';
111 mudela_stream_r
<< _ ("% midi copyright:") << copyright_str_
<< '\n';
112 mudela_stream_r
<< _ ("% instrument:") << instrument_str_
<< '\n';
114 // don't use last duration mode
115 // mudela_stream_r << "\\duration 4;\n";
116 if (mudela_voice_p_list_
.size_i () == 1)
117 mudela_voice_p_list_
.head_
->car_
->output (mudela_stream_r
);
119 for (Cons
<Mudela_voice
>* i
= mudela_voice_p_list_
.head_
; i
; i
= i
->next_
)
121 mudela_stream_r
<< "{ ";
122 i
->car_
->output (mudela_stream_r
);
123 mudela_stream_r
<< "} ";
126 mudela_stream_r
<< (mudela_voice_p_list_
.size_i () > 1 ? "\n>" : "\n}");
127 mudela_stream_r
<< " % " << name_str () << '\n';
131 Mudela_staff::output_mudela_begin_bar (Mudela_stream
& mudela_stream_r
, Moment now_mom
, int bar_i
)
133 Moment bar_mom
= mudela_time_signature_l_
->bar_mom ();
134 Moment into_bar_mom
= now_mom
- Moment (bar_i
- 1) * bar_mom
;
138 mudela_stream_r
<< "|\n";
140 mudela_stream_r
<< "% " << String_convert::i2dec_str (bar_i
, 0, ' ');
142 mudela_stream_r
<< ":" << Duration_convert::dur2_str (Duration_convert::mom2_dur (into_bar_mom
));
143 mudela_stream_r
<< '\n';
147 #if 0 // not used for now
149 Mudela_staff::output_mudela_rest (Mudela_stream
& mudela_stream_r
, Moment begin_mom
, Moment end_mom
)
151 Moment bar_mom
= mudela_time_signature_l_
->bar_mom ();
152 Moment now_mom
= begin_mom
;
154 int begin_bar_i
= (int) (now_mom
/ bar_mom
) + 1;
155 int end_bar_i
= (int) (end_mom
/ bar_mom
) + 1;
157 if (end_bar_i
== begin_bar_i
)
159 output_mudela_rest_remain (mudela_stream_r
, end_mom
- begin_mom
);
163 // multiple bars involved
164 int bar_i
= (int) (now_mom
/ bar_mom
) + 1;
167 Moment begin_bar_mom
= Moment (begin_bar_i
- 1) * bar_mom
;
168 if (now_mom
> begin_bar_mom
)
170 int next_bar_i
= (int) (now_mom
/ bar_mom
) + 2;
171 Moment next_bar_mom
= Moment (next_bar_i
- 1) * bar_mom
;
172 assert (next_bar_mom
<= end_mom
);
174 Moment remain_mom
= next_bar_mom
- now_mom
;
175 if (remain_mom
> Moment (0))
177 output_mudela_rest_remain (mudela_stream_r
, remain_mom
);
178 now_mom
+= remain_mom
;
181 bar_i
= check_end_bar_i (now_mom
, bar_i
);
185 int count_i
= end_bar_i
- bar_i
;
186 for (int i
= 0; i
< count_i
; i
++)
188 int begin_bar_i
= check_begin_bar_i (now_mom
, bar_i
);
190 output_mudela_begin_bar (mudela_stream_r
, now_mom
, begin_bar_i
);
191 mudela_stream_r
<< "r1 ";
192 // *mudela_stream_r.os_p_ << flush;
194 LOGOUT (NORMAL_ver
) << begin_bar_i
<< flush
;
195 bar_i
= check_end_bar_i (now_mom
, bar_i
);
199 // use "int i" here, and gcc 2.7.2 hits internal compiler error
200 int ii
= check_begin_bar_i (now_mom
, bar_i
);
202 output_mudela_begin_bar (mudela_stream_r
, now_mom
, ii
);
204 // bar_i = check_end_bar_i (now_mom, bar_i);
206 Moment remain_mom
= end_mom
- Moment (end_bar_i
- 1) * bar_mom
;
207 if (remain_mom
> Moment (0))
209 output_mudela_rest_remain (mudela_stream_r
, remain_mom
);
210 now_mom
+= remain_mom
;
212 assert (now_mom
== end_mom
);
216 Mudela_staff::output_mudela_rest_remain (Mudela_stream
& mudela_stream_r
, Moment mom
)
218 if (Duration_convert::no_quantify_b_s
)
220 Duration dur
= Duration_convert::mom2_dur (mom
);
221 mudela_stream_r
<< "r" << dur
.str () << " ";
222 // assert (mom == dur.mom ());
223 assert (mom
== dur
.length ());
227 Duration dur
= Duration_convert::mom2standardised_dur (mom
);
229 mudela_stream_r
<< "r" << dur
.str () << " ";
235 Mudela_staff::process ()
238 group items into voices
241 assert (mudela_score_l_g
);
242 mudela_key_l_
= mudela_score_l_g
->mudela_key_l_
;
243 mudela_time_signature_l_
= mudela_score_l_g
->mudela_time_signature_l_
;
244 mudela_tempo_l_
= mudela_score_l_g
->mudela_tempo_l_
;
246 Cons_list
<Mudela_item
> items
;
247 for (Cons
<Mudela_item
>* i
= mudela_item_p_list_
.head_
; i
; i
= i
->next_
)
248 items
.append (new Cons
<Mudela_item
> (i
->car_
, 0));
250 while (items
.size_i ())