--- /dev/null
+//
+// 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
+
--- /dev/null
+//
+// 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
+
--- /dev/null
+//
+// 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
+
--- /dev/null
+//
+// 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
+
--- /dev/null
+//
+// 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
+
--- /dev/null
+//
+// 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
+
--- /dev/null
+//
+// 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
+
--- /dev/null
+//
+// 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_;
+}
--- /dev/null
+//
+// 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";
+}
+
--- /dev/null
+//
+// 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;
+ }
+}
+
--- /dev/null
+//
+// 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);
+}
+
--- /dev/null
+//
+// 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);
+}
+
+
--- /dev/null
+//
+// 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";
+}
+