]> git.donarmstrong.com Git - lilypond.git/blob - midi2ly/mudela-staff.cc
release: 1.1.56
[lilypond.git] / midi2ly / 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 "midi2ly-proto.hh"
12 #include "midi2ly-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 #include "killing-cons.tcc"
21
22 extern Mudela_score* mudela_score_l_g;
23
24 Mudela_staff::Mudela_staff (int number_i, String copyright_str, String track_name_str, String instrument_str)
25 {
26   number_i_ = number_i;
27   copyright_str_ = copyright_str;
28   instrument_str_ = instrument_str;
29   name_str_ = track_name_str;
30   mudela_key_l_ = 0;
31   mudela_time_signature_l_ = 0;
32   mudela_tempo_l_ = 0;
33 }
34
35 void
36 Mudela_staff::add_item (Mudela_item* mudela_item_p)
37 {
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);
41 }
42
43 void
44 Mudela_staff::eat_voice (Cons_list<Mudela_item>& items)
45 {
46   Mudela_voice* voice_p = new Mudela_voice (this);
47   mudela_voice_p_list_.append (new Killing_cons<Mudela_voice> (voice_p, 0));
48
49   //    Moment mom = items.top ()->at_mom ();
50   Moment mom = 0;
51
52   for (Cons<Mudela_item>** pp = &items.head_; *pp;)
53     {
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)
59         {
60           Moment dur = i->car_->at_mom () - mom;
61           // ugh, need score
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 ();
65         }
66       if (i->car_->at_mom () == mom)
67         {
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_);
71           delete c;
72         }
73       else if (*pp)
74         pp = &i->next_;
75       LOGOUT (DEBUG_ver) << "mom: " << mom.str () << '\n';
76     }
77 }
78
79 String
80 Mudela_staff::id_str ()
81 {
82   String id (name_str ());
83   char *cp = id.ch_l ();
84   char *end = cp + id.length_i ();
85   for (;cp < end; cp++)
86     {
87       if (!isalpha (*cp))
88         {
89           *cp = 'X';
90         }
91     }
92   return id;
93 }
94
95 String
96 Mudela_staff::name_str ()
97 {
98   if (name_str_.length_i ())
99     return name_str_;
100   return String ("track") + to_str (char ('A' - 1 + number_i_));
101 }
102
103
104
105 void
106 Mudela_staff::output (Mudela_stream& mudela_stream_r)
107 {
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';
113
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);
118   else
119       for (Cons<Mudela_voice>* i = mudela_voice_p_list_.head_; i; i = i->next_)
120       {
121         mudela_stream_r << "{ ";
122         i->car_->output (mudela_stream_r);
123         mudela_stream_r << "} ";
124       }
125
126   mudela_stream_r << (mudela_voice_p_list_.size_i () > 1 ? "\n>" : "\n}");
127   mudela_stream_r << " % " << name_str () << '\n';
128 }
129
130 void
131 Mudela_staff::output_mudela_begin_bar (Mudela_stream& mudela_stream_r, Moment now_mom, int bar_i)
132 {
133   Moment bar_mom = mudela_time_signature_l_->bar_mom ();
134   Moment into_bar_mom = now_mom - Moment (bar_i - 1) * bar_mom;
135   if (bar_i > 1)
136     {
137       if (!into_bar_mom)
138         mudela_stream_r << "|\n";
139     }
140   mudela_stream_r << "% " << String_convert::i2dec_str (bar_i, 0, ' ');
141   if (into_bar_mom)
142     mudela_stream_r << ":" << Duration_convert::dur2_str (Duration_convert::mom2_dur (into_bar_mom));
143   mudela_stream_r << '\n';
144 }
145
146
147 #if 0 // not used for now
148 void
149 Mudela_staff::output_mudela_rest (Mudela_stream& mudela_stream_r, Moment begin_mom, Moment end_mom)
150 {
151   Moment bar_mom = mudela_time_signature_l_->bar_mom ();
152   Moment now_mom = begin_mom;
153
154   int begin_bar_i = (int) (now_mom / bar_mom) + 1;
155   int end_bar_i = (int) (end_mom / bar_mom) + 1;
156
157   if (end_bar_i == begin_bar_i)
158     {
159       output_mudela_rest_remain (mudela_stream_r, end_mom - begin_mom);
160       return;
161     }
162
163   // multiple bars involved
164   int bar_i = (int) (now_mom / bar_mom) + 1;
165
166   //fill current bar
167   Moment begin_bar_mom = Moment (begin_bar_i - 1) * bar_mom;
168   if (now_mom > begin_bar_mom)
169     {
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);
173
174       Moment remain_mom = next_bar_mom - now_mom;
175       if (remain_mom > Moment (0))
176         {
177           output_mudela_rest_remain (mudela_stream_r, remain_mom);
178           now_mom += remain_mom;
179         }
180
181       bar_i = check_end_bar_i (now_mom, bar_i);
182     }
183
184   // fill whole bars
185   int count_i = end_bar_i - bar_i;
186   for (int i = 0; i < count_i; i++)
187     {
188       int begin_bar_i = check_begin_bar_i (now_mom, bar_i);
189       if (begin_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;
193       if (begin_bar_i)
194         LOGOUT (NORMAL_ver) << begin_bar_i << flush;
195       bar_i = check_end_bar_i (now_mom, bar_i);
196       now_mom += bar_mom;
197     }
198
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);
201   if (ii)
202     output_mudela_begin_bar (mudela_stream_r, now_mom, ii);
203
204   //    bar_i = check_end_bar_i (now_mom, bar_i);
205
206   Moment remain_mom = end_mom - Moment (end_bar_i - 1) * bar_mom;
207   if (remain_mom > Moment (0))
208     {
209       output_mudela_rest_remain (mudela_stream_r, remain_mom);
210       now_mom += remain_mom;
211     }
212   assert (now_mom == end_mom);
213 }
214
215 void
216 Mudela_staff::output_mudela_rest_remain (Mudela_stream& mudela_stream_r, Moment mom)
217 {
218   if (Duration_convert::no_quantify_b_s)
219     {
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 ());
224       return;
225     }
226
227   Duration dur = Duration_convert::mom2standardised_dur (mom);
228   if (dur.type_i_>-10)
229     mudela_stream_r << "r" << dur.str () << " ";
230 }
231 #endif
232
233
234 void
235 Mudela_staff::process ()
236 {
237   /*
238      group items into voices
239      */
240
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_;
245
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));
249
250   while (items.size_i ())
251     eat_voice (items);
252 }