-#include "tstream.hh"
+/*
+ score.cc -- implement Score
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+#include "tex-stream.hh"
#include "score.hh"
-#include "sccol.hh"
+#include "score-column.hh"
#include "pscore.hh"
#include "staff.hh"
#include "debug.hh"
-#include "paper.hh"
+#include "paper-def.hh"
+#include "main.hh"
+#include "source.hh"
+#include "source-file.hh"
+#include "score-walker.hh"
+#include "midi-output.hh"
+#include "midi-def.hh"
+extern String default_out_fn;
void
-Score::process()
+Score::setup_music()
{
- *mlog << "\nProcessing ... ";
-
- assert (paper_);
-
- /// distribute commands to disciples
- pscore_ = new PScore(paper_);
- for (PCursor<Staff*> i(staffs_); i.ok(); i++) {
- i->process_commands(last());
- i->set_output(pscore_);
- i->process();
+ *mlog << "\nSetting up music ..." << flush;
+ if (last() == Moment(0)) {
+ errorlevel_i_ |= 1;
+ error("Need to have music in a score.", defined_ch_c_l_);
+ }
+
+ for (iter_top(staffs_,i); i.ok(); i++) {
+ i->setup_staffcols();
+ i->OK();
}
+}
+
+void
+Score::process_music()
+{
+ *mlog << "Processing music ..." << flush;
+ for (Score_walker w(this); w.ok(); w++) {
+ w.process();
+ }
+}
- // do this after processing, staffs first have to generate PCols.
- do_pcols();
+void
+Score::process()
+{
+ setup_music();
+
+ paper();
+ midi();
+}
+
+void
+Score::paper()
+{
+ if (!paper_p_)
+ return;
+
+ pscore_p_ = new PScore(paper_p_);
- clean_cols(); // can't move this farther up.
+ find_col(0, false)->set_breakable(); // ugh
+ find_col(last(), false)->set_breakable();
+ do_cols();
+
+ for (iter_top(staffs_,i); i.ok(); i++)
+ i->set_output(pscore_p_);
+
+ process_music();
+ clean_cols(); // can't move clean_cols() farther up.
+ print();
calc_idealspacing();
// debugging
- print ();
OK();
+ *mlog << endl;
+ pscore_p_->process();
- pscore_->preprocess();
- *mlog << "Calculating ... ";
- pscore_->calc_breaking();
- *mlog << "Postprocessing ... ";
- pscore_->postprocess();
-
- // TODO: calculate vertical structs?
- // TODO: calculate mixed structs.?
- *mlog << "\n";
+ // output
+ paper_output();
+
}
-// remove empty cols.
+/**
+ Remove empty cols, preprocess other columns.
+ */
void
Score::clean_cols()
-{
- for (PCursor<Staff * > i(staffs_); i.ok(); i++)
+{
+ for (iter_top(staffs_,i); i.ok(); i++)
i->clean_cols();
-
- for (PCursor<Score_column*> c(cols_); c.ok(); ) {
- if (!c->pcol_->used()) {
- c.del();
+
+ for (iter_top(cols_,c); c.ok(); ) {
+ if (!c->pcol_l_->used_b()) {
+ delete c.get_p();
} else {
c->preprocess();
c++;
}
}
-
- pscore_->clean_cols();
}
-/*
+
+/**
+ Create columns at time #w#.
this sux. We should have Score_column create the appropriate PCol.
- Unfortunately, PCols don't know about their position.
+ Unfortunately, PCols don't know about their position.
+
+ @return cursor pointing to the nonmusical (first) column
*/
-// todo
PCursor<Score_column*>
-Score::create_cols(Real w)
+Score::create_cols(Moment w)
{
Score_column* c1 = new Score_column(w);
Score_column* c2 = new Score_column(w);
- c1->musical = false;
- c2->musical = true;
+ c1->musical_b_ = false;
+ c2->musical_b_ = true;
- PCursor<Score_column*> i(cols_);
+ iter_top(cols_,i);
for (; i.ok(); i++) {
- assert(i->when != w);
- if (i->when > w)
+ assert(i->when() != w);
+ if (i->when() > w)
break;
}
}
PCursor<Score_column*>
-Score::find_col(Real w,bool mus)
+Score::find_col(Moment w, bool mus)
{
- PCursor<Score_column*> i(cols_);
+ iter_top( cols_,i);
+
for (; i.ok(); i++) {
- if (i->when == w && i->musical == mus)
+ if (i->when() == w && i->musical_b_ == mus)
return i;
- if (i->when > w)
+ if (i->when() > w)
break;
}
i = create_cols(w);
}
void
-Score::do_pcols()
+Score::do_cols()
{
- PCursor<Score_column*> i(cols_);
+ iter_top(cols_,i);
for (; i.ok(); i++) {
- pscore_->add(i->pcol_);
+ pscore_p_->add(i->pcol_l_);
}
}
-Real
+
+Moment
Score::last() const
{
- Real l = 0;
- for (PCursor<Staff*> i(staffs_); i.ok(); i++) {
- l = MAX(l, i->last());
+ Moment l = 0;
+ for (iter_top(staffs_,i); i.ok(); i++) {
+ l = l>? i->last();
}
return l;
}
+void
+Score::set(Paper_def *pap_p)
+{
+ delete paper_p_;
+ paper_p_ = pap_p;
+}
+
+void
+Score::set(Midi_def* midi_p)
+{
+ delete midi_p_;
+ midi_p_ = midi_p;
+}
+
void
Score::OK() const
{
#ifndef NDEBUG
- for (PCursor<Staff*> i(staffs_); i.ok(); i++) {
+ for (iter_top(staffs_,i); i.ok(); i++) {
i->OK();
- assert(i->score_ == this);
+ assert(i->score_l_ == this);
}
staffs_.OK();
cols_.OK();
- for (PCursor<Score_column*> cc(cols_); cc.ok() && (cc+1).ok(); cc++) {
- assert(cc->when <= (cc+1)->when);
+ for (iter_top(cols_,cc); cc.ok() && (cc+1).ok(); cc++) {
+ assert(cc->when() <= (cc+1)->when());
}
#endif
}
{
#ifndef NPRINT
mtor << "score {\n";
- for (PCursor<Staff*> i(staffs_); i.ok(); i++) {
+ for (iter_top(staffs_,i); i.ok(); i++) {
i->print();
}
- for (PCursor<Score_column*> i(cols_); i.ok(); i++) {
+ for (iter_top(cols_,i); i.ok(); i++) {
i->print();
}
- if (pscore_)
- pscore_->print();
+ if (pscore_p_)
+ pscore_p_->print();
+ if (midi_p_)
+ midi_p_->print();
mtor << "}\n";
#endif
}
-Score::Score(Paperdef*p)
+Score::Score()
{
- pscore_=0;
- paper_ = p;
+ pscore_p_=0;
+ paper_p_ = 0;
+ midi_p_ = 0;
+ errorlevel_i_ = 0;
+ defined_ch_c_l_ = 0;
}
Score::~Score()
{
- delete pscore_;
+ delete pscore_p_;
+ delete paper_p_;
+ delete midi_p_;
}
void
-Score::output(String s)
+Score::paper_output()
{
OK();
- if (paper_->outfile=="")
- paper_->outfile = s;
+ if (paper_p_->outfile=="")
+ paper_p_->outfile = default_out_fn + ".out";
+
+ if ( errorlevel_i_ ) {
+ *mlog << "lilypond: warning: no output to: " << paper_p_->outfile
+ << " (errorlevel=" << errorlevel_i_ << ")" << endl;
+ return;
+ }
+
+ *mlog << "TeX output to " << paper_p_->outfile << " ...\n";
- *mlog << "output to " << paper_->outfile << "...\n";
- Tex_stream the_output(paper_->outfile);
- pscore_->output(the_output);
+ Tex_stream the_output(paper_p_->outfile);
+
+ the_output << "% outputting Score, defined at: " <<
+ source_l_g->
+ sourcefile_l (defined_ch_c_l_)->file_line_no_str(defined_ch_c_l_) << "\n";
+ pscore_p_->output(the_output);
}
+void
+Score::midi()
+{
+ if (!midi_p_)
+ return;
+ if (midi_p_->outfile_str_ == "")
+ midi_p_->outfile_str_ = default_out_fn + ".midi";
+
+ *mlog << "midi output to " << midi_p_->outfile_str_ << " ...\n";
+ Midi_output(this, midi_p_);
+}
void
Score::add(Staff*s)
{
- s->score_ = this;
+ s->score_l_ = this;
staffs_.bottom().add(s);
}
-