lilypond-0.1.15
[lilypond.git] / mi2mu / midi-parser.y
blobc1ec3edfedf2c5b777feb1aeb72cd6c3d61c7865
1 %{
3 #include "mi2mu-proto.hh"
4 #include "proto.hh"
5 #include "plist.hh"
6 #include "warn.hh"
7 #include "mi2mu-global.hh"
8 //#include "midi-parser.hh"
9 #include "my-midi-parser.hh"
10 #include "my-midi-lexer.hh"
11 #include "duration-convert.hh"
12 #include "string-convert.hh"
13 #include "mudela-item.hh"
14 #include "mudela-score.hh"
15 #include "mudela-staff.hh"
17 #ifndef NDEBUG
18 #define YYDEBUG 1
19 #endif
23 %union {
24 Byte byte;
25 char c;
26 int i;
27 String* str_p;
28 Mudela_item* mudela_item_p; // Voice_element* ? jup, just about :-)
29 Mudela_score* mudela_score_p; // Input_score* ?
30 Mudela_staff* mudela_staff_p; // Input_music* ?
33 %token HEADER TRACK
34 %token SYSEX_EVENT1 SYSEX_EVENT2
35 %token META_EVENT
36 %token SEQUENCE
37 %token END_OF_TRACK TEMPO SMPTE_OFFSET TIME KEY SSME
39 %token<i> I8 U8 INT16 INT32 INT7_8UNSET INT7_8SET VARINT
40 %token<i> RUNNING_STATUS DATA_ENTRY ALL_NOTES_OFF
41 %token<i> NOTE_OFF NOTE_ON
42 %token<i> POLYPHONIC_AFTERTOUCH CONTROLMODE_CHANGE PROGRAM_CHANGE
43 %token<i> CHANNEL_AFTERTOUCH PITCHWHEEL_RANGE
44 %token<i> YYTEXT YYCOPYRIGHT YYTRACK_NAME YYINSTRUMENT_NAME YYLYRIC YYMARKER YYCUE_POINT
45 %token<str_p> DATA
47 %type <i> varint
48 %type <mudela_score_p> header mudela_score
49 %type <mudela_staff_p> track
50 %type <mudela_item_p> item
51 %type <mudela_item_p> the_item meta_item the_meta_item text_item mudela_item sysex_item
52 %type <mudela_item_p> running_status data_entry all_notes_off
53 %type <mudela_item_p> note_off note_on
54 %type <mudela_item_p> polyphonic_aftertouch controlmode_change program_change
55 %type <mudela_item_p> channel_aftertouch pitchwheel_range
59 midi: /* empty */
60 | midi mudela_score {
61 midi_parser_l_g->add_score ($2);
65 mudela_score:
66 header {
68 | mudela_score track {
69 $$->add_staff ($2);
70 // ugh
71 $2->set_tempo (midi_parser_l_g->mudela_tempo_p_->useconds_per_4_i());
72 $2->set_meter (midi_parser_l_g->mudela_meter_p_->num_i(),
73 midi_parser_l_g->mudela_meter_p_->den_i(),
74 midi_parser_l_g->mudela_meter_p_->clocks_1_i(),
75 8);
76 if (midi_parser_l_g->copyright_str_.length_i())
77 $2->copyright_str_ = midi_parser_l_g->copyright_str_;
78 if (midi_parser_l_g->track_name_str_.length_i())
79 $2->name_str_ = midi_parser_l_g->track_name_str_;
80 if (midi_parser_l_g->instrument_str_.length_i())
81 $2->instrument_str_ = midi_parser_l_g->instrument_str_;
82 midi_parser_l_g->reset();
86 header:
87 HEADER INT32 INT16 INT16 INT16 {
88 // ugh, already constructed;
89 // need to have score in My_midi_parser...
90 // $$ = new Mudela_score ($3, $4, $5);
91 $$ = midi_parser_l_g->mudela_score_p_;
92 $$->format_i_ = $3;
93 $$->tracks_i_ = $4;
94 $$->tempo_i_ = $5;
95 midi_parser_l_g->set_division_4 ($5);
99 track:
100 TRACK INT32 {
101 LOGOUT (NORMAL_ver) << "\ntrack " << midi_parser_l_g->track_i_ << ": " << flush;
102 $$ = new Mudela_staff (midi_parser_l_g->track_i_++,
103 // silly, cause not set yet!
104 midi_parser_l_g->copyright_str_,
105 midi_parser_l_g->track_name_str_,
106 midi_parser_l_g->instrument_str_);
107 //ugh, need to know now!
108 midi_parser_l_g->mudela_staff_l_ = $$;
110 | track item {
111 if ($2) {
112 $2->mudela_column_l_ = midi_parser_l_g->mudela_column_l_;
113 $$->add_item ($2);
118 item:
119 varint the_item {
120 $$ = $2;
121 if ($2) {
122 String str = $2->str();
123 if (str.length_i())
124 LOGOUT (DEBUG_ver) << str << " " << flush;
129 varint:
130 VARINT {
131 midi_parser_l_g->forward ($1);
135 the_item:
136 meta_item {
138 | mudela_item {
140 | sysex_item {
144 meta_item:
145 META_EVENT the_meta_item {
146 $$ = $2;
149 META_EVENT U8 U8 U8 {
150 $$ = 0;
154 the_meta_item:
155 SEQUENCE INT16 {
157 | text_item DATA {
158 Mudela_text::Type type = (Mudela_text::Type)$1;
159 $$ = 0;
160 switch (type)
162 case Mudela_text::COPYRIGHT:
163 midi_parser_l_g->copyright_str_ = *$2;
164 break;
165 case Mudela_text::TRACK_NAME:
166 midi_parser_l_g->track_name_str_ = *$2;
167 break;
168 case Mudela_text::INSTRUMENT_NAME:
169 midi_parser_l_g->instrument_str_ = *$2;
170 break;
171 default:
172 $$ = new Mudela_text (type, *$2);
173 break;
175 LOGOUT (DEBUG_ver) << *$2 << endl;
176 delete $2;
178 | END_OF_TRACK {
179 $$ = 0;
181 | TEMPO U8 U8 U8 {
182 $$ = new Mudela_tempo ( ($2 << 16) + ($3 << 8) + $4);
183 LOGOUT (DEBUG_ver) << $$->str() << endl;
184 midi_parser_l_g->set_tempo ( ($2 << 16) + ($3 << 8) + $4);
186 | SMPTE_OFFSET U8 U8 U8 U8 U8 {
187 $$ = 0;
189 | TIME U8 U8 U8 U8 {
190 $$ = new Mudela_meter ($2, $3, $4, $5);
191 LOGOUT (DEBUG_ver) << $$->str() << endl;
192 midi_parser_l_g->set_meter ($2, $3, $4, $5);
194 | KEY I8 I8 {
195 $$ = new Mudela_key ($2, $3);
196 midi_parser_l_g->set_key ($2, $3 );
198 | SSME DATA {
199 $$ = new Mudela_text ((Mudela_text::Type)0, *$2);
200 delete $2;
204 text_item:
205 YYTEXT {
206 LOGOUT (DEBUG_ver) << "\n% Text: ";
208 | YYCOPYRIGHT {
209 LOGOUT (DEBUG_ver) << "\n% Copyright: ";
211 | YYTRACK_NAME {
212 LOGOUT (DEBUG_ver) << "\n% Track name: ";
214 | YYINSTRUMENT_NAME {
215 LOGOUT (DEBUG_ver) << "\n% Instrument name: ";
217 | YYLYRIC {
218 LOGOUT (DEBUG_ver) << "\n% Lyric: ";
220 | YYMARKER {
221 LOGOUT (DEBUG_ver) << "\n% Marker: ";
223 | YYCUE_POINT {
224 LOGOUT (DEBUG_ver) << "\n% Cue point: ";
228 mudela_item:
229 running_status {
231 | data_entry {
233 | all_notes_off {
235 | note_off {
237 | note_on {
239 | polyphonic_aftertouch {
241 | controlmode_change {
243 | program_change {
245 | channel_aftertouch {
247 | pitchwheel_range {
251 running_status:
252 RUNNING_STATUS mudela_item {
253 $$ = $2;
257 data_entry:
258 DATA_ENTRY U8 {
259 $$ = 0;
263 all_notes_off:
264 ALL_NOTES_OFF U8 U8 {
265 midi_parser_l_g->note_end_all();
266 $$ = 0;
270 note_off:
271 NOTE_OFF U8 U8 {
272 int i = $1;
273 i = i & ~0x80;
274 midi_parser_l_g->note_end ($1 & ~0x80, $2, $3);
275 $$ = 0;
279 note_on:
280 NOTE_ON U8 U8 {
281 int i = $1;
282 i = i & ~0x90;
283 $$ = 0;
284 if ($3)
285 midi_parser_l_g->note_begin ($1 & ~0x90, $2, $3);
287 sss: some broken devices encode NOTE_OFF as
288 NOTE_ON with zero volume
290 else
291 midi_parser_l_g->note_end ($1 & ~0x90, $2, $3);
295 polyphonic_aftertouch:
296 POLYPHONIC_AFTERTOUCH U8 U8 {
297 $$ = 0;
301 controlmode_change:
302 CONTROLMODE_CHANGE U8 U8 {
303 $$ = 0;
307 program_change:
308 PROGRAM_CHANGE U8 {
309 $$ = 0;
313 channel_aftertouch:
314 CHANNEL_AFTERTOUCH U8 U8 {
315 $$ = 0;
319 pitchwheel_range:
320 PITCHWHEEL_RANGE U8 U8 {
321 $$ = 0;
325 sysex_item:
326 SYSEX_EVENT1 DATA {
327 $$ = 0;
329 | SYSEX_EVENT2 DATA { // U8 ?
330 $$ = 0;