2 // mudela-score.cc -- implement Mudela_score
4 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
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
)
27 column_l_array_
.push (new Mudela_column (this, Moment (0)));
28 // mudela_key_l_ = &key_c;
30 mudela_meter_l_
= &meter_4
;
31 mudela_tempo_l_
= &tempo_60
;
34 Mudela_score::~Mudela_score()
39 Mudela_score::add_item (Mudela_item
* mudela_item_p
)
41 mudela_staff_p_list_
.bottom()->add_item (mudela_item_p
);
45 Mudela_score::add_staff (Mudela_staff
* mudela_staff_p
)
47 mudela_staff_p_list_
.bottom().add (mudela_staff_p
);
51 Mudela_score::find_column_l (Moment mom
)
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
];
60 int upper_i
= max (0, column_l_array_
.size () - 1);
65 Moment i_mom
= column_l_array_
[i
]->at_mom ();
67 return column_l_array_
[i
];
72 if ((upper_i
== lower_i
) || (i
== column_l_array_
.size () - 1))
74 // we don't do inserts
76 Mudela_column
* col_p
= new Mudela_column (this, mom
);
77 column_l_array_
.push (col_p
);
80 i
= (upper_i
+ lower_i
+ 1 ) / 2;
88 Mudela_score::get_column_l (Moment mom
)
90 if ( column_l_array_
[column_l_array_
.size() - 1]->at_mom () > mom
)
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];
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;
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()))
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";
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";
157 quantify_durations();
159 LOGOUT(NORMAL_ver
) << "\nCreating voices..." << endl
;
161 for (PCursor
<Mudela_staff
*> i (mudela_staff_p_list_
); i
.ok(); i
++)
163 LOGOUT(NORMAL_ver
) << "track " << track_i
++ << ": " << flush
;
165 LOGOUT(NORMAL_ver
) << endl
;
170 Mudela_score::filter_tempo()
172 LOGOUT(NORMAL_ver
) << "\nNOT Filtering tempo..." << endl
;
176 Mudela_score::quantify_columns()
179 if (Duration_convert::no_quantify_b_s
)
181 LOGOUT(NORMAL_ver
) << "\nNOT Quantifying columns..." << endl
;
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
;
210 Mudela_score::quantify_durations()
212 // LOGOUT(NORMAL_ver) << "\nQuantifying durations..." << endl;
216 Mudela_score::settle_columns()
218 // LOGOUT(NORMAL_ver) << "\nNOT Settling columns..." << endl;
220 LOGOUT(NORMAL_ver
) << "\nSettling columns..." << endl
;
223 assert (!column_l_array_
.size());
224 int n
= mudela_column_p_list_
.size();
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
);
231 int n
= column_l_array_
.size();
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
)
240 for (int i
= 0; i
< n
; i
++)
245 start_mom
= column_l_array_
[i
]->at_mom();
249 // find all columns within noise's distance
251 && (column_l_array_
[i
]->at_mom() - start_mom
< noise_mom
))
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
;