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