]> git.donarmstrong.com Git - lilypond.git/blob - mi2mu/mudela-staff.cc
release: 1.0.3
[lilypond.git] / mi2mu / mudela-staff.cc
1 //
2 // mudela-staff.cc -- implement Mudela_staff
3 //
4 // copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
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_key_l_ = 0;
29   mudela_time_signature_l_ = 0;
30   mudela_tempo_l_ = 0;
31 }
32
33 void
34 Mudela_staff::add_item (Mudela_item* mudela_item_p)
35 {
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);
39 }
40
41 void
42 Mudela_staff::eat_voice (Link_list<Mudela_item*>& items)
43 {
44   Mudela_voice* voice_p = new Mudela_voice (this);
45   mudela_voice_p_list_.bottom().add (voice_p);
46
47   //    Moment mom = items.top()->at_mom();
48   Moment mom = 0;
49
50   for  (PCursor<Mudela_item*> i (items); i.ok();)
51     {
52       LOGOUT(DEBUG_ver) << "At: " << i->at_mom ().str () << "; ";
53       LOGOUT(DEBUG_ver) << "dur: " << i->duration_mom ().str () << "; ";
54       LOGOUT(DEBUG_ver) << "mom: " << mom.str () << " -> ";
55       if  (i->at_mom() > mom)
56         {
57           Moment dur = i->at_mom() - mom;
58           // ugh, need score
59           Mudela_column* start = mudela_score_l_g->find_column_l (mom);
60           voice_p->add_item (new Mudela_skip (start, dur));
61           mom = i->at_mom();
62         }
63       if  (i->at_mom() == mom)
64         {
65           mom = i->at_mom() + i->duration_mom();
66           voice_p->add_item (i.remove_p());
67           // ugh
68         }
69       else if  (i.ok())
70         i++;
71       LOGOUT(DEBUG_ver) << "mom: " << mom.str () << '\n';
72     }
73 }
74
75 String
76 Mudela_staff::id_str()
77 {
78   String id (name_str ());
79   char *cp = id.ch_l ();
80   char *end = cp + id.length_i();
81   for (;cp < end; cp++)
82     {
83       if (!isalpha (*cp))
84         {
85           *cp = 'X';
86         }
87     }
88   return id;
89 }
90
91 String
92 Mudela_staff::name_str()
93 {
94   if  (name_str_.length_i())
95     return name_str_;
96   return String ("track") + to_str (char ('A' - 1 + number_i_));
97 }
98
99
100
101 void
102 Mudela_staff::output (Mudela_stream& mudela_stream_r)
103 {
104   mudela_stream_r << id_str() << " = \\melodic";
105   mudela_stream_r <<  (mudela_voice_p_list_.size() > 1 ? "<" : "{");
106   mudela_stream_r << '\n';
107   mudela_stream_r << _ ("% midi copyright:") << copyright_str_ << '\n';
108   mudela_stream_r << _ ("% instrument:") << instrument_str_ << '\n';
109
110   // don't use last duration mode
111   //  mudela_stream_r << "\\duration 4;\n";
112   if  (mudela_voice_p_list_.size() == 1)
113     mudela_voice_p_list_.top()->output (mudela_stream_r);
114   else
115     for  (PCursor<Mudela_voice*> i (mudela_voice_p_list_); i.ok(); i++)
116       {
117         mudela_stream_r << "{ ";
118         i->output (mudela_stream_r);
119         mudela_stream_r << "} ";
120       }
121
122   mudela_stream_r <<  (mudela_voice_p_list_.size() > 1 ? "\n>" : "\n}");
123   mudela_stream_r << " % " << name_str() << '\n';
124 }
125
126 void
127 Mudela_staff::output_mudela_begin_bar (Mudela_stream& mudela_stream_r, Moment now_mom, int bar_i)
128 {
129   Moment bar_mom = mudela_time_signature_l_->bar_mom();
130   Moment into_bar_mom = now_mom - Moment (bar_i - 1) * bar_mom;
131   if  (bar_i > 1)
132     {
133       if  (!into_bar_mom)
134         mudela_stream_r << "|\n";
135     }
136   mudela_stream_r << "% " << String_convert::i2dec_str (bar_i, 0, ' ');
137   if  (into_bar_mom)
138     mudela_stream_r << ":" << Duration_convert::dur2_str (Duration_convert::mom2_dur (into_bar_mom));
139   mudela_stream_r << '\n';
140 }
141
142
143 #if 0 // not used for now
144 void
145 Mudela_staff::output_mudela_rest (Mudela_stream& mudela_stream_r, Moment begin_mom, Moment end_mom)
146 {
147   Moment bar_mom = mudela_time_signature_l_->bar_mom();
148   Moment now_mom = begin_mom;
149
150   int begin_bar_i = (int) (now_mom / bar_mom) + 1;
151   int end_bar_i = (int) (end_mom / bar_mom) + 1;
152
153   if  (end_bar_i == begin_bar_i)
154     {
155       output_mudela_rest_remain (mudela_stream_r, end_mom - begin_mom);
156       return;
157     }
158
159   // multiple bars involved
160   int bar_i = (int) (now_mom / bar_mom) + 1;
161
162   //fill current bar
163   Moment begin_bar_mom = Moment (begin_bar_i - 1) * bar_mom;
164   if  (now_mom > begin_bar_mom)
165     {
166       int next_bar_i = (int) (now_mom / bar_mom) + 2;
167       Moment next_bar_mom = Moment (next_bar_i - 1) * bar_mom;
168       assert (next_bar_mom <= end_mom);
169
170       Moment remain_mom = next_bar_mom - now_mom;
171       if  (remain_mom > Moment (0))
172         {
173           output_mudela_rest_remain (mudela_stream_r, remain_mom);
174           now_mom += remain_mom;
175         }
176
177       bar_i = check_end_bar_i (now_mom, bar_i);
178     }
179
180   // fill whole bars
181   int count_i = end_bar_i - bar_i;
182   for  (int i = 0; i < count_i; i++)
183     {
184       int begin_bar_i = check_begin_bar_i (now_mom, bar_i);
185       if  (begin_bar_i)
186         output_mudela_begin_bar (mudela_stream_r, now_mom, begin_bar_i);
187       mudela_stream_r << "r1 ";
188       //        *mudela_stream_r.os_p_ << flush;
189       if  (begin_bar_i)
190         LOGOUT(NORMAL_ver) << begin_bar_i << flush;
191       bar_i = check_end_bar_i (now_mom, bar_i);
192       now_mom += bar_mom;
193     }
194
195   // use "int i" here, and gcc 2.7.2 hits internal compiler error
196   int ii = check_begin_bar_i (now_mom, bar_i);
197   if  (ii)
198     output_mudela_begin_bar (mudela_stream_r, now_mom, ii);
199
200   //    bar_i = check_end_bar_i (now_mom, bar_i);
201
202   Moment remain_mom = end_mom - Moment (end_bar_i - 1) * bar_mom;
203   if  (remain_mom > Moment (0))
204     {
205       output_mudela_rest_remain (mudela_stream_r, remain_mom);
206       now_mom += remain_mom;
207     }
208   assert (now_mom == end_mom);
209 }
210
211 void
212 Mudela_staff::output_mudela_rest_remain (Mudela_stream& mudela_stream_r, Moment mom)
213 {
214   if  (Duration_convert::no_quantify_b_s)
215     {
216       Duration dur = Duration_convert::mom2_dur (mom);
217       mudela_stream_r << "r" << dur.str() << " ";
218       //        assert (mom == dur.mom());
219       assert (mom == dur.length());
220       return;
221     }
222
223   Duration dur = Duration_convert::mom2standardised_dur (mom);
224   if  (dur.type_i_>-10)
225     mudela_stream_r << "r" << dur.str() << " ";
226 }
227 #endif
228
229
230 void
231 Mudela_staff::process()
232 {
233   /*
234      group items into voices
235      */
236
237   assert (mudela_score_l_g);
238   mudela_key_l_ = mudela_score_l_g->mudela_key_l_;
239   mudela_time_signature_l_ = mudela_score_l_g->mudela_time_signature_l_;
240   mudela_tempo_l_ = mudela_score_l_g->mudela_tempo_l_;
241
242   Link_list<Mudela_item*> items;
243   for  (PCursor<Mudela_item*> i (mudela_item_p_list_); i.ok(); i++)
244     items.bottom().add (*i);
245
246   while  (items.size())
247     eat_voice (items);
248 }