2 // mudela-score.cc -- implement Mudela_score
4 // copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
9 #include "duration-convert.hh"
10 #include "midi2ly-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 #include "killing-cons.tcc"
19 //static Mudela_key key_c (0, 0);
20 static Mudela_time_signature time_sig_4 (4, 2, 24, 8);
21 // useconds per 4: 250000 === 60 4 per minute
22 static Mudela_tempo tempo_60 (1000000);
24 Mudela_score::Mudela_score (int format_i, int tracks_i, int tempo_i)
30 column_l_array_.push (new Mudela_column (this, Rational (0)));
31 // mudela_key_l_ = &key_c;
33 mudela_time_signature_l_ = &time_sig_4;
34 mudela_tempo_l_ = &tempo_60;
37 Mudela_score::~Mudela_score ()
42 Mudela_score::add_item (Mudela_item* mudela_item_p)
44 last_staff_l_->add_item (mudela_item_p);
48 Mudela_score::add_staff (Mudela_staff* mudela_staff_p)
50 mudela_staff_p_list_.append (new Killing_cons<Mudela_staff> (mudela_staff_p, 0));
51 last_staff_l_ = mudela_staff_p;
55 Mudela_score::find_column_l (Rational mom)
57 int upper_i = max (0, column_l_array_.size () - 1);
62 Rational i_mom = column_l_array_ [i]->at_mom ();
64 return column_l_array_ [i];
69 if ( (upper_i == lower_i) || (i == column_l_array_.size () - 1))
71 // we don't do inserts
73 Mudela_column* col_p = new Mudela_column (this, mom);
74 column_l_array_.push (col_p);
77 i = (upper_i + lower_i + 1 ) / 2;
84 Mudela_score::get_column_l (Rational mom)
88 for (i=column_l_array_.size () - 1; !c && i >=0; i--)
90 if (column_l_array_ [i]->at_mom () == mom )
91 c = column_l_array_[i];
92 else if (column_l_array_[i]->at_mom () < mom)
97 c = new Mudela_column (this, mom);
98 column_l_array_.insert (c, i+1);
101 assert (c->at_mom () == mom);
106 Mudela_score::output (String filename_str)
108 LOGOUT (NORMAL_ver) << _f ("Lily output to %s...", filename_str) << endl;
110 // ugh, ugly midi type 1 fix
111 if ( (mudela_staff_p_list_.size_i () == 1)
112 && !mudela_staff_p_list_.head_->car_->number_i_)
113 mudela_staff_p_list_.head_->car_->number_i_ = 1;
116 Mudela_stream mudela_stream (filename_str);
117 for (Cons<Mudela_staff>* i = mudela_staff_p_list_.head_; i; i = i->next_)
119 LOGOUT (NORMAL_ver) << _f ("track %d:", track_i++) << flush;
120 i->car_->output (mudela_stream);
121 mudela_stream << '\n';
122 LOGOUT (NORMAL_ver) << endl;
125 mudela_stream << "\\score{\n";
126 if (mudela_staff_p_list_.size_i () > 1)
127 mudela_stream << "< \n";
128 for (Cons<Mudela_staff>* i = mudela_staff_p_list_.head_; i; i = i->next_)
130 if ( (mudela_staff_p_list_.size_i () != 1)
131 && (i->car_ == mudela_staff_p_list_.head_->car_))
133 mudela_stream << "\\context Staff = \"" << i->car_->id_str () << "\" ";
134 mudela_stream << String ("\\" + i->car_->id_str ()) << '\n';
136 if (mudela_staff_p_list_.size_i () > 1)
137 mudela_stream << ">\n";
139 mudela_stream << "\\paper{}\n";
142 mudela_stream << "\\midi{\n";
144 // let's not use silly 0 track
145 last_cons (mudela_staff_p_list_.head_)->car_->mudela_tempo_l_->output (mudela_stream);
146 mudela_stream << "}\n";
149 mudela_stream << "}\n";
153 Mudela_score::process ()
155 LOGOUT (NORMAL_ver) << '\n' << _ ("Processing...") << endl;
157 LOGOUT (DEBUG_ver) << "columns\n";
162 quantify_durations ();
164 LOGOUT (NORMAL_ver) << '\n' << _ ("Creating voices...") << endl;
166 for (Cons<Mudela_staff>* i = mudela_staff_p_list_.head_; i; i = i->next_)
168 LOGOUT (NORMAL_ver) << _ ("track ") << track_i++ << ": " << flush;
170 LOGOUT (NORMAL_ver) << endl;
175 Mudela_score::filter_tempo ()
177 LOGOUT (NORMAL_ver) << '\n' << _ ("NOT Filtering tempo...") << endl;
181 Mudela_score::quantify_columns ()
184 if (Duration_convert::no_quantify_b_s)
186 LOGOUT (NORMAL_ver) << '\n' << _ ("NOT Quantifying columns...") << endl;
190 LOGOUT (NORMAL_ver) << '\n' << _ ("Quantifying columns...") << endl;
192 int current_bar_i = 0;
193 Rational bar_mom = mudela_time_signature_l_->bar_mom ();
195 int n = 5 >? Duration_convert::no_smaller_than_i_s;
196 n = Duration_convert::type2_i (n);
197 Rational s = Rational (1, n);
198 for (int i = 0; i < column_l_array_.size (); i++)
200 column_l_array_ [i]->at_mom_ =
201 s * Rational ( (int) ( (column_l_array_ [i]->at_mom ()) / s));
203 int bar_i = (int) (column_l_array_ [i]->at_mom () / bar_mom) + 1;
204 if (bar_i > current_bar_i)
207 LOGOUT (NORMAL_ver) << "[" << bar_i << "]" << flush;
208 current_bar_i = bar_i;
211 LOGOUT (NORMAL_ver) << endl;
215 Mudela_score::quantify_durations ()
221 Mudela_score::settle_columns ()
223 LOGOUT (NORMAL_ver) << '\n' << _ ("Settling columns...") << endl;
225 int n = column_l_array_.size ();
229 Rational start_mom = 0;
231 Duration smallest_dur;
232 smallest_dur.durlog_i_ = 6;
233 Rational const noise_mom = Duration_convert::dur2_mom (smallest_dur)
235 for (int i = 0; i < n; i++)
240 start_mom = column_l_array_ [i]->at_mom ();
244 // find all columns within noise's distance
246 && (column_l_array_ [i]->at_mom () - start_mom < noise_mom))
249 // bluntly set all to time of first in group
250 for (int j = start_i; j < end_i; j++)
251 column_l_array_ [j]->at_mom_ = start_mom;