2 // mudela-staff.cc -- implement Mudela_staff
4 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
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 extern Mudela_score
* mudela_score_l_g
;
22 Mudela_staff::Mudela_staff (int number_i
, String copyright_str
, String track_name_str
, String instrument_str
)
25 copyright_str_
= copyright_str
;
26 instrument_str_
= instrument_str
;
27 name_str_
= track_name_str
;
34 Mudela_staff::add_item (Mudela_item
* mudela_item_p
)
36 mudela_item_p_list_
.bottom().add (mudela_item_p
);
37 if (mudela_item_p
->mudela_column_l_
)
38 mudela_item_p
->mudela_column_l_
->add_item (mudela_item_p
);
42 Mudela_staff::eat_voice (Link_list
<Mudela_item
*>& items
)
44 Mudela_voice
* voice_p
= new Mudela_voice (this);
45 mudela_voice_p_list_
.bottom().add (voice_p
);
47 // Moment mom = items.top()->at_mom();
50 for (PCursor
<Mudela_item
*> i (items
); i
.ok();)
52 LOGOUT(DEBUG_ver
) << "At: " << i
->at_mom() << "; ";
53 LOGOUT(DEBUG_ver
) << "dur: " << i
->duration_mom() << "; ";
54 LOGOUT(DEBUG_ver
) << "mom: " << mom
<< " -> ";
55 if (i
->at_mom() > mom
)
57 Moment dur
= i
->at_mom() - mom
;
59 Mudela_column
* start
= mudela_score_l_g
->find_column_l (mom
);
60 voice_p
->add_item (new Mudela_skip (start
, dur
));
63 if (i
->at_mom() == mom
)
65 mom
= i
->at_mom() + i
->duration_mom();
66 voice_p
->add_item (i
.remove_p());
71 LOGOUT(DEBUG_ver
) << "mom: " << mom
<< "\n";
76 Mudela_staff::id_str()
78 String str
= name_str();
79 for (int i
= 0; i
< str
.length_i(); i
++)
80 if ( (!i
&& !isalpha (str
[ i
]))
81 || !isalnum (str
[ i
]))
82 * (str
.ch_l() + i
) = '_';
87 Mudela_staff::name_str()
89 if (name_str_
.length_i())
91 return String ("track") + String (number_i_
);
95 Mudela_staff::output (Mudela_stream
& mudela_stream_r
)
97 mudela_stream_r
<< "$" << id_str() << " = \\melodic";
98 mudela_stream_r
<< (mudela_voice_p_list_
.size() > 1 ? "<" : "{");
99 mudela_stream_r
<< "\n";
100 mudela_stream_r
<< _("% midi copyright:") << copyright_str_
<< "\n";
101 mudela_stream_r
<< _("% instrument:") << instrument_str_
<< "\n";
103 // don't use last duration mode
104 mudela_stream_r
<< "\\duration 4;\n";
105 if (mudela_voice_p_list_
.size() == 1)
106 mudela_voice_p_list_
.top()->output (mudela_stream_r
);
108 for (PCursor
<Mudela_voice
*> i (mudela_voice_p_list_
); i
.ok(); i
++)
110 mudela_stream_r
<< "{ ";
111 i
->output (mudela_stream_r
);
112 mudela_stream_r
<< "} ";
115 mudela_stream_r
<< (mudela_voice_p_list_
.size() > 1 ? "\n>" : "\n}");
116 mudela_stream_r
<< " % " << name_str() << "\n";
120 Mudela_staff::output_mudela_begin_bar (Mudela_stream
& mudela_stream_r
, Moment now_mom
, int bar_i
)
122 Moment bar_mom
= mudela_meter_l_
->bar_mom();
123 Moment into_bar_mom
= now_mom
- Moment (bar_i
- 1) * bar_mom
;
127 mudela_stream_r
<< "|\n";
129 mudela_stream_r
<< "% " << String_convert::i2dec_str (bar_i
, 0, ' ');
131 mudela_stream_r
<< ":" << Duration_convert::dur2_str (Duration_convert::mom2_dur (into_bar_mom
));
132 mudela_stream_r
<< "\n";
136 #if 0 // not used for now
138 Mudela_staff::output_mudela_rest (Mudela_stream
& mudela_stream_r
, Moment begin_mom
, Moment end_mom
)
140 Moment bar_mom
= mudela_meter_l_
->bar_mom();
141 Moment now_mom
= begin_mom
;
143 int begin_bar_i
= (int) (now_mom
/ bar_mom
) + 1;
144 int end_bar_i
= (int) (end_mom
/ bar_mom
) + 1;
146 if (end_bar_i
== begin_bar_i
)
148 output_mudela_rest_remain (mudela_stream_r
, end_mom
- begin_mom
);
152 // multiple bars involved
153 int bar_i
= (int) (now_mom
/ bar_mom
) + 1;
156 Moment begin_bar_mom
= Moment (begin_bar_i
- 1) * bar_mom
;
157 if (now_mom
> begin_bar_mom
)
159 int next_bar_i
= (int) (now_mom
/ bar_mom
) + 2;
160 Moment next_bar_mom
= Moment (next_bar_i
- 1) * bar_mom
;
161 assert (next_bar_mom
<= end_mom
);
163 Moment remain_mom
= next_bar_mom
- now_mom
;
164 if (remain_mom
> Moment (0))
166 output_mudela_rest_remain (mudela_stream_r
, remain_mom
);
167 now_mom
+= remain_mom
;
170 bar_i
= check_end_bar_i (now_mom
, bar_i
);
174 int count_i
= end_bar_i
- bar_i
;
175 for (int i
= 0; i
< count_i
; i
++)
177 int begin_bar_i
= check_begin_bar_i (now_mom
, bar_i
);
179 output_mudela_begin_bar (mudela_stream_r
, now_mom
, begin_bar_i
);
180 mudela_stream_r
<< "r1 ";
181 // *mudela_stream_r.os_p_ << flush;
183 LOGOUT(NORMAL_ver
) << begin_bar_i
<< flush
;
184 bar_i
= check_end_bar_i (now_mom
, bar_i
);
188 // use "int i" here, and gcc 2.7.2 hits internal compiler error
189 int ii
= check_begin_bar_i (now_mom
, bar_i
);
191 output_mudela_begin_bar (mudela_stream_r
, now_mom
, ii
);
193 // bar_i = check_end_bar_i (now_mom, bar_i);
195 Moment remain_mom
= end_mom
- Moment (end_bar_i
- 1) * bar_mom
;
196 if (remain_mom
> Moment (0))
198 output_mudela_rest_remain (mudela_stream_r
, remain_mom
);
199 now_mom
+= remain_mom
;
201 assert (now_mom
== end_mom
);
205 Mudela_staff::output_mudela_rest_remain (Mudela_stream
& mudela_stream_r
, Moment mom
)
207 if (Duration_convert::no_quantify_b_s
)
209 Duration dur
= Duration_convert::mom2_dur (mom
);
210 mudela_stream_r
<< "r" << dur
.str() << " ";
211 // assert (mom == dur.mom());
212 assert (mom
== dur
.length());
216 Duration dur
= Duration_convert::mom2standardised_dur (mom
);
218 mudela_stream_r
<< "r" << dur
.str() << " ";
224 Mudela_staff::process()
227 group items into voices
230 assert (mudela_score_l_g
);
231 mudela_key_l_
= mudela_score_l_g
->mudela_key_l_
;
232 mudela_meter_l_
= mudela_score_l_g
->mudela_meter_l_
;
233 mudela_tempo_l_
= mudela_score_l_g
->mudela_tempo_l_
;
235 Link_list
<Mudela_item
*> items
;
236 for (PCursor
<Mudela_item
*> i (mudela_item_p_list_
); i
.ok(); i
++)
237 items
.bottom().add (*i
);