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
;
28 mudela_meter_p_
= new Mudela_meter (4, 2, 24, 8);
29 mudela_tempo_p_
= new Mudela_tempo (1000000);
32 Mudela_staff::~Mudela_staff()
34 delete mudela_meter_p_
;
35 delete mudela_tempo_p_
;
39 Mudela_staff::add_item (Mudela_item
* mudela_item_p
)
41 mudela_item_p_list_
.bottom().add (mudela_item_p
);
42 if (mudela_item_p
->mudela_column_l_
)
43 mudela_item_p
->mudela_column_l_
->add_item (mudela_item_p
);
47 Mudela_staff::eat_voice (Link_list
<Mudela_item
*>& items
)
49 Mudela_voice
* voice_p
= new Mudela_voice (this);
50 mudela_voice_p_list_
.bottom().add (voice_p
);
52 // Moment mom = items.top()->at_mom();
55 for (PCursor
<Mudela_item
*> i (items
); i
.ok();)
57 LOGOUT(DEBUG_ver
) << "At: " << i
->at_mom() << "; ";
58 LOGOUT(DEBUG_ver
) << "dur: " << i
->duration_mom() << "; ";
59 LOGOUT(DEBUG_ver
) << "mom: " << mom
<< " -> ";
60 if (i
->at_mom() > mom
)
62 Moment dur
= i
->at_mom() - mom
;
64 Mudela_column
* start
= mudela_score_l_g
->find_column_l (mom
);
65 voice_p
->add_item (new Mudela_skip (start
, dur
));
68 if (i
->at_mom() == mom
)
70 mom
= i
->at_mom() + i
->duration_mom();
71 voice_p
->add_item (i
.remove_p());
76 LOGOUT(DEBUG_ver
) << "mom: " << mom
<< "\n";
81 Mudela_staff::id_str()
83 String str
= name_str();
84 for (int i
= 0; i
< str
.length_i(); i
++)
85 if ( (!i
&& !isalpha (str
[ i
]))
86 || !isalnum (str
[ i
]))
87 * (str
.ch_l() + i
) = '_';
92 Mudela_staff::name_str()
94 if (name_str_
.length_i())
96 return String ("track") + String (number_i_
);
100 Mudela_staff::output (Mudela_stream
& mudela_stream_r
)
102 mudela_stream_r
<< "$" << id_str() << " = \\melodic";
103 mudela_stream_r
<< (mudela_voice_p_list_
.size() > 1 ? "<" : "{");
104 mudela_stream_r
<< "\n";
105 mudela_stream_r
<< "% midi copyright:" << copyright_str_
<< "\n";
106 mudela_stream_r
<< "% instrument:" << instrument_str_
<< "\n";
108 if (mudela_voice_p_list_
.size() == 1)
109 mudela_voice_p_list_
.top()->output (mudela_stream_r
);
111 for (PCursor
<Mudela_voice
*> i (mudela_voice_p_list_
); i
.ok(); i
++)
113 mudela_stream_r
<< "{ ";
114 i
->output (mudela_stream_r
);
115 mudela_stream_r
<< "} ";
118 mudela_stream_r
<< (mudela_voice_p_list_
.size() > 1 ? "\n>" : "\n}");
119 mudela_stream_r
<< " % " << name_str() << "\n";
123 Mudela_staff::output_mudela_begin_bar (Mudela_stream
& mudela_stream_r
, Moment now_mom
, int bar_i
)
125 Moment bar_mom
= mudela_meter_p_
->bar_mom();
126 Moment into_bar_mom
= now_mom
- Moment (bar_i
- 1) * bar_mom
;
130 mudela_stream_r
<< "|\n";
132 mudela_stream_r
<< "% " << String_convert::i2dec_str (bar_i
, 0, ' ');
134 mudela_stream_r
<< ":" << Duration_convert::dur2_str (Duration_convert::mom2_dur (into_bar_mom
));
135 mudela_stream_r
<< "\n";
139 #if 0 // not used for now
141 Mudela_staff::output_mudela_rest (Mudela_stream
& mudela_stream_r
, Moment begin_mom
, Moment end_mom
)
143 Moment bar_mom
= mudela_meter_p_
->bar_mom();
144 Moment now_mom
= begin_mom
;
146 int begin_bar_i
= (int) (now_mom
/ bar_mom
) + 1;
147 int end_bar_i
= (int) (end_mom
/ bar_mom
) + 1;
149 if (end_bar_i
== begin_bar_i
)
151 output_mudela_rest_remain (mudela_stream_r
, end_mom
- begin_mom
);
155 // multiple bars involved
156 int bar_i
= (int) (now_mom
/ bar_mom
) + 1;
159 Moment begin_bar_mom
= Moment (begin_bar_i
- 1) * bar_mom
;
160 if (now_mom
> begin_bar_mom
)
162 int next_bar_i
= (int) (now_mom
/ bar_mom
) + 2;
163 Moment next_bar_mom
= Moment (next_bar_i
- 1) * bar_mom
;
164 assert (next_bar_mom
<= end_mom
);
166 Moment remain_mom
= next_bar_mom
- now_mom
;
167 if (remain_mom
> Moment (0))
169 output_mudela_rest_remain (mudela_stream_r
, remain_mom
);
170 now_mom
+= remain_mom
;
173 bar_i
= check_end_bar_i (now_mom
, bar_i
);
177 int count_i
= end_bar_i
- bar_i
;
178 for (int i
= 0; i
< count_i
; i
++)
180 int begin_bar_i
= check_begin_bar_i (now_mom
, bar_i
);
182 output_mudela_begin_bar (mudela_stream_r
, now_mom
, begin_bar_i
);
183 mudela_stream_r
<< "r1 ";
184 // *mudela_stream_r.os_p_ << flush;
186 LOGOUT(NORMAL_ver
) << begin_bar_i
<< flush
;
187 bar_i
= check_end_bar_i (now_mom
, bar_i
);
191 // use "int i" here, and gcc 2.7.2 hits internal compiler error
192 int ii
= check_begin_bar_i (now_mom
, bar_i
);
194 output_mudela_begin_bar (mudela_stream_r
, now_mom
, ii
);
196 // bar_i = check_end_bar_i (now_mom, bar_i);
198 Moment remain_mom
= end_mom
- Moment (end_bar_i
- 1) * bar_mom
;
199 if (remain_mom
> Moment (0))
201 output_mudela_rest_remain (mudela_stream_r
, remain_mom
);
202 now_mom
+= remain_mom
;
204 assert (now_mom
== end_mom
);
208 Mudela_staff::output_mudela_rest_remain (Mudela_stream
& mudela_stream_r
, Moment mom
)
210 if (Duration_convert::no_quantify_b_s
)
212 Duration dur
= Duration_convert::mom2_dur (mom
);
213 mudela_stream_r
<< "r" << dur
.str() << " ";
214 // assert (mom == dur.mom());
215 assert (mom
== dur
.length());
219 Duration dur
= Duration_convert::mom2standardised_dur (mom
);
221 mudela_stream_r
<< "r" << dur
.str() << " ";
227 Mudela_staff::process()
230 group items into voices
233 Link_list
<Mudela_item
*> items
;
234 for (PCursor
<Mudela_item
*> i (mudela_item_p_list_
); i
.ok(); i
++)
235 items
.bottom().add (*i
);
242 Mudela_staff::set_tempo (int useconds_per_4_i
)
244 delete mudela_tempo_p_
;
245 mudela_tempo_p_
= new Mudela_tempo (useconds_per_4_i
);
249 Mudela_staff::set_meter (int num_i
, int den_i
, int clocks_i
, int count_32_i
)
251 delete mudela_meter_p_
;
252 mudela_meter_p_
= new Mudela_meter (num_i
, den_i
, clocks_i
, count_32_i
);