lilypond-0.1.14
[lilypond.git] / mi2mu / mudela-score.cc
blob5b951dac39e8478efceec89703c960b7f8f7c7a3
1 //
2 // mudela-score.cc -- implement Mudela_score
3 //
4 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
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"
17 //static Mudela_key key_c (0, 0);
18 static Mudela_meter meter_4 (4, 2, 24, 8);
19 // useconds per 4: 250000 === 60 4 per minute
20 static Mudela_tempo tempo_60 (1000000);
22 Mudela_score::Mudela_score (int format_i, int tracks_i, int tempo_i)
24 format_i_ = format_i;
25 tracks_i_ = tracks_i;
26 tempo_i_ = tempo_i;
27 column_l_array_.push (new Mudela_column (this, Moment (0)));
28 // mudela_key_l_ = &key_c;
29 mudela_key_l_ = 0;
30 mudela_meter_l_ = &meter_4;
31 mudela_tempo_l_ = &tempo_60;
34 Mudela_score::~Mudela_score()
38 void
39 Mudela_score::add_item (Mudela_item* mudela_item_p)
41 mudela_staff_p_list_.bottom()->add_item (mudela_item_p);
44 void
45 Mudela_score::add_staff (Mudela_staff* mudela_staff_p)
47 mudela_staff_p_list_.bottom().add (mudela_staff_p);
50 Mudela_column*
51 Mudela_score::find_column_l (Moment mom)
53 #if 0
54 // should do binary search
55 for (int i = 0; i < column_l_array_.size (); i++ )
56 if ( column_l_array_[i]->at_mom () == mom )
57 return column_l_array_[i];
58 return 0;
59 #else
60 int upper_i = max (0, column_l_array_.size () - 1);
61 int lower_i = 0;
62 int i = 0; //upper_i;
63 while (1)
65 Moment i_mom = column_l_array_ [i]->at_mom ();
66 if (i_mom == mom)
67 return column_l_array_ [i];
68 if (mom < i_mom)
69 upper_i = i;
70 else
71 lower_i = i;
72 if ((upper_i == lower_i) || (i == column_l_array_.size () - 1))
74 // we don't do inserts
75 assert (0);
76 Mudela_column* col_p = new Mudela_column (this, mom);
77 column_l_array_.push (col_p);
78 return col_p;
80 i = (upper_i + lower_i + 1 ) / 2;
82 assert (0);
83 return 0;
84 #endif
87 Mudela_column*
88 Mudela_score::get_column_l (Moment mom)
90 if ( column_l_array_ [column_l_array_.size() - 1]->at_mom () > mom )
92 error ("ugh");
93 exit (1);
95 if ( column_l_array_[column_l_array_.size() - 1]->at_mom () < mom )
96 column_l_array_.push (new Mudela_column (this, mom));
98 return column_l_array_ [column_l_array_.size() - 1];
101 void
102 Mudela_score::output (String filename_str)
104 LOGOUT(NORMAL_ver) << "Lily output to " << filename_str << " ..." << endl;
106 // ugh, ugly midi type 1 fix
107 if ( (mudela_staff_p_list_.size() == 1) && !mudela_staff_p_list_.top()->number_i_)
108 mudela_staff_p_list_.top()->number_i_ = 1;
110 int track_i = 0;
111 Mudela_stream mudela_stream (filename_str);
112 for (PCursor<Mudela_staff*> i (mudela_staff_p_list_); i.ok(); i++)
114 LOGOUT(NORMAL_ver) << "track " << track_i++ << ": " << flush;
115 i->output (mudela_stream);
116 mudela_stream << "\n";
117 LOGOUT(NORMAL_ver) << endl;
120 mudela_stream << "\\score{\n";
121 if (mudela_staff_p_list_.size() > 1)
122 mudela_stream << "<\n\\multi 3;\n";
123 for (PCursor<Mudela_staff*> i (mudela_staff_p_list_); i.ok(); i++)
125 if ( (mudela_staff_p_list_.size() != 1)
126 && (i == mudela_staff_p_list_.top()))
127 continue;
128 mudela_stream << "\\melodic{ ";
129 mudela_stream << "\\$" << i->id_str();
130 mudela_stream << " }\n";
132 if (mudela_staff_p_list_.size() > 1)
133 mudela_stream << ">\n";
135 mudela_stream << "\\paper{}\n";
137 mudela_stream << "\\midi{\n";
138 // let's not use silly 0 track
139 mudela_staff_p_list_.bottom()->mudela_tempo_p_->output (mudela_stream);
140 mudela_stream << "}\n";
142 mudela_stream << "}\n";
145 void
146 Mudela_score::process()
148 LOGOUT(NORMAL_ver) << "\nProcessing..." << endl;
150 LOGOUT(DEBUG_ver) << "columns\n";
151 // for (PCursor<Mudela_column*> i (mudela_column_p_list_); i.ok(); i++)
152 // LOGOUT(DEBUG_ver) << "At: " << i->at_mom() << "\n";
154 settle_columns();
155 filter_tempo();
156 quantify_columns();
157 quantify_durations();
159 LOGOUT(NORMAL_ver) << "\nCreating voices..." << endl;
160 int track_i = 0;
161 for (PCursor<Mudela_staff*> i (mudela_staff_p_list_); i.ok(); i++)
163 LOGOUT(NORMAL_ver) << "track " << track_i++ << ": " << flush;
164 i->process();
165 LOGOUT(NORMAL_ver) << endl;
169 void
170 Mudela_score::filter_tempo()
172 LOGOUT(NORMAL_ver) << "\nNOT Filtering tempo..." << endl;
175 void
176 Mudela_score::quantify_columns()
178 // ugh
179 if (Duration_convert::no_quantify_b_s)
181 LOGOUT(NORMAL_ver) << "\nNOT Quantifying columns..." << endl;
182 return;
185 LOGOUT(NORMAL_ver) << "\nQuantifying columns..." << endl;
187 int current_bar_i = 0;
188 Moment bar_mom = mudela_meter_l_->bar_mom();
190 int n = 5 >? Duration_convert::no_smaller_than_i_s;
191 n = Duration_convert::type2_i (n);
192 Moment s = Moment (1, n);
193 Moment sh = Moment (1, 2 * n);
194 for (int i = 0; i < column_l_array_.size(); i++)
196 column_l_array_ [i]->at_mom_ =
197 s * Moment( (int) ( (column_l_array_ [i]->at_mom()) / s));
199 int bar_i = (int) (column_l_array_ [i]->at_mom () / bar_mom) + 1;
200 if (bar_i > current_bar_i)
202 LOGOUT (NORMAL_ver) << '[' << bar_i << ']' << flush;
203 current_bar_i = bar_i;
206 LOGOUT(NORMAL_ver) << endl;
209 void
210 Mudela_score::quantify_durations()
212 // LOGOUT(NORMAL_ver) << "\nQuantifying durations..." << endl;
215 void
216 Mudela_score::settle_columns()
218 // LOGOUT(NORMAL_ver) << "\nNOT Settling columns..." << endl;
219 // return;
220 LOGOUT(NORMAL_ver) << "\nSettling columns..." << endl;
222 #if 0
223 assert (!column_l_array_.size());
224 int n = mudela_column_p_list_.size();
225 // huh?
226 // column_l_array_.set_size (n);
227 for (PCursor<Mudela_column*> i (mudela_column_p_list_); i.ok(); i++)
228 column_l_array_.push (*i);
229 #endif
231 int n = column_l_array_.size();
233 int start_i = 0;
234 int end_i = 0;
235 Moment start_mom = 0;
236 Duration smallest_dur;
237 smallest_dur.durlog_i_ = 6;
238 Moment const noise_mom = Duration_convert::dur2_mom (smallest_dur)
239 / Moment (2);
240 for (int i = 0; i < n; i++)
242 if (!start_i)
244 start_i = end_i = i;
245 start_mom = column_l_array_ [i]->at_mom();
246 continue;
249 // find all columns within noise's distance
250 while ( (i < n)
251 && (column_l_array_ [i]->at_mom() - start_mom < noise_mom))
252 end_i = ++i;
254 // bluntly set all to time of first in group
255 for (int j = start_i; j < end_i; j++)
256 column_l_array_ [j]->at_mom_ = start_mom;
258 start_i = end_i = 0;