]> git.donarmstrong.com Git - lilypond.git/commitdiff
patch::: 0.1.9.jcn2: pats
authorJan Nieuwenhuizen <janneke@gnu.org>
Wed, 20 Aug 1997 14:32:20 +0000 (16:32 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Wed, 20 Aug 1997 14:32:20 +0000 (16:32 +0200)
pl 9.jcn2
- redo of mi2mu frontend (midi-parser)
- bf: String_convert::bin2_i; added bin2_u
- bf's: Binary_source_file
- bf: constr. Tempo/Timing_req

34 files changed:
NEWS
VERSION
bin/genheader.in
flower/include/string-convert.hh
flower/string-convert.cc
lib/binary-source-file.cc
lib/include/binary-source-file.hh
lib/include/source.hh
lib/source-file.cc
lib/source.cc
lily/include/command-request.hh
lily/score.cc
mi2mu/Makefile
mi2mu/TODO
mi2mu/VERSION
mi2mu/include/mi2mu-proto.hh
mi2mu/include/midi-parser.hh [new file with mode: 0644]
mi2mu/include/midi-score-parser.hh [new file with mode: 0644]
mi2mu/include/midi-track-parser.hh [new file with mode: 0644]
mi2mu/include/mudela-score.hh
mi2mu/include/my-midi-lexer.hh
mi2mu/include/my-midi-parser.hh
mi2mu/main.cc
mi2mu/midi-lexer.l
mi2mu/midi-parser.cc [new file with mode: 0644]
mi2mu/midi-parser.y
mi2mu/midi-score-parser.cc [new file with mode: 0644]
mi2mu/midi-track-parser.cc [new file with mode: 0644]
mi2mu/mudela-item.cc
mi2mu/mudela-score.cc
mi2mu/mudela-staff.cc
mi2mu/mudela-stream.cc
mi2mu/my-midi-lexer.cc
mi2mu/my-midi-parser.cc

diff --git a/NEWS b/NEWS
index c0a1a5bda08e83d54fd3ebf0525e83b27ad8d53d..741694ca8d53b1da2ee92db5aa5ef09a732ab5c0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+pl 9.jcn2
+       - redo of mi2mu frontend (midi-parser)
+       - bf: String_convert::bin2_i; added bin2_u
+       - bf's: Binary_source_file
+       - bf: constr. Tempo/Timing_req
+
 pl 9   
        - declare rhythic_request
        - preliminary support for real \mudelaheaders
diff --git a/VERSION b/VERSION
index ba28d0f309bf0574846d9d1e76de8cc71de691df..2f45472eddbab1b397a82ec56b3b81de2e7cd7b6 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -3,4 +3,4 @@ TOPLEVEL_MINOR_VERSION = 1
 TOPLEVEL_PATCH_LEVEL = 9
 
 # use to send patches, always empty for released version:
-TOPLEVEL_MY_PATCH_LEVEL = .jcn1
+TOPLEVEL_MY_PATCH_LEVEL = .jcn2
index 9b6bb4d6cb8f4d6d4a403d58fa8bc22d7ab0ba9a..8643a3794fdaf8b264d683778f4ef0d89ca929a5 100644 (file)
@@ -6,7 +6,7 @@ my $fn;
 sub
     do_init
 {
-    $MAILADRESS=$ENV{MAILADRESS};
+    $MAILADDRESS=$ENV{MAILADDRESS};
      @pw=(getpwuid($<));
      $username=$pw[6];
 
@@ -34,7 +34,7 @@ sub
 
   source file of $PROJECT
 
-  (c) 1997 $username <$MAILADRESS>
+  (c) 1997 $username <$MAILADDRESS>
 */\n";
     print $headstr;
 }
index 63785ac28d6e94becef8ebb5c3ffa40c60f5b4ae..1d3f5d0300130f72326f1e9ee8037410c7e19d06 100644 (file)
@@ -21,7 +21,8 @@ public:
     static String bin2dec_str (String bin_str);
     static String bin2hex_str (String bin_str);
     static String dec2bin_str (String str);
-    static int bin2_i (String str);
+    static int bin2_i (String bin_str);
+    static unsigned bin2_u (String bin_str);
     static String char_str (char c, int n);
     static int dec2_i (String dec_str);
     static double dec2_f (String dec_str);
index c105169cee55d179e8963dd9dbb95febefb08741..5acdb4c88f55003a16702b66771773275df37b36 100644 (file)
@@ -40,15 +40,21 @@ String_convert::bin2hex_str (String bin_str)
 int
 String_convert::bin2_i (String bin_str)
 {
-  assert (bin_str.length_i() <= 4);
+  return bin2_u (bin_str);
+}
+
+unsigned
+String_convert::bin2_u (String bin_str)
+{
+  assert (bin_str.length_i() <= (int)sizeof(unsigned));
 
-  int result_i = 0;
+  unsigned result_u = 0;
   for ( int i = 0; i < bin_str.length_i(); i++) 
     {
-       result_i <<= 8;
-       result_i += (Byte)bin_str[ i ];
+       result_u <<= 8;
+       result_u += (Byte)bin_str[ i ];
     }
-  return result_i;
+  return result_u;
 }
 
 // breendet imp from String
index 666012f0c62c9a7a35a3dc30454891493de69dd0..8c4aac44741aeb2cf7716848fab5b1830ca4fcfb 100644 (file)
@@ -27,7 +27,7 @@ Binary_source_file::~Binary_source_file()
 }
 
 String
-Binary_source_file::error_str( char const* pos_ch_c_l )
+Binary_source_file::error_str( char const* pos_ch_c_l ) const
 {
     assert( this );
     if ( !in_b( pos_ch_c_l ) )
@@ -53,7 +53,7 @@ Binary_source_file::error_str( char const* pos_ch_c_l )
 }
 
 int
-Binary_source_file::line_i( char const* pos_ch_c_l )
+Binary_source_file::line_i( char const* pos_ch_c_l ) const
 {
     if ( !in_b( pos_ch_c_l ) )
        return 0;
index bc8279f6abe54044a5e4867fda833f9ff8adeed4..63127ea9ad03b8b43f8840346117fc8ca507cacb 100644 (file)
@@ -13,8 +13,8 @@ public:
        Binary_source_file( String& filename_str );
        virtual ~Binary_source_file();
 
-       virtual String error_str( char const* pos_ch_c_l );
-       virtual int line_i( char const* pos_ch_c_l );
+       virtual String error_str( char const* pos_ch_c_l ) const;
+       virtual int line_i( char const* pos_ch_c_l ) const;
 };
 
 #endif // BINARY_SOURCE_FILE_HH //
index 1d199671ffa1383977a14c42ae3dfc9b8ba3a427..fc0ca2728d196f89759f8abf826039489df54036 100644 (file)
 class Sources 
 {
 public:
+    Sources();
+
     Source_file * get_file_l( String &filename );
     Source_file* sourcefile_l( char const* ch_C );
     void set_path(File_path*p_C);
-    Sources();
     void set_binary(bool);
-    ~Sources();
+
 private:
     const File_path * path_C_;
     void add( Source_file* sourcefile_p );
index a67b46630016a03a21c33bcb564901d6a3e26ed2..4ac7017f051eb67ca1a774ba31e6fc1458b88e4b 100644 (file)
@@ -57,12 +57,14 @@ Source_file::name_str()const
 {
     return name_str_;
 }
+
 Source_file::~Source_file()
 {
     delete istream_p_;
     istream_p_ = 0;
     delete storage_p_;
 }
+
 String
 Source_file::error_str( char const* pos_ch_C )const
 {
index e60041553c84050e6237ce1e6ed35a5a714bdb2c..dd1c5f27d60f440088ef0ad26ce89d6c9692bd3a 100644 (file)
 #include "source.hh"
 #include "path.hh"
 
+Sources::Sources()
+{
+    path_C_= 0;
+    binary_b_ = false;
+}
+
+void
+Sources::set_binary(bool bo)
+{
+       binary_b_ = bo;
+}
+
 void
 Sources::set_path(File_path *f_C)
 {
@@ -47,12 +59,6 @@ Sources::get_file_l(String &file_str ) //UGH
     return f_p;
 }
 
-Sources::Sources()
-{
-    path_C_= 0;
-    binary_b_ = false;
-}
-
 void
 Sources::add( Source_file* sourcefile_p )
 {
@@ -74,5 +80,3 @@ Sources::sourcefile_l( char const* ch_C )
     return 0;
 }
 
-Sources::~Sources()
-{}
index 1a78f14d758b8a5917032eea588ab794b2b0b2c3..f5adca4428b9194c647087aa2caf2b61aed9d80f 100644 (file)
@@ -53,7 +53,6 @@ class Timing_req  : public Command_req  {
 public:
     REQUESTMETHODS(Timing_req, timing);
     virtual Tempo_req * tempo(){return 0; }
-    Tempo_req();
 };
 
 
index fd11b56542a483f23861e67cb84eb77a1d1685cd..f421259e3fffdd8d5a5570db5a6858e58659685b 100644 (file)
@@ -28,8 +28,9 @@ extern String default_out_fn;
 
 Score::Score()
 {
-  header_p_ =0;
-  pscore_p_=0;
+  header_p_ = 0;
+  music_p_ = 0;
+  pscore_p_ = 0;
   audio_score_p_ = 0;
   paper_p_ = 0;
   midi_p_ = 0;
@@ -42,7 +43,7 @@ Score::Score (Score const &s)
   music_p_ = s.music_p_->clone();
   midi_p_ = new Midi_def (*s.midi_p_);
   paper_p_ = new Paper_def (*s.paper_p_);
-  header_p_ = new Header(*s.header_p_);
+  header_p_ = new Header (*s.header_p_);
 }
 
 Score::~Score()
index 7100902c8fa69f12397afbdafe4dac39fa774659..85bcfed18e8ceb8dc3b90122fb59c4f5bd381658 100644 (file)
@@ -75,7 +75,8 @@ DEPFILES = $(wildcard $(depdir)/*.dep)
 -include /dev/null $(DEPFILES)
 #
 localclean:
-       rm -f $(outdir)/{midi-parser,midi-lexer}.*
+# obsoliet
+#      rm -f $(outdir)/{midi-parser,midi-lexer}.*
 
 localinstall: installexe
 
index e9cb89c1431a2cd7624fd1826d8d29ae18312e08..e5221769554046fdbae1a4416b2f52a10f172a0a 100644 (file)
@@ -6,16 +6,6 @@ grep for TODO and ugh/ugr
 
 IMPORTANT
 
-       * fix parser: either 
-          - parse into midi-items (merge with lily/midi-*) and pass
-            these nealy up, same for track and score.  look at all
-            tracks a time (vertically through score), creating columns 
-            and mudela items in time-order (no searching for columns).
-         or
-          - junk lex/yacc altogether, parse on byte level, straight
-            from memore, vertically through score.  there might be no
-            need for midi-items, here.
-
        * get rid of (last few?) midi-specifics in mudela-*
 
        * find / remove trend (tempo) of mudela columns
@@ -64,16 +54,8 @@ PROJECTS
 
 BUGS
 
-       * mi2mu nonexist.midi ?
-
        * output of 0 duration c'0
 
-       * no output on certain midis
-
-       * silly progress indicator upon mudela output
-
-       * check for illegal track names, e.g. "Piano________ = \melodic"
-
        * array memleaks(?): use Link_array / create Pointer_array? 
 
        * fix "#undef MEVENT_LIST" source tree: Array<Midi_event*> 
index 22b9eff149db9de3da073571260d946582181667..bbbdde49e2748096232ea62ec58d745a685bc3ff 100644 (file)
@@ -1,6 +1,6 @@
 MAJOR_VERSION = 0
 MINOR_VERSION = 0
-PATCH_LEVEL = 19
+PATCH_LEVEL = 20
 # use to send patches, always empty for released version:
 MY_PATCH_LEVEL = 
 #
index 5aa6579ae3a12f6b9ae374ef9581b21058882a72..da4d89ba548f96df297119f4f1f6a02641ca2978 100644 (file)
 #ifndef MI2MU_PROTO_HH
 #define MI2MU_PROTO_HH
 
-
+class Midi_parser;
+struct Midi_parser_info;
+class Midi_score_parser;
+class Midi_track_parser;
 class Mudela_stream;
 class Mudela_item;
 class Mudela_key;
@@ -21,8 +24,6 @@ class Mudela_text;
 class Mudela_score;
 class Mudela_staff;
 class Mudela_voice;
-class My_midi_lexer;
-class My_midi_parser;
 class Mudela_column;
 
 #endif // MI2MU_PROTO_HH
diff --git a/mi2mu/include/midi-parser.hh b/mi2mu/include/midi-parser.hh
new file mode 100644 (file)
index 0000000..55c75a5
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+  midi-parser.hh -- declare Midi_parser
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+*/
+
+
+#ifndef MIDI_PARSER_HH
+#define MIDI_PARSER_HH
+
+// must, gcc 2.7.2{,.1} hits ico on midi-track-parser.cc:134 (@Midi_note)
+#define INLINES
+
+#ifdef INLINES
+
+#define next_byte() (inline_next_byte (__FUNCTION__))
+#define peek_byte() (inline_peek_byte (__FUNCTION__))
+#define forward_byte_L(n) (inline_forward_byte_L (__FUNCTION__, n))
+
+#else
+
+#define next_byte()\
+  ((info_l_->byte_L_ < info_l_->end_byte_L_ ?\
+    *info_l_->byte_L_++\
+   : (Byte const)exit (__FUNCTION__": unexpected EOF")));
+
+#define peek_byte()\
+  ((info_l_->byte_L_ < info_l_->end_byte_L_ ?\
+    *info_l_->byte_L_\
+  : (Byte const)exit (__FUNCTION__": unexpected EOF")));
+
+#define forward_byte_L(n) (inline_forward_byte_L (__FUNCTION__, n))
+
+#endif
+
+#include "proto.hh"
+#include "moment.hh"
+
+struct Midi_parser_info
+{
+  Midi_parser_info();
+  int division_1_i_;
+  int format_i_;
+  int tracks_i_;
+  int errorlevel_i_;
+  Byte const* byte_L_;
+  Byte const* end_byte_L_;
+  Source_file* source_l_;
+  Moment bar_mom_;
+};
+
+#include "string.hh"
+
+class Midi_parser
+{
+public:
+  Midi_parser ();
+
+  Midi_parser_info* info_l_;
+
+protected:
+//  Byte const* inline_forward_byte_L (int n)
+  Byte const* inline_forward_byte_L (char const* fun, int n)
+  {
+    if (info_l_->byte_L_ + n < info_l_->end_byte_L_ )
+      {
+      Byte const* p = info_l_->byte_L_;
+      info_l_->byte_L_ += n;
+      return p;
+    }
+//    exit (__FUNCTION__": unexpected EOF");
+    exit (String (fun) + ": unexpected EOF");
+    return 0;
+  }
+
+#ifdef INLINES
+//  Byte inline_next_byte () 
+  Byte inline_next_byte (char const* fun) 
+    {
+      if (info_l_->byte_L_ < info_l_->end_byte_L_)
+        return *info_l_->byte_L_++;
+//    exit (__FUNCTION__": unexpected EOF");
+      exit (String (fun) + ": unexpected EOF");
+      return 0;
+    }
+
+//  Byte inline_peek_byte ()
+  Byte inline_peek_byte (char const* fun)
+    {
+      if (info_l_->byte_L_ < info_l_->end_byte_L_)
+       return *info_l_->byte_L_;
+//      exit (__FUNCTION__": unexpected EOF");
+      exit (String (fun) + ": unexpected EOF");
+      return 0;
+    }
+#endif
+
+  int get_i (int);
+  String get_str (int);
+  unsigned get_u (int);
+  int get_var_i ();
+  int exit (String);
+  void error (String);
+  String message (String);
+  void warning (String);
+};
+
+#endif // MIDI_PARSER_HH
diff --git a/mi2mu/include/midi-score-parser.hh b/mi2mu/include/midi-score-parser.hh
new file mode 100644 (file)
index 0000000..f9c8b64
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  midi-score-parser.hh -- declare 
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+*/
+
+
+#ifndef MIDI_SCORE_PARSER_HH
+#define MIDI_SCORE_PARSER_HH
+
+#include "midi-parser.hh"
+#include "proto.hh"
+#include "mi2mu-proto.hh"
+#include "parray.hh"
+
+class Midi_score_parser : public Midi_parser
+{
+public:
+  Mudela_score* parse (String filename_str, Sources*);
+
+private:
+  void open (String filename_str, Sources*);
+
+  void parse_header ();
+  // why the #*&$#{%) has Link_array another behaviour than Link_list??
+  //  int find_earliest_i (Link_array<Midi_track_parser*>& tracks);
+  int find_earliest_i (Link_array<Midi_track_parser>& tracks);
+  Mudela_score* parse_score ();
+};         
+
+#endif // MIDI_SCORE_PARSER_HH
diff --git a/mi2mu/include/midi-track-parser.hh b/mi2mu/include/midi-track-parser.hh
new file mode 100644 (file)
index 0000000..021197c
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+  midi-track-parser.hh -- declare 
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+*/
+
+
+#ifndef MIDI_TRACK_PARSER_HH
+#define MIDI_TRACK_PARSER_HH
+
+#include "proto.hh"
+#include "plist.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);
+  ~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_;
+  Link_list<Mudela_note*> open_note_l_list_;
+  Mudela_staff* mudela_staff_p_;
+  Midi_parser_info* track_info_p_;
+};
+
+#endif // MIDI_TRACK_PARSER_HH
index 6d752fe1d6529e132f35e1e081bbb9db8bd8e121..d1102f08088f80d234097c7cd1f183529f52746e 100644 (file)
@@ -20,7 +20,8 @@ public:
     void add_item (Mudela_item* mudela_item_p);
     void add_staff (Mudela_staff* mudela_staff_p);
 
-    Mudela_column* mudela_column_l (Moment mom);
+    Mudela_column* find_column_l (Moment mom);
+    Mudela_column* get_column_l (Moment mom);
 
     void output (String filename_str);
     void process();
@@ -36,10 +37,9 @@ private:
     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?
+   // wants Pointer_array!
+//    Pointer_list<Mudela_column*> mudela_column_p_list_;
     Link_array<Mudela_column> column_l_array_;
 
 // ugh, ugh, ugh
index 7b8b809aa7c46b0628d7369c69ea7260ff4b3203..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,41 +0,0 @@
-//
-// my-midi-lexer.hh -- declare My_midi_lexer
-//
-// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
-
-#ifndef MY_MIDI_LEXER_HH
-#define MY_MIDI_LEXER_HH
-
-#include <FlexLexer.h>
-#include "proto.hh"
-#include "varray.hh"
-#include "string.hh"
-
-int yylex();
-void yyerror(const char *s);
-
-/// (midi_lexer)
-class My_midi_lexer : yyFlexLexer {
-public:
-    My_midi_lexer (String& filename_str, Sources*);
-    ~My_midi_lexer();
-
-    int close_i();
-    void error (char const* sz_l);
-    char const* here_ch_C();
-    static int varint2_i (String str);
-    int yylex();
-    Source_file* source_file_l_ ;
-
-private:
-    int char_count_;
-    int running_status_i_;
-
-public: // ugh
-    int errorlevel_i_;
-};
-
-extern My_midi_lexer* midi_lexer_l_g;
-
-#endif // MY_MIDI_LEXER_HH
-
index bcebb14ff6e78c699c7645974b8d3f27cd6d1692..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,75 +0,0 @@
-//
-// my-midi-parser.hh -- declare My_midi_parser
-//
-// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
-
-#ifndef MY_MIDI_PARSER_HH
-#define MY_MIDI_PARSER_HH
-
-#include "mi2mu-proto.hh"
-#include "proto.hh"
-#include "plist.hh"
-#include "string.hh"
-#include "moment.hh"
-
-#include "string.hh"
-#include "moment.hh"
-
-int yyparse();
-
-/** 
-  An interface to the YACC midi parser.
-  (midi_parser)
- */
-class My_midi_parser {
-public:
-    My_midi_parser (String filename_str,Sources *);
-    ~My_midi_parser();
-
-    void add_score (Mudela_score* mudela_score_p);
-    void error (char const* sz_l);
-    int parse();
-    void forward (int i);
-    Moment at_mom();
-    void note_begin (int channel_i, int pitch_i, int dyn_i);
-    void note_end (int channel_i, int pitch_i, int aftertouch_i);
-    void note_end_all();
-
-    void reset();
-    void set_division_4 (int division_4_i);
-    void set_key (int accidentals_i, int minor_i);
-    void set_meter (int num_i, int den_i, int clocks_i, int count_32_i);
-    void set_tempo (int useconds_per_4_i);
-
-    int bar_i_;
-
-    // ugh
-    int track_i_;
-    String filename_str_;
-    String copyright_str_;
-    String instrument_str_;
-    String track_name_str_;
-
-    // ugh
-    Mudela_key* mudela_key_p_;
-    Mudela_meter* mudela_meter_p_;
-    Mudela_tempo* mudela_tempo_p_;
-
-    Mudela_staff* mudela_staff_l_;
-    Mudela_score* mudela_score_p_;
-    Mudela_column* mudela_column_l_;
-
-private:
-    Link_list<Mudela_note*> open_mudela_note_l_list_;
-
-    int division_1_i_;
-
-    char const* defined_ch_C_;
-    int fatal_error_i_;
-    My_midi_lexer* midi_lexer_p_;
-};
-
-extern My_midi_parser* midi_parser_l_g;
-
-#endif // MY_MIDI_PARSER_HH
-
index c138322590561659d39ed54018392462f5f199c1..25dfab069453c28284ec76733af06eac77339b82 100644 (file)
@@ -4,6 +4,7 @@
 //
 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
 
+#include <assert.h>
 #include "string-convert.hh"
 #include "lgetopt.hh"
 #include "path.hh"
 #include "source.hh"
 
 #include "mi2mu-global.hh"
-#include "my-midi-parser.hh"
+#include "midi-score-parser.hh"
 #include "mudela-score.hh"
 #include "version.hh"
 
+// ugh
+String filename_str_g;
+
+// ugh
+Mudela_score* mudela_score_l_g = 0;
+
 Sources source;
-Sources* source_l_g = &source;
 
 static File_path path;
 
@@ -102,8 +108,8 @@ main (int argc_i, char* argv_sz_a[])
   Getopt_long getopt_long (argc_i, argv_sz_a, long_option_init_a);
 
   String output_str;
-  while  (Long_option_init const* long_option_init_p = getopt_long())
-       switch  (long_option_init_p->shortname) 
+  while (Long_option_init const* long_option_init_p = getopt_long())
+       switch (long_option_init_p->shortname) 
          {
        case 'b':
            Duration_convert::no_quantify_b_s = true;
@@ -136,7 +142,7 @@ main (int argc_i, char* argv_sz_a[])
        case 's': 
          {
                int i = String_convert::dec2_i (getopt_long.optional_argument_ch_C_);
-               if  (!i) 
+               if (!i) 
                  {
                    identify();
                    usage();
@@ -166,32 +172,31 @@ main (int argc_i, char* argv_sz_a[])
   identify();
 
   path.add ("");
-  source_l_g->set_path (&path);
+  source.set_binary (true);
+  source.set_path (&path);
 
   char const* arg_sz = 0;
-  while  ( (arg_sz = getopt_long.get_next_arg())) 
+  while ( (arg_sz = getopt_long.get_next_arg ())) 
     {
-       My_midi_parser midi_parser (arg_sz, & source);
-       midi_parser_l_g = &midi_parser;
+       filename_str_g = arg_sz;
+       Midi_score_parser midi_parser;
+       Mudela_score* score_p = midi_parser.parse (arg_sz, &source);
+
+       if (!score_p)
+         return 1;
 
-       int error_i = midi_parser.parse();
-       if  (error_i)
-           return error_i;
+       mudela_score_l_g = score_p;
+       score_p->process();
 
-       if  (!output_str.length_i()) 
+       if (!output_str.length_i ()) 
          {
            String d, dir, base, ext;
-
            split_path (arg_sz, d, dir, base, ext);
-           
            output_str = base + ext + ".ly";
          }
 
-       assert (midi_parser.mudela_score_p_);
-       midi_parser.mudela_score_p_->process();
-       midi_parser.mudela_score_p_->output (output_str);
-
-       midi_parser_l_g = 0;
+       score_p->output (output_str);
+       delete score_p;
     }
   return 0;
 }
index 485312b974627fc70728435fce449ce207d9bc18..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,522 +0,0 @@
-%{//-*-Fundamental-*-
-// midi-lexer.l
-
-/* 
-  yes, i know that midi is not really a (n evolving?) language,
-  and that using lex/yacc to parse midi is overkill, as well as
-  a grand example of misuse and asking for performance loss.
-
-  it is, however, quite robust, simple, and very easy to extend
-  incrementally.
- */
-
-/*
-  backup rules
-
-  after making a change to the lexer rules, run 
-      flex -b <this lexer file>
-  and make sure that 
-      lex.backup
-  contains no backup states, but only the reminder
-      Compressed tables always back up.
-  (don-t forget to rm lex.yy.cc :-)
- */
-
-#include "string-convert.hh"
-#include "mi2mu-global.hh"
-#include "mi2mu-proto.hh"
-#include "my-midi-lexer.hh"
-#include "midi-parser.hh"
-
-#define YY_USER_ACTION char_count_ += YYLeng(); // ugh
-
-%}
-
-%option c++
-%option noyywrap
-%option nodefault
-%option debug
-%option yyclass="My_midi_lexer"
-%option stack
-
-%x data
-%x event
-%x i8
-%x u8
-%x int16
-%x int32
-%x meta_event
-%x track
-
-U8             [\x00-\xff]
-I8             {U8}
-INT16          {U8}{U8}
-BACKUP_INT16_0 {U8}
-INT32          {INT16}{INT16}
-BACKUP_INT32_0 {U8}
-BACKUP_INT32_1 {U8}{U8}
-BACKUP_INT32_2 {INT16}{U8}
-INT7_8UNSET    [\x00-\x7f]
-INT7_8SET      [\x80-\xff]
-VARINT         {INT7_8SET}{0,3}{INT7_8UNSET}
-BACKUP_VARINT_0 {INT7_8SET}
-BACKUP_VARINT_1 {INT7_8SET}{INT7_8SET}
-BACKUP_VARINT_2 {INT7_8SET}{INT7_8SET}{INT7_8SET}
-
-HEADER         MThd
-TRACK          MTrk
-BACKUP_TOP_0   MT
-BACKUP_TOP_1   MTh
-BACKUP_TOP_2   MTr
-
-RUNNING_STATUS [\x00-\x5f]
-DATA_ENTRY     [\x60-\x79]
-ALL_NOTES_OFF  [\x7a-\x7f]
-NOTE_OFF       [\x80-\x8f]
-NOTE_ON                [\x90-\x9f]
-POLYPHONIC_AFTERTOUCH  [\xa0-\xaf]
-CONTROLMODE_CHANGE     [\xb0-\xbf]
-PROGRAM_CHANGE [\xc0-\xcf]
-CHANNEL_AFTERTOUCH     [\xd0-\xdf]
-PITCHWHEEL_RANGE       [\xe0-\xef]
-
-SYSEX_EVENT1   [\xf0]
-SYSEX_EVENT2   [\xf7]
-
-META_EVENT     [\xff]
-
-SEQUENCE       [\x00][\x02]
-YYTEXT         [\x01] 
-YYCOPYRIGHT    [\x02]
-YYTRACK_NAME   [\x03]
-YYINSTRUMENT_NAME      [\x04]
-YYLYRIC                [\x05]
-YYMARKER               [\x06]
-YYCUE_POINT    [\x07]
-
-END_OF_TRACK   [\x2f][\x00]
-TEMPO          [\x51][\x03]
-SMPTE_OFFSET   [\x54][\x05]
-TIME           [\x58][\x04]
-KEY            [\x59][\x02]
-SSME           [\0x7f][\x03]
-
-%%
-
-{HEADER} {
-       LOGOUT(DEBUG_ver) << "lex: header" << endl;
-       yy_push_state(int16); 
-       yy_push_state(int16); 
-       yy_push_state(int16); 
-       yy_push_state(int32); 
-       return HEADER;
-}
-
-{TRACK} {
-       LOGOUT(DEBUG_ver) << "lex: track" << endl;
-       yy_push_state(track); 
-       yy_push_state(int32); 
-       return TRACK;
-}
-{U8}   {
-       error(String("top level: header expected: ")
-               + String_convert::bin2hex_str(String(*YYText())));
-       exit(1);
-}
-{BACKUP_TOP_0} {
-       error(String("top level: header expected: ")
-               + String_convert::bin2hex_str(String(*(YYText()))));
-       exit(1);
-}
-{BACKUP_TOP_1} {
-       error(String("top level: header expected: ")
-               + String_convert::bin2hex_str(String(*(YYText()))));
-       exit(1);
-}
-{BACKUP_TOP_2} {
-       error(String("top level: header expected: ")
-               + String_convert::bin2hex_str(String(*(YYText()))));
-       exit(1);
-}
-<int32>{INT32} { // really signed? 
-       LOGOUT(DEBUG_ver) << "lex: int32" << endl;
-       assert(YYLeng() == 4);
-       String str((Byte const*)YYText(), YYLeng());
-       yylval.i = String_convert::bin2_i(str);
-       yy_pop_state();
-       return INT32;
-}
-<int32>{BACKUP_INT32_0} {
-       error(String("int32: int32 expected: ")
-               + String_convert::bin2hex_str(String(*(YYText()))));
-       exit(1);
-}
-<int32>{BACKUP_INT32_1} {
-       error(String("int32: int32 expected: ")
-               + String_convert::bin2hex_str(String(*(YYText()))));
-       exit(1);
-}
-<int32>{BACKUP_INT32_2} {
-       error(String("int32: int32 expected: ")
-               + String_convert::bin2hex_str(String(*(YYText()))));
-       exit(1);
-}
-<int16>{INT16} { // really signed?
-       LOGOUT(DEBUG_ver) << "lex: int16" << endl;
-       assert(YYLeng() == 2);
-       String str((Byte const*)YYText(), YYLeng());
-       yylval.i = (short)String_convert::bin2_i(str);
-       yy_pop_state();
-       return INT16;
-}
-<int16>{BACKUP_INT16_0} {
-       error(String("int16: int16 expected: ")
-               + String_convert::bin2hex_str(String(*(YYText()))));
-       exit(1);
-}
-<i8>{I8}       {
-       LOGOUT(DEBUG_ver) << "lex: i8" << endl;
-       assert(YYLeng() == 1);
-//     yylval.byte = *(signed char*)YYText();
-       yylval.i = *(signed char*)YYText();
-       yy_pop_state(); 
-       return I8;
-}
-<u8>{U8}       {
-       LOGOUT(DEBUG_ver) << "lex: u8" << endl;
-       assert(YYLeng() == 1);
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       yy_pop_state(); 
-       return U8;
-}
-
-<track>{VARINT} {
-       String str((Byte const*)YYText(), YYLeng());
-       yylval.i = My_midi_lexer::varint2_i(str);
-       LOGOUT(DEBUG_ver) << String("lex: track: varint(") 
-               + String(yylval.i) + "): "
-               + String_convert::bin2hex_str(str) << endl;
-       yy_push_state(event); 
-       return VARINT;
-}
-<track>{U8}    {
-       error(String("track: illegal byte: ") 
-               + String_convert::bin2hex_str(String(*YYText())));
-       exit(1);
-}
-<track>{BACKUP_VARINT_0}{U8} {
-       error(String("track: varint expected: ")
-               + String_convert::bin2hex_str(String(*(YYText()))));
-       exit(1);
-}
-<track>{BACKUP_VARINT_1}{U8} {
-       error(String("track: varint expected: ")
-               + String_convert::bin2hex_str(String(*(YYText()))));
-       exit(1);
-}
-<track>{BACKUP_VARINT_2}{U8} {
-       error(String("track: varint expected: ")
-               + String_convert::bin2hex_str(String(*(YYText()))));
-       exit(1);
-}
-<event>{RUNNING_STATUS}        {
-//     yylval.byte = *(Byte*)YYText();
-//     yylval.i = *(Byte*)YYText();
-       yylval.i = running_status_i_;
-       LOGOUT(DEBUG_ver) << String ("lex: running status: ") + String(yylval.i) << endl;
-       /*
-        'running status' rather means 'missing status'.
-        we'll put the running status data back, prepend (unput) 
-        the running status, and try again.
-        */
-       yyless(0);
-       unput(running_status_i_);
-       return RUNNING_STATUS;
-}
-<event>{DATA_ENTRY}    {
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       LOGOUT(DEBUG_ver) << String ("lex: undefined data entry: ") + String(yylval.i) << endl;
-       yy_pop_state(); 
-       yy_push_state(u8);
-       return DATA_ENTRY;
-}
-<event>{ALL_NOTES_OFF} {
-       LOGOUT(DEBUG_ver) << "lex: all note off" << endl;
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       LOGOUT(DEBUG_ver) << String ("lex: all notes off: ") + String(yylval.i) << endl;
-       yy_pop_state(); 
-       yy_push_state(u8);
-       yy_push_state(u8);
-       return ALL_NOTES_OFF;
-}
-<event>{NOTE_OFF}      {
-       LOGOUT(DEBUG_ver) << "lex: note off" << endl;
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       running_status_i_ = yylval.i;
-       yy_pop_state(); 
-       yy_push_state(u8);
-       yy_push_state(u8);
-       return NOTE_OFF;
-}
-<event>{NOTE_ON}       {
-       LOGOUT(DEBUG_ver) << "lex: note on" << endl;
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       running_status_i_ = yylval.i;
-       yy_pop_state(); 
-       yy_push_state(u8);
-       yy_push_state(u8);
-       return NOTE_ON;
-}
-<event>{POLYPHONIC_AFTERTOUCH} {
-       LOGOUT(DEBUG_ver) << "lex: polyphonic aftertouch" << endl;
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       running_status_i_ = yylval.i;
-       yy_pop_state(); 
-       yy_push_state(u8);
-       yy_push_state(u8);
-       return POLYPHONIC_AFTERTOUCH;
-}
-<event>{CONTROLMODE_CHANGE}    {
-       LOGOUT(DEBUG_ver) << "lex: controlmode change" << endl;
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       running_status_i_ = yylval.i;
-       yy_pop_state(); 
-       yy_push_state(u8);
-       yy_push_state(u8);
-       return CONTROLMODE_CHANGE;
-}
-<event>{PROGRAM_CHANGE}        {
-       LOGOUT(DEBUG_ver) << "lex: program change" << endl;
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       running_status_i_ = yylval.i;
-       yy_pop_state(); 
-       yy_push_state(u8);
-       return PROGRAM_CHANGE;
-}
-<event>{CHANNEL_AFTERTOUCH}    {
-       LOGOUT(DEBUG_ver) << "lex: channel aftertouch" << endl;
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       running_status_i_ = yylval.i;
-       yy_pop_state(); 
-       yy_push_state(u8);
-       yy_push_state(u8);
-       return CHANNEL_AFTERTOUCH;
-}
-<event>{PITCHWHEEL_RANGE} {
-       LOGOUT(DEBUG_ver) << "lex: pitchwheel range" << endl;
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       running_status_i_ = yylval.i;
-       yy_pop_state(); 
-       yy_push_state(u8);
-       yy_push_state(u8);
-       return PITCHWHEEL_RANGE;
-}
-<event>{SYSEX_EVENT1} {        // len data
-       LOGOUT(DEBUG_ver) << "lex: sysex1" << endl;
-       yy_pop_state(); 
-       yy_push_state(data);
-       return SYSEX_EVENT1;
-}
-<event>{SYSEX_EVENT2} {        // len data
-       LOGOUT(DEBUG_ver) << "lex: sysex2" << endl;
-       yy_pop_state(); 
-//     yy_push_state(u8); //?
-       yy_push_state(data);
-       return SYSEX_EVENT2;
-}
-<event>{META_EVENT}    {
-       LOGOUT(DEBUG_ver) << "lex: meta" << endl;
-       yy_push_state(meta_event);
-       return META_EVENT;
-}
-<event>{U8}    {
-       error(String("event: illegal byte: ") 
-               + String_convert::bin2hex_str(String(*YYText())));
-       exit(1);
-}
-<meta_event>{SEQUENCE} {       // ssss sequence number
-       LOGOUT(DEBUG_ver) << "lex: sequence" << endl;
-       yy_pop_state();
-       yy_pop_state();
-       yy_push_state(int16);
-       return SEQUENCE;
-}
-<meta_event>{YYTEXT}   {               // len data
-       LOGOUT(DEBUG_ver) << "lex: text" << endl;
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       yy_pop_state();
-       yy_pop_state();
-       yy_push_state(data);
-       return YYTEXT;
-}
-<meta_event>{YYCOPYRIGHT}      {
-       LOGOUT(DEBUG_ver) << "lex: copyright" << endl;
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       yy_pop_state();
-       yy_pop_state();
-       yy_push_state(data);
-       return YYCOPYRIGHT;
-}
-<meta_event>{YYTRACK_NAME}     {
-       LOGOUT(DEBUG_ver) << "lex: track name" << endl;
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       yy_pop_state();
-       yy_pop_state();
-       yy_push_state(data);
-       return YYTRACK_NAME;
-}
-<meta_event>{YYINSTRUMENT_NAME}        {
-       LOGOUT(DEBUG_ver) << "lex: instrument name" << endl;
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       yy_pop_state();
-       yy_pop_state();
-       yy_push_state(data);
-       return YYINSTRUMENT_NAME;
-}
-<meta_event>{YYLYRIC}  {
-       LOGOUT(DEBUG_ver) << "lex: lyric" << endl;
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       yy_pop_state();
-       yy_pop_state();
-       yy_push_state(data);
-       return YYLYRIC;
-}
-<meta_event>{YYMARKER} {
-       LOGOUT(DEBUG_ver) << "lex: marker" << endl;
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       yy_pop_state();
-       yy_pop_state();
-       yy_push_state(data);
-       return YYMARKER;
-}
-<meta_event>{YYCUE_POINT}      {
-       LOGOUT(DEBUG_ver) << "lex: cue point" << endl;
-//     yylval.byte = *(Byte*)YYText();
-       yylval.i = *(Byte*)YYText();
-       yy_pop_state();
-       yy_pop_state();
-       yy_push_state(data);
-       return YYCUE_POINT;
-}
-<meta_event>{TEMPO}    {       // tttttt usec
-       LOGOUT(DEBUG_ver) << "lex: tempo" << endl;
-       yy_pop_state();
-       yy_pop_state();
-       yy_push_state(u8);
-       yy_push_state(u8);
-       yy_push_state(u8);
-       return TEMPO;
-}
-<meta_event>{SMPTE_OFFSET}     {               // hr mn se fr ff
-       LOGOUT(DEBUG_ver) << "lex: smpte offset" << endl;
-       yy_pop_state();
-       yy_pop_state();
-       yy_push_state(u8);
-       yy_push_state(u8);
-       yy_push_state(u8);
-       yy_push_state(u8);
-       yy_push_state(u8);
-       return SMPTE_OFFSET;
-}
-<meta_event>{TIME}     {               // nn dd cc bb
-       LOGOUT(DEBUG_ver) << "lex: time" << endl;
-       yy_pop_state();
-       yy_pop_state();
-       yy_push_state(u8);
-       yy_push_state(u8);
-       yy_push_state(u8);
-       yy_push_state(u8);
-       return TIME;
-}
-<meta_event>{KEY}      {       // sf mi
-       LOGOUT(DEBUG_ver) << "lex: key" << endl;
-       yy_pop_state();
-       yy_pop_state();
-       yy_push_state(i8);
-       yy_push_state(i8);
-       return KEY;
-}
-<meta_event>{SSME}     {       // len data
-       LOGOUT(DEBUG_ver) << "lex: smme" << endl;
-       yy_pop_state();
-       yy_pop_state();
-       yy_push_state(data);
-       return SSME;
-}
-<meta_event>{END_OF_TRACK} {
-       LOGOUT(DEBUG_ver) << "lex: end of track" << endl;
-       yy_pop_state();
-       yy_pop_state();
-       yy_pop_state();
-       return END_OF_TRACK;
-}
-<meta_event>{U8} {
-       warning(String("meta_event: unimplemented event: ")
-               + String_convert::bin2hex_str(String(*YYText()))
-// huh?
-//             ,this->here_ch_C() 
-       );
-       yy_pop_state();
-       yy_pop_state();
-       yy_push_state(u8); 
-       yy_push_state(u8);
-       return U8;
-}
-
-<data>{VARINT} {
-       LOGOUT(DEBUG_ver) << "lex: data" << endl;
-       String str((Byte const*)YYText(), YYLeng());
-       int i = My_midi_lexer::varint2_i(str);
-       String* str_p = new String;
-       while (i--)
-               *str_p += (char)yyinput();
-       yylval.str_p = str_p;
-       yy_pop_state();
-       return DATA;
-}
-<data>{U8}     {
-       error(String("data: illegal byte: ")
-               + String_convert::bin2hex_str(String(*YYText())));
-       exit(1);
-}
-<data>{BACKUP_VARINT_0}{U8} {
-       error(String("data: varint expected: ")
-               + String_convert::bin2hex_str(String(*(YYText()))));
-       exit(1);
-}
-<data>{BACKUP_VARINT_1}{U8} {
-       error(String("data: varint expected: ")
-               + String_convert::bin2hex_str(String(*(YYText()))));
-       exit(1);
-}
-<data>{BACKUP_VARINT_2}{U8} {
-       error(String("data: varint expected: ")
-               + String_convert::bin2hex_str(String(*(YYText()))));
-       exit(1);
-}
-
-<<EOF>> {
-//     LOGOUT(NORMAL_ver) << "<<EOF>>";
-
-       if (!close_i())
-         yyterminate(); // can't move this, since it actually rets a YY_NULL
-}
-
-%%
-
diff --git a/mi2mu/midi-parser.cc b/mi2mu/midi-parser.cc
new file mode 100644 (file)
index 0000000..c63c95d
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+  midi-parser.cc -- implement 
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+*/
+
+#include <assert.h>
+#include "string-convert.hh"
+#include "source-file.hh"
+#include "mi2mu-global.hh"
+#include "midi-parser.hh"
+
+Midi_parser_info::Midi_parser_info ()
+{
+  division_1_i_ = 0;
+  format_i_ = 0;
+  tracks_i_ = 0;
+  errorlevel_i_ = 0;
+  byte_L_ = 0;
+  end_byte_L_ = 0;
+}
+
+Midi_parser::Midi_parser ()
+{
+  info_l_ = 0;
+}
+
+int
+Midi_parser::exit (String str)
+{
+  error (str);
+  ::exit (1);
+  return 0;
+}
+
+void
+Midi_parser::error (String str)
+{
+  ::message (message (str));
+}
+
+int
+Midi_parser::get_i (int n)
+{
+  assert (n <= (int)sizeof(int));
+  return String_convert::bin2_i (get_str (n));
+}
+
+unsigned
+Midi_parser::get_u (int n)
+{
+  assert (n <= (int)sizeof(int));
+  return String_convert::bin2_i (get_str (n));
+}
+
+String
+Midi_parser::get_str (int n)
+{
+  assert (n > 0);
+  Byte const* p = forward_byte_L (n);
+  return String (p, n);
+}
+
+int
+Midi_parser::get_var_i ()
+{
+  int var_i = 0;
+
+  while (1)
+    {
+      Byte byte = next_byte ();
+      var_i <<= 7;
+      var_i += byte & 0x7f;
+      if (!(byte & 0x80))
+       return var_i;
+    }
+  exit ("get_var_i:");
+  return 0;
+}
+
+String
+Midi_parser::message (String str)
+{
+  return String ("mi2mu: ") 
+    + info_l_->source_l_->name_str () + ": "
+    + String_convert::i2dec_str (info_l_->source_l_->line_i ((char const*)info_l_->byte_L_), 0, 0) + ": "
+    + str + "\n"
+    + info_l_->source_l_->error_str ((char const*)info_l_->byte_L_);
+}
+
+void
+Midi_parser::warning (String str)
+{
+  ::message (message (String ("warning: ") + str));
+}
index c1ec3edfedf2c5b777feb1aeb72cd6c3d61c7865..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,332 +0,0 @@
-%{
-
-#include "mi2mu-proto.hh"
-#include "proto.hh"
-#include "plist.hh"
-#include "warn.hh"
-#include "mi2mu-global.hh"
-//#include "midi-parser.hh"
-#include "my-midi-parser.hh"
-#include "my-midi-lexer.hh"
-#include "duration-convert.hh"
-#include "string-convert.hh"
-#include "mudela-item.hh"
-#include "mudela-score.hh"
-#include "mudela-staff.hh"
-
-#ifndef NDEBUG
-#define YYDEBUG 1
-#endif
-
-%}
-
-%union {
-    Byte byte;
-    char c;
-    int i;
-    String* str_p;
-    Mudela_item* mudela_item_p;        // Voice_element* ? jup, just about :-)
-    Mudela_score* mudela_score_p; // Input_score* ?
-    Mudela_staff* mudela_staff_p; // Input_music* ?
-}
-
-%token HEADER TRACK
-%token SYSEX_EVENT1 SYSEX_EVENT2
-%token META_EVENT
-%token SEQUENCE
-%token END_OF_TRACK TEMPO SMPTE_OFFSET TIME KEY SSME
-
-%token<i> I8 U8 INT16 INT32 INT7_8UNSET INT7_8SET VARINT
-%token<i> RUNNING_STATUS DATA_ENTRY ALL_NOTES_OFF
-%token<i> NOTE_OFF NOTE_ON 
-%token<i> POLYPHONIC_AFTERTOUCH CONTROLMODE_CHANGE PROGRAM_CHANGE 
-%token<i> CHANNEL_AFTERTOUCH PITCHWHEEL_RANGE
-%token<i> YYTEXT YYCOPYRIGHT YYTRACK_NAME YYINSTRUMENT_NAME YYLYRIC YYMARKER YYCUE_POINT
-%token<str_p> DATA
-
-%type <i> varint
-%type <mudela_score_p> header mudela_score
-%type <mudela_staff_p> track
-%type <mudela_item_p> item
-%type <mudela_item_p> the_item meta_item the_meta_item text_item mudela_item sysex_item
-%type <mudela_item_p> running_status data_entry all_notes_off
-%type <mudela_item_p> note_off note_on
-%type <mudela_item_p> polyphonic_aftertouch controlmode_change program_change
-%type <mudela_item_p> channel_aftertouch pitchwheel_range
-
-%%
-
-midi:  /* empty */
-       | midi mudela_score {
-               midi_parser_l_g->add_score ($2);                
-       }
-       ;
-
-mudela_score:
-       header {
-       }
-       | mudela_score track {
-               $$->add_staff ($2);
-               // ugh
-               $2->set_tempo (midi_parser_l_g->mudela_tempo_p_->useconds_per_4_i());
-               $2->set_meter (midi_parser_l_g->mudela_meter_p_->num_i(), 
-                       midi_parser_l_g->mudela_meter_p_->den_i(), 
-                       midi_parser_l_g->mudela_meter_p_->clocks_1_i(), 
-                       8);
-               if  (midi_parser_l_g->copyright_str_.length_i())
-                       $2->copyright_str_ = midi_parser_l_g->copyright_str_;
-               if  (midi_parser_l_g->track_name_str_.length_i())
-                       $2->name_str_ = midi_parser_l_g->track_name_str_;
-               if  (midi_parser_l_g->instrument_str_.length_i())
-                       $2->instrument_str_ = midi_parser_l_g->instrument_str_;
-               midi_parser_l_g->reset();
-       }
-       ;
-
-header:        
-       HEADER INT32 INT16 INT16 INT16 {
-               // ugh, already constructed; 
-               // need to have score in My_midi_parser...
-//             $$ = new Mudela_score ($3, $4, $5);
-               $$ = midi_parser_l_g->mudela_score_p_;
-               $$->format_i_ = $3;
-               $$->tracks_i_ = $4;
-               $$->tempo_i_ =  $5;
-               midi_parser_l_g->set_division_4 ($5);
-       }
-       ;
-
-track: 
-       TRACK INT32 {
-               LOGOUT (NORMAL_ver) << "\ntrack " << midi_parser_l_g->track_i_ << ": " << flush;
-               $$ = new Mudela_staff (midi_parser_l_g->track_i_++,
-                       // silly, cause not set yet!
-                       midi_parser_l_g->copyright_str_,
-                       midi_parser_l_g->track_name_str_,
-                       midi_parser_l_g->instrument_str_);
-               //ugh, need to know now!
-               midi_parser_l_g->mudela_staff_l_ = $$;
-       }
-       | track item {
-               if  ($2) {
-                       $2->mudela_column_l_ = midi_parser_l_g->mudela_column_l_;
-                       $$->add_item ($2);
-               }
-       }
-       ;
-
-item:  
-       varint the_item {
-               $$ = $2;
-               if  ($2) {
-                       String str = $2->str();
-                       if  (str.length_i())
-                               LOGOUT (DEBUG_ver) << str << " " << flush;
-               }
-       }
-       ;
-       
-varint:
-       VARINT {
-               midi_parser_l_g->forward ($1);
-       }
-       ;
-
-the_item: 
-       meta_item { 
-       }
-       | mudela_item {
-       }
-       | sysex_item {
-       }
-       ;
-
-meta_item:
-       META_EVENT the_meta_item {
-               $$ = $2;
-       }
-       |
-       META_EVENT U8 U8 U8 {
-               $$ = 0;
-       }
-       ;
-
-the_meta_item:
-       SEQUENCE INT16 {
-       }
-       | text_item DATA {
-               Mudela_text::Type type = (Mudela_text::Type)$1;
-               $$ = 0;
-               switch  (type)
-                       {
-                       case Mudela_text::COPYRIGHT:
-                               midi_parser_l_g->copyright_str_ = *$2;
-                               break;
-                       case Mudela_text::TRACK_NAME:
-                               midi_parser_l_g->track_name_str_ = *$2;
-                               break;
-                       case Mudela_text::INSTRUMENT_NAME:
-                               midi_parser_l_g->instrument_str_ = *$2;
-                               break;
-                       default:
-                               $$ = new Mudela_text (type, *$2);
-                               break;
-                       }
-               LOGOUT (DEBUG_ver) << *$2 << endl;
-               delete $2;
-       }
-       | END_OF_TRACK {
-               $$ = 0;
-       }
-       | TEMPO U8 U8 U8 { 
-               $$ = new Mudela_tempo ( ($2 << 16) +  ($3 << 8) + $4);
-               LOGOUT (DEBUG_ver) << $$->str() << endl;
-               midi_parser_l_g->set_tempo ( ($2 << 16) +  ($3 << 8) + $4);
-       }
-       | SMPTE_OFFSET U8 U8 U8 U8 U8 { 
-               $$ = 0;
-       }
-       | TIME U8 U8 U8 U8 { 
-               $$ = new Mudela_meter ($2, $3, $4, $5);
-               LOGOUT (DEBUG_ver) << $$->str() << endl;
-               midi_parser_l_g->set_meter ($2, $3, $4, $5);
-       }
-       | KEY I8 I8 { 
-               $$ = new Mudela_key ($2, $3);
-               midi_parser_l_g->set_key ($2, $3 );
-       }
-       | SSME DATA {
-               $$ = new Mudela_text ((Mudela_text::Type)0, *$2);
-               delete $2;
-       }
-       ;
-
-text_item: 
-       YYTEXT {
-               LOGOUT (DEBUG_ver) << "\n% Text: ";
-       }
-       | YYCOPYRIGHT {
-               LOGOUT (DEBUG_ver) << "\n% Copyright: ";
-       }
-       | YYTRACK_NAME {
-               LOGOUT (DEBUG_ver) << "\n% Track  name: ";
-       }
-       | YYINSTRUMENT_NAME {
-               LOGOUT (DEBUG_ver) << "\n% Instrument  name: ";
-       }
-       | YYLYRIC {
-               LOGOUT (DEBUG_ver) << "\n% Lyric: ";
-       }
-       | YYMARKER {
-               LOGOUT (DEBUG_ver) << "\n% Marker: ";
-       }
-       | YYCUE_POINT {
-               LOGOUT (DEBUG_ver) << "\n% Cue point: ";
-       }
-       ;
-
-mudela_item: 
-       running_status {
-       }
-       | data_entry {
-       }
-       | all_notes_off {
-       }
-       | note_off {
-       }
-       | note_on {
-       }
-       | polyphonic_aftertouch {
-       }
-       | controlmode_change {
-       }
-       | program_change {
-       }
-       | channel_aftertouch {
-       }
-       | pitchwheel_range {
-       }
-       ;
-
-running_status:
-       RUNNING_STATUS mudela_item {
-               $$ = $2;
-       }
-       ;
-
-data_entry:
-       DATA_ENTRY U8 {
-               $$ = 0;
-       }
-       ;
-
-all_notes_off:
-       ALL_NOTES_OFF U8 U8 {
-               midi_parser_l_g->note_end_all();
-               $$ = 0;
-       }
-       ;
-
-note_off:
-       NOTE_OFF U8 U8 {
-               int i = $1;
-               i = i & ~0x80;
-               midi_parser_l_g->note_end ($1 & ~0x80, $2, $3);
-               $$ = 0;
-       }
-       ;
-
-note_on:
-       NOTE_ON U8 U8 {
-               int i = $1;
-               i = i & ~0x90;
-               $$ = 0;
-                if  ($3)
-                       midi_parser_l_g->note_begin ($1 & ~0x90, $2, $3);
-               /*
-                 sss: some broken devices encode NOTE_OFF as 
-                      NOTE_ON with zero volume
-                */
-               else 
-                       midi_parser_l_g->note_end ($1 & ~0x90, $2, $3);
-       }
-       ;
-
-polyphonic_aftertouch:
-       POLYPHONIC_AFTERTOUCH U8 U8 {
-               $$ = 0;
-       }
-       ;
-
-controlmode_change:
-       CONTROLMODE_CHANGE U8 U8 {
-               $$ = 0;
-       }
-       ;
-
-program_change:
-       PROGRAM_CHANGE U8 {
-               $$ = 0;
-       }
-       ;
-
-channel_aftertouch:
-       CHANNEL_AFTERTOUCH U8 U8 {
-               $$ = 0;
-       }
-       ;
-
-pitchwheel_range:
-       PITCHWHEEL_RANGE U8 U8 {
-               $$ = 0;
-       }
-       ;
-
-sysex_item:
-       SYSEX_EVENT1 DATA {
-               $$ = 0;
-       }
-       | SYSEX_EVENT2 DATA { // U8 ?
-               $$ = 0;
-       }
-       ;
diff --git a/mi2mu/midi-score-parser.cc b/mi2mu/midi-score-parser.cc
new file mode 100644 (file)
index 0000000..d1a7000
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+  midi-score-parser.cc -- implement 
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+*/
+
+#include "moment.hh"
+#include "source-file.hh"
+#include "source.hh"
+#include "mi2mu-global.hh"
+#include "midi-score-parser.hh"
+#include "midi-track-parser.hh"
+#include "mudela-item.hh"
+#include "mudela-score.hh"
+
+
+void
+Midi_score_parser::open (String filename_str, Sources* sources_l)
+{
+  info_l_->source_l_ = sources_l->get_file_l (filename_str);
+  if (!info_l_->source_l_)
+    ::error ("can't find: `" + filename_str + "'");
+  info_l_->byte_L_ = (Byte const*)info_l_->source_l_->ch_C ();
+//  info_l_->end_byte_L_ = info_l_->byte_L_ + info_l_->source_l_->length_i ();
+  info_l_->end_byte_L_ = info_l_->byte_L_ + info_l_->source_l_->length_i () + 1;
+}
+
+Mudela_score*
+Midi_score_parser::parse (String filename_str, Sources* sources_l)
+{
+  Midi_parser_info info;
+  info_l_ = &info;
+  open (filename_str, sources_l);
+  parse_header ();
+  return parse_score ();
+}
+
+void
+Midi_score_parser::parse_header ()
+{
+  String str = get_str (4);
+  if ( str != "MThd" )
+    exit ("MIDI header expected");
+
+  int length_i = get_i (4);
+  // is this signed?
+  if (length_i < 6)
+    exit ("Invalid header length");
+  info_l_->format_i_ = get_i (2);
+  if (info_l_->format_i_ != 0 && info_l_->format_i_ != 1)
+    exit ("Invalid midi format");
+  info_l_->tracks_i_ = get_i (2);
+  if (info_l_->tracks_i_ < 0 || info_l_->tracks_i_ > 32 )
+    exit ("Invalid number of tracks");
+  info_l_->division_1_i_ = get_i (2) * 4;
+  if (info_l_->division_1_i_ < 0)
+    exit ("Cannot handle non-metrical time");
+  forward_byte_L (length_i - 6);
+}
+
+int
+Midi_score_parser::find_earliest_i (Link_array<Midi_track_parser>& tracks)
+{
+  int earliest_i = 0;
+  Moment earliest_mom = infinity_mom;
+  for (int i = 0; i < tracks.size(); i++)
+    {
+      if ( tracks [i]->at_mom () < earliest_mom )
+       {
+         earliest_mom = tracks [i]->at_mom ();
+         earliest_i = i;
+       }
+    }
+  return earliest_i;
+}
+    
+Mudela_score*
+Midi_score_parser::parse_score ()
+{
+  Mudela_meter m4 (1, 4, 0, 0);
+  Moment bar4_mom = m4.bar_mom ();
+
+  Link_array<Midi_track_parser> tracks;
+  for (int i = 0; i < info_l_->tracks_i_; i++)
+    tracks.push (new Midi_track_parser (info_l_));
+
+  int current_bar_i = 0;
+
+  Mudela_score* score_p = new Mudela_score( 1, 1, 1 );
+  while (tracks.size ())
+    {
+      int i = find_earliest_i (tracks);
+      Moment at_mom = tracks [i]->at_mom ();
+      Mudela_column* column_l = score_p->get_column_l (at_mom);
+      Mudela_staff* staff_p = tracks [i]->parse (column_l);
+      if ( staff_p ) 
+       {
+         score_p->add_staff (staff_p);
+         delete tracks [i];
+         tracks.del (i);
+       }
+
+      //  brr, musta have some progress
+      for (int ii = 0; !info_l_->bar_mom_ && ii < tracks.size (); ii++)
+       info_l_->bar_mom_ = tracks [ii]->info_l_->bar_mom_;
+      
+      int bar_i = (int) (at_mom 
+           / (info_l_->bar_mom_ ? info_l_->bar_mom_ : bar4_mom)) + 1;
+      if (bar_i > current_bar_i) 
+       {
+         LOGOUT (NORMAL_ver) << '[' << bar_i << ']' << flush; 
+         current_bar_i = bar_i;
+       }
+    }
+  return score_p;
+}
+    
diff --git a/mi2mu/midi-track-parser.cc b/mi2mu/midi-track-parser.cc
new file mode 100644 (file)
index 0000000..8f346f5
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+  midi-track-parser.cc -- implement 
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
+*/
+
+#include <assert.h>
+#include "string-convert.hh"
+#include "mi2mu-global.hh"
+#include "midi-track-parser.hh"
+#include "mudela-column.hh"
+#include "mudela-item.hh"
+#include "mudela-staff.hh"
+
+Midi_track_parser::Midi_track_parser (Midi_parser_info* info_l)
+{
+  info_l_ = info_l;
+  at_mom_ = 0;
+  track_info_p_ = 0;
+  mudela_staff_p_ = new Mudela_staff (0, "", "", "");
+  parse_header ();
+  parse_delta_time ();
+}
+
+Midi_track_parser::~Midi_track_parser ()
+{
+  delete mudela_staff_p_;
+  delete track_info_p_;
+}
+
+Moment
+Midi_track_parser::at_mom ()
+{
+  return at_mom_;
+}
+
+bool
+Midi_track_parser::eot ()
+{
+  if ( info_l_->byte_L_ < info_l_->end_byte_L_ )
+    return false;
+  return true;
+}
+
+void
+Midi_track_parser::note_end (Mudela_column* col_l, int channel_i, int pitch_i, int aftertouch_i )
+{
+  // junk dynamics
+  (void)aftertouch_i;
+
+  for (PCursor<Mudela_note*> i (open_note_l_list_.top ()); i.ok (); i++) 
+    {
+      if ((i->pitch_i_ == pitch_i) && (i->channel_i_ == channel_i)) 
+       {
+         i->end_column_l_ = col_l;
+         // LOGOUT(DEBUG_ver) << "Note: " << pitch_i;
+         // LOGOUT(DEBUG_ver) << "; " << i->mudela_column_l_->at_mom_;
+         // LOGOUT(DEBUG_ver) << ", " << i->end_column_l_->at_mom_ << "\n";
+         i.remove_p();
+         return;
+       }
+    }
+  warning (String ("junking note-end event: ")
+          + " channel = " + String_convert::i2dec_str (channel_i, 0, ' ')
+          + ", pitch = " + String_convert::i2dec_str (pitch_i, 0, ' '));
+}
+
+void
+Midi_track_parser::note_end_all (Mudela_column* col_l) 
+{
+  // find 
+  for  (PCursor<Mudela_note*> i (open_note_l_list_.top ()); i.ok (); i++) 
+    {
+      i->end_column_l_ = col_l;
+      i.remove_p();
+      // ugh
+      if  (!i.ok())
+       break;
+    }
+}
+
+Mudela_staff*
+Midi_track_parser::parse (Mudela_column* col_l)
+{
+  Moment mom = at_mom ();
+  while (!eot () && (mom == at_mom ()))
+    {
+      Mudela_item* p = parse_event (col_l);
+      if (p)
+       mudela_staff_p_->add_item (p);
+    }
+
+  if (!eot())
+    return 0;
+
+  Mudela_staff* p = mudela_staff_p_;
+  mudela_staff_p_ = 0;
+  return p;
+}
+
+void
+Midi_track_parser::parse_delta_time ()
+{
+  if (eot ())
+    return;
+  int delta_i = get_var_i ();
+  at_mom_ += Moment (delta_i, info_l_->division_1_i_); 
+}
+
+Mudela_item*
+Midi_track_parser::parse_event (Mudela_column* col_l)
+{ 
+  Byte byte = peek_byte ();
+  // RUNNING_STATUS    [\x00-\x5f]
+  if (byte <= 0x5f) 
+    {
+      if (running_byte_ <= 0x5f) 
+       exit ("Invalid running status");
+      /*
+       'running status' rather means 'missing status'.
+       we'll just pretend we read the running status byte.
+       */
+      byte = running_byte_;
+    }
+  else
+    byte = next_byte ();
+
+  Mudela_item* item_p = 0;
+  // DATA_ENTRY        [\x60-\x79]
+  if ((byte >= 0x60) && (byte <= 0x79))
+    {
+           next_byte ();
+    }
+  // ALL_NOTES_OFF     [\x7a-\x7f]
+  else if ((byte >= 0x7a) && (byte <= 0x7f))
+    {
+      next_byte ();
+      next_byte ();
+      note_end_all (col_l);
+    }
+  // NOTE_OFF  [\x80-\x8f]
+  else if ((byte >= 0x80) && (byte <= 0x8f))
+    {
+      running_byte_ = byte;
+      int channel_i = byte & ~0x90;
+      int pitch_i = (int)next_byte ();
+      int dyn_i = (int)next_byte ();
+      note_end (col_l, channel_i, pitch_i, dyn_i);
+    }
+  // NOTE_ON           [\x90-\x9f]
+  else if ((byte >= 0x90) && (byte <= 0x9f))
+    {
+      running_byte_ = byte;
+      int channel_i = byte & ~0x90;
+      int pitch_i = (int)next_byte ();
+      int dyn_i = (int)next_byte ();
+      /*
+       sss: some broken devices encode NOTE_OFF as 
+       NOTE_ON with zero volume
+       */
+      if (dyn_i)
+       {
+         Mudela_note* p = new Mudela_note (col_l, channel_i, pitch_i, dyn_i);
+         item_p = p;
+         open_note_l_list_.bottom ().add (p);
+       }
+      else
+       {
+         note_end (col_l, channel_i, pitch_i, dyn_i);
+       }
+    }
+  // POLYPHONIC_AFTERTOUCH     [\xa0-\xaf]
+  else if ((byte >= 0xa0) && (byte <= 0xaf))
+    {
+      running_byte_ = byte;
+      next_byte ();
+      next_byte ();
+    }
+  // CONTROLMODE_CHANGE        [\xb0-\xbf]
+  else if ((byte >= 0xb0) && (byte <= 0xbf))
+    {
+      running_byte_ = byte;
+      next_byte ();
+      next_byte ();
+    }
+  // PROGRAM_CHANGE    [\xc0-\xcf]
+  else if ((byte >= 0xc0) && (byte <= 0xcf))
+    {
+      running_byte_ = byte;
+      next_byte ();
+    }
+  // CHANNEL_AFTERTOUCH        [\xd0-\xdf]
+  else if ((byte >= 0xd0) && (byte <= 0xdf))
+    {
+      running_byte_ = byte;
+      next_byte ();
+      next_byte ();
+    }
+  // PITCHWHEEL_RANGE  [\xe0-\xef]
+  else if ((byte >= 0xe0) && (byte <= 0xef))
+    {
+      running_byte_ = byte;
+      next_byte ();
+      next_byte ();
+    }
+  // SYSEX_EVENT1      [\xf0]
+  else if (byte == 0xf0)
+    {
+      int length_i = get_var_i ();
+      String str = get_str (length_i);
+    }
+  // SYSEX_EVENT2      [\xf7]
+  else if (byte == 0xf7)
+    {
+      int length_i = get_var_i ();
+      String str = get_str (length_i);
+    }
+  // META_EVENT        [\xff]
+  else if (byte == 0xff)
+    {
+      // SEQUENCE      [\x00][\x02]
+      byte = next_byte ();
+      if (byte == 0)
+       {
+         next_byte ();
+         get_i (2);
+       }
+      // YYTEXT                [\x01] 
+      // YYCOPYRIGHT   [\x02]
+      // YYTRACK_NAME  [\x03]
+      // YYINSTRUMENT_NAME     [\x04]
+      // YYLYRIC               [\x05]
+      // YYMARKER              [\x06]
+      // YYCUE_POINT   [\x07]
+      else if ((byte >= 0x01) && (byte <= 0x07))
+       {
+         // LOGOUT (DEBUG_ver) << "\n% Text(" << (int)byte << "):" << flush;
+         int length_i = get_var_i ();
+         String str = get_str (length_i);
+         // LOGOUT (DEBUG_ver) << str << endl;
+         item_p = new Mudela_text ((Mudela_text::Type)byte, str);
+       }
+      // END_OF_TRACK  [\x2f][\x00]
+      else
+       {
+         Byte next = peek_byte ();
+         if ((byte == 0x2f) && (next == 0x00))
+           {
+             next_byte ();
+             info_l_->byte_L_ = info_l_->end_byte_L_;
+           }
+         // TEMPO              [\x51][\x03]
+         else if ((byte == 0x51) && (next == 0x03))
+           {
+             next_byte ();
+             unsigned useconds_per_4_u = get_u (3);
+             // $$ = new Mudela_tempo ( ($2 << 16) +  ($3 << 8) + $4);
+             // LOGOUT (DEBUG_ver) << $$->str() << endl;
+             item_p = new Mudela_tempo ( useconds_per_4_u );
+           }
+         // SMPTE_OFFSET       [\x54][\x05]
+         else if ((byte == 0x54) && (next == 0x05))
+           {
+             next_byte ();
+             (int)next_byte ();
+             (int)next_byte ();
+             (int)next_byte ();
+             (int)next_byte ();
+             (int)next_byte ();
+           }
+         // TIME               [\x58][\x04]
+         else if ((byte == 0x58) && (next == 0x04))
+           {
+             next_byte ();
+             int num_i = (int)next_byte ();
+             int den_i = (int)next_byte ();
+             int clocks_4_i = (int)next_byte ();
+             int count_32_i = (int)next_byte ();
+             Mudela_meter* p = new Mudela_meter ( num_i, den_i, clocks_4_i, count_32_i );
+             item_p = p;
+             info_l_->bar_mom_ = p->bar_mom ();
+           }
+         // KEY                [\x59][\x02]
+         else if ((byte == 0x59) && (next == 0x02))
+           {
+             next_byte ();
+             int accidentals_i = (int)next_byte ();
+             int minor_i = (int)next_byte ();
+             item_p = new Mudela_key (accidentals_i, minor_i);
+           }
+         // SSME               [\0x7f][\x03]
+         else if ((byte == 0x7f) && (next == 0x03))
+           {
+             next_byte ();
+             int length_i = get_var_i ();
+             String str = get_str (length_i);
+             item_p = new Mudela_text ((Mudela_text::Type)byte, str);
+           }
+         else
+           exit ("Invalid MIDI meta-event");
+       }
+    }
+  else
+    exit ("Invalid MIDI event");
+
+  if (item_p)
+    item_p->mudela_column_l_ = col_l;
+
+  parse_delta_time ();
+
+  return item_p;
+}
+
+void
+Midi_track_parser::parse_header ()
+{ 
+  String str = get_str (4);
+  if ( str != "MTrk" )
+    exit ("MIDI track expected");
+
+  int length_i = get_i (4);
+  // is this signed?
+  if (length_i < 0)
+    exit ("Invalid track length");
+  assert (!track_info_p_);
+  track_info_p_ = new Midi_parser_info (*info_l_);
+  track_info_p_->end_byte_L_ = track_info_p_->byte_L_ + length_i;
+  forward_byte_L (length_i);
+//  forward_byte_L (length_i-1);
+  info_l_ = track_info_p_;
+}
+
index 3179662b726e40e565a1994ef1550f8135022cc7..300ada5d4c01e36518d7048765ea87ff04c72d7c 100644 (file)
@@ -3,6 +3,7 @@
 //
 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
 
+#include <assert.h>
 #include "mi2mu-global.hh"
 #include "string-convert.hh"
 #include "duration-convert.hh"
@@ -17,13 +18,13 @@ Mudela_item::Mudela_item (Mudela_column* mudela_column_l)
 }
 
 Moment
-Mudela_item::at_mom()
+Mudela_item::at_mom ()
 {
-  return mudela_column_l_->at_mom();
+  return mudela_column_l_->at_mom ();
 }
 
 Moment
-Mudela_item::duration_mom()
+Mudela_item::duration_mom ()
 {
   return Moment (0);
 }
@@ -31,7 +32,7 @@ Mudela_item::duration_mom()
 void
 Mudela_item::output (Mudela_stream& mudela_stream_r)
 {
-  mudela_stream_r << str() << String (" ");
+  mudela_stream_r << str () << String (" ");
 }
 
 Mudela_key::Mudela_key (int accidentals_i, int minor_i)
@@ -39,22 +40,22 @@ Mudela_key::Mudela_key (int accidentals_i, int minor_i)
 {
   accidentals_i_ = accidentals_i;
   minor_i_ = minor_i;
-  if  (accidentals_i >= 0)
+  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()
+Mudela_key::str ()
 {
   String str = "\\key ";
-  if  (!minor_i_) 
+  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"; 
+       + String ('"') + "; % not supported yet\n"; 
   return str;
 }
 
@@ -71,7 +72,7 @@ Mudela_key::notename_str (int pitch_i)
   
   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)) 
+  if (accidental_i &&  (accidentals_i_ < 0)) 
     {
        accidental_i = - accidental_i;
        notename_i =  (notename_i + 1) % 7;
@@ -98,7 +99,7 @@ Mudela_meter::Mudela_meter (int num_i, int den_i, int clocks_4_i, int count_32_i
 {
   sync_dur_.durlog_i_ = 3 ;
   sync_f_ = 1.0;
-  if  (count_32_i != 8)
+  if (count_32_i != 8)
        warning (String ("#32 in quarter: ") + String (count_32_i));
   num_i_ = num_i;
   den_i_ = den_i;
@@ -106,7 +107,7 @@ Mudela_meter::Mudela_meter (int num_i, int den_i, int clocks_4_i, int count_32_i
 }
 
 Moment
-Mudela_meter::bar_mom()
+Mudela_meter::bar_mom ()
 {
   Duration d;
   d.durlog_i_ =   den_i_;
@@ -114,25 +115,25 @@ Mudela_meter::bar_mom()
 }
 
 int
-Mudela_meter::clocks_1_i()
+Mudela_meter::clocks_1_i ()
 {
   return clocks_1_i_;
 }
 
 int
-Mudela_meter::den_i()
+Mudela_meter::den_i ()
 {
   return den_i_;
 }
 
 int
-Mudela_meter::num_i()
+Mudela_meter::num_i ()
 {
   return num_i_;
 }
 
 String
-Mudela_meter::str()
+Mudela_meter::str ()
 {
   String str = "\\meter "
        + String (num_i_) + "/" + String (1 << den_i_) 
@@ -160,22 +161,38 @@ Mudela_note::Mudela_note (Mudela_column* mudela_column_l, int channel_i, int pit
   end_column_l_ = 0;
 }
 
+Duration
+Mudela_note::duration ()
+{
+  assert (end_column_l_);
+  Moment mom = end_column_l_->at_mom () - at_mom ();
+  return Duration_convert::mom2_dur (mom);
+}
+
+Moment
+Mudela_note::duration_mom ()
+{
+// ugh
+//    return Duration_convert::dur2_mom (duration ());
+  return end_column_l_->at_mom () - at_mom ();
+}
+
 String
-Mudela_note::str()
+Mudela_note::str ()
 {
-  Duration dur = duration();
-  if  (dur.durlog_i_ < -10)
+  Duration dur = duration ();
+  if (dur.durlog_i_ < -10)
        return "";
 
   String name_str 
     = mudela_column_l_->mudela_score_l_->mudela_key_l_->notename_str (pitch_i_);
 
-  if  (simple_plet_b_s)
+  if (simple_plet_b_s)
        return name_str + Duration_convert::dur2_str (dur) + " ";
 
   //ugh
   String str;
-  if  (dur.plet_b())
+  if (dur.plet_b ())
        str += String ("\\plet ")
            + String_convert::i2dec_str (dur.plet_.iso_i_, 0, 0)
            + "/"
@@ -188,28 +205,12 @@ Mudela_note::str()
   tmp.set_plet (1,1);
   str += Duration_convert::dur2_str (tmp);
 
-  if  (dur.plet_b())
+  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();
-  return Duration_convert::mom2_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)
 {
@@ -217,25 +218,25 @@ Mudela_skip::Mudela_skip (Mudela_column* mudela_column_l, Moment skip_mom)
 }
 
 Duration
-Mudela_skip::duration()
+Mudela_skip::duration ()
 {
        return Duration_convert::mom2_dur (mom_);
 }
 
 Moment
-Mudela_skip::duration_mom()
+Mudela_skip::duration_mom ()
 {
-  return Duration_convert::dur2_mom (duration());
+  return Duration_convert::dur2_mom (duration ());
 }
 
 String
-Mudela_skip::str()
+Mudela_skip::str ()
 {
-  if  (!mom_)
+  if (!mom_)
        return String ("");
 
-  Duration dur = duration();
-  if  (dur.durlog_i_<-10)
+  Duration dur = duration ();
+  if (dur.durlog_i_<-10)
        return "";
 
   String str = "\\skip ";
@@ -252,7 +253,7 @@ Mudela_tempo::Mudela_tempo (int useconds_per_4_i)
 }
 
 String
-Mudela_tempo::str()
+Mudela_tempo::str ()
 {
   String str = "\\tempo 4=";
   str += String (get_tempo_i (Moment (1, 4)));
@@ -261,7 +262,7 @@ Mudela_tempo::str()
 }
 
 int 
-Mudela_tempo::useconds_per_4_i()
+Mudela_tempo::useconds_per_4_i ()
 {
   return useconds_per_4_i_;
 }
@@ -280,10 +281,10 @@ Mudela_text::Mudela_text (Mudela_text::Type type, String text_str)
 }
 
 String
-Mudela_text::str()
+Mudela_text::str ()
 {
-  if  (!text_str_.length_i() 
-       ||  (text_str_.length_i() != (int)strlen (text_str_.ch_C())))
+  if (!text_str_.length_i () 
+       ||  (text_str_.length_i () != (int)strlen (text_str_.ch_C ())))
        return "";
 
   return "% " + text_str_ + "\n";
index 843bab56c77b51bdfa3e4ba453910c9e5e398ef0..c8f575d04c4feac9173bda934b901a961c125a25 100644 (file)
@@ -3,6 +3,7 @@
 //
 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
 
+#include <assert.h>
 #include "moment.hh"
 #include "duration.hh"
 #include "duration-convert.hh"
 #include "mudela-staff.hh"
 #include "mudela-stream.hh"
 
+static Mudela_key key_c (0, 0);
+static Mudela_meter meter_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)
 {
   format_i_ = format_i;
   tracks_i_ = tracks_i;
   tempo_i_ = tempo_i;
-  mudela_column_p_list_.bottom().add (new Mudela_column (this, Moment (0)));
+  column_l_array_.push (new Mudela_column (this, Moment (0)));
+  mudela_key_l_ = &key_c;
+  mudela_meter_l_ = &meter_4;
+  mudela_tempo_l_ = &tempo_60;
 }
 
 Mudela_score::~Mudela_score()
@@ -38,23 +47,27 @@ Mudela_score::add_staff (Mudela_staff* mudela_staff_p)
 }
 
 Mudela_column*
-Mudela_score::mudela_column_l (Moment mom)
+Mudela_score::find_column_l (Moment mom)
+{
+  // should do binary search
+  for (int i = 0; i < column_l_array_.size (); i++ )
+    if ( column_l_array_[i]->at_mom () == mom )
+        return column_l_array_[i];
+  return 0;
+}
+
+Mudela_column*
+Mudela_score::get_column_l (Moment mom)
 {
-  for  (PCursor<Mudela_column*> i (mudela_column_p_list_); i.ok(); i++) 
+  if ( column_l_array_ [column_l_array_.size() - 1]->at_mom () > mom )
     {
-       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;
+      error ("ugh");
+      exit (1);
     }
+  if ( column_l_array_[column_l_array_.size() - 1]->at_mom () < mom )
+    column_l_array_.push (new Mudela_column (this, mom));
 
-  Mudela_column* p = new Mudela_column (this, mom);
-  mudela_column_p_list_.bottom().add (p);
-  return p;
+  return column_l_array_ [column_l_array_.size() - 1];
 }
 
 void
@@ -93,7 +106,7 @@ Mudela_score::output (String filename_str)
 
   mudela_stream << "\\paper{}\n";
 
-  mudela_stream << "\\midi{ ";
+  mudela_stream << "\\midi{\n";
        // let's not use silly 0 track
        mudela_staff_p_list_.bottom()->mudela_tempo_p_->output (mudela_stream);
   mudela_stream << "}\n";
@@ -107,8 +120,8 @@ 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";
+//  for  (PCursor<Mudela_column*> i (mudela_column_p_list_); i.ok(); i++)
+//     LOGOUT(DEBUG_ver) << "At: " << i->at_mom() << "\n";
 
   settle_columns();
   filter_tempo();
@@ -171,12 +184,16 @@ Mudela_score::settle_columns()
 //    return;
   LOGOUT(NORMAL_ver) << "\nSettling columns..." << endl;
 
+#if 0
   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);
+#endif
+
+  int n = column_l_array_.size();
 
   int start_i = 0;
   int end_i = 0;
index 3f1373a4acfecf3bc7cb605f57c6f28fc4c3d0ea..b8535618b911ecbfe637304a0ccf89e6a92dc2b5 100644 (file)
@@ -3,6 +3,7 @@
 //
 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
 
+#include <assert.h>
 #include <ctype.h>
 #include "moment.hh"
 #include "duration-convert.hh"
@@ -14,9 +15,9 @@
 #include "mudela-staff.hh"
 #include "mudela-stream.hh"
 #include "mudela-voice.hh"
-#include "my-midi-parser.hh"
 #include "mudela-score.hh"
 
+extern Mudela_score* mudela_score_l_g;
 
 Mudela_staff::Mudela_staff (int number_i, String copyright_str, String track_name_str, String instrument_str)
 {
@@ -60,7 +61,7 @@ Mudela_staff::eat_voice (Link_list<Mudela_item*>& items)
        {
          Moment dur = i->at_mom() - mom;
          // ugh, need score
-         Mudela_column* start = midi_parser_l_g->mudela_score_p_->mudela_column_l (mom);
+         Mudela_column* start = mudela_score_l_g->find_column_l (mom);
          voice_p->add_item (new Mudela_skip (start, dur));
          mom = i->at_mom();
        }
index 1f171bf8eda95192bb68b9c620fa9730b5498e1a..545887091f31796b3f1abc403b23453a77ba772f 100644 (file)
@@ -5,13 +5,15 @@
 //
 // (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
 
+#include <assert.h>
 #include <time.h>
 #include <fstream.h>
 #include "mi2mu-global.hh"
-#include "my-midi-parser.hh"
 #include "mudela-item.hh"
 #include "mudela-stream.hh"
 
+extern String filename_str_g;
+
 static int const INDENT_i = 8;
 
 Mudela_stream::Mudela_stream (String filename_str)
@@ -73,7 +75,9 @@ Mudela_stream::header()
   time_t t (time (0));
   *os_p_ << ctime (&t);
   *os_p_ << "% from input file: ";
-  *os_p_ << midi_parser_l_g->filename_str_;
+  //  *os_p_ << midi_parser_l_g->filename_str_;
+  // ugh
+  *os_p_ << filename_str_g;
   *os_p_ << "\n\n";    
   // ugh
   *os_p_ << "\\version \"0.1.1\";\n";
index 483fce69275bb20767fb1191102b0adfda535f8a..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,91 +0,0 @@
-//
-// my-midi-lexer.cc -- implement My_midi_lexer
-//
-// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
-
-#include "string-convert.hh"
-#include "mi2mu-global.hh"
-#include "my-midi-lexer.hh"
-#include "source.hh"
-#include "source-file.hh"
-
-int
-yylex() 
-{
-  return midi_lexer_l_g->yylex();
-}
-
-My_midi_lexer* midi_lexer_l_g = 0;
-
-My_midi_lexer::My_midi_lexer (String &filename_str, Sources * sources)
-{
-  source_file_l_ = sources->get_file_l(filename_str);
-  if  (!source_file_l_)
-       ::error  ("can't find: `" + filename_str + "'");
-  switch_streams (source_file_l_->istream_l(), 0);
-  errorlevel_i_ = 0;
-  char_count_ = 0;
-  running_status_i_ = 0;
-}
-
-My_midi_lexer::~My_midi_lexer()
-{
-//    delete source_file_p_;
-}
-
-void
-My_midi_lexer::error (char const* sz_l)
-{
-  if (1|| !source_file_l_) 
-    {
-       cerr << "error at EOF: `" << sz_l << "'\n";
-    }
-  else 
-    {
-       
-       // FIXME
-       #if 0
-       char const* ch_C = here_ch_C();
-       if  (ch_C) 
-         {
-           ch_C--;
-           while  ( (*ch_C == ' ') ||  (*ch_C == '\t') ||  (*ch_C == '\n'))
-               ch_C--;
-           ch_C++;
-         }
-       errorlevel_i_ |= 1;
-       error (sz_l);
-       #endif
-    }
-}
-
-char const*
-My_midi_lexer::here_ch_C()
-{
-  return source_file_l_->ch_C() + char_count_ ;
-}
-
-int
-My_midi_lexer::varint2_i (String str)
-{
-  int var_i = 0;
-
-  for  (int i = 0; i < str.length_i(); i++) 
-    {
-       Byte byte = str[ i ];
-       var_i <<= 7;
-       var_i += byte & 0x7f;
-       if  (!  (byte & 0x80))
-           return var_i;
-    }
-  cout << "\nvarint2_i:" << String_convert::bin2hex_str (str) << endl;
-  assert (0); // illegal varint
-  return 0;
-}
-
-int
-My_midi_lexer::close_i()
-{
-  return 0;
-}
-
index 2a7e2d77bcf5216738b9d1e03b44925620c87274..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,232 +0,0 @@
-//
-// my-midi-parser.cc -- implement My_midi_parser
-//
-// copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
-
-#include "string-convert.hh"
-#include "duration-convert.hh"
-#include "mi2mu-global.hh"
-#include "my-midi-lexer.hh"
-#include "my-midi-parser.hh"
-#include "mudela-column.hh"
-#include "mudela-item.hh"
-#include "mudela-score.hh"
-#include "mudela-staff.hh"
-
-void
-yyerror(char const* sz_l)
-{
-  midi_parser_l_g->error (sz_l);
-}
-
-
-My_midi_parser* midi_parser_l_g = 0;
-
-My_midi_parser::My_midi_parser (String filename_str, Sources *sources_l)
-{
-  filename_str_ = filename_str;
-  midi_lexer_p_ = new My_midi_lexer (filename_str_,sources_l);
-  midi_lexer_l_g = midi_lexer_p_;    // ugh
-
-  bar_i_ = 1;
-
-  defined_ch_C_ = 0;
-  fatal_error_i_ = 0;
-  
-  mudela_column_l_ = 0;
-  mudela_score_p_ = new Mudela_score (1, 1, 1);
-
-
-  // ugh, belong to Mudela_{score,staff}
-  track_i_ = 0;
-  mudela_staff_l_ = 0;
-  mudela_key_p_ = 0;
-  mudela_tempo_p_ = 0;
-  mudela_meter_p_ = 0;
-
-  reset();
-}
-
-My_midi_parser::~My_midi_parser()
-{
-  midi_lexer_l_g = 0;    // ugh
-
-  delete midi_lexer_p_;
-  delete mudela_key_p_;
-  delete mudela_tempo_p_;
-  delete mudela_meter_p_;
-  delete mudela_score_p_;
-}
-
-void
-My_midi_parser::reset()
-{
-//    open_mudela_note_l_list_.clear();
-  open_mudela_note_l_list_.junk_links();
-
-  // ugh
-  delete mudela_key_p_;
-  mudela_key_p_ = new Mudela_key (0, 0);
-  // useconds per 4: 250000 === 60 4 per minute
-  delete mudela_tempo_p_;
-  mudela_tempo_p_ = new Mudela_tempo (1000000);
-  delete mudela_meter_p_;
-  mudela_meter_p_ = new Mudela_meter (4, 2, 24, 8);
-
-  bar_i_ = 1;
-  mudela_column_l_ = mudela_score_p_->mudela_column_l (0);
-
-  // ugh
-  copyright_str_ = "";
-  track_name_str_ = "";
-  instrument_str_ = "";
-}
-
-void
-My_midi_parser::add_score (Mudela_score* mudela_score_p)
-{
-  assert (mudela_score_p_);
-
-#if 0 // ugh, already constructed
-  mudela_score_p_ = mudela_score_p;
-  if  (!mudela_column_l_)
-       mudela_column_l_ = mudela_score_p_->mudela_column_l (0);
-#endif
-       
-  mudela_score_p_->mudela_key_l_ = mudela_key_p_;
-  mudela_score_p_->mudela_meter_l_ = mudela_meter_p_;
-  mudela_score_p_->mudela_tempo_l_ = mudela_tempo_p_;
-  bar_i_ = 1;
-}
-
-void
-My_midi_parser::error (char const* sz_l)
-{
-  midi_lexer_l_g->error (sz_l);
-
-  if  (fatal_error_i_)
-       exit (fatal_error_i_);
-}
-
-void
-My_midi_parser::forward (int i)
-{
-  if  (!i)
-       return;
-
-  Duration dur;
-  dur.durlog_i_ = -100;
-  dur.set_ticks (i);
-  Moment mom = at_mom() + Duration_convert::dur2_mom (dur);
-
-  mudela_column_l_ = mudela_score_p_->mudela_column_l (mom);
-
-  if  (i) 
-    {
-       int bars_i = (int) (mom / mudela_meter_p_->bar_mom());
-       if  (bars_i > bar_i_)
-           LOGOUT(NORMAL_ver) << '[' << bar_i_ << ']' << flush; 
-       bar_i_ = bars_i;
-    }
-}
-
-Moment
-My_midi_parser::at_mom()
-{
-  assert (mudela_column_l_);
-//    return mudela_column_l_ ? mudela_column_l_->at_mom() : 0;
-  return mudela_column_l_->at_mom();
-}
-
-void
-My_midi_parser::note_begin (int channel_i, int pitch_i, int dyn_i)
-{
-  // junk dynamics
-  (void)dyn_i;
-
-  Mudela_note* p = new Mudela_note (mudela_column_l_, channel_i, pitch_i, dyn_i);
-//  ugh, score doesn't know about last staff yet...
-//    mudela_score_p_->add_item (p);
-  mudela_staff_l_->add_item (p);
-  open_mudela_note_l_list_.bottom().add (p);
-}
-
-void
-My_midi_parser::note_end (int channel_i, int pitch_i, int aftertouch_i)
-{
-  // junk dynamics
-  (void)aftertouch_i;
-
-  // find 
-  for  (PCursor<Mudela_note*> i (open_mudela_note_l_list_); i.ok(); i++) 
-    {
-       if  ( (i->pitch_i_ == pitch_i) &&  (i->channel_i_ == channel_i)) 
-         {
-           i->end_column_l_ = mudela_column_l_;
-           LOGOUT(DEBUG_ver) << "Note: " << pitch_i;
-           LOGOUT(DEBUG_ver) << "; " << i->mudela_column_l_->at_mom_;
-           LOGOUT(DEBUG_ver) << ", " << i->end_column_l_->at_mom_ << "\n";
-           i.remove_p();
-           return;
-         }
-    }
-  warning (String ("junking note-end event: ")
-       + " channel = " + String_convert::i2dec_str (channel_i, 0, ' ')
-       + ", pitch = " + String_convert::i2dec_str (pitch_i, 0, ' '));
-}
-
-void
-My_midi_parser::note_end_all()
-{
-  // find 
-  for  (PCursor<Mudela_note*> i (open_mudela_note_l_list_); i.ok(); i++) 
-    {
-       i->end_column_l_ = mudela_column_l_;
-       i.remove_p();
-       // ugh
-       if  (!i.ok())
-           break;
-    }
-}
-
-int
-My_midi_parser::parse()
-{
-  LOGOUT(NORMAL_ver) << "\nParsing..." << flush;
-  int i = ::yyparse();
-  if  (!i)
-       note_end_all();
-  return i;
-}
-
-void
-My_midi_parser::set_division_4 (int division_4_i)
-{
-  division_1_i_ = division_4_i * 4;
-  // ugh
-  Duration::division_1_i_s = division_1_i_;
-  if  (division_4_i < 0)
-       warning ("seconds iso metrical time");
-}
-
-void
-My_midi_parser::set_key (int accidentals_i, int minor_i)
-{
-  delete mudela_key_p_;
-  mudela_key_p_ = new Mudela_key (accidentals_i, minor_i);
-}
-
-void
-My_midi_parser::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);
-}
-
-void
-My_midi_parser::set_tempo (int useconds_per_4_i)
-{
-  delete mudela_tempo_p_;
-  mudela_tempo_p_ = new Mudela_tempo (useconds_per_4_i);
-}
-