-#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 music ... ";
-
- assert (paper_p_);
+ *mlog << "\nSetting up music ..." << flush;
if (last() == Moment(0)) {
- error("Need to have music in a score.");
+ errorlevel_i_ |= 1;
+ error("Need to have music in a score.", defined_ch_c_l_);
}
- // distribute commands to disciples
- pscore_p_ = new PScore(paper_p_);
+
for (iter_top(staffs_,i); i.ok(); i++) {
- i->truncate_cols(last());
- i->set_output(pscore_p_);
- i->process();
+ i->setup_staffcols();
+ i->OK();
}
+}
+
+void
+Score::process_music()
+{
+ *mlog << "Processing music ..." << flush;
+ for (Score_walker w(this); w.ok(); w++) {
+ w.process();
+ }
+}
+
+void
+Score::process()
+{
+ setup_music();
+
+ paper();
+ midi();
+}
+
+void
+Score::paper()
+{
+ if (!paper_p_)
+ return;
+
+ pscore_p_ = new PScore(paper_p_);
- // do this after processing, staffs first have to generate PCols.
+ 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
OK();
- pscore_p_->process();
- *mlog << "\n";
+ *mlog << endl;
+ pscore_p_->process();
+
+ // output
+ paper_output();
+
}
-// remove empty cols.
+/**
+ Remove empty cols, preprocess other columns.
+ */
void
Score::clean_cols()
-{
+{
for (iter_top(staffs_,i); i.ok(); i++)
i->clean_cols();
-
+
for (iter_top(cols_,c); c.ok(); ) {
- if (!c->pcol_l_->used()) {
- delete c.get();
+ if (!c->pcol_l_->used_b()) {
+ delete c.get_p();
} else {
c->preprocess();
c++;
}
}
}
-/*
+
+/**
+ 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
*/
PCursor<Score_column*>
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;
iter_top(cols_,i);
}
PCursor<Score_column*>
-Score::find_col(Moment w,bool mus)
+Score::find_col(Moment w, bool mus)
{
- iter_top(cols_,i);
+ 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)
break;
}
void
-Score::do_cols()
+Score::do_cols()
{
iter_top(cols_,i);
for (; i.ok(); i++) {
pscore_p_->add(i->pcol_l_);
}
- clean_cols(); // can't move clean_cols() farther up.
}
+
Moment
Score::last() const
{
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
{
}
if (pscore_p_)
pscore_p_->print();
+ if (midi_p_)
+ midi_p_->print();
mtor << "}\n";
#endif
}
-Score::Score(Paperdef*p)
+Score::Score()
{
pscore_p_=0;
- paper_p_ = p; // ?? safe?
+ paper_p_ = 0;
+ midi_p_ = 0;
errorlevel_i_ = 0;
+ defined_ch_c_l_ = 0;
}
Score::~Score()
{
delete pscore_p_;
delete paper_p_;
+ delete midi_p_;
}
void
-Score::output(String s)
+Score::paper_output()
{
OK();
if (paper_p_->outfile=="")
- paper_p_->outfile = s;
-
+ 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 << "output to " << paper_p_->outfile << "...\n";
+ *mlog << "TeX output to " << paper_p_->outfile << " ...\n";
Tex_stream the_output(paper_p_->outfile);
- the_output << "% outputting Score, defined at: " << define_spot_str_ << "\n";
+
+ 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_l_ = this;
staffs_.bottom().add(s);
}
-
-void
-Score::add_marks(Array<String> s_arr, Array<Moment> m_arr)
-{
- for (int i=0; i < s_arr.size(); i++) {
- String mark_str (s_arr[i]);
- if (markers_assoc_.elt_query(mark_str) &&
- m_arr[i] != markers_assoc_[mark_str])
-
- error("Conflicting marker: `" + s_arr[i]+ "\'");
- else
- markers_assoc_[s_arr[i]] = m_arr[i];
- }
-}