]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-0.0.39
authorfred <fred>
Wed, 5 Mar 1997 16:57:31 +0000 (16:57 +0000)
committerfred <fred>
Wed, 5 Mar 1997 16:57:31 +0000 (16:57 +0000)
lily/midi-item.cc [new file with mode: 0644]
lily/score-walker.cc [new file with mode: 0644]
lily/slur-reg.cc [new file with mode: 0644]
lily/template1.cc [new file with mode: 0644]
lily/warn.cc [new file with mode: 0644]

diff --git a/lily/midi-item.cc b/lily/midi-item.cc
new file mode 100644 (file)
index 0000000..51ba40d
--- /dev/null
@@ -0,0 +1,228 @@
+//
+// midiitem.cc
+//
+// source file of the LilyPond music typesetter
+//
+// (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include <limits.h>
+#include "proto.hh"
+#include "plist.hh"
+#include "pcol.hh"
+#include "debug.hh"
+#include "misc.hh"
+#include "string.hh"
+#include "string-convert.hh"
+#include "request.hh"
+#include "musicalrequest.hh"
+#include "voice.hh"
+#include "midi-item.hh"
+#include "midi-stream.hh"
+
+Midi_chunk::Midi_chunk()
+{
+}
+
+void
+Midi_chunk::add( String str )
+{
+    data_str_ += str;
+}
+
+void
+Midi_chunk::set( String header_str, String data_str, String footer_str )
+{
+    data_str_ = data_str;
+    footer_str_ = footer_str;
+    header_str_ = header_str;
+}
+  
+String
+Midi_chunk::str() const
+{
+    String str = header_str_;
+    String length_str = String_convert::i2hex_str( data_str_.length_i() + footer_str_.length_i(), 8, '0' );
+    length_str = String_convert::hex2bin_str( length_str );
+    str += length_str;
+    str += data_str_;
+    str += footer_str_;
+    return str;
+}
+
+Midi_duration::Midi_duration( Real seconds_f )
+{
+    seconds_f_ = seconds_f;
+}
+
+String
+Midi_duration::str() const
+{
+    return String( "<duration: " ) + String( seconds_f_ ) + ">";
+}
+
+Midi_header::Midi_header( int format_i, int tracks_i, int clocks_per_4_i )
+{
+    String str;
+       
+    String format_str = String_convert::i2hex_str( format_i, 4, '0' );
+    str += String_convert::hex2bin_str( format_str );
+       
+    String tracks_str = String_convert::i2hex_str( tracks_i, 4, '0' );
+    str += String_convert::hex2bin_str( tracks_str );
+
+    String tempo_str = String_convert::i2hex_str( clocks_per_4_i, 4, '0' );
+    str += String_convert::hex2bin_str( tempo_str );
+
+    set( "MThd", str, "" );
+}
+
+String
+Midi_item::i2varint_str( int i )
+{
+    int buffer_i = i & 0x7f;
+    while ( (i >>= 7) > 0 ) {
+       buffer_i <<= 8;
+       buffer_i |= 0x80;
+       buffer_i += (i & 0x7f);
+    }
+
+    String str;
+    while ( 1 ) {
+       str += (char)buffer_i;
+       if ( buffer_i & 0x80 )
+           buffer_i >>= 8;
+       else
+           break;
+    }
+    return str;
+}
+
+void 
+Midi_item::output_midi( Midi_stream& midi_stream_r ) const
+{
+    midi_stream_r << str();
+}
+
+Midi_key::Midi_key( int accidentals_i, int minor_i )
+{
+       accidentals_i_ = accidentals_i;
+       minor_i_ = minor_i;
+}
+
+String
+Midi_key::str() const
+{
+    String str = "ff5902";
+    str += String_convert::i2hex_str( accidentals_i_, 2, '0' );
+    str += String_convert::i2hex_str( minor_i_, 2, '0' );
+    return String_convert::hex2bin_str( str );
+}
+
+Midi_note::Midi_note( Melodic_req* melreq_l, int channel_i, bool on_bo  )
+{
+    assert(melreq_l);
+    pitch_i_ = melreq_l->pitch() + c0_pitch_i_c_;   
+    channel_i_ = channel_i;
+
+    // poor man-s staff dynamics:
+    dynamic_byte_ =  (melreq_l)? 0x64 - 0x10 * channel_i_:0;
+    on_b_ = on_bo;
+}
+
+String
+Midi_note::str() const
+{
+    if ( pitch_i_ != INT_MAX ) {
+       Byte status_byte = ( on_b_ ? 0x90 : 0x80 ) + channel_i_;
+       String str = String( (char)status_byte );
+       str += (char)pitch_i_;
+       // poor man-s staff dynamics:
+       str += (char)dynamic_byte_;
+       return str;
+    }
+    return String( "" );
+}
+
+Midi_tempo::Midi_tempo( int per_minute_4_i )
+{
+    per_minute_4_i_ = per_minute_4_i;
+}
+
+String
+Midi_tempo::str() const
+{
+    int useconds_per_4_i = 60 * (int)1e6 / per_minute_4_i_;
+    String str = "ff5103";
+    str += String_convert::i2hex_str( useconds_per_4_i, 6, '0' );
+    return String_convert::hex2bin_str( str );
+}
+
+Midi_text::Midi_text( Midi_text::Type type, String text_str )
+{
+       type_ = type;
+       text_str_ = text_str;
+}
+
+String
+Midi_text::str() const
+{
+       String str = "ff" + String_convert::i2hex_str( type_, 2, '0' );
+       str = String_convert::hex2bin_str( str );
+       str += i2varint_str( text_str_.length_i() );
+       str += text_str_;
+       return str;
+}
+
+Midi_track::Midi_track( int number_i )
+{
+//                4D 54 72 6B     MTrk
+//                00 00 00 3B     chunk length (59)
+//        00      FF 58 04 04 02 18 08    time signature
+//        00      FF 51 03 07 A1 20       tempo
+// FF 59 02 sf mi  Key Signature
+//         sf = -7:  7 flats
+//         sf = -1:  1 flat
+//         sf = 0:  key of C
+//         sf = 1:  1 sharp
+//         sf = 7: 7 sharps
+//         mi = 0:  major key
+//         mi = 1:  minor key
+
+    number_i_ = number_i;
+       
+    char const* data_ch_c_l = "00" "ff58" "0404" "0218" "08"
+//     "00" "ff51" "0307" "a120"
+// why a key at all, in midi?
+// key: C
+//     "00" "ff59" "02" "00" "00"
+// key: F (scsii-menuetto)
+//                               "00" "ff59" "02" "ff" "00"
+       ;
+
+    String data_str;
+    // only for format 0 (currently using format 1)?
+    data_str += String_convert::hex2bin_str( data_ch_c_l );
+
+    char const* footer_ch_c_l = "00" "ff2f" "00";
+    String footer_str = String_convert::hex2bin_str( footer_ch_c_l );
+
+    set( "MTrk", data_str, footer_str );
+}
+
+void 
+Midi_track::add( int delta_time_i, String event_str )
+{
+    assert(delta_time_i >= 0);
+    Midi_chunk::add( i2varint_str( delta_time_i ) + event_str );
+}
+
+void 
+Midi_track::add( Moment delta_time_moment, Midi_item* mitem_l )
+{
+    // use convention of 384 clocks per 4
+    // use Duration_convert
+    int delta_time_i = delta_time_moment * Moment( 384 ) / Moment( 1, 4 );
+    add( delta_time_i, mitem_l->str() );
+}
+
diff --git a/lily/score-walker.cc b/lily/score-walker.cc
new file mode 100644 (file)
index 0000000..d011c33
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+  score-walker.cc -- implement Score_walker
+
+  source file of the LilyPond music typesetter
+
+  (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+#include "proto.hh"
+#include "plist.hh"
+#include "debug.hh"
+#include "score-walker.hh"
+#include "score.hh"
+#include "staff-walker.hh"
+#include "staff.hh"
+#include "score-column.hh"
+
+Score_walker::Score_walker(Score *s)
+    :PCursor<Score_column *> (s->cols_)
+{
+    score_l_ = s;
+    for (iter_top(s->staffs_,i); i.ok(); i++) {
+       Staff_walker* w_p=i->get_walker_p();
+       w_p->score_walk_l_ =this;
+       walker_p_arr_.push(w_p);
+    }
+
+    if(ok()) {
+       s->find_col(0, false)->set_breakable();
+       s->find_col(s->last(), false)->set_breakable();
+    }
+    reinit();
+}
+
+
+void
+Score_walker::reinit()
+{
+    disallow_break_walk_l_arr = walker_p_arr_;
+    disallow_break_count_ = disallow_break_walk_l_arr.size();
+}
+
+
+/** Advance the cursor, and all Staff_walkers contained in this. Reset
+  runtime fields */
+void 
+Score_walker::operator ++(int )
+{
+    Moment last = ptr()->when();
+    
+    PCursor<Score_column *>::operator++(0);
+    if (ok() && ptr()->when() == last)
+       PCursor<Score_column *>::operator++(0);
+    reinit();
+    if (!ok())
+       return;
+    for (int i=0; i< walker_p_arr_.size(); i++) {
+       if (walker_p_arr_[i]->ok() &&
+           walker_p_arr_[i]->when() < when()) {
+
+           walker_p_arr_[i]->operator++(0);
+       }
+    }
+}
+
+/** Allow the command_column to be breakable for one staff. If all
+  staffs allow, then allow a break here.  */
+void
+Score_walker::allow_break(Staff_walker*w)
+{
+    for (int i=0; i < disallow_break_walk_l_arr.size(); i++) {
+       if (w == disallow_break_walk_l_arr[i]) {
+           disallow_break_count_ --;
+           disallow_break_walk_l_arr[i] =0;
+
+           if (!disallow_break_count_) {
+               PCursor<Score_column*> col_cursor = *this;
+               if (ptr()->musical_b())
+                   col_cursor --;
+               col_cursor->set_breakable();
+           }
+       }
+    }
+}
+
+Moment
+Score_walker::when()
+{
+    return ptr()->when();
+}
+
+void
+Score_walker::process()
+{
+    for (int i=0; i < walker_p_arr_.size(); i++) {
+       Staff_walker *w = walker_p_arr_[i];
+       if ( w->ok() && w->when() == when() ) {
+           walker_p_arr_[i]->process();
+       }
+    }
+    if (when().denominator() == 1) {
+       *mlog << "." <<flush;
+    }
+}
+
+Score_walker::~Score_walker()
+{
+    for (int i=0; i < walker_p_arr_.size(); i++) 
+       delete walker_p_arr_[i];
+    assert( !score_l_->find_col(score_l_->last(), true)->used_b());
+}
+
+
diff --git a/lily/slur-reg.cc b/lily/slur-reg.cc
new file mode 100644 (file)
index 0000000..f2b7113
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+  slur-reg.cc -- implement Slur_register
+
+  (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+#include "proto.hh"
+#include "plist.hh"
+#include "musicalrequest.hh"
+#include "complex-walker.hh"
+#include "slur-reg.hh"
+#include "slur.hh"
+#include "debug.hh"
+#include "notehead.hh"
+
+void
+Slur_register::set_feature(Features i)
+{
+    dir_i_ = i.direction_i_;
+}
+
+Slur_register::Slur_register()
+{
+    set_feature(Features::dir(0));
+}
+
+bool
+Slur_register::try_request(Request *req_l)
+{
+    if(!req_l->slur())
+       return false;
+
+    new_slur_req_l_arr_.push(req_l->slur());
+    return true;
+}
+
+void
+Slur_register::acknowledge_element(Staff_elem_info info)
+{
+    if (info.elem_p_->name() == Notehead::static_name()) { 
+       Notehead *head_p =(Notehead*) info.elem_p_ ;// ugh
+       for (int i = 0; i < slur_l_stack_.size(); i++)
+           slur_l_stack_[i]->add(head_p );
+       for (int i = 0; i < end_slur_l_arr_.size(); i++)
+           end_slur_l_arr_[i]->add(head_p);
+    }
+}
+/*
+  abracadabra
+  */
+void
+Slur_register::process_requests()
+{
+    Array<Slur*> start_slur_l_arr_;
+    for (int i=0; i< new_slur_req_l_arr_.size(); i++) {
+       Slur_req* slur_req_l = new_slur_req_l_arr_[i];
+       // end slur: move the slur to other array
+       if (slur_req_l->spantype == Span_req::STOP) {
+           if (slur_l_stack_.empty())
+               warning("can't find slur to end",
+                     slur_req_l->defined_ch_c_l_);
+           else {
+               end_slur_l_arr_.push(slur_l_stack_.pop());
+               requests_arr_.pop();
+           }
+       } else  if (slur_req_l->spantype == Span_req::START) {
+           // push a new slur onto stack.
+           //(use temp. array to wait for all slur STOPs)
+           Slur * s_p =new Slur;
+           requests_arr_.push(slur_req_l);
+           start_slur_l_arr_.push(s_p);
+           announce_element(Staff_elem_info(s_p, slur_req_l));
+       }
+    }
+    for (int i=0; i < start_slur_l_arr_.size(); i++)
+       slur_l_stack_.push(start_slur_l_arr_[i]);
+}
+
+void
+Slur_register::pre_move_processing()
+{
+    for (int i = 0; i < end_slur_l_arr_.size(); i++) {
+       if (dir_i_) 
+           end_slur_l_arr_[i]->dir_i_ = dir_i_;
+       typeset_element(end_slur_l_arr_[i]);
+    }
+    end_slur_l_arr_.set_size(0);
+}
+
+void
+Slur_register::post_move_processing()
+{
+    new_slur_req_l_arr_.set_size(0);
+}
+Slur_register::~Slur_register()
+{
+    for (int i=0; i < requests_arr_.size(); i++) {
+       warning("unterminated slur", requests_arr_[i]->defined_ch_c_l_);
+    }
+}
diff --git a/lily/template1.cc b/lily/template1.cc
new file mode 100644 (file)
index 0000000..5aa1906
--- /dev/null
@@ -0,0 +1,25 @@
+#include "proto.hh"
+#include "idealspacing.hh"
+#include "plist.hh"
+#include "pcol.hh"
+#include "item.hh"
+#include "musicalrequest.hh"
+#include "spanner.hh"
+#include "scoreline.hh" 
+#include "staffline.hh"
+
+#include "pcursor.tcc"
+#include "plist.tcc"
+
+
+#define IPLC_instantiate(a) IPL_instantiate(a); PL_instantiate(const a)
+
+
+IPLC_instantiate(Line_of_score);
+IPLC_instantiate(Line_of_staff);
+IPLC_instantiate(Item);
+IPLC_instantiate(Spanner);
+IPLC_instantiate(PStaff);
+IPLC_instantiate(Idealspacing);
+IPLC_instantiate(PCol);
+
diff --git a/lily/warn.cc b/lily/warn.cc
new file mode 100644 (file)
index 0000000..ad548c6
--- /dev/null
@@ -0,0 +1,81 @@
+#include "proto.hh"
+#include "plist.hh"
+#include "debug.hh"
+#include "lexer.hh"
+#include "moment.hh"
+#include "time-description.hh"
+#include "source-file.hh"
+#include "source.hh"
+#include "main.hh"
+
+ostream &warnout (cerr);
+ostream *mlog(&cerr);
+/*
+void
+warning(String s)
+{
+    WARN << s;
+}
+*/
+
+void
+error(String s)
+{
+    if (busy_parsing())
+       yyerror(s);
+    else
+       cerr <<  "error: " << s << "\n";
+       
+    exit(1);
+}
+
+void
+error_t(const String& s, const Moment& r)
+{
+    String t_mom = String(trunc(r)) + String(r - Moment(trunc(r)));
+    String e=s+ " (t = " +  t_mom + ")";
+    error(e);
+}
+
+void
+error_t(const String& s, Time_description const &t_tdes)
+{
+    String e=s+ " (at t=" + String(t_tdes.bars_i_) + ": " + String(t_tdes.whole_in_measure_) + ")\n";
+    error(e);
+}
+
+void
+message( String message_str, char const* context_ch_c_l )
+{
+    String str = "lilypond: ";
+    Source_file* sourcefile_l = source_l_g->sourcefile_l( context_ch_c_l );
+    if ( sourcefile_l ) {
+       str += sourcefile_l->file_line_no_str(context_ch_c_l) + String(": ");
+    }
+    str += message_str;
+    if ( sourcefile_l ) {
+       str += ":\n";
+       str += sourcefile_l->error_str( context_ch_c_l );
+    }
+    if ( busy_parsing() )
+       cerr << endl;
+    cerr << str << endl;
+}
+
+void
+warning( String message_str, char const* context_ch_c_l )
+{
+    message( "warning: " + message_str, context_ch_c_l );
+}
+
+void
+error( String message_str, char const* context_ch_c_l )
+{
+    message( message_str, context_ch_c_l );
+    // since when exits error again?
+    // i-d say: error: errorlevel |= 1; -> no output upon error
+    //          warning: recovery -> output (possibly wrong)
+    if ( lexer )
+        lexer->errorlevel_i_ |= 1;
+//    exit( 1 );
+}