]> git.donarmstrong.com Git - lilypond.git/blobdiff - src/score.cc
partial: 0.0.39-1.jcn
[lilypond.git] / src / score.cc
index feb7db93e727438e65c1a1b176001a5efe5cd350..0dd16ecbf729cb28f82a248b6d91e3141f245899 100644 (file)
-#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)
@@ -62,8 +117,8 @@ 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);
 
@@ -87,11 +142,12 @@ Score::create_cols(Moment w)
 }
 
 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;
@@ -103,14 +159,14 @@ Score::find_col(Moment w,bool mus)
 }
 
 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
 {    
@@ -121,6 +177,20 @@ 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
 {
@@ -151,45 +221,64 @@ Score::print() 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)
@@ -197,17 +286,3 @@ 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];
-    }
-}