]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-1.1.55
authorfred <fred>
Wed, 14 Apr 1999 11:41:32 +0000 (11:41 +0000)
committerfred <fred>
Wed, 14 Apr 1999 11:41:32 +0000 (11:41 +0000)
midi2ly/include/midi-track-parser.hh [new file with mode: 0644]
midi2ly/include/mudela-column.hh [new file with mode: 0644]
midi2ly/include/mudela-item.hh [new file with mode: 0644]
midi2ly/include/mudela-score.hh [new file with mode: 0644]
midi2ly/include/mudela-staff.hh [new file with mode: 0644]
midi2ly/include/mudela-voice.hh [new file with mode: 0644]
midi2ly/mudela-column.cc [new file with mode: 0644]
midi2ly/mudela-score.cc [new file with mode: 0644]
midi2ly/mudela-staff.cc [new file with mode: 0644]

diff --git a/midi2ly/include/midi-track-parser.hh b/midi2ly/include/midi-track-parser.hh
new file mode 100644 (file)
index 0000000..d873e19
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+  midi-track-parser.hh -- declare 
+
+  source file of the GNU LilyPond music typesetter
+
+  (c)  1997--1998 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+
+#ifndef MIDI_TRACK_PARSER_HH
+#define MIDI_TRACK_PARSER_HH
+
+#include "proto.hh"
+#include "cons.hh"
+#include "moment.hh"
+#include "mi2mu-proto.hh"
+#include "midi-parser.hh"
+
+class Midi_track_parser : public Midi_parser
+{
+public:
+
+  Midi_track_parser (Midi_parser_info* info_l, int i);
+  ~Midi_track_parser ();
+
+  Moment at_mom ();
+  Mudela_staff* parse (Mudela_column* col_l);
+
+private:
+  bool eot ();
+  void note_end (Mudela_column* col_l, int channel_i, int pitch_i, int aftertouch_i );
+  void note_end_all (Mudela_column* col_l) ;
+  void parse_delta_time ();
+  Mudela_item* parse_event (Mudela_column* col_l);
+  void parse_header ();
+
+  Moment at_mom_;
+  Byte running_byte_;
+  Cons_list<Mudela_note> open_note_l_list_;
+  Mudela_staff* mudela_staff_p_;
+  Midi_parser_info* track_info_p_;
+};
+
+#endif // MIDI_TRACK_PARSER_HH
diff --git a/midi2ly/include/mudela-column.hh b/midi2ly/include/mudela-column.hh
new file mode 100644 (file)
index 0000000..a09cebb
--- /dev/null
@@ -0,0 +1,29 @@
+//
+// mudela-column.hh -- declare Mudela_column
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#ifndef MUDELA_COLUMN_HH
+#define MUDELA_COLUMN_HH
+
+#include "proto.hh"
+#include "mi2mu-proto.hh"
+#include "moment.hh"
+#include "cons.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 ();
+
+    Cons_list<Mudela_item> mudela_item_l_list_;
+    Moment at_mom_;
+    Mudela_score* mudela_score_l_;
+};
+
+#endif // MUDELA_COLUMN_HH
+
diff --git a/midi2ly/include/mudela-item.hh b/midi2ly/include/mudela-item.hh
new file mode 100644 (file)
index 0000000..e1b52b7
--- /dev/null
@@ -0,0 +1,130 @@
+//
+// mudela-item.hh -- declare mudela_item
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#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 ~Mudela_item ();
+    
+  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_;
+};
+
+class Mudela_time_signature : public Mudela_item 
+{
+public:
+  Mudela_time_signature (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?
+  static 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_;
+  Moment seconds_per_1_mom_;
+};
+
+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/midi2ly/include/mudela-score.hh b/midi2ly/include/mudela-score.hh
new file mode 100644 (file)
index 0000000..8e75d02
--- /dev/null
@@ -0,0 +1,51 @@
+//
+// mudela-score.hh -- declare Mudela_score
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#ifndef MUDELA_SCORE_HH
+#define MUDELA_SCORE_HH
+
+#include "mi2mu-proto.hh"
+#include "proto.hh"
+#include "cons.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* find_column_l (Moment mom);
+  Mudela_column* get_column_l (Moment mom);
+
+  void output (String filename_str);
+  void process ();
+
+  // ugh
+  Mudela_key* mudela_key_l_;
+  Mudela_time_signature* mudela_time_signature_l_;
+  Mudela_tempo* mudela_tempo_l_;
+  Mudela_staff * last_staff_l_;
+private:
+  void filter_tempo ();
+  void quantify_columns ();
+  void quantify_durations ();
+  void settle_columns ();
+
+  Cons_list<Mudela_staff> mudela_staff_p_list_;
+  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/midi2ly/include/mudela-staff.hh b/midi2ly/include/mudela-staff.hh
new file mode 100644 (file)
index 0000000..8c0afa0
--- /dev/null
@@ -0,0 +1,43 @@
+//
+// mudela-staff.hh -- declare mudela_staff
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#ifndef MUDELA_STAFF_HH
+#define MUDELA_STAFF_HH
+
+#include "mi2mu-proto.hh"
+#include "proto.hh"
+#include "cons.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);
+
+  void add_item (Mudela_item* mudela_item_p);
+  void eat_voice (Cons_list<Mudela_item>& items);
+  String id_str ();
+  String name_str ();
+  void output (Mudela_stream& mudela_stream_r);
+  void process ();
+
+  String copyright_str_;
+  String instrument_str_;
+  String name_str_;
+  Mudela_key* mudela_key_l_;
+  Mudela_time_signature* mudela_time_signature_l_;
+  Mudela_tempo* mudela_tempo_l_;
+  int number_i_;
+
+private:
+  void output_mudela_begin_bar (Mudela_stream& mudela_stream_r, Moment now_mom, int bar_i);
+
+  Cons_list<Mudela_voice> mudela_voice_p_list_;
+  Cons_list<Mudela_item> mudela_item_p_list_;
+};
+
+#endif // MUDELA_STAFF_HH
+
diff --git a/midi2ly/include/mudela-voice.hh b/midi2ly/include/mudela-voice.hh
new file mode 100644 (file)
index 0000000..db196da
--- /dev/null
@@ -0,0 +1,26 @@
+//
+// mudela-voice.hh -- declare Mudela_voice
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#ifndef MUDELA_VOICE_HH
+#define MUDELA_VOICE_HH
+
+#include "mi2mu-proto.hh"
+#include "cons.hh"
+
+/// (mudela_voice)
+class Mudela_voice
+{
+public:
+  Mudela_voice (Mudela_staff* mudela_staff_l);
+  void add_item (Mudela_item* mudela_item_l);
+  void output (Mudela_stream& mudela_stream_r);
+
+private:
+  Mudela_staff* mudela_staff_l_;
+  Cons_list<Mudela_item> mudela_item_l_list_;
+};
+
+#endif // MUDELA_VOICE_HH
+
diff --git a/midi2ly/mudela-column.cc b/midi2ly/mudela-column.cc
new file mode 100644 (file)
index 0000000..833b351
--- /dev/null
@@ -0,0 +1,24 @@
+//
+// mudela-column.cc -- implement Mudela_column
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#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_.append (new Cons<Mudela_item> (mudela_item_l, 0));
+}
+
+Moment
+Mudela_column::at_mom()
+{
+  return at_mom_;
+}
diff --git a/midi2ly/mudela-score.cc b/midi2ly/mudela-score.cc
new file mode 100644 (file)
index 0000000..6916d80
--- /dev/null
@@ -0,0 +1,256 @@
+//
+// mudela-score.cc -- implement Mudela_score
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#include <assert.h>
+#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"
+
+#include "killing-cons.tcc"
+
+//static Mudela_key key_c (0, 0);
+static Mudela_time_signature time_sig_4 (4, 2, 24, 8);
+// useconds per 4: 250000 === 60 4 per minute
+static Mudela_tempo tempo_60 (1000000);
+
+Mudela_score::Mudela_score (int format_i, int tracks_i, int tempo_i)
+{
+  last_staff_l_ =0;
+  format_i_ = format_i;
+  tracks_i_ = tracks_i;
+  tempo_i_ = tempo_i;
+  column_l_array_.push (new Mudela_column (this, Moment (0)));
+  //  mudela_key_l_ = &key_c;
+  mudela_key_l_ = 0;
+  mudela_time_signature_l_ = &time_sig_4;
+  mudela_tempo_l_ = &tempo_60;
+}
+
+Mudela_score::~Mudela_score ()
+{
+}
+
+void
+Mudela_score::add_item (Mudela_item* mudela_item_p)
+{
+  last_staff_l_->add_item (mudela_item_p);
+}
+
+void
+Mudela_score::add_staff (Mudela_staff* mudela_staff_p)
+{
+  mudela_staff_p_list_.append (new Killing_cons<Mudela_staff> (mudela_staff_p, 0));
+  last_staff_l_ = mudela_staff_p;
+}
+
+Mudela_column*
+Mudela_score::find_column_l (Moment mom)
+{
+  int upper_i = max (0, column_l_array_.size () - 1);
+  int lower_i = 0;
+  int i = 0; //upper_i;
+  while (1)
+    {
+      Moment i_mom = column_l_array_ [i]->at_mom ();
+      if (i_mom == mom)
+       return column_l_array_ [i];
+      if (mom < i_mom)
+       upper_i = i;
+      else
+       lower_i = i;
+      if ( (upper_i == lower_i) || (i == column_l_array_.size () - 1))
+       {
+         // we don't do inserts
+         assert (0);
+         Mudela_column* col_p = new Mudela_column (this, mom);
+         column_l_array_.push (col_p);
+         return col_p;
+        }
+      i = (upper_i + lower_i + 1 ) / 2;
+    }
+  assert (0);
+  return 0;
+}
+
+Mudela_column*
+Mudela_score::get_column_l (Moment mom)
+{
+  int i;
+  Mudela_column *c=0;
+  for (i=column_l_array_.size () - 1; !c && i >=0; i--)
+    {
+      if (column_l_array_ [i]->at_mom () == mom )
+       c = column_l_array_[i];
+      else if (column_l_array_[i]->at_mom () < mom)
+       break;
+    }
+  if (!c)
+    {
+      c = new Mudela_column (this, mom);
+      column_l_array_.insert (c, i+1);
+    }
+
+  assert (c->at_mom () == mom);
+  return c;
+}
+
+void
+Mudela_score::output (String filename_str)
+{
+  LOGOUT (NORMAL_ver) << _f ("Lily output to %s...", filename_str) << endl;
+  
+  // ugh, ugly midi type 1 fix
+  if ( (mudela_staff_p_list_.size_i () == 1)
+       && !mudela_staff_p_list_.head_->car_->number_i_)
+    mudela_staff_p_list_.head_->car_->number_i_ = 1;
+  
+  int track_i = 0;
+  Mudela_stream mudela_stream (filename_str);
+  for (Cons<Mudela_staff>* i = mudela_staff_p_list_.head_; i; i = i->next_)
+    {
+      LOGOUT (NORMAL_ver) << _ ("track ") << track_i++ << ": " << flush;
+      i->car_->output (mudela_stream);
+      mudela_stream << '\n';
+      LOGOUT (NORMAL_ver) << endl;
+    }
+  
+  mudela_stream << "\\score{\n";
+  if (mudela_staff_p_list_.size_i () > 1)
+    mudela_stream << "< \n";
+  for (Cons<Mudela_staff>* i = mudela_staff_p_list_.head_; i; i = i->next_)
+    {
+      if ( (mudela_staff_p_list_.size_i () != 1)
+          && (i->car_ == mudela_staff_p_list_.head_->car_))
+       continue;
+      mudela_stream << "\\type Staff = \"" << i->car_->id_str () << "\" ";
+      mudela_stream << String ("\\" +  i->car_->id_str ()) << "\n";
+    }
+  if (mudela_staff_p_list_.size_i () > 1)
+    mudela_stream << ">\n";
+  
+  mudela_stream << "\\paper{}\n";
+  
+#if 0
+  mudela_stream << "\\midi{\n";
+  
+  // let's not use silly 0 track
+  last_cons (mudela_staff_p_list_.head_)->car_->mudela_tempo_l_->output (mudela_stream);
+  mudela_stream << "}\n";
+#endif
+  
+  mudela_stream << "}\n";
+}
+  
+void
+Mudela_score::process ()
+{
+  LOGOUT (NORMAL_ver) << '\n' << _ ("Processing...") << endl;
+  
+  LOGOUT (DEBUG_ver) << "columns\n";
+  
+  settle_columns ();
+  filter_tempo ();
+  quantify_columns ();
+  quantify_durations ();
+  
+  LOGOUT (NORMAL_ver) << '\n' << _ ("Creating voices...") << endl;
+  int track_i = 0;
+  for (Cons<Mudela_staff>* i = mudela_staff_p_list_.head_; i; i = i->next_)
+    {
+      LOGOUT (NORMAL_ver) << _ ("track ") << track_i++ << ": " << flush;
+      i->car_->process ();
+      LOGOUT (NORMAL_ver) << endl;
+    }
+}
+  
+void
+Mudela_score::filter_tempo ()
+{
+  LOGOUT (NORMAL_ver) << '\n' << _ ("NOT Filtering tempo...") << endl;
+}
+  
+void
+Mudela_score::quantify_columns ()
+{
+  // ugh
+  if (Duration_convert::no_quantify_b_s)
+    {
+      LOGOUT (NORMAL_ver) << '\n' << _ ("NOT Quantifying columns...") << endl;
+      return;
+    }
+  
+  LOGOUT (NORMAL_ver) << '\n' << _ ("Quantifying columns...") << endl;
+  
+  int current_bar_i = 0;
+  Moment bar_mom = mudela_time_signature_l_->bar_mom ();
+  
+  int n = 5 >? Duration_convert::no_smaller_than_i_s;
+  n = Duration_convert::type2_i (n);
+  Moment s = Moment (1, n);
+  for (int i = 0; i < column_l_array_.size (); i++)
+    {
+      column_l_array_ [i]->at_mom_ =
+       s * Moment ( (int) ( (column_l_array_ [i]->at_mom ()) / s));
+  
+      int bar_i = (int) (column_l_array_ [i]->at_mom () / bar_mom) + 1;
+      if (bar_i > current_bar_i)
+
+       {
+         LOGOUT (NORMAL_ver) << "[" << bar_i << "]" << flush;
+         current_bar_i = bar_i;
+       }
+    }
+  LOGOUT (NORMAL_ver) << endl;
+}
+  
+void
+Mudela_score::quantify_durations ()
+{
+  
+}
+  
+void
+Mudela_score::settle_columns ()
+{
+  LOGOUT (NORMAL_ver) << '\n' << _ ("Settling columns...") << endl;
+  
+  int n = column_l_array_.size ();
+  
+  int start_i = 0;
+  int end_i = 0;
+  Moment start_mom = 0;
+
+  Duration smallest_dur;
+  smallest_dur.durlog_i_ =  6;
+  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/midi2ly/mudela-staff.cc b/midi2ly/mudela-staff.cc
new file mode 100644 (file)
index 0000000..d6088e1
--- /dev/null
@@ -0,0 +1,252 @@
+//
+// mudela-staff.cc -- implement Mudela_staff
+//
+// copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#include <assert.h>
+#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"
+#include "mudela-score.hh"
+
+#include "killing-cons.tcc"
+
+extern Mudela_score* mudela_score_l_g;
+
+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_key_l_ = 0;
+  mudela_time_signature_l_ = 0;
+  mudela_tempo_l_ = 0;
+}
+
+void
+Mudela_staff::add_item (Mudela_item* mudela_item_p)
+{
+  mudela_item_p_list_.append (new Killing_cons <Mudela_item> (mudela_item_p, 0));
+  if (mudela_item_p->mudela_column_l_)
+    mudela_item_p->mudela_column_l_->add_item (mudela_item_p);
+}
+
+void
+Mudela_staff::eat_voice (Cons_list<Mudela_item>& items)
+{
+  Mudela_voice* voice_p = new Mudela_voice (this);
+  mudela_voice_p_list_.append (new Killing_cons<Mudela_voice> (voice_p, 0));
+
+  //    Moment mom = items.top ()->at_mom ();
+  Moment mom = 0;
+
+  for (Cons<Mudela_item>** pp = &items.head_; *pp;)
+    {
+      Cons<Mudela_item>* i = *pp;
+      LOGOUT (DEBUG_ver) << "At: " << i->car_->at_mom ().str () << "; ";
+      LOGOUT (DEBUG_ver) << "dur: " << i->car_->duration_mom ().str () << "; ";
+      LOGOUT (DEBUG_ver) << "mom: " << mom.str () << " -> ";
+      if (i->car_->at_mom () > mom)
+       {
+         Moment dur = i->car_->at_mom () - mom;
+         // ugh, need score
+         Mudela_column* start = mudela_score_l_g->find_column_l (mom);
+         voice_p->add_item (new Mudela_skip (start, dur));
+         mom = i->car_->at_mom ();
+       }
+      if (i->car_->at_mom () == mom)
+       {
+         mom = i->car_->at_mom () + i->car_->duration_mom ();
+         Cons<Mudela_item>* c = items.remove_cons (pp);
+         voice_p->add_item (c->car_);
+         delete c;
+       }
+      else if (*pp)
+       pp = &i->next_;
+      LOGOUT (DEBUG_ver) << "mom: " << mom.str () << '\n';
+    }
+}
+
+String
+Mudela_staff::id_str ()
+{
+  String id (name_str ());
+  char *cp = id.ch_l ();
+  char *end = cp + id.length_i ();
+  for (;cp < end; cp++)
+    {
+      if (!isalpha (*cp))
+       {
+         *cp = 'X';
+       }
+    }
+  return id;
+}
+
+String
+Mudela_staff::name_str ()
+{
+  if (name_str_.length_i ())
+    return name_str_;
+  return String ("track") + to_str (char ('A' - 1 + number_i_));
+}
+
+
+
+void
+Mudela_staff::output (Mudela_stream& mudela_stream_r)
+{
+  mudela_stream_r << id_str () << " = \\notes";
+  mudela_stream_r << (mudela_voice_p_list_.size_i () > 1 ? "<" : "{");
+  mudela_stream_r << '\n';
+  mudela_stream_r << _ ("% midi copyright:") << copyright_str_ << '\n';
+  mudela_stream_r << _ ("% instrument:") << instrument_str_ << '\n';
+
+  // don't use last duration mode
+  //  mudela_stream_r << "\\duration 4;\n";
+  if (mudela_voice_p_list_.size_i () == 1)
+    mudela_voice_p_list_.head_->car_->output (mudela_stream_r);
+  else
+      for (Cons<Mudela_voice>* i = mudela_voice_p_list_.head_; i; i = i->next_)
+      {
+       mudela_stream_r << "{ ";
+       i->car_->output (mudela_stream_r);
+       mudela_stream_r << "} ";
+      }
+
+  mudela_stream_r << (mudela_voice_p_list_.size_i () > 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_time_signature_l_->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_time_signature_l_->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_>-10)
+    mudela_stream_r << "r" << dur.str () << " ";
+}
+#endif
+
+
+void
+Mudela_staff::process ()
+{
+  /*
+     group items into voices
+     */
+
+  assert (mudela_score_l_g);
+  mudela_key_l_ = mudela_score_l_g->mudela_key_l_;
+  mudela_time_signature_l_ = mudela_score_l_g->mudela_time_signature_l_;
+  mudela_tempo_l_ = mudela_score_l_g->mudela_tempo_l_;
+
+  Cons_list<Mudela_item> items;
+  for (Cons<Mudela_item>* i = mudela_item_p_list_.head_; i; i = i->next_)
+    items.append (new Cons<Mudela_item> (i->car_, 0));
+
+  while (items.size_i ())
+    eat_voice (items);
+}