]> git.donarmstrong.com Git - lilypond.git/blob - mi2mu/mudela-score.cc
patch::: 0.1.9.jcn2: pats
[lilypond.git] / mi2mu / mudela-score.cc
1 //
2 // mudela-score.cc -- implement Mudela_score
3 //
4 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
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 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);
21
22 Mudela_score::Mudela_score (int format_i, int tracks_i, int tempo_i)
23 {
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_meter_l_ = &meter_4;
30   mudela_tempo_l_ = &tempo_60;
31 }
32
33 Mudela_score::~Mudela_score()
34 {
35 }
36
37 void 
38 Mudela_score::add_item (Mudela_item* mudela_item_p)
39 {
40   mudela_staff_p_list_.bottom()->add_item (mudela_item_p);
41 }
42
43 void
44 Mudela_score::add_staff (Mudela_staff* mudela_staff_p)
45 {
46   mudela_staff_p_list_.bottom().add (mudela_staff_p);
47 }
48
49 Mudela_column*
50 Mudela_score::find_column_l (Moment mom)
51 {
52   // should do binary search
53   for (int i = 0; i < column_l_array_.size (); i++ )
54     if ( column_l_array_[i]->at_mom () == mom )
55         return column_l_array_[i];
56   return 0;
57 }
58
59 Mudela_column*
60 Mudela_score::get_column_l (Moment mom)
61 {
62   if ( column_l_array_ [column_l_array_.size() - 1]->at_mom () > mom )
63     {
64       error ("ugh");
65       exit (1);
66     }
67   if ( column_l_array_[column_l_array_.size() - 1]->at_mom () < mom )
68     column_l_array_.push (new Mudela_column (this, mom));
69
70   return column_l_array_ [column_l_array_.size() - 1];
71 }
72
73 void
74 Mudela_score::output (String filename_str)
75 {
76   LOGOUT(NORMAL_ver) << "Lily output to " << filename_str << " ..." << endl;
77   
78   // ugh, ugly midi type 1 fix
79   if  ( (mudela_staff_p_list_.size() == 1) && !mudela_staff_p_list_.top()->number_i_)
80         mudela_staff_p_list_.top()->number_i_ = 1;
81
82   int track_i = 0;
83   Mudela_stream mudela_stream (filename_str);
84   for  (PCursor<Mudela_staff*> i (mudela_staff_p_list_); i.ok(); i++) 
85     {
86         LOGOUT(NORMAL_ver) << "track " << track_i++ << ": " << flush;
87         i->output (mudela_stream);
88         mudela_stream << "\n";
89         LOGOUT(NORMAL_ver) << endl;
90     }
91
92   mudela_stream << "\\score{\n";
93   if  (mudela_staff_p_list_.size() > 1)
94         mudela_stream << "<\n\\multi 3;\n";
95   for  (PCursor<Mudela_staff*> i (mudela_staff_p_list_); i.ok(); i++) 
96     {
97         if  ( (mudela_staff_p_list_.size() != 1) 
98             &&  (i == mudela_staff_p_list_.top()))
99             continue;
100         mudela_stream << "\\melodic{ ";
101         mudela_stream << "\\$" << i->id_str();
102         mudela_stream << " }\n";
103     }
104   if  (mudela_staff_p_list_.size() > 1)
105         mudela_stream << ">\n";
106
107   mudela_stream << "\\paper{}\n";
108
109   mudela_stream << "\\midi{\n";
110         // let's not use silly 0 track
111         mudela_staff_p_list_.bottom()->mudela_tempo_p_->output (mudela_stream);
112   mudela_stream << "}\n";
113
114   mudela_stream << "}\n";
115 }
116
117 void
118 Mudela_score::process()
119 {
120   LOGOUT(NORMAL_ver) << "\nProcessing..." << endl;
121         
122   LOGOUT(DEBUG_ver) << "columns\n";
123 //  for  (PCursor<Mudela_column*> i (mudela_column_p_list_); i.ok(); i++)
124 //      LOGOUT(DEBUG_ver) << "At: " << i->at_mom() << "\n";
125
126   settle_columns();
127   filter_tempo();
128   quantify_columns();
129   quantify_durations();
130
131   LOGOUT(NORMAL_ver) << "\nCreating voices..." << endl;
132   int track_i = 0;
133   for  (PCursor<Mudela_staff*> i (mudela_staff_p_list_); i.ok(); i++)  
134     {
135         LOGOUT(NORMAL_ver) << "track " << track_i++ << ": " << flush;
136         i->process();
137         LOGOUT(NORMAL_ver) << endl;
138     }
139 }
140
141 void
142 Mudela_score::filter_tempo()
143 {
144   LOGOUT(NORMAL_ver) << "\nNOT Filtering tempo..." << endl;
145 }
146
147 void
148 Mudela_score::quantify_columns()
149 {
150   // ugh
151   if  (Duration_convert::no_quantify_b_s) 
152     {
153         LOGOUT(NORMAL_ver) << "\nNOT Quantifying columns..." << endl;
154         return;
155     }
156
157   LOGOUT(NORMAL_ver) << "\nQuantifying columns..." << endl;
158
159   int n = 5 >? Duration_convert::no_smaller_than_i_s;
160   Moment s = Moment (1, n);
161   Moment sh = Moment (1, 2 * n);
162   for  (int i = 0; i < column_l_array_.size(); i++) 
163     {
164 //      Moment mom = column_l_array_[ i ]->at_mom();
165 //      column_l_array_[ i ]->at_mom_ = Duration_convert::dur2_mom (dur);
166         column_l_array_[ i ]->at_mom_ =
167 //          s * (int) ( (sh + column_l_array_[ i ]->at_mom()) / s);
168             s * (int) ( (column_l_array_[ i ]->at_mom()) / s);
169         LOGOUT(NORMAL_ver) << '.';
170     }
171   LOGOUT(NORMAL_ver) << endl;
172 }
173
174 void
175 Mudela_score::quantify_durations()
176 {
177 //    LOGOUT(NORMAL_ver) << "\nQuantifying durations..." << endl;
178 }
179
180 void
181 Mudela_score::settle_columns()
182 {
183 //    LOGOUT(NORMAL_ver) << "\nNOT Settling columns..." << endl;
184 //    return;
185   LOGOUT(NORMAL_ver) << "\nSettling columns..." << endl;
186
187 #if 0
188   assert (!column_l_array_.size());
189   int n = mudela_column_p_list_.size();
190 // huh?
191 //    column_l_array_.set_size (n);
192   for  (PCursor<Mudela_column*> i (mudela_column_p_list_); i.ok(); i++)
193         column_l_array_.push (*i);
194 #endif
195
196   int n = column_l_array_.size();
197
198   int start_i = 0;
199   int end_i = 0;
200   Moment start_mom = 0;
201   Duration smallest_dur;
202   smallest_dur.durlog_i_ =  6;
203   Moment const noise_mom = Duration_convert::dur2_mom (smallest_dur)
204         / Moment (2);
205   for  (int i = 0; i < n; i++) 
206     {
207         if  (!start_i) 
208           {
209             start_i = end_i = i;
210             start_mom = column_l_array_[ i ]->at_mom();
211             continue;
212           }
213
214         // find all columns within noise's distance
215         while  ( (i < n)
216             &&  (column_l_array_[ i ]->at_mom() - start_mom < noise_mom))
217             end_i = ++i;
218
219         // bluntly set all to time of first in group
220         for  (int j = start_i; j < end_i; j++)
221             column_l_array_[ j ]->at_mom_ = start_mom;
222
223         start_i = end_i = 0;
224     }
225 }
226