]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-1.1.55
authorfred <fred>
Mon, 25 Jan 1999 09:50:40 +0000 (09:50 +0000)
committerfred <fred>
Mon, 25 Jan 1999 09:50:40 +0000 (09:50 +0000)
midi2ly/include/midi-parser.hh [new file with mode: 0644]
midi2ly/midi-score-parser.cc [new file with mode: 0644]

diff --git a/midi2ly/include/midi-parser.hh b/midi2ly/include/midi-parser.hh
new file mode 100644 (file)
index 0000000..9dca4db
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+  midi-parser.hh -- declare Midi_parser
+
+  source file of the GNU LilyPond music typesetter
+
+  (c)  1997--1998 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+
+#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"
+#include "mi2mu-proto.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_;
+  Mudela_score* score_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 (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 (String (fun) + ": unexpected EOF");
+    return 0;
+  }
+
+#ifdef INLINES
+  Byte inline_next_byte (char const* fun) 
+    {
+      if (info_l_->byte_L_ < info_l_->end_byte_L_)
+        return *info_l_->byte_L_++;
+      exit (String (fun) + ": unexpected EOF");
+      return 0;
+    }
+
+  Byte inline_peek_byte (char const* fun)
+    {
+      if (info_l_->byte_L_ < info_l_->end_byte_L_)
+       return *info_l_->byte_L_;
+      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/midi2ly/midi-score-parser.cc b/midi2ly/midi-score-parser.cc
new file mode 100644 (file)
index 0000000..c20fe46
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+  midi-score-parser.cc -- implement
+
+  source file of the GNU LilyPond music typesetter
+
+  (c)  1997--1998 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+#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 (_f ("can't find file: `%s\'", 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 () + 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 (_f ("can't handle %s", _ ("non-metrical time")));
+  // ugh
+  Duration::division_1_i_s = info_l_->division_1_i_;
+  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 ()
+{
+  int current_bar_i = 0;
+  Mudela_time_signature m4 (4, 2, 24, 8);
+  Moment bar4_mom = m4.bar_mom ();
+
+  Mudela_score* score_p = new Mudela_score( 1, 1, 1 );
+  info_l_->score_l_ = score_p;
+
+  Link_array<Midi_track_parser> tracks;
+  for (int i = 0; i < info_l_->tracks_i_; i++)
+    tracks.push (new Midi_track_parser (info_l_, i));
+
+  LOGOUT (NORMAL_ver) << _ ("Parsing...\n");
+  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;
+}