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"));
61 Duration::division_1_i_s
= info_l_
->division_1_i_
;
62 forward_byte_L (length_i
- 6);
66 Midi_score_parser::find_earliest_i (Link_array
<Midi_track_parser
>& tracks
)
69 Moment earliest_mom
= infinity_mom
;
70 for (int i
= 0; i
< tracks
.size(); i
++)
72 if ( tracks
[i
]->at_mom () < earliest_mom
)
74 earliest_mom
= tracks
[i
]->at_mom ();
82 Midi_score_parser::parse_score ()
84 int current_bar_i
= 0;
85 Mudela_meter
m4 (4, 2, 24, 8);
86 Moment bar4_mom
= m4
.bar_mom ();
88 Mudela_score
* score_p
= new Mudela_score( 1, 1, 1 );
89 info_l_
->score_l_
= score_p
;
91 Link_array
<Midi_track_parser
> tracks
;
92 for (int i
= 0; i
< info_l_
->tracks_i_
; i
++)
93 tracks
.push (new Midi_track_parser (info_l_
, i
));
95 LOGOUT (NORMAL_ver
) << _("Parsing...\n");
96 while (tracks
.size ())
98 int i
= find_earliest_i (tracks
);
99 Moment at_mom
= tracks
[i
]->at_mom ();
100 Mudela_column
* column_l
= score_p
->get_column_l (at_mom
);
101 Mudela_staff
* staff_p
= tracks
[i
]->parse (column_l
);
104 score_p
->add_staff (staff_p
);
109 // brr, musta have some progress
110 for (int ii
= 0; !info_l_
->bar_mom_
&& ii
< tracks
.size (); ii
++)
111 info_l_
->bar_mom_
= tracks
[ii
]->info_l_
->bar_mom_
;
113 int bar_i
= (int) (at_mom
114 / (info_l_
->bar_mom_
? info_l_
->bar_mom_
: bar4_mom
)) + 1;
115 if (bar_i
> current_bar_i
)
117 LOGOUT (NORMAL_ver
) << '[' << bar_i
<< ']' << flush
;
118 current_bar_i
= bar_i
;