2 midi-score-parser.cc -- implement
4 source file of the GNU LilyPond music typesetter
6 (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
10 #include "source-file.hh"
12 #include "mi2mu-global.hh"
13 #include "midi-score-parser.hh"
14 #include "midi-track-parser.hh"
15 #include "mudela-item.hh"
16 #include "mudela-score.hh"
20 Midi_score_parser::open (String filename_str, Sources* sources_l)
22 info_l_->source_l_ = sources_l->get_file_l (filename_str);
23 if (!info_l_->source_l_)
24 ::error ("can't find: `" + filename_str + "'");
25 info_l_->byte_L_ = (Byte const*)info_l_->source_l_->ch_C ();
26 // info_l_->end_byte_L_ = info_l_->byte_L_ + info_l_->source_l_->length_i ();
27 info_l_->end_byte_L_ = info_l_->byte_L_ + info_l_->source_l_->length_i () + 1;
31 Midi_score_parser::parse (String filename_str, Sources* sources_l)
33 Midi_parser_info info;
35 open (filename_str, sources_l);
37 return parse_score ();
41 Midi_score_parser::parse_header ()
43 String str = get_str (4);
45 exit ("MIDI header expected");
47 int length_i = get_i (4);
50 exit ("Invalid header length");
51 info_l_->format_i_ = get_i (2);
52 if (info_l_->format_i_ != 0 && info_l_->format_i_ != 1)
53 exit ("Invalid midi format");
54 info_l_->tracks_i_ = get_i (2);
55 if (info_l_->tracks_i_ < 0 || info_l_->tracks_i_ > 32 )
56 exit ("Invalid number of tracks");
57 info_l_->division_1_i_ = get_i (2) * 4;
58 if (info_l_->division_1_i_ < 0)
59 exit ("Cannot handle non-metrical time");
60 forward_byte_L (length_i - 6);
64 Midi_score_parser::find_earliest_i (Link_array<Midi_track_parser>& tracks)
67 Moment earliest_mom = infinity_mom;
68 for (int i = 0; i < tracks.size(); i++)
70 if ( tracks [i]->at_mom () < earliest_mom )
72 earliest_mom = tracks [i]->at_mom ();
80 Midi_score_parser::parse_score ()
82 Mudela_meter m4 (1, 4, 0, 0);
83 Moment bar4_mom = m4.bar_mom ();
85 Link_array<Midi_track_parser> tracks;
86 for (int i = 0; i < info_l_->tracks_i_; i++)
87 tracks.push (new Midi_track_parser (info_l_));
89 int current_bar_i = 0;
91 Mudela_score* score_p = new Mudela_score( 1, 1, 1 );
92 while (tracks.size ())
94 int i = find_earliest_i (tracks);
95 Moment at_mom = tracks [i]->at_mom ();
96 Mudela_column* column_l = score_p->get_column_l (at_mom);
97 Mudela_staff* staff_p = tracks [i]->parse (column_l);
100 score_p->add_staff (staff_p);
105 // brr, musta have some progress
106 for (int ii = 0; !info_l_->bar_mom_ && ii < tracks.size (); ii++)
107 info_l_->bar_mom_ = tracks [ii]->info_l_->bar_mom_;
109 int bar_i = (int) (at_mom
110 / (info_l_->bar_mom_ ? info_l_->bar_mom_ : bar4_mom)) + 1;
111 if (bar_i > current_bar_i)
113 LOGOUT (NORMAL_ver) << '[' << bar_i << ']' << flush;
114 current_bar_i = bar_i;