]> git.donarmstrong.com Git - lilypond.git/commitdiff
partial: 0.1.8.jcn
authorJan Nieuwenhuizen <janneke@gnu.org>
Fri, 15 Aug 1997 11:50:30 +0000 (13:50 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Fri, 15 Aug 1997 11:50:30 +0000 (13:50 +0200)
13 files changed:
mi2mu/include/mi2mu-global.hh [new file with mode: 0644]
mi2mu/include/mudela-column.hh [new file with mode: 0644]
mi2mu/include/mudela-item.hh [new file with mode: 0644]
mi2mu/include/mudela-score.hh [new file with mode: 0644]
mi2mu/include/mudela-staff.hh [new file with mode: 0644]
mi2mu/include/mudela-stream.hh [new file with mode: 0644]
mi2mu/include/mudela-voice.hh [new file with mode: 0644]
mi2mu/mudela-column.cc [new file with mode: 0644]
mi2mu/mudela-item.cc [new file with mode: 0644]
mi2mu/mudela-score.cc [new file with mode: 0644]
mi2mu/mudela-staff.cc [new file with mode: 0644]
mi2mu/mudela-stream.cc [new file with mode: 0644]
mi2mu/mudela-voice.cc [new file with mode: 0644]

diff --git a/mi2mu/include/mi2mu-global.hh b/mi2mu/include/mi2mu-global.hh
new file mode 100644 (file)
index 0000000..cb577d0
--- /dev/null
@@ -0,0 +1,32 @@
+//
+// mi2mu-global.hh -- declare global (sic) stuff for mi2mu
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef MI2MU_GLOBAL_HH
+#define MI2MU_GLOBAL_HH
+
+#include "string.hh"
+#include "proto.hh"
+
+#define monitor_p_g &cout
+enum Verbose { QUIET_ver, BRIEF_ver, NORMAL_ver, VERBOSE_ver, DEBUG_ver };
+extern Verbose level_ver;
+#if 0 // NPRINT
+    // not what i want, all output goes through tors.
+    // set verbosity level.
+    #define LOGOUT(threshold) if  (0) *monitor_p_g
+#else
+    #define LOGOUT(threshold) if  (level_ver >= threshold) *monitor_p_g
+#endif
+
+extern Sources* source_l_g;
+// huh?
+void message (String message_str); //, char const* context_ch_C);
+void warning (String message_str); //, char const* context_ch_C);
+void error (String message_str); //, char const* context_ch_C);
+
+String mi2mu_version_str();
+
+#endif // MI2MU_GLOBAL_HH
+
diff --git a/mi2mu/include/mudela-column.hh b/mi2mu/include/mudela-column.hh
new file mode 100644 (file)
index 0000000..24d5196
--- /dev/null
@@ -0,0 +1,29 @@
+//
+// mudela-column.hh -- declare Mudela_column
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef MUDELA_COLUMN_HH
+#define MUDELA_COLUMN_HH
+
+#include "proto.hh"
+#include "mi2mu-proto.hh"
+#include "moment.hh"
+#include "plist.hh"
+
+/// (mudela_column)
+class Mudela_column 
+{
+public:
+    Mudela_column (Mudela_score* mudela_score_l, Moment mom);
+
+    void add_item (Mudela_item* mudela_item_l);
+    Moment at_mom();
+
+    Link_list<Mudela_item*> mudela_item_l_list_;
+    Moment at_mom_;
+    Mudela_score* mudela_score_l_;
+};
+
+#endif // MUDELA_COLUMN_HH
+
diff --git a/mi2mu/include/mudela-item.hh b/mi2mu/include/mudela-item.hh
new file mode 100644 (file)
index 0000000..ba0d77c
--- /dev/null
@@ -0,0 +1,130 @@
+//
+// mudela-item.hh -- declare mudela_item
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef MUDELA_ITEM_HH
+#define MUDELA_ITEM_HH
+
+#include "mi2mu-proto.hh"
+#include "string.hh"
+#include "moment.hh"
+#include "duration.hh"
+
+// should these:
+// * be Mudela_items
+// * be Voice_elements/requests
+// * get a name-change
+// ?
+
+/// (mudela_item)
+class Mudela_item 
+{
+public:
+    Mudela_item (Mudela_column* mudela_column_l);
+    
+    virtual Moment at_mom();
+    virtual Moment duration_mom();
+    void output (Mudela_stream& mudela_stream_r);
+    virtual String str() = 0;
+
+    Mudela_column* mudela_column_l_;
+};
+
+class Mudela_key : public Mudela_item 
+{
+public:
+    Mudela_key (int accidentals_i, int minor_i);
+
+    String notename_str (int pitch_i);
+    virtual String str();
+
+private:
+    int accidentals_i_;
+    int minor_i_;
+    int key_i_;
+};
+
+class Mudela_meter : public Mudela_item 
+{
+public:
+    Mudela_meter (int num_i, int den_i, int division_4_i, int count_32_i);
+
+    Duration i2_dur (int time_i, int division_1_i);
+    int clocks_1_i();
+    int den_i();
+    int num_i();
+    virtual String str();
+    Moment bar_mom();
+
+private:
+    Real sync_f_;
+    Duration sync_dur_;
+    int clocks_1_i_;
+    int num_i_;
+    int den_i_;
+};
+
+class Mudela_note : public Mudela_item 
+{
+public:
+    Mudela_note (Mudela_column* mudela_column_l, int channel_i, int pitch_i, int dyn_i);
+
+    Duration duration();
+    virtual Moment duration_mom();
+    virtual String str();
+    
+//    int const c0_pitch_i_c_ = 60; // huh?
+    int const c0_pitch_i_c_ = 48;
+
+    static bool const simple_plet_b_s = false;
+    int channel_i_;
+    int pitch_i_;
+    Mudela_column* end_column_l_;
+};
+
+class Mudela_skip : public Mudela_item 
+{
+public:
+    Mudela_skip (Mudela_column* mudela_column_l, Moment skip_mom);
+
+    Duration duration();
+    virtual Moment duration_mom();
+    virtual String str();
+
+private:
+    Moment mom_;
+};
+
+
+class Mudela_tempo : public Mudela_item 
+{
+public:
+    Mudela_tempo (int useconds_per_4_i);
+
+    int get_tempo_i (Moment moment);
+    virtual String str();
+    int useconds_per_4_i();
+
+private:
+    int useconds_per_4_i_;
+    Real seconds_per_1_f_;
+};
+
+class Mudela_text : public Mudela_item 
+{
+public:
+    enum Type { 
+       TEXT = 1, COPYRIGHT, TRACK_NAME, INSTRUMENT_NAME, LYRIC, 
+       MARKER, CUE_POINT
+    };
+    Mudela_text (Mudela_text::Type type,  String str);
+    virtual String str();
+
+private:
+    Type type_;
+    String text_str_;
+};
+
+#endif // MUDELA_ITEM_HH
+
diff --git a/mi2mu/include/mudela-score.hh b/mi2mu/include/mudela-score.hh
new file mode 100644 (file)
index 0000000..6d752fe
--- /dev/null
@@ -0,0 +1,53 @@
+//
+// mudela-score.hh -- declare Mudela_score
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef MUDELA_SCORE_HH
+#define MUDELA_SCORE_HH
+
+#include "mi2mu-proto.hh"
+#include "proto.hh"
+#include "plist.hh"
+#include "parray.hh"
+
+/// (mudela_score)
+class Mudela_score {
+public:
+    Mudela_score (int format_i, int tracks_i, int tempo_i);
+    ~Mudela_score();
+
+    void add_item (Mudela_item* mudela_item_p);
+    void add_staff (Mudela_staff* mudela_staff_p);
+
+    Mudela_column* mudela_column_l (Moment mom);
+
+    void output (String filename_str);
+    void process();
+
+    // ugh
+    Mudela_key* mudela_key_l_;
+    Mudela_meter* mudela_meter_l_;
+    Mudela_tempo* mudela_tempo_l_;
+
+private:
+    void filter_tempo();
+    void quantify_columns();
+    void quantify_durations();
+    void settle_columns();
+
+    Pointer_list<Mudela_column*> mudela_column_p_list_;
+    Pointer_list<Mudela_staff*> mudela_staff_p_list_;
+//    Link_array<Mudela_column*> column_l_array_;
+    // huh?
+    Link_array<Mudela_column> column_l_array_;
+
+// ugh, ugh, ugh
+public:
+    int format_i_;
+    int tracks_i_;
+    int tempo_i_;
+};
+
+#endif // MUDELA_SCORE_HH
+
diff --git a/mi2mu/include/mudela-staff.hh b/mi2mu/include/mudela-staff.hh
new file mode 100644 (file)
index 0000000..06fc8b2
--- /dev/null
@@ -0,0 +1,48 @@
+//
+// mudela-staff.hh -- declare mudela_staff
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef MUDELA_STAFF_HH
+#define MUDELA_STAFF_HH
+
+#include "mi2mu-proto.hh"
+#include "proto.hh"
+#include "plist.hh"
+#include "string.hh"
+
+/// (mudela_staff)
+class Mudela_staff {
+public:
+    Mudela_staff (int number_i, String copyright_str, String track_name_str, String instrument_str);
+    ~Mudela_staff();
+
+    void add_item (Mudela_item* mudela_item_p);
+    void eat_voice (Link_list<Mudela_item*>& items);
+    String id_str();
+    String name_str();
+    void output (Mudela_stream& mudela_stream_r);
+    void process();
+    void set_meter (int num_i, int den_i, int clocks_i, int count_32_i);
+    void set_tempo (int useconds_i);
+
+    String copyright_str_;
+    String instrument_str_;
+    String name_str_;
+    Mudela_meter* mudela_meter_p_;
+    Mudela_tempo* mudela_tempo_p_;
+    int number_i_;
+
+private:
+    void output_mudela_begin_bar (Mudela_stream& mudela_stream_r, Moment now_mom, int bar_i);
+#if 0
+    void output_mudela_rest (Mudela_stream& mudela_stream_r, Moment begin_mom, Moment end_mom);
+    void output_mudela_rest_remain (Mudela_stream& mudela_stream_r, Moment mom);
+#endif
+
+    Pointer_list<Mudela_voice*> mudela_voice_p_list_;
+    Pointer_list<Mudela_item*> mudela_item_p_list_;
+};
+
+#endif // MUDELA_STAFF_HH
+
diff --git a/mi2mu/include/mudela-stream.hh b/mi2mu/include/mudela-stream.hh
new file mode 100644 (file)
index 0000000..f353838
--- /dev/null
@@ -0,0 +1,40 @@
+//
+//  mudela-stream.hh -- part of LilyPond
+//
+//  copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+// should i be named Mudela_stream?
+
+#ifndef MUDELA_STREAM_HH
+#define MUDELA_STREAM_HH
+
+#include "mi2mu-proto.hh"
+#include "string.hh"
+
+/// Lily output
+class Mudela_stream {
+public:    
+    Mudela_stream (String filename_str);
+    ~Mudela_stream();
+
+    Mudela_stream& operator << (String str);
+    Mudela_stream& operator << (Mudela_item& mudela_item_r);
+
+private:
+    void handle_pending_indent();
+    void header();
+    void open();
+    void output (String str);
+    void output_wrapped (String str);
+
+    ostream* os_p_;
+    String filename_str_;
+    int indent_i_;
+    int column_i_;
+    int pending_indent_i_;
+    int wrap_column_i_;
+    bool comment_mode_b_;
+};
+
+#endif // MUDELA_STREAM_HH
+
diff --git a/mi2mu/include/mudela-voice.hh b/mi2mu/include/mudela-voice.hh
new file mode 100644 (file)
index 0000000..ab4aef1
--- /dev/null
@@ -0,0 +1,29 @@
+//
+// mudela-voice.hh -- declare Mudela_voice
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#ifndef MUDELA_VOICE_HH
+#define MUDELA_VOICE_HH
+
+#include "mi2mu-proto.hh"
+#include "plist.hh"
+
+/// (mudela_voice)
+class Mudela_voice {
+public:
+    Mudela_voice (Mudela_staff* mudela_staff_l);
+
+    void add_item (Mudela_item* mudela_item_l);
+    Moment begin_mom();
+    Moment end_mom();
+
+    void output (Mudela_stream& mudela_stream_r);
+
+private:
+    Mudela_staff* mudela_staff_l_;
+    Link_list<Mudela_item*> mudela_item_l_list_;
+};
+
+#endif // MUDELA_VOICE_HH
+
diff --git a/mi2mu/mudela-column.cc b/mi2mu/mudela-column.cc
new file mode 100644 (file)
index 0000000..871be0c
--- /dev/null
@@ -0,0 +1,24 @@
+//
+// mudela-column.cc -- implement Mudela_column
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include "mudela-column.hh"
+
+Mudela_column::Mudela_column (Mudela_score* mudela_score_l, Moment mom)
+{
+    mudela_score_l_ = mudela_score_l;
+    at_mom_ = mom;
+}
+
+void 
+Mudela_column::add_item (Mudela_item* mudela_item_l)
+{
+    mudela_item_l_list_.bottom().add (mudela_item_l);
+}
+
+Moment
+Mudela_column::at_mom()
+{
+    return at_mom_;
+}
diff --git a/mi2mu/mudela-item.cc b/mi2mu/mudela-item.cc
new file mode 100644 (file)
index 0000000..4e8f7cc
--- /dev/null
@@ -0,0 +1,295 @@
+//
+// mudela-item.cc -- implement Mudela_item
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include "mi2mu-global.hh"
+#include "string-convert.hh"
+#include "duration-convert.hh"
+#include "mudela-column.hh"
+#include "mudela-item.hh"
+#include "mudela-stream.hh"
+#include "mudela-score.hh"
+
+Mudela_item::Mudela_item (Mudela_column* mudela_column_l)
+{
+    mudela_column_l_ = mudela_column_l;
+}
+
+Moment
+Mudela_item::at_mom()
+{
+    return mudela_column_l_->at_mom();
+}
+
+Moment
+Mudela_item::duration_mom()
+{
+    return Moment (0);
+}
+
+void
+Mudela_item::output (Mudela_stream& mudela_stream_r)
+{
+    mudela_stream_r << str() << String (" ");
+}
+
+Mudela_key::Mudela_key (int accidentals_i, int minor_i)
+    : Mudela_item (0)
+{
+    accidentals_i_ = accidentals_i;
+    minor_i_ = minor_i;
+    if  (accidentals_i >= 0)
+       key_i_ =   ((accidentals_i % 7)[ "cgdaebf" ] - 'a' - 2) % 7;
+    else
+       key_i_ =   ((-accidentals_i % 7)[ "cfbeadg" ] - 'a' - 2) % 7;
+}
+
+String
+Mudela_key::str()
+{
+    String str = "\\key ";
+    if  (!minor_i_) 
+       str += String ((char)  ((key_i_ + 2) % 7 + 'A'));
+    else // heu, -2: should be - 1 1/2: A -> fis
+       str += String ((char)  ((key_i_ + 2 - 2) % 7 + 'a'));
+    str = String ("% \"") + str
+       + String('"') + "; % not supported yet\n"; 
+    return str;
+}
+
+String
+Mudela_key::notename_str (int pitch_i)
+{
+    // this may seem very smart,
+    // but it-s only an excuse not to read a notename table
+
+    // major scale: do-do
+    // minor scale: la-la  (= + 5)
+    static int notename_i_a[ 12 ] = { 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6 };
+    int notename_i = notename_i_a[  (minor_i_ * 5 + pitch_i) % 12 ];
+    
+    static int accidentals_i_a[ 12 ] = { 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 };
+    int accidental_i = accidentals_i_a[ minor_i_ * 5 + pitch_i % 12 ];
+    if  (accidental_i &&  (accidentals_i_ < 0)) {
+       accidental_i = - accidental_i;
+       notename_i =  (notename_i + 1) % 7;
+    }
+
+    String notename_str = (char)  ( ((notename_i + 2) % 7) + 'a');
+    while  (accidental_i-- > 0)
+       notename_str += "is";
+    accidental_i++;
+    while  (accidental_i++ < 0)
+       if   ((notename_str == "a") ||  (notename_str == "e"))
+           notename_str += "s";
+       else
+           notename_str += "es";
+    accidental_i--;
+
+    String de_octavate_str = String ('\'',  (Mudela_note::c0_pitch_i_c_ + 11 - pitch_i) / 12);
+    String octavate_str = String ('\'',  (pitch_i - Mudela_note::c0_pitch_i_c_) / 12);
+    return de_octavate_str + notename_str + octavate_str;
+}
+
+Mudela_meter::Mudela_meter (int num_i, int den_i, int clocks_4_i, int count_32_i)
+   : Mudela_item (0)
+{
+    sync_dur_.type_i_ = 8 ;
+    sync_f_ = 1.0;
+    if  (count_32_i != 8)
+       warning (String ("#32 in quarter: ") + String (count_32_i));
+    num_i_ = num_i;
+    den_i_ = den_i;
+    clocks_1_i_ = clocks_4_i * 4; 
+}
+
+Moment
+Mudela_meter::bar_mom()
+{
+    Duration d;
+    d.type_i_ =  (1 << den_i_);
+    return Moment (num_i_) * Duration_convert::dur2_mom (d);
+}
+
+int
+Mudela_meter::clocks_1_i()
+{
+    return clocks_1_i_;
+}
+
+int
+Mudela_meter::den_i()
+{
+    return den_i_;
+}
+
+int
+Mudela_meter::num_i()
+{
+    return num_i_;
+}
+
+String
+Mudela_meter::str()
+{
+    String str = "\\meter "
+       + String (num_i_) + "/" + String (1 << den_i_) 
+       + ";\n";
+    return str;
+}
+
+
+// statics Mudela_note
+/*
+ this switch can be used to write simple plets like 
+     c4*2/3 
+ as  
+     \plet 2/3; c4 \plet 1/1;
+ */
+bool const Mudela_note::simple_plet_b_s = true;
+
+Mudela_note::Mudela_note (Mudela_column* mudela_column_l, int channel_i, int pitch_i, int dyn_i)
+    : Mudela_item (mudela_column_l)
+{
+    // junk dynamics
+    (void)dyn_i;
+    channel_i_ = channel_i;
+    pitch_i_ = pitch_i;        
+    end_column_l_ = 0;
+}
+
+String
+Mudela_note::str()
+{
+    Duration dur = duration();
+    if  (!dur.type_i_)
+       return "";
+
+    String name_str = mudela_column_l_->mudela_score_l_->mudela_key_l_->notename_str (pitch_i_);
+
+    if  (simple_plet_b_s)
+       return name_str + Duration_convert::dur2_str (dur) + " ";
+
+    //ugh
+    String str;
+    if  (dur.plet_b())
+       str += String ("\\plet ")
+           + String_convert::i2dec_str (dur.plet_.iso_i_, 0, 0)
+           + "/"
+           + String_convert::i2dec_str (dur.plet_.type_i_, 0, 0)
+           + "; ";
+
+    str += name_str;
+
+    Duration tmp = dur;
+    tmp.set_plet (1,1);
+    str += Duration_convert::dur2_str (tmp);
+
+    if  (dur.plet_b())
+       str += String (" \\plet 1/1;");
+
+    return str + " ";
+}
+
+Duration
+Mudela_note::duration()
+{
+    assert (end_column_l_);
+    Moment mom = end_column_l_->at_mom() - at_mom();
+    if  (Duration_convert::no_quantify_b_s)
+       return Duration_convert::mom2_dur (mom);
+
+    return Duration_convert::mom2standardised_dur (mom);
+}
+
+Moment
+Mudela_note::duration_mom()
+{
+// ugh
+//    return Duration_convert::dur2_mom (duration());
+    return end_column_l_->at_mom() - at_mom();
+}
+
+Mudela_skip::Mudela_skip (Mudela_column* mudela_column_l, Moment skip_mom)
+    : Mudela_item (mudela_column_l)
+{
+    mom_ = skip_mom;
+}
+
+Duration
+Mudela_skip::duration()
+{
+    if  (Duration_convert::no_quantify_b_s)
+       return Duration_convert::mom2_dur (mom_);
+
+    return Duration_convert::mom2standardised_dur (mom_);
+}
+
+Moment
+Mudela_skip::duration_mom()
+{
+    return Duration_convert::dur2_mom (duration());
+}
+
+String
+Mudela_skip::str()
+{
+    if  (!mom_)
+       return String ("");
+
+    Duration dur = duration();
+    if  (!dur.type_i_)
+       return "";
+
+    String str = "\\skip ";
+    str += Duration_convert::dur2_str (dur) + "; ";
+
+    return str;
+}
+
+Mudela_tempo::Mudela_tempo (int useconds_per_4_i)
+   : Mudela_item (0)
+{
+    useconds_per_4_i_ = useconds_per_4_i;
+    seconds_per_1_f_ = (Real)useconds_per_4_i_ * 4 / 1e6;
+}
+
+String
+Mudela_tempo::str()
+{
+    String str = "\\tempo 4=";
+    str += String (get_tempo_i (Moment (1, 4)));
+    str += ";\n";
+    return str;
+}
+
+int 
+Mudela_tempo::useconds_per_4_i()
+{
+    return useconds_per_4_i_;
+}
+
+int
+Mudela_tempo::get_tempo_i (Moment moment)
+{
+    return Moment (60) / moment / Moment (seconds_per_1_f_);
+}
+
+Mudela_text::Mudela_text (Mudela_text::Type type, String text_str)
+   : Mudela_item (0)
+{
+    type_ = type;
+    text_str_ = text_str;
+}
+
+String
+Mudela_text::str()
+{
+    if  (!text_str_.length_i() 
+       ||  (text_str_.length_i() != (int)strlen (text_str_.ch_C())))
+       return "";
+
+    return "% " + text_str_ + "\n";
+}
+
diff --git a/mi2mu/mudela-score.cc b/mi2mu/mudela-score.cc
new file mode 100644 (file)
index 0000000..2a82a63
--- /dev/null
@@ -0,0 +1,200 @@
+//
+// mudela-score.cc -- implement Mudela_score
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include "moment.hh"
+#include "duration.hh"
+#include "duration-convert.hh"
+#include "mi2mu-global.hh"
+#include "mudela-column.hh"
+#include "mudela-item.hh"
+#include "mudela-score.hh"
+#include "mudela-staff.hh"
+#include "mudela-stream.hh"
+
+Mudela_score::Mudela_score (int format_i, int tracks_i, int tempo_i)
+{
+    format_i_ = format_i;
+    tracks_i_ = tracks_i;
+    tempo_i_ = tempo_i;
+    mudela_column_p_list_.bottom().add (new Mudela_column (this, Moment (0)));
+}
+
+Mudela_score::~Mudela_score()
+{
+}
+
+void 
+Mudela_score::add_item (Mudela_item* mudela_item_p)
+{
+    mudela_staff_p_list_.bottom()->add_item (mudela_item_p);
+}
+
+void
+Mudela_score::add_staff (Mudela_staff* mudela_staff_p)
+{
+    mudela_staff_p_list_.bottom().add (mudela_staff_p);
+}
+
+Mudela_column*
+Mudela_score::mudela_column_l (Moment mom)
+{
+    for  (PCursor<Mudela_column*> i (mudela_column_p_list_); i.ok(); i++) {
+       if  (i->at_mom() > mom) {
+           Mudela_column* p = new Mudela_column (this, mom);
+           i.insert (p);
+           return p;
+       }
+       if  (i->at_mom() == mom)
+           return *i;
+    }
+
+    Mudela_column* p = new Mudela_column (this, mom);
+    mudela_column_p_list_.bottom().add (p);
+    return p;
+}
+
+void
+Mudela_score::output (String filename_str)
+{
+    LOGOUT(NORMAL_ver) << "Lily output to " << filename_str << " ..." << endl;
+    
+    // ugh, ugly midi type 1 fix
+    if  ( (mudela_staff_p_list_.size() == 1) && !mudela_staff_p_list_.top()->number_i_)
+       mudela_staff_p_list_.top()->number_i_ = 1;
+
+    int track_i = 0;
+    Mudela_stream mudela_stream (filename_str);
+    for  (PCursor<Mudela_staff*> i (mudela_staff_p_list_); i.ok(); i++) {
+       LOGOUT(NORMAL_ver) << "track " << track_i++ << ": " << flush;
+       i->output (mudela_stream);
+       mudela_stream << "\n";
+       LOGOUT(NORMAL_ver) << endl;
+    }
+
+    mudela_stream << "\\score{\n";
+    if  (mudela_staff_p_list_.size() > 1)
+       mudela_stream << "<\n\\multi 3;\n";
+    for  (PCursor<Mudela_staff*> i (mudela_staff_p_list_); i.ok(); i++) {
+       if  ( (mudela_staff_p_list_.size() != 1) 
+           &&  (i == mudela_staff_p_list_.top()))
+           continue;
+       mudela_stream << "\\melodic{ ";
+       mudela_stream << "\\$" << i->id_str();
+       mudela_stream << " }\n";
+    }
+    if  (mudela_staff_p_list_.size() > 1)
+       mudela_stream << ">\n";
+
+    mudela_stream << "\\paper{}\n";
+
+    mudela_stream << "\\midi{ ";
+       // let's not use silly 0 track
+       mudela_staff_p_list_.bottom()->mudela_tempo_p_->output (mudela_stream);
+    mudela_stream << "}\n";
+
+    mudela_stream << "}\n";
+}
+
+void
+Mudela_score::process()
+{
+    LOGOUT(NORMAL_ver) << "\nProcessing..." << endl;
+       
+    LOGOUT(DEBUG_ver) << "columns\n";
+    for  (PCursor<Mudela_column*> i (mudela_column_p_list_); i.ok(); i++)
+       LOGOUT(DEBUG_ver) << "At: " << i->at_mom() << "\n";
+
+    settle_columns();
+    filter_tempo();
+    quantify_columns();
+    quantify_durations();
+
+    LOGOUT(NORMAL_ver) << "\nCreating voices..." << endl;
+    int track_i = 0;
+    for  (PCursor<Mudela_staff*> i (mudela_staff_p_list_); i.ok(); i++)  {
+       LOGOUT(NORMAL_ver) << "track " << track_i++ << ": " << flush;
+       i->process();
+       LOGOUT(NORMAL_ver) << endl;
+    }
+}
+
+void
+Mudela_score::filter_tempo()
+{
+    LOGOUT(NORMAL_ver) << "\nNOT Filtering tempo..." << endl;
+}
+
+void
+Mudela_score::quantify_columns()
+{
+    // ugh
+    if  (Duration_convert::no_quantify_b_s) {
+       LOGOUT(NORMAL_ver) << "\nNOT Quantifying columns..." << endl;
+       return;
+    }
+
+    LOGOUT(NORMAL_ver) << "\nQuantifying columns..." << endl;
+
+    int n = 32 >? Duration_convert::no_smaller_than_i_s;
+    Moment s = Moment (1, n);
+    Moment sh = Moment (1, 2 * n);
+    for  (int i = 0; i < column_l_array_.size(); i++) {
+//     Moment mom = column_l_array_[ i ]->at_mom();
+//     column_l_array_[ i ]->at_mom_ = Duration_convert::dur2_mom (dur);
+       column_l_array_[ i ]->at_mom_ =
+//         s * (int) ( (sh + column_l_array_[ i ]->at_mom()) / s);
+           s * (int) ( (column_l_array_[ i ]->at_mom()) / s);
+       LOGOUT(NORMAL_ver) << '.';
+    } 
+    LOGOUT(NORMAL_ver) << endl;
+}
+
+void
+Mudela_score::quantify_durations()
+{
+//    LOGOUT(NORMAL_ver) << "\nQuantifying durations..." << endl;
+}
+
+void
+Mudela_score::settle_columns()
+{
+//    LOGOUT(NORMAL_ver) << "\nNOT Settling columns..." << endl;
+//    return;
+    LOGOUT(NORMAL_ver) << "\nSettling columns..." << endl;
+
+    assert (!column_l_array_.size());
+    int n = mudela_column_p_list_.size();
+// huh?
+//    column_l_array_.set_size (n);
+    for  (PCursor<Mudela_column*> i (mudela_column_p_list_); i.ok(); i++)
+       column_l_array_.push (*i);
+
+    int start_i = 0;
+    int end_i = 0;
+    Moment start_mom = 0;
+    Duration smallest_dur;
+    smallest_dur.type_i_ =  64;
+    Moment const noise_mom = Duration_convert::dur2_mom (smallest_dur)
+       / Moment (2);
+    for  (int i = 0; i < n; i++) {
+       if  (!start_i) {
+           start_i = end_i = i;
+           start_mom = column_l_array_[ i ]->at_mom();
+           continue;
+       }
+
+       // find all columns within noise's distance
+       while  ( (i < n)
+           &&  (column_l_array_[ i ]->at_mom() - start_mom < noise_mom))
+           end_i = ++i;
+
+       // bluntly set all to time of first in group
+       for  (int j = start_i; j < end_i; j++)
+           column_l_array_[ j ]->at_mom_ = start_mom;
+
+       start_i = end_i = 0;
+    }
+}
+
diff --git a/mi2mu/mudela-staff.cc b/mi2mu/mudela-staff.cc
new file mode 100644 (file)
index 0000000..0c13ec4
--- /dev/null
@@ -0,0 +1,237 @@
+//
+// mudela-staff.cc -- implement Mudela_staff
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include <ctype.h>
+#include "moment.hh"
+#include "duration-convert.hh"
+#include "string-convert.hh"
+#include "mi2mu-proto.hh"
+#include "mi2mu-global.hh"
+#include "mudela-column.hh"
+#include "mudela-item.hh"
+#include "mudela-staff.hh"
+#include "mudela-stream.hh"
+#include "mudela-voice.hh"
+
+Mudela_staff::Mudela_staff (int number_i, String copyright_str, String track_name_str, String instrument_str)
+{
+    number_i_ = number_i;
+    copyright_str_ = copyright_str;
+    instrument_str_ = instrument_str;
+    name_str_ = track_name_str;
+    mudela_meter_p_ = new Mudela_meter (4, 2, 24, 8);
+    mudela_tempo_p_ = new Mudela_tempo (1000000);
+}
+
+Mudela_staff::~Mudela_staff()
+{
+    delete mudela_meter_p_;
+    delete mudela_tempo_p_;
+}
+
+void
+Mudela_staff::add_item (Mudela_item* mudela_item_p)
+{
+    mudela_item_p_list_.bottom().add (mudela_item_p);
+    if  (mudela_item_p->mudela_column_l_)
+       mudela_item_p->mudela_column_l_->add_item (mudela_item_p);
+}
+
+void
+Mudela_staff::eat_voice (Link_list<Mudela_item*>& items)
+{
+    Mudela_voice* voice_p = new Mudela_voice (this);
+    mudela_voice_p_list_.bottom().add (voice_p);
+
+//    Moment mom = items.top()->at_mom();
+    Moment mom = 0;
+
+    for  (PCursor<Mudela_item*> i (items); i.ok();) {
+       LOGOUT(DEBUG_ver) << "At: " << i->at_mom() << "; ";
+       LOGOUT(DEBUG_ver) << "dur: " << i->duration_mom() << "; ";
+       LOGOUT(DEBUG_ver) << "mom: " << mom << " -> ";
+       if  (i->at_mom() > mom) {
+           // ugh, liek
+           voice_p->add_item (new Mudela_skip (i->mudela_column_l_, i->at_mom() - mom));
+           mom = i->at_mom();
+       }
+       if  (i->at_mom() == mom) {
+           mom = i->at_mom() + i->duration_mom();
+           voice_p->add_item (i.remove_p());
+           // ugh
+       }
+       else if  (i.ok())
+           i++;
+       LOGOUT(DEBUG_ver) << "mom: " << mom << "\n";
+    }
+}
+
+String
+Mudela_staff::id_str()
+{
+    String str = name_str();
+    for  (int i = 0; i < str.length_i(); i++)
+       if  ( (!i && !isalpha (str[ i ]))
+           || !isalnum (str[ i ]))
+           * (str.ch_l() + i) = '_';
+    return str;
+}
+
+String
+Mudela_staff::name_str()
+{
+    if  (name_str_.length_i())
+       return name_str_;
+    return String ("track") + String (number_i_);
+}
+
+void
+Mudela_staff::output (Mudela_stream& mudela_stream_r)
+{
+    mudela_stream_r << "$" << id_str() << " = \\melodic";
+    mudela_stream_r <<  (mudela_voice_p_list_.size() > 1 ? "<" : "{");
+    mudela_stream_r << "\n";
+    mudela_stream_r << "% midi copyright:" << copyright_str_ << "\n";
+    mudela_stream_r << "% instrument:" << instrument_str_ << "\n";
+
+    if  (mudela_voice_p_list_.size() == 1)
+       mudela_voice_p_list_.top()->output (mudela_stream_r);
+    else
+       for  (PCursor<Mudela_voice*> i (mudela_voice_p_list_); i.ok(); i++) {
+           mudela_stream_r << "{ ";
+           i->output (mudela_stream_r);
+           mudela_stream_r << "} ";
+       }
+
+    mudela_stream_r <<  (mudela_voice_p_list_.size() > 1 ? "\n>" : "\n}");
+    mudela_stream_r << " % " << name_str() << "\n";
+}
+
+void
+Mudela_staff::output_mudela_begin_bar (Mudela_stream& mudela_stream_r, Moment now_mom, int bar_i)
+{
+    Moment bar_mom = mudela_meter_p_->bar_mom();
+    Moment into_bar_mom = now_mom - Moment (bar_i - 1) * bar_mom;
+    if  (bar_i > 1) {
+       if  (!into_bar_mom)
+           mudela_stream_r << "|\n";
+    }
+    mudela_stream_r << "% " << String_convert::i2dec_str (bar_i, 0, ' ');
+    if  (into_bar_mom)
+       mudela_stream_r << ":" << Duration_convert::dur2_str (Duration_convert::mom2_dur (into_bar_mom));
+    mudela_stream_r << "\n";
+}
+
+
+#if 0 // not used for now
+void 
+Mudela_staff::output_mudela_rest (Mudela_stream& mudela_stream_r, Moment begin_mom, Moment end_mom)
+{
+    Moment bar_mom = mudela_meter_p_->bar_mom();
+    Moment now_mom = begin_mom;
+
+    int begin_bar_i = (int) (now_mom / bar_mom) + 1; 
+    int end_bar_i = (int) (end_mom / bar_mom) + 1;
+
+    if  (end_bar_i == begin_bar_i) {
+       output_mudela_rest_remain (mudela_stream_r, end_mom - begin_mom);
+       return;
+    }
+
+    // multiple bars involved
+    int bar_i = (int) (now_mom / bar_mom) + 1;
+
+    //fill current bar
+    Moment begin_bar_mom = Moment (begin_bar_i - 1) * bar_mom;
+    if  (now_mom > begin_bar_mom) {
+       int next_bar_i = (int) (now_mom / bar_mom) + 2; 
+       Moment next_bar_mom = Moment (next_bar_i - 1) * bar_mom;
+       assert (next_bar_mom <= end_mom);
+
+       Moment remain_mom = next_bar_mom - now_mom;
+       if  (remain_mom > Moment (0)) {
+           output_mudela_rest_remain (mudela_stream_r, remain_mom);
+           now_mom += remain_mom;
+       }
+
+       bar_i = check_end_bar_i (now_mom, bar_i);
+    }
+
+    // fill whole bars
+    int count_i = end_bar_i - bar_i;
+    for  (int i = 0; i < count_i; i++) {
+       int begin_bar_i = check_begin_bar_i (now_mom, bar_i);
+       if  (begin_bar_i)
+           output_mudela_begin_bar (mudela_stream_r, now_mom, begin_bar_i);
+       mudela_stream_r << "r1 ";
+//     *mudela_stream_r.os_p_ << flush;
+       if  (begin_bar_i)
+           LOGOUT(NORMAL_ver) << begin_bar_i << flush; 
+       bar_i = check_end_bar_i (now_mom, bar_i);
+       now_mom += bar_mom;
+    }
+
+    // use "int i" here, and gcc 2.7.2 hits internal compiler error
+    int ii = check_begin_bar_i (now_mom, bar_i);
+    if  (ii)
+       output_mudela_begin_bar (mudela_stream_r, now_mom, ii);
+
+//    bar_i = check_end_bar_i (now_mom, bar_i);
+
+    Moment remain_mom = end_mom - Moment (end_bar_i - 1) * bar_mom;
+       if  (remain_mom > Moment (0)) {
+       output_mudela_rest_remain (mudela_stream_r, remain_mom);
+       now_mom += remain_mom;
+    }
+    assert (now_mom == end_mom);
+}
+
+void
+Mudela_staff::output_mudela_rest_remain (Mudela_stream& mudela_stream_r, Moment mom)
+{
+    if  (Duration_convert::no_quantify_b_s) {
+       Duration dur = Duration_convert::mom2_dur (mom);
+       mudela_stream_r << "r" << dur.str() << " ";
+//     assert (mom == dur.mom());
+       assert (mom == dur.length());
+       return;
+    }
+       
+    Duration dur = Duration_convert::mom2standardised_dur (mom);
+    if  (dur.type_i_)
+       mudela_stream_r << "r" << dur.str() << " ";
+}
+#endif
+
+
+void
+Mudela_staff::process()
+{
+    /* 
+      group items into voices
+     */
+
+    Link_list<Mudela_item*> items;
+    for  (PCursor<Mudela_item*> i (mudela_item_p_list_); i.ok(); i++)
+       items.bottom().add (*i);
+    
+    while  (items.size())
+       eat_voice (items);
+}
+
+void
+Mudela_staff::set_tempo (int useconds_per_4_i)
+{
+    delete mudela_tempo_p_;
+    mudela_tempo_p_ = new Mudela_tempo (useconds_per_4_i);
+}
+
+void
+Mudela_staff::set_meter (int num_i, int den_i, int clocks_i, int count_32_i)
+{
+    delete mudela_meter_p_;
+    mudela_meter_p_ = new Mudela_meter (num_i, den_i, clocks_i, count_32_i);
+}
+
diff --git a/mi2mu/mudela-stream.cc b/mi2mu/mudela-stream.cc
new file mode 100644 (file)
index 0000000..7b7dbb8
--- /dev/null
@@ -0,0 +1,165 @@
+//
+// mudela-stream.cc
+//
+// source file of the LilyPond music typesetter
+//
+// (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include <time.h>
+#include <fstream.h>
+#include "mi2mu-global.hh"
+#include "my-midi-parser.hh"
+#include "mudela-item.hh"
+#include "mudela-stream.hh"
+
+static int const INDENT_i = 8;
+
+Mudela_stream::Mudela_stream (String filename_str)
+{
+    filename_str_ = filename_str;
+    os_p_ = 0;
+    indent_i_ = 0;
+    comment_mode_b_ = false;
+    column_i_ = 0;
+    wrap_column_i_ = 68;
+    open();
+    header();
+}
+
+Mudela_stream::~Mudela_stream()
+{
+    delete os_p_;
+    if  (indent_i_)
+       warning ("lily indent level: " + String (indent_i_));
+}
+
+Mudela_stream&
+Mudela_stream::operator << (String str)
+{
+    static String word_sep_str = "{} \t\n";
+    while  (str.length_i()) {
+       int i = str.index_any_i (word_sep_str) + 1;
+       if  (!i)
+           i = str.length_i();
+       String word = str.left_str (i);
+       str = str.mid_str (i, str.length_i());
+       output_wrapped (word);
+    }
+    return *this;
+}
+
+Mudela_stream&
+Mudela_stream::operator << (Mudela_item& mudela_item_r)
+{
+    mudela_item_r.output (*this);
+    *os_p_ << flush;
+    return *this;
+}
+
+void
+Mudela_stream::handle_pending_indent()
+{
+    *os_p_ << String ('\t', pending_indent_i_);
+    column_i_ += pending_indent_i_ * INDENT_i;
+    pending_indent_i_ = 0;
+}
+
+void
+Mudela_stream::header()
+{
+    *os_p_ << "% Creator: " << mi2mu_version_str() << "\n";
+    *os_p_ << "% Automatically generated, at ";
+    time_t t (time (0));
+    *os_p_ << ctime (&t);
+    *os_p_ << "% from input file: ";
+    *os_p_ << midi_parser_l_g->filename_str_;
+    *os_p_ << "\n\n";    
+    // ugh
+    *os_p_ << "\\version \"0.1.1\";\n";
+}
+
+void
+Mudela_stream::open()
+{
+    os_p_ = new ofstream (filename_str_);
+    if  (!*os_p_)
+       error  ("can't open: `" + filename_str_ + "\'");
+}
+
+void
+Mudela_stream::output (String str)
+{
+    for  (int i = 0; i < str.length_i(); i++) {
+       char c = str[ i ];
+       switch  (c) {
+           case '{' :
+           case '<' :
+               handle_pending_indent();
+               if  (column_i_ == indent_i_ * INDENT_i)
+                   output ("\t");
+               indent_i_++;
+               *os_p_ << c;
+               column_i_++;
+               break;
+           case '}' :
+           case '>' :
+               assert (indent_i_);
+               indent_i_--;
+               if  (pending_indent_i_)
+                   pending_indent_i_--;
+               handle_pending_indent();
+               *os_p_ << c;
+               column_i_++;
+               break;
+           case '%' :
+               handle_pending_indent();
+               comment_mode_b_ = true;
+               *os_p_ << c;
+               column_i_++;
+               break;
+           case '\t' :
+               handle_pending_indent();
+               *os_p_ << c;
+               column_i_ += INDENT_i;
+               break;
+           case '\n' :
+               *os_p_ << endl;
+               pending_indent_i_ = indent_i_;
+               column_i_ = 0;
+               comment_mode_b_ = false;
+               break;
+           default :
+               handle_pending_indent();
+               *os_p_ << c;
+               column_i_++;
+               break;
+       }       
+    }
+}
+
+void
+Mudela_stream::output_wrapped (String str)
+{
+    // enough room left -> doit
+    if  (column_i_ + str.length_i() <= wrap_column_i_) {
+       output (str);
+       return;
+    }
+
+    // we're at BOL already; this will never fit -> doit
+    if  (column_i_ == indent_i_ * INDENT_i) {
+       output (str);
+       return;
+    }
+    
+    // ok, let's wrap
+    // preserve comment mode
+    if  (comment_mode_b_)
+       output (String ("\n%"));
+    else 
+       output (String ("\n"));
+    
+    output (str);
+}
+
+
diff --git a/mi2mu/mudela-voice.cc b/mi2mu/mudela-voice.cc
new file mode 100644 (file)
index 0000000..5fd2704
--- /dev/null
@@ -0,0 +1,74 @@
+//
+// mudela-voice.cc -- implement Mudela_voice
+//
+// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
+
+#include "string-convert.hh"
+#include "mi2mu-global.hh"
+#include "mudela-column.hh"
+#include "mudela-item.hh"
+#include "mudela-staff.hh"
+#include "mudela-stream.hh"
+#include "mudela-voice.hh"
+
+Mudela_voice::Mudela_voice (Mudela_staff* mudela_staff_l)
+{
+    mudela_staff_l_ = mudela_staff_l;
+}
+
+void
+Mudela_voice::add_item (Mudela_item* mudela_item_l)
+{
+    mudela_item_l_list_.bottom().add (mudela_item_l);
+}
+
+Moment 
+Mudela_voice::begin_mom()
+{
+    return mudela_item_l_list_.size() ? 
+       mudela_item_l_list_.top()->at_mom() : Moment (0);
+}
+
+Moment 
+Mudela_voice::end_mom()
+{
+    return mudela_item_l_list_.size() ? 
+       mudela_item_l_list_.bottom()->at_mom() : Moment (0);
+}
+
+static int const FAIRLY_LONG_VOICE_i = 6;
+
+void
+Mudela_voice::output (Mudela_stream& mudela_stream_r)
+{
+    if  (!mudela_item_l_list_.size())
+       return;
+    
+    if  (mudela_item_l_list_.size() > FAIRLY_LONG_VOICE_i)
+       mudela_stream_r << "\n";
+
+    int current_bar_i = 0;
+    Moment bar_mom = mudela_staff_l_->mudela_meter_p_->bar_mom();
+
+    for  (PCursor<Mudela_item*> i (mudela_item_l_list_); i.ok(); i++) {
+       Moment at_mom = i->mudela_column_l_->at_mom();
+       int bar_i = (int) (at_mom / bar_mom) + 1;
+       if  (bar_i > current_bar_i) {
+           if  (current_bar_i) {
+               if  (at_mom == Moment (bar_i - 1) * bar_mom)
+                   mudela_stream_r << "|";
+               mudela_stream_r << "\n% ";
+               mudela_stream_r << String_convert::i2dec_str (bar_i, 0, ' ');
+               mudela_stream_r << "\n";
+           }
+           LOGOUT(NORMAL_ver) << '[' << bar_i << ']' << flush; 
+           current_bar_i = bar_i;
+       }
+
+       mudela_stream_r << i->str();
+    }
+
+    if  (mudela_item_l_list_.size() > FAIRLY_LONG_VOICE_i)
+       mudela_stream_r << "\n";
+}
+