]> git.donarmstrong.com Git - lilypond.git/blob - mi2mu/mudela-score.cc
partial: 1.0.1.jcn
[lilypond.git] / mi2mu / mudela-score.cc
1 //
2 // mudela-score.cc -- implement Mudela_score
3 //
4 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
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_meter meter_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_meter_l_ = &meter_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   if ( column_l_array_ [column_l_array_.size() - 1]->at_mom () > mom )
95     {
96       error (_("ugh"));
97       exit (1);
98     }
99   if ( column_l_array_[column_l_array_.size() - 1]->at_mom () < mom )
100     column_l_array_.push (new Mudela_column (this, mom));
101
102   return column_l_array_ [column_l_array_.size() - 1];
103 }
104
105 void
106 Mudela_score::output (String filename_str)
107 {
108   LOGOUT(NORMAL_ver) << _("Lily output to ") << filename_str << " ..." << endl;
109
110   // ugh, ugly midi type 1 fix
111   if  ( (mudela_staff_p_list_.size() == 1) && !mudela_staff_p_list_.top()->number_i_)
112     mudela_staff_p_list_.top()->number_i_ = 1;
113
114   int track_i = 0;
115   Mudela_stream mudela_stream (filename_str);
116   for  (PCursor<Mudela_staff*> i (mudela_staff_p_list_); i.ok(); i++)
117     {
118       LOGOUT(NORMAL_ver) << _("track ") << track_i++ << ": " << flush;
119       i->output (mudela_stream);
120       mudela_stream << "\n";
121       LOGOUT(NORMAL_ver) << endl;
122     }
123
124   mudela_stream << "\\score{\n";
125   if  (mudela_staff_p_list_.size() > 1)
126     mudela_stream << "\\multi 3 < \\type Staff\n";
127   for  (PCursor<Mudela_staff*> i (mudela_staff_p_list_); i.ok(); i++)
128     {
129       if  ( (mudela_staff_p_list_.size() != 1)
130             &&  (i == mudela_staff_p_list_.top()))
131         continue;
132       mudela_stream << "< \\melodic{ ";
133       mudela_stream << "\\$" << i->id_str();
134       mudela_stream << " } >\n";
135     }
136   if  (mudela_staff_p_list_.size() > 1)
137     mudela_stream << ">\n";
138
139   mudela_stream << "\\paper{}\n";
140
141   mudela_stream << "\\midi{\n";
142   // let's not use silly 0 track
143   mudela_staff_p_list_.bottom()->mudela_tempo_l_->output (mudela_stream);
144   mudela_stream << "}\n";
145
146   mudela_stream << "}\n";
147 }
148
149 void
150 Mudela_score::process()
151 {
152   LOGOUT(NORMAL_ver) << _("\nProcessing...") << endl;
153
154   LOGOUT(DEBUG_ver) << "columns\n";
155   //  for  (PCursor<Mudela_column*> i (mudela_column_p_list_); i.ok(); i++)
156   //    LOGOUT(DEBUG_ver) << "At: " << i->at_mom() << "\n";
157
158   settle_columns();
159   filter_tempo();
160   quantify_columns();
161   quantify_durations();
162
163   LOGOUT(NORMAL_ver) << _("\nCreating voices...") << endl;
164   int track_i = 0;
165   for  (PCursor<Mudela_staff*> i (mudela_staff_p_list_); i.ok(); i++)
166     {
167       LOGOUT(NORMAL_ver) << _("track ") << track_i++ << ": " << flush;
168       i->process();
169       LOGOUT(NORMAL_ver) << endl;
170     }
171 }
172
173 void
174 Mudela_score::filter_tempo()
175 {
176   LOGOUT(NORMAL_ver) << _("\nNOT Filtering tempo...") << endl;
177 }
178
179 void
180 Mudela_score::quantify_columns()
181 {
182   // ugh
183   if  (Duration_convert::no_quantify_b_s)
184     {
185       LOGOUT(NORMAL_ver) << _("\nNOT Quantifying columns...") << endl;
186       return;
187     }
188
189   LOGOUT(NORMAL_ver) << _("\nQuantifying columns...") << endl;
190
191   int current_bar_i = 0;
192   Moment bar_mom = mudela_meter_l_->bar_mom();
193
194   int n = 5 >? Duration_convert::no_smaller_than_i_s;
195   n = Duration_convert::type2_i (n);
196   Moment s = Moment (1, n);
197   Moment sh = Moment (1, 2 * n);
198   for  (int i = 0; i < column_l_array_.size(); i++)
199     {
200       column_l_array_ [i]->at_mom_ =
201         s * Moment( (int) ( (column_l_array_ [i]->at_mom()) / s));
202
203       int bar_i = (int) (column_l_array_ [i]->at_mom () / bar_mom) + 1;
204       if (bar_i > current_bar_i)
205         {
206           LOGOUT (NORMAL_ver) << '[' << bar_i << ']' << flush;
207           current_bar_i = bar_i;
208         }
209     }
210   LOGOUT(NORMAL_ver) << endl;
211 }
212
213 void
214 Mudela_score::quantify_durations()
215 {
216   //    LOGOUT(NORMAL_ver) << "\nQuantifying durations..." << endl;
217 }
218
219 void
220 Mudela_score::settle_columns()
221 {
222   //    LOGOUT(NORMAL_ver) << "\nNOT Settling columns..." << endl;
223   //    return;
224   LOGOUT(NORMAL_ver) << _("\nSettling columns...") << endl;
225
226 #if 0
227   assert (!column_l_array_.size());
228   int n = mudela_column_p_list_.size();
229   // huh?
230   //    column_l_array_.set_size (n);
231   for  (PCursor<Mudela_column*> i (mudela_column_p_list_); i.ok(); i++)
232     column_l_array_.push (*i);
233 #endif
234
235   int n = column_l_array_.size();
236
237   int start_i = 0;
238   int end_i = 0;
239   Moment start_mom = 0;
240   Duration smallest_dur;
241   smallest_dur.durlog_i_ =  6;
242   Moment const noise_mom = Duration_convert::dur2_mom (smallest_dur)
243     / Moment (2);
244   for  (int i = 0; i < n; i++)
245     {
246       if  (!start_i)
247         {
248           start_i = end_i = i;
249           start_mom = column_l_array_ [i]->at_mom();
250           continue;
251         }
252
253       // find all columns within noise's distance
254       while  ( (i < n)
255                &&  (column_l_array_ [i]->at_mom() - start_mom < noise_mom))
256         end_i = ++i;
257
258       // bluntly set all to time of first in group
259       for  (int j = start_i; j < end_i; j++)
260         column_l_array_ [j]->at_mom_ = start_mom;
261
262       start_i = end_i = 0;
263     }
264 }
265