]> git.donarmstrong.com Git - lilypond.git/blobdiff - src/score.cc
partial: 0.0.39-1.jcn
[lilypond.git] / src / score.cc
index 60ab3931f9f35a4d204203a72d5abb095654a105..0dd16ecbf729cb28f82a248b6d91e3141f245899 100644 (file)
-#include "staffcommands.hh"
-#include "tstream.hh"
-#include "getcommand.hh"
-#include "inputcommands.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::setup_music()
+{
+    *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();
+   }
+}
 
 void
 Score::process()
 {
-    *mlog << "Processing ... ";
-    
-    if (!paper_)
-       paper_ = new Paperdef;
+    setup_music();
+
+    paper();
+    midi();
+}
+
+void
+Score::paper()
+{
+    if (!paper_p_)
+       return;
     
-    /// distribute commands to disciples
-    distribute_commands();
+    pscore_p_ = new PScore(paper_p_);
+
+    find_col(0, false)->set_breakable(); // ugh
+    find_col(last(), false)->set_breakable();
+    do_cols();
     
-    pscore_ = new PScore(paper_);
-    for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
-       sc->set_output(pscore_);
-       sc->process();
-    }
+    for (iter_top(staffs_,i); i.ok(); i++) 
+       i->set_output(pscore_p_);
 
-    // do this after processing, staffs first have to generate PCols.
-    do_pcols();
+    
+    process_music();
+    clean_cols();    // can't move clean_cols() farther up.
+    print();
     calc_idealspacing();
-    clean_cols();              // ugh. Would want to clean the columns before anything else.
-
 
+    // debugging
     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 * > sc(staffs_); sc.ok(); sc++)
-       sc->clean_cols();
-    
-    for (PCursor<Score_column*> c(cols_); c.ok(); ) {
-       if (!c->pcol_->used()) {
-           mtor << "removing : ";
-           c->print();
-           c.del();
-       } else
+{
+    for (iter_top(staffs_,i); i.ok(); i++)
+       i->clean_cols();
+
+    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*> scc(cols_);
+    iter_top(cols_,i);
 
-    for (; scc.ok(); scc++) {
-       assert(scc->when != w);
-       if (scc->when > w)
+    for (; i.ok(); i++) {
+       assert(i->when() != w);
+       if (i->when() > w)
            break;
     }
 
-    if (!scc.ok()) {
+    if (!i.ok()) {
        cols_.bottom().add(c1);
        cols_.bottom().add(c2);
-       scc = cols_.bottom();
-       scc --;
+       i = cols_.bottom();
+       i --;
     } else {
-       scc.insert(c1);
-       scc.insert(c2);
-       scc -= 2;
+       i.insert(c1);
+       i.insert(c2);
+       i -= 2;
     }
-    return scc;
+    return i;
 }
 
 PCursor<Score_column*>
-Score::find_col(Real w,bool mus)
+Score::find_col(Moment w, bool mus)
 {
-    PCursor<Score_column*> scc(cols_);
-    for (; scc.ok(); scc++) {
-       if (scc->when == w && scc->musical == mus)
-           return scc;
-       if (scc->when > w)
+    iter_top( cols_,i);
+    
+    for (; i.ok(); i++) {
+       if (i->when() == w && i->musical_b_ == mus)
+           return i;
+       if (i->when() > w)
            break;
     }
-    scc = create_cols(w);
+    i = create_cols(w);
     if (mus)
-       scc++;
-    return scc;
+       i++;
+    return i;
 }
 
 void
-Score::distribute_commands()
+Score::do_cols()    
 {
-    for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
-       sc->process_input_commands(input_commands_, last());
+    iter_top(cols_,i);
+    for (; i.ok(); i++) {
+       pscore_p_->add(i->pcol_l_);
     }
 }
-void
-Score::add(Staff*s)
-{
-    s->score_ = this;
-    staffs_.bottom().add(s);    
-}
 
+Moment
+Score::last() const
+{    
+    Moment l = 0;
+    for (iter_top(staffs_,i); i.ok(); i++) {
+       l = l>? i->last();
+    }
+    return l;
+}
 
 void
-Score::do_pcols()
+Score::set(Paper_def *pap_p)
 {
-    PCursor<Score_column*> sc(cols_);
-    for (; sc.ok(); sc++) {
-       pscore_->add(sc->pcol_);
-    }
+    delete paper_p_;
+    paper_p_ = pap_p;
 }
-Real
-Score::last() const
+
+void
+Score::set(Midi_def* midi_p)
 {    
-    Real l = 0;
-    for (PCursor<Staff*> stc(staffs_); stc.ok(); stc++) {
-       l = MAX(l, stc->last());
-    }
-    return l;
+    delete midi_p_;
+    midi_p_ = midi_p;
 }
 
 void
 Score::OK() const
 {
 #ifndef NDEBUG
-    for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
-       sc->OK();
-       assert(sc->score_ == this);
+    for (iter_top(staffs_,i); i.ok(); i++) {
+       i->OK();
+       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    
 }
@@ -169,53 +213,76 @@ Score::print() const
 {
 #ifndef NPRINT
     mtor << "score {\n"; 
-    for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
-       sc->print();
+    for (iter_top(staffs_,i); i.ok(); i++) {
+       i->print();
     }
-    for (PCursor<Score_column*> sc(cols_); sc.ok(); sc++) {
-       sc->print();
+    for (iter_top(cols_,i); i.ok(); i++) {
+       i->print();
     }
+    if (pscore_p_)
+       pscore_p_->print();
+    if (midi_p_)
+       midi_p_->print();
+    
     mtor << "}\n";
 #endif
 }
 
 Score::Score()
 {
-    pscore_=0;
-    paper_ = 0;
+    pscore_p_=0;
+    paper_p_ = 0;
+    midi_p_ = 0;
+    errorlevel_i_ = 0;
+    defined_ch_c_l_ = 0;
 }
 
 Score::~Score()
 {
-    delete pscore_;
-    for (int i=0; i<input_commands_.sz(); i++)
-       delete input_commands_[i];    
-    delete paper_;
+    delete pscore_p_;
+    delete paper_p_;
+    delete midi_p_;
 }
+
 void
-Score::set(Paperdef*p)
+Score::paper_output()
 {
-    delete paper_;
-    paper_ = p;
+    OK();
+    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";
+    
+    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::output(String s)
+Score::midi()
 {
-    OK();
-    if (paper_->outfile=="")
-       paper_->outfile = s;
+    if (!midi_p_)
+       return;
+
+    if (midi_p_->outfile_str_ == "")
+       midi_p_->outfile_str_ = default_out_fn + ".midi";
     
-    *mlog << "output to " << paper_->outfile << "...\n";
-    Tex_stream the_output(paper_->outfile);    
-    pscore_->output(the_output);
+    *mlog << "midi output to " << midi_p_->outfile_str_ << " ...\n";    
+    Midi_output(this, midi_p_);
 }
 
-
 void
-Score::add(svec<Command*> &s)
+Score::add(Staff*s)
 {
-    input_commands_.add(get_reset_command());
-    input_commands_.concat(s);
+    s->score_l_ = this;
+    staffs_.bottom().add(s);
 }
-