]> git.donarmstrong.com Git - lilypond.git/blob - lily/score.cc
release: 0.0.68pre
[lilypond.git] / lily / score.cc
1 /*
2   score.cc -- implement Score
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8 #include "tex-stream.hh"
9 #include "score.hh"
10 #include "score-column.hh"
11 #include "p-score.hh"
12 #include "debug.hh"
13 #include "paper-def.hh"
14 #include "main.hh"
15 #include "source.hh"
16 #include "source-file.hh"
17 #include "midi-output.hh"
18 #include "midi-def.hh"
19 #include "p-col.hh"
20 #include "score-reg.hh"
21 #include "music-iterator.hh"
22 #include "music.hh"
23 #include "music-list.hh"
24 #include "input-register.hh"
25
26 extern String default_out_fn;
27
28 Score::Score(Score const &s)
29 {
30     assert(!pscore_p_);
31     music_p_ = s.music_p_->clone();
32     midi_p_ = new Midi_def(*s.midi_p_);
33     paper_p_ = new Paper_def(*s.paper_p_);
34 }
35
36 void
37 Score::setup_music()
38 {
39     *mlog << "\nSetting up requests..." << flush;
40     
41     Score_register * score_reg =  
42         (Score_register*)lookup_reg("Score_register")->get_group_register_p();
43
44     score_reg->set_score (this);
45     Music_iterator * iter = Music_iterator::static_get_iterator_p(music_p_, 
46                                                                   score_reg);
47     iter->construct_children();
48
49     while ( iter->ok() || score_reg->extra_mom_pq_.size() ) {
50         Moment w = INFTY;
51         if (iter->ok() ) 
52             w = iter->next_moment();
53         
54         if (score_reg->extra_mom_pq_.size() && 
55             score_reg->extra_mom_pq_.front() <= w)
56             
57             w = score_reg->extra_mom_pq_.get();
58
59         mtor << "processing moment " << w << "\n";
60
61         Score_column* c1 = new Score_column(w);
62         Score_column* c2 = new Score_column(w);
63         
64         c1->musical_b_ = false;
65         c2->musical_b_ = true;
66         
67         cols_.bottom().add(c1);
68         cols_.bottom().add(c2);
69         score_reg->set_cols(c1,c2);
70         
71         score_reg->post_move_processing();
72         iter->next( w );
73         
74         score_reg->process_requests();
75         score_reg->do_announces();
76         score_reg->pre_move_processing();
77     }
78     delete iter;
79     score_reg->do_removal_processing();
80     delete score_reg;
81 }
82
83 void
84 Score::process()
85 {
86     paper();
87 }
88
89 void
90 Score::paper()
91 {
92     if (!paper_p_)
93         return;
94
95     if( errorlevel_i_){
96         // should we? hampers debugging. 
97         warning("Errors found, /*not processing score*/");
98 //      return;
99     }
100     pscore_p_ = new PScore(paper_p_);
101     setup_music();
102     do_cols();
103     
104     clean_cols();    // can't move clean_cols() farther up.
105     print();
106     calc_idealspacing();
107
108     // debugging
109     OK();
110     *mlog << endl;
111     pscore_p_->process();
112
113     // output
114     paper_output();
115     
116 }
117
118 /**
119   Remove empty cols, preprocess other columns.
120   */
121 void
122 Score::clean_cols()
123 {
124 #if 1
125     for (iter_top(cols_,c); c.ok(); ) {
126         if (!c->pcol_l_->used_b()) {
127             delete c.remove_p();
128         } else {
129             c->preprocess();
130             c++;
131         }
132     }
133 #endif
134 }
135
136 PCursor<Score_column*>
137 Score::find_col(Moment w, bool mus)
138 {
139     iter_top( cols_,i);
140     
141     for (; i.ok(); i++) {
142         if (i->when() == w && i->musical_b_ == mus)
143             return i;
144         if (i->when() > w)
145             break;
146     }
147     assert(false);
148     return i;
149 }
150
151 void
152 Score::do_cols()    
153 {
154     iter_top(cols_,i);
155     for (; i.ok(); i++) {
156         pscore_p_->add(i->pcol_l_);
157     }
158 }
159
160 Moment
161 Score::last() const
162 {    
163     Moment l = 0;
164     // TODO
165     return l;
166 }
167
168 void
169 Score::set(Paper_def *pap_p)
170 {
171     delete paper_p_;
172     paper_p_ = pap_p;
173 }
174
175 void
176 Score::set(Midi_def* midi_p)
177 {    
178     delete midi_p_;
179     midi_p_ = midi_p;
180 }
181
182 void
183 Score::OK() const
184 {
185 #ifndef NDEBUG
186     cols_.OK();
187     for (iter_top(cols_,cc); cc.ok() && (cc+1).ok(); cc++) {
188         assert(cc->when() <= (cc+1)->when());
189     }
190 #endif    
191 }
192
193
194 void
195 Score::print() const
196 {
197 #ifndef NPRINT
198     mtor << "score {\n"; 
199     music_p_->print();
200     for (iter_top(cols_,i); i.ok(); i++) {
201         i->print();
202     }
203     if (pscore_p_)
204         pscore_p_->print();
205     if (midi_p_)
206         midi_p_->print();
207     
208     mtor << "}\n";
209 #endif
210 }
211
212 Score::Score()
213 {
214     pscore_p_=0;
215     paper_p_ = 0;
216     midi_p_ = 0;
217     errorlevel_i_ = 0;
218 }
219
220 Score::~Score()
221 {
222     delete music_p_;
223     delete pscore_p_;
224     delete paper_p_;
225     delete midi_p_;
226 }
227
228 void
229 Score::paper_output()
230 {
231     if (paper_p_->outfile=="")
232         paper_p_->outfile = default_out_fn + ".out";
233
234     if ( errorlevel_i_ ) { 
235         *mlog << "lilypond: warning: no output to: " << paper_p_->outfile 
236         << " (errorlevel=" << errorlevel_i_ << ")" << endl;
237         return;
238     }
239
240     *mlog << "TeX output to " << paper_p_->outfile << " ...\n";
241     
242     Tex_stream the_output(paper_p_->outfile);
243     
244     the_output << "% outputting Score, defined at: " <<
245         location_str() << "\n";
246     pscore_p_->output(the_output);
247     
248 }
249
250 void
251 Score::midi()
252 {
253 #if 0
254     if (!midi_p_)
255         return;
256
257     if (midi_p_->outfile_str_ == "")
258         midi_p_->outfile_str_ = default_out_fn + ".midi";
259     
260     *mlog << "midi output to " << midi_p_->outfile_str_ << " ...\n";    
261     Midi_output(this, midi_p_);
262 #endif
263 }
264