2 midi-score-parser.cc -- implement
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--1998 Jan Nieuwenhuizen <janneke@gnu.org>
10 #include "source-file.hh"
12 #include "midi2ly-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 (_f ("can't find file: `%s'", 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 () + 1;
30 Midi_score_parser::parse (String filename_str
, Sources
* sources_l
)
32 Midi_parser_info info
;
34 open (filename_str
, sources_l
);
36 return parse_score ();
40 Midi_score_parser::parse_header ()
42 String str
= get_str (4);
44 exit (_ ("MIDI header expected"));
46 int length_i
= get_i (4);
49 exit (_ ("invalid header length"));
50 info_l_
->format_i_
= get_i (2);
51 if (info_l_
->format_i_
!= 0 && info_l_
->format_i_
!= 1)
52 exit (_("invalid MIDI format"));
53 info_l_
->tracks_i_
= get_i (2);
54 if (info_l_
->tracks_i_
< 0 || info_l_
->tracks_i_
> 32 )
55 exit (_("invalid number of tracks"));
56 info_l_
->division_1_i_
= get_i (2) * 4;
57 if (info_l_
->division_1_i_
< 0)
58 exit (_ ("can't handle non-metrical time"));
60 Duration::division_1_i_s
= info_l_
->division_1_i_
;
61 forward_byte_L (length_i
- 6);
65 Midi_score_parser::find_earliest_i (Link_array
<Midi_track_parser
>& tracks
)
68 Rational earliest_mom
= infinity_rat
;
69 for (int i
= 0; i
< tracks
.size(); i
++)
71 if ( tracks
[i
]->at_mom () < earliest_mom
)
73 earliest_mom
= tracks
[i
]->at_mom ();
81 Midi_score_parser::parse_score ()
83 int current_bar_i
= 0;
84 Mudela_time_signature
m4 (4, 2, 24, 8);
85 Rational bar4_mom
= m4
.bar_mom ();
87 Mudela_score
* score_p
= new Mudela_score( 1, 1, 1 );
88 info_l_
->score_l_
= score_p
;
90 Link_array
<Midi_track_parser
> tracks
;
91 for (int i
= 0; i
< info_l_
->tracks_i_
; i
++)
92 tracks
.push (new Midi_track_parser (info_l_
, i
));
94 LOGOUT (NORMAL_ver
) << _ ("Parsing...");
95 LOGOUT (NORMAL_ver
) << "\n";
96 while (tracks
.size ())
98 int i
= find_earliest_i (tracks
);
99 Rational 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
;