]> git.donarmstrong.com Git - lilypond.git/blob - mi2mu/mudela-score.cc
patch::: 1.1.38.jcn1: Cons
[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 #include "killing-cons.tcc"
18
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);
23
24 Mudela_score::Mudela_score (int format_i, int tracks_i, int tempo_i)
25 {
26   format_i_ = format_i;
27   tracks_i_ = tracks_i;
28   tempo_i_ = tempo_i;
29   column_l_array_.push (new Mudela_column (this, Moment (0)));
30   //  mudela_key_l_ = &key_c;
31   mudela_key_l_ = 0;
32   mudela_time_signature_l_ = &time_sig_4;
33   mudela_tempo_l_ = &tempo_60;
34 }
35
36 Mudela_score::~Mudela_score ()
37 {
38 }
39
40 void
41 Mudela_score::add_item (Mudela_item* mudela_item_p)
42 {
43   mudela_staff_p_list_.tail_car_l ()->add_item (mudela_item_p);
44 }
45
46 void
47 Mudela_score::add_staff (Mudela_staff* mudela_staff_p)
48 {
49   mudela_staff_p_list_.append (new Killing_cons<Mudela_staff> (mudela_staff_p, 0));
50 }
51
52 Mudela_column*
53 Mudela_score::find_column_l (Moment mom)
54 {
55   int upper_i = max (0, column_l_array_.size () - 1);
56   int lower_i = 0;
57   int i = 0; //upper_i;
58   while (1)
59     {
60       Moment i_mom = column_l_array_ [i]->at_mom ();
61       if (i_mom == mom)
62         return column_l_array_ [i];
63       if (mom < i_mom)
64         upper_i = i;
65       else
66         lower_i = i;
67       if ( (upper_i == lower_i) || (i == column_l_array_.size () - 1))
68         {
69           // we don't do inserts
70           assert (0);
71           Mudela_column* col_p = new Mudela_column (this, mom);
72           column_l_array_.push (col_p);
73           return col_p;
74         }
75       i = (upper_i + lower_i + 1 ) / 2;
76     }
77   assert (0);
78   return 0;
79 }
80
81 Mudela_column*
82 Mudela_score::get_column_l (Moment mom)
83 {
84   int i;
85   Mudela_column *c=0;
86   for (i=column_l_array_.size () - 1; !c && i >=0; i--)
87     {
88       if (column_l_array_ [i]->at_mom () == mom )
89         c = column_l_array_[i];
90       else if (column_l_array_[i]->at_mom () < mom)
91         break;
92     }
93   if (!c)
94     {
95       c = new Mudela_column (this, mom);
96       column_l_array_.insert (c, i+1);
97     }
98
99   assert (c->at_mom () == mom);
100   return c;
101 }
102
103
104 void
105 Mudela_score::output (String filename_str)
106 {
107   LOGOUT (NORMAL_ver) << _f ("Lily output to %s...", filename_str) << endl;
108
109   // ugh, ugly midi type 1 fix
110   if ( (mudela_staff_p_list_.size_i () == 1)
111        && !mudela_staff_p_list_.car_l ()->number_i_)
112     mudela_staff_p_list_.car_l ()->number_i_ = 1;
113
114   int track_i = 0;
115   Mudela_stream mudela_stream (filename_str);
116   for (Cons<Mudela_staff>* i = mudela_staff_p_list_.head_cons_p_; i; i = i->next_cons_p_)
117     {
118       LOGOUT (NORMAL_ver) << _ ("track ") << track_i++ << ": " << flush;
119       i->car_p_->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_i () > 1)
126     mudela_stream << "< \n";
127   for (Cons<Mudela_staff>* i = mudela_staff_p_list_.head_cons_p_; i; i = i->next_cons_p_)
128     {
129       if ( (mudela_staff_p_list_.size_i () != 1)
130             && (i->car_p_ == mudela_staff_p_list_.car_l ()))
131         continue;
132       mudela_stream << "\\type Staff = \"" << i->car_p_->id_str () << "\" ";
133       mudela_stream << String ("\\" +  i->car_p_->id_str ()) << "\n";
134     }
135   if (mudela_staff_p_list_.size_i () > 1)
136     mudela_stream << ">\n";
137
138   mudela_stream << "\\paper{}\n";
139
140   mudela_stream << "\\midi{\n";
141   // let's not use silly 0 track
142   mudela_staff_p_list_.tail_car_l ()->mudela_tempo_l_->output (mudela_stream);
143   mudela_stream << "}\n";
144
145   mudela_stream << "}\n";
146 }
147
148 void
149 Mudela_score::process ()
150 {
151   LOGOUT (NORMAL_ver) << '\n' << _ ("Processing...") << endl;
152
153   LOGOUT (DEBUG_ver) << "columns\n";
154
155   settle_columns ();
156   filter_tempo ();
157   quantify_columns ();
158   quantify_durations ();
159
160   LOGOUT (NORMAL_ver) << '\n' << _ ("Creating voices...") << endl;
161   int track_i = 0;
162   for (Cons<Mudela_staff>* i = mudela_staff_p_list_.head_cons_p_; i; i = i->next_cons_p_)
163     {
164       LOGOUT (NORMAL_ver) << _ ("track ") << track_i++ << ": " << flush;
165       i->car_p_->process ();
166       LOGOUT (NORMAL_ver) << endl;
167     }
168 }
169
170 void
171 Mudela_score::filter_tempo ()
172 {
173   LOGOUT (NORMAL_ver) << '\n' << _ ("NOT Filtering tempo...") << endl;
174 }
175
176 void
177 Mudela_score::quantify_columns ()
178 {
179   // ugh
180   if (Duration_convert::no_quantify_b_s)
181     {
182       LOGOUT (NORMAL_ver) << '\n' << _ ("NOT Quantifying columns...") << endl;
183       return;
184     }
185
186   LOGOUT (NORMAL_ver) << '\n' << _ ("Quantifying columns...") << endl;
187
188   int current_bar_i = 0;
189   Moment bar_mom = mudela_time_signature_l_->bar_mom ();
190
191   int n = 5 >? Duration_convert::no_smaller_than_i_s;
192   n = Duration_convert::type2_i (n);
193   Moment s = Moment (1, n);
194   for (int i = 0; i < column_l_array_.size (); i++)
195     {
196       column_l_array_ [i]->at_mom_ =
197         s * Moment ( (int) ( (column_l_array_ [i]->at_mom ()) / s));
198
199       int bar_i = (int) (column_l_array_ [i]->at_mom () / bar_mom) + 1;
200       if (bar_i > current_bar_i)
201         {
202           LOGOUT (NORMAL_ver) << "[" << bar_i << "]" << flush;
203           current_bar_i = bar_i;
204         }
205     }
206   LOGOUT (NORMAL_ver) << endl;
207 }
208
209 void
210 Mudela_score::quantify_durations ()
211 {
212   //    LOGOUT (NORMAL_ver) << '\n' << "Quantifying durations..." << endl;
213 }
214
215 void
216 Mudela_score::settle_columns ()
217 {
218   LOGOUT (NORMAL_ver) << '\n' << _ ("Settling columns...") << endl;
219
220   int n = column_l_array_.size ();
221
222   int start_i = 0;
223   int end_i = 0;
224   Moment start_mom = 0;
225   Duration smallest_dur;
226   smallest_dur.durlog_i_ =  6;
227   Moment const noise_mom = Duration_convert::dur2_mom (smallest_dur)
228     / Moment (2);
229   for (int i = 0; i < n; i++)
230     {
231       if (!start_i)
232         {
233           start_i = end_i = i;
234           start_mom = column_l_array_ [i]->at_mom ();
235           continue;
236         }
237
238       // find all columns within noise's distance
239       while ( (i < n)
240                && (column_l_array_ [i]->at_mom () - start_mom < noise_mom))
241         end_i = ++i;
242
243       // bluntly set all to time of first in group
244       for (int j = start_i; j < end_i; j++)
245         column_l_array_ [j]->at_mom_ = start_mom;
246
247       start_i = end_i = 0;
248     }
249 }
250