]> git.donarmstrong.com Git - lilypond.git/blob - mi2mu/mudela-score.cc
92329cd74d6baa13339772fe7cfb53a76184dbfb
[lilypond.git] / mi2mu / mudela-score.cc
1 //
2 // mudela-score.cc -- implement Mudela_score
3 //
4 // copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
5
6 #include <assert.h>
7 #include "moment.hh"
8 #include "duration.hh"
9 #include "duration-convert.hh"
10 #include "mi2mu-global.hh"
11 #include "mudela-column.hh"
12 #include "mudela-item.hh"
13 #include "mudela-score.hh"
14 #include "mudela-staff.hh"
15 #include "mudela-stream.hh"
16
17 // ugh, cygnus' b19 gcc
18 #include "list.tcc"
19 #include "cursor.tcc"
20
21 //static Mudela_key key_c (0, 0);
22 static Mudela_time_signature time_sig_4 (4, 2, 24, 8);
23 // useconds per 4: 250000 === 60 4 per minute
24 static Mudela_tempo tempo_60 (1000000);
25
26 Mudela_score::Mudela_score (int format_i, int tracks_i, int tempo_i)
27 {
28   format_i_ = format_i;
29   tracks_i_ = tracks_i;
30   tempo_i_ = tempo_i;
31   column_l_array_.push (new Mudela_column (this, Moment (0)));
32   //  mudela_key_l_ = &key_c;
33   mudela_key_l_ = 0;
34   mudela_time_signature_l_ = &time_sig_4;
35   mudela_tempo_l_ = &tempo_60;
36 }
37
38 Mudela_score::~Mudela_score()
39 {
40 }
41
42 void
43 Mudela_score::add_item (Mudela_item* mudela_item_p)
44 {
45   mudela_staff_p_list_.bottom()->add_item (mudela_item_p);
46 }
47
48 void
49 Mudela_score::add_staff (Mudela_staff* mudela_staff_p)
50 {
51   mudela_staff_p_list_.bottom().add (mudela_staff_p);
52 }
53
54 Mudela_column*
55 Mudela_score::find_column_l (Moment mom)
56 {
57 #if 0
58   // should do binary search
59   for (int i = 0; i < column_l_array_.size (); i++ )
60     if ( column_l_array_[i]->at_mom () == mom )
61       return column_l_array_[i];
62   return 0;
63 #else
64   int upper_i = max (0, column_l_array_.size () - 1);
65   int lower_i = 0;
66   int i = 0; //upper_i;
67   while (1)
68     {
69       Moment i_mom = column_l_array_ [i]->at_mom ();
70       if (i_mom == mom)
71         return column_l_array_ [i];
72       if (mom < i_mom)
73         upper_i = i;
74       else
75         lower_i = i;
76       if ((upper_i == lower_i) || (i == column_l_array_.size () - 1))
77         {
78           // we don't do inserts
79           assert (0);
80           Mudela_column* col_p = new Mudela_column (this, mom);
81           column_l_array_.push (col_p);
82           return col_p;
83         }
84       i = (upper_i + lower_i + 1 ) / 2;
85     }
86   assert (0);
87   return 0;
88 #endif
89 }
90
91 Mudela_column*
92 Mudela_score::get_column_l (Moment mom)
93 {
94   int i;
95   Mudela_column *c=0;
96   for (i=column_l_array_.size() - 1; !c && i >=0; i--)
97     {
98       if (column_l_array_ [i]->at_mom () == mom )
99         c = column_l_array_[i];
100       else if (column_l_array_[i]->at_mom () < mom)
101         break;
102     }
103   if (!c)
104     {
105       c = new Mudela_column (this, mom);
106       column_l_array_.insert (c, i+1);
107     }
108
109   assert (c->at_mom () == mom);
110   return c;
111 }
112
113 void
114 Mudela_score::output (String filename_str)
115 {
116   LOGOUT(NORMAL_ver) << _f ("Lily output to %s...", filename_str) << endl;
117
118   // ugh, ugly midi type 1 fix
119   if  ( (mudela_staff_p_list_.size() == 1) && !mudela_staff_p_list_.top()->number_i_)
120     mudela_staff_p_list_.top()->number_i_ = 1;
121
122   int track_i = 0;
123   Mudela_stream mudela_stream (filename_str);
124   for  (PCursor<Mudela_staff*> i (mudela_staff_p_list_); i.ok(); i++)
125     {
126       LOGOUT(NORMAL_ver) << _ ("track ") << track_i++ << ": " << flush;
127       i->output (mudela_stream);
128       mudela_stream << '\n';
129       LOGOUT(NORMAL_ver) << endl;
130     }
131
132   mudela_stream << "\\score{\n";
133   if  (mudela_staff_p_list_.size() > 1)
134     mudela_stream << "< \n";
135   for  (PCursor<Mudela_staff*> i (mudela_staff_p_list_); i.ok(); i++)
136     {
137       if  ( (mudela_staff_p_list_.size() != 1)
138             &&  (i == mudela_staff_p_list_.top()))
139         continue;
140       mudela_stream << "\\type Staff = \"" << i->id_str() << "\" ";
141       mudela_stream << "\\$" << i->id_str() << "\n";
142     }
143   if  (mudela_staff_p_list_.size() > 1)
144     mudela_stream << ">\n";
145
146   mudela_stream << "\\paper{}\n";
147
148   mudela_stream << "\\midi{\n";
149   // let's not use silly 0 track
150   mudela_staff_p_list_.bottom()->mudela_tempo_l_->output (mudela_stream);
151   mudela_stream << "}\n";
152
153   mudela_stream << "}\n";
154 }
155
156 void
157 Mudela_score::process()
158 {
159   LOGOUT(NORMAL_ver) << '\n' << _ ("Processing...") << endl;
160
161   LOGOUT(DEBUG_ver) << "columns\n";
162   //  for  (PCursor<Mudela_column*> i (mudela_column_p_list_); i.ok(); i++)
163   //    LOGOUT(DEBUG_ver) << "At: " << i->at_mom() << '\n';
164
165   settle_columns();
166   filter_tempo();
167   quantify_columns();
168   quantify_durations();
169
170   LOGOUT(NORMAL_ver) << '\n' << _ ("Creating voices...") << endl;
171   int track_i = 0;
172   for  (PCursor<Mudela_staff*> i (mudela_staff_p_list_); i.ok(); i++)
173     {
174       LOGOUT(NORMAL_ver) << _ ("track ") << track_i++ << ": " << flush;
175       i->process();
176       LOGOUT(NORMAL_ver) << endl;
177     }
178 }
179
180 void
181 Mudela_score::filter_tempo()
182 {
183   LOGOUT(NORMAL_ver) << '\n' << _ ("NOT Filtering tempo...") << endl;
184 }
185
186 void
187 Mudela_score::quantify_columns()
188 {
189   // ugh
190   if  (Duration_convert::no_quantify_b_s)
191     {
192       LOGOUT(NORMAL_ver) << '\n' << _("NOT Quantifying columns...") << endl;
193       return;
194     }
195
196   LOGOUT(NORMAL_ver) << '\n' << _("Quantifying columns...") << endl;
197
198   int current_bar_i = 0;
199   Moment bar_mom = mudela_time_signature_l_->bar_mom();
200
201   int n = 5 >? Duration_convert::no_smaller_than_i_s;
202   n = Duration_convert::type2_i (n);
203   Moment s = Moment (1, n);
204   Moment sh = Moment (1, 2 * n);
205   for  (int i = 0; i < column_l_array_.size(); i++)
206     {
207       column_l_array_ [i]->at_mom_ =
208         s * Moment( (int) ( (column_l_array_ [i]->at_mom()) / s));
209
210       int bar_i = (int) (column_l_array_ [i]->at_mom () / bar_mom) + 1;
211       if (bar_i > current_bar_i)
212         {
213           LOGOUT (NORMAL_ver) << "[" << bar_i << "]" << flush;
214           current_bar_i = bar_i;
215         }
216     }
217   LOGOUT(NORMAL_ver) << endl;
218 }
219
220 void
221 Mudela_score::quantify_durations()
222 {
223   //    LOGOUT(NORMAL_ver) << '\n' << "Quantifying durations..." << endl;
224 }
225
226 void
227 Mudela_score::settle_columns()
228 {
229   //    LOGOUT(NORMAL_ver) << '\n' << "NOT Settling columns..." << endl;
230   //    return;
231   LOGOUT(NORMAL_ver) << '\n' << _("Settling columns...") << endl;
232
233 #if 0
234   assert (!column_l_array_.size());
235   int n = mudela_column_p_list_.size();
236   // huh?
237   //    column_l_array_.set_size (n);
238   for  (PCursor<Mudela_column*> i (mudela_column_p_list_); i.ok(); i++)
239     column_l_array_.push (*i);
240 #endif
241
242   int n = column_l_array_.size();
243
244   int start_i = 0;
245   int end_i = 0;
246   Moment start_mom = 0;
247   Duration smallest_dur;
248   smallest_dur.durlog_i_ =  6;
249   Moment const noise_mom = Duration_convert::dur2_mom (smallest_dur)
250     / Moment (2);
251   for  (int i = 0; i < n; i++)
252     {
253       if  (!start_i)
254         {
255           start_i = end_i = i;
256           start_mom = column_l_array_ [i]->at_mom();
257           continue;
258         }
259
260       // find all columns within noise's distance
261       while  ( (i < n)
262                &&  (column_l_array_ [i]->at_mom() - start_mom < noise_mom))
263         end_i = ++i;
264
265       // bluntly set all to time of first in group
266       for  (int j = start_i; j < end_i; j++)
267         column_l_array_ [j]->at_mom_ = start_mom;
268
269       start_i = end_i = 0;
270     }
271 }
272