]> git.donarmstrong.com Git - lilypond.git/blob - mi2mu/mudela-staff.cc
patch::: 0.1.9.jcn2: pats
[lilypond.git] / mi2mu / mudela-staff.cc
1 //
2 // mudela-staff.cc -- implement Mudela_staff
3 //
4 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
5
6 #include <assert.h>
7 #include <ctype.h>
8 #include "moment.hh"
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"
19
20 extern Mudela_score* mudela_score_l_g;
21
22 Mudela_staff::Mudela_staff (int number_i, String copyright_str, String track_name_str, String instrument_str)
23 {
24   number_i_ = number_i;
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);
30 }
31
32 Mudela_staff::~Mudela_staff()
33 {
34   delete mudela_meter_p_;
35   delete mudela_tempo_p_;
36 }
37
38 void
39 Mudela_staff::add_item (Mudela_item* mudela_item_p)
40 {
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);
44 }
45
46 void
47 Mudela_staff::eat_voice (Link_list<Mudela_item*>& items)
48 {
49   Mudela_voice* voice_p = new Mudela_voice (this);
50   mudela_voice_p_list_.bottom().add (voice_p);
51
52   //    Moment mom = items.top()->at_mom();
53   Moment mom = 0;
54
55   for  (PCursor<Mudela_item*> i (items); i.ok();) 
56     {
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) 
61         {
62           Moment dur = i->at_mom() - mom;
63           // ugh, need score
64           Mudela_column* start = mudela_score_l_g->find_column_l (mom);
65           voice_p->add_item (new Mudela_skip (start, dur));
66           mom = i->at_mom();
67         }
68       if  (i->at_mom() == mom) 
69         {
70           mom = i->at_mom() + i->duration_mom();
71           voice_p->add_item (i.remove_p());
72           // ugh
73         }
74       else if  (i.ok())
75         i++;
76       LOGOUT(DEBUG_ver) << "mom: " << mom << "\n";
77     }
78 }
79
80 String
81 Mudela_staff::id_str()
82 {
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) = '_';
88   return str;
89 }
90
91 String
92 Mudela_staff::name_str()
93 {
94   if  (name_str_.length_i())
95     return name_str_;
96   return String ("track") + String (number_i_);
97 }
98
99 void
100 Mudela_staff::output (Mudela_stream& mudela_stream_r)
101 {
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";
107
108   if  (mudela_voice_p_list_.size() == 1)
109     mudela_voice_p_list_.top()->output (mudela_stream_r);
110   else
111     for  (PCursor<Mudela_voice*> i (mudela_voice_p_list_); i.ok(); i++) 
112       {
113         mudela_stream_r << "{ ";
114         i->output (mudela_stream_r);
115         mudela_stream_r << "} ";
116       }
117
118   mudela_stream_r <<  (mudela_voice_p_list_.size() > 1 ? "\n>" : "\n}");
119   mudela_stream_r << " % " << name_str() << "\n";
120 }
121
122 void
123 Mudela_staff::output_mudela_begin_bar (Mudela_stream& mudela_stream_r, Moment now_mom, int bar_i)
124 {
125   Moment bar_mom = mudela_meter_p_->bar_mom();
126   Moment into_bar_mom = now_mom - Moment (bar_i - 1) * bar_mom;
127   if  (bar_i > 1) 
128     {
129       if  (!into_bar_mom)
130         mudela_stream_r << "|\n";
131     }
132   mudela_stream_r << "% " << String_convert::i2dec_str (bar_i, 0, ' ');
133   if  (into_bar_mom)
134     mudela_stream_r << ":" << Duration_convert::dur2_str (Duration_convert::mom2_dur (into_bar_mom));
135   mudela_stream_r << "\n";
136 }
137
138
139 #if 0 // not used for now
140 void 
141 Mudela_staff::output_mudela_rest (Mudela_stream& mudela_stream_r, Moment begin_mom, Moment end_mom)
142 {
143   Moment bar_mom = mudela_meter_p_->bar_mom();
144   Moment now_mom = begin_mom;
145
146   int begin_bar_i = (int) (now_mom / bar_mom) + 1; 
147   int end_bar_i = (int) (end_mom / bar_mom) + 1;
148
149   if  (end_bar_i == begin_bar_i) 
150     {
151       output_mudela_rest_remain (mudela_stream_r, end_mom - begin_mom);
152       return;
153     }
154
155   // multiple bars involved
156   int bar_i = (int) (now_mom / bar_mom) + 1;
157
158   //fill current bar
159   Moment begin_bar_mom = Moment (begin_bar_i - 1) * bar_mom;
160   if  (now_mom > begin_bar_mom) 
161     {
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);
165
166       Moment remain_mom = next_bar_mom - now_mom;
167       if  (remain_mom > Moment (0)) 
168         {
169           output_mudela_rest_remain (mudela_stream_r, remain_mom);
170           now_mom += remain_mom;
171         }
172
173       bar_i = check_end_bar_i (now_mom, bar_i);
174     }
175
176   // fill whole bars
177   int count_i = end_bar_i - bar_i;
178   for  (int i = 0; i < count_i; i++) 
179     {
180       int begin_bar_i = check_begin_bar_i (now_mom, bar_i);
181       if  (begin_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;
185       if  (begin_bar_i)
186         LOGOUT(NORMAL_ver) << begin_bar_i << flush; 
187       bar_i = check_end_bar_i (now_mom, bar_i);
188       now_mom += bar_mom;
189     }
190
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);
193   if  (ii)
194     output_mudela_begin_bar (mudela_stream_r, now_mom, ii);
195
196   //    bar_i = check_end_bar_i (now_mom, bar_i);
197
198   Moment remain_mom = end_mom - Moment (end_bar_i - 1) * bar_mom;
199   if  (remain_mom > Moment (0)) 
200     {
201       output_mudela_rest_remain (mudela_stream_r, remain_mom);
202       now_mom += remain_mom;
203     }
204   assert (now_mom == end_mom);
205 }
206
207 void
208 Mudela_staff::output_mudela_rest_remain (Mudela_stream& mudela_stream_r, Moment mom)
209 {
210   if  (Duration_convert::no_quantify_b_s) 
211     {
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());
216       return;
217     }
218         
219   Duration dur = Duration_convert::mom2standardised_dur (mom);
220   if  (dur.type_i_>-10)
221     mudela_stream_r << "r" << dur.str() << " ";
222 }
223 #endif
224
225
226 void
227 Mudela_staff::process()
228 {
229   /* 
230      group items into voices
231      */
232
233   Link_list<Mudela_item*> items;
234   for  (PCursor<Mudela_item*> i (mudela_item_p_list_); i.ok(); i++)
235     items.bottom().add (*i);
236   
237   while  (items.size())
238     eat_voice (items);
239 }
240
241 void
242 Mudela_staff::set_tempo (int useconds_per_4_i)
243 {
244   delete mudela_tempo_p_;
245   mudela_tempo_p_ = new Mudela_tempo (useconds_per_4_i);
246 }
247
248 void
249 Mudela_staff::set_meter (int num_i, int den_i, int clocks_i, int count_32_i)
250 {
251   delete mudela_meter_p_;
252   mudela_meter_p_ = new Mudela_meter (num_i, den_i, clocks_i, count_32_i);
253 }
254