]> git.donarmstrong.com Git - lilypond.git/blob - mi2mu/midi-parser.y
release: 0.0.40
[lilypond.git] / mi2mu / midi-parser.y
1 %{
2
3 #include "mi2mu.hh"
4
5 #ifndef NDEBUG
6 #define YYDEBUG 1
7 #endif
8
9 %}
10
11 %union {
12     Byte byte;
13     char c;
14     int i;
15     String* str_p;
16     Request* request_p;
17     Midi_event* midi_event_p;   // Voice_element* ?
18     Midi_score* midi_score_p;   // Input_score* ?
19     Midi_track* midi_track_p;   // Input_music* ?
20 }
21
22 %token HEADER TRACK
23 %token SYSEX_EVENT1 SYSEX_EVENT2
24 %token META_EVENT
25 %token SEQUENCE
26 %token END_OF_TRACK TEMPO SMPTE_OFFSET TIME KEY SSME
27
28 %token<i> I8 U8 INT16 INT32 INT7_8UNSET INT7_8SET VARINT
29 %token<i> RUNNING_STATUS DATA_ENTRY ALL_NOTES_OFF
30 %token<i> NOTE_OFF NOTE_ON 
31 %token<i> POLYPHONIC_AFTERTOUCH CONTROLMODE_CHANGE PROGRAM_CHANGE 
32 %token<i> CHANNEL_AFTERTOUCH PITCHWHEEL_RANGE
33 %token<i> YYTEXT YYCOPYRIGHT YYTRACK_NAME YYINSTRUMENT_NAME YYLYRIC YYMARKER YYCUE_POINT
34 %token<str_p> DATA
35
36 %type <i> varint
37 %type <midi_score_p> header midi_score
38 %type <midi_track_p> track
39 %type <midi_event_p> event
40 %type <midi_event_p> the_event meta_event the_meta_event text_event midi_event sysex_event
41 %type <midi_event_p> running_status data_entry all_notes_off
42 %type <midi_event_p> note_off note_on
43 %type <midi_event_p> polyphonic_aftertouch controlmode_change program_change
44 %type <midi_event_p> channel_aftertouch pitchwheel_range
45
46 %%
47
48 midi:   /* empty */
49         | midi midi_score {
50                 midi_parser_l_g->add_score( $2 );               
51         }
52         ;
53
54 midi_score:
55         header {
56         }
57         | midi_score track {
58                 $$->add_track( $2 );
59                 if ( midi_parser_l_g->copyright_str_.length_i() )
60                         $2->copyright_str_ = midi_parser_l_g->copyright_str_;
61                 if ( midi_parser_l_g->track_name_str_.length_i() )
62                         $2->name_str_ = midi_parser_l_g->track_name_str_;
63                 if ( midi_parser_l_g->instrument_str_.length_i() )
64                         $2->instrument_str_ = midi_parser_l_g->instrument_str_;
65                 midi_parser_l_g->reset();
66         }
67         ;
68
69 header: 
70         HEADER INT32 INT16 INT16 INT16 {
71                 $$ = new Midi_score( $3, $4, $5 );
72                 midi_parser_l_g->set_division_4( $5 );
73         }
74         ;
75
76 track: 
77         TRACK INT32 {
78                 mtor << "\ntrack " << midi_parser_l_g->track_i_++ << ": " << flush;
79                 $$ = new Midi_track( midi_parser_l_g->track_i_++,
80                         // silly, cause not set yet!
81                         midi_parser_l_g->copyright_str_,
82                         midi_parser_l_g->track_name_str_,
83                         midi_parser_l_g->instrument_str_ );
84         }
85         | track event {
86                 $$->add_event( midi_parser_l_g->mom(), $2 );
87         }
88         ;
89
90 event:  
91         varint the_event {
92                 $$ = $2;
93                 if ( $2 ) {
94                         String str = $2->mudela_str( false );
95                         if ( str.length_i() )
96                                 dtor << str << " " << flush;
97                 }
98         }
99         ;
100         
101 varint:
102         VARINT {
103                 midi_parser_l_g->forward( $1 );
104                 if ( $1 ) {
105                         int bars_i = (int)( midi_parser_l_g->mom() / midi_parser_l_g->midi_time_p_->bar_mom() );
106                         if ( bars_i > midi_parser_l_g->bar_i_ )
107                                 mtor << '[' << midi_parser_l_g->bar_i_++ 
108                                         << ']' << flush; 
109                 }
110         }
111         ;
112
113 the_event: 
114         meta_event { 
115         }
116         | midi_event {
117         }
118         | sysex_event {
119         }
120         ;
121
122 meta_event:
123         META_EVENT the_meta_event {
124                 $$ = $2;
125         }
126         |
127         META_EVENT U8 U8 U8 {
128                 $$ = 0;
129         }
130         ;
131
132 the_meta_event:
133         SEQUENCE INT16 {
134         }
135         | text_event DATA {
136                 Midi_text::Type type = (Midi_text::Type)$1;
137                 $$ = 0;
138                 switch ( type )
139                         {
140                         case Midi_text::COPYRIGHT:
141                                 midi_parser_l_g->copyright_str_ = *$2;
142                                 break;
143                         case Midi_text::TRACK_NAME:
144                                 midi_parser_l_g->track_name_str_ = *$2;
145                                 while ( midi_parser_l_g->track_name_str_.index_i( ' ' ) != -1 )
146                                         *(midi_parser_l_g->track_name_str_.ch_l() + midi_parser_l_g->track_name_str_.index_i( ' ' ) ) = '_';
147                                 break;
148                         case Midi_text::INSTRUMENT_NAME:
149                                 midi_parser_l_g->instrument_str_ = *$2;
150                                 break;
151                         default:
152                                 $$ = new Midi_text( type, *$2 );
153                                 break;
154                         }
155                 dtor << *$2 << endl;
156                 delete $2;
157         }
158         | END_OF_TRACK {
159                 $$ = 0;
160         }
161         | TEMPO U8 U8 U8 { 
162                 $$ = new Midi_tempo( ( $2 << 16 ) + ( $3 << 8 ) + $4 );
163                 dtor << $$->mudela_str( false ) << endl;
164                 midi_parser_l_g->set_tempo( ( $2 << 16 ) + ( $3 << 8 ) + $4 );
165         }
166         | SMPTE_OFFSET U8 U8 U8 U8 U8 { 
167                 $$ = 0;
168         }
169         | TIME U8 U8 U8 U8 { 
170                 $$ = new Midi_time( $2, $3, $4, $5 );
171                 dtor << $$->mudela_str( true ) << endl;
172                 midi_parser_l_g->set_time( $2, $3, $4, $5 );
173         }
174         | KEY I8 I8 { 
175                 $$ = new Midi_key( $2, $3 );
176                 midi_parser_l_g->set_key( $2, $3  );
177         }
178         | SSME DATA {
179                 $$ = new Midi_text( (Midi_text::Type)0, *$2 );
180                 delete $2;
181         }
182         ;
183
184 text_event: 
185         YYTEXT {
186                 dtor << "\n% Text: ";
187         }
188         | YYCOPYRIGHT {
189                 dtor << "\n% Copyright: ";
190         }
191         | YYTRACK_NAME {
192                 dtor << "\n% Track  name: ";
193         }
194         | YYINSTRUMENT_NAME {
195                 dtor << "\n% Instrument  name: ";
196         }
197         | YYLYRIC {
198                 dtor << "\n% Lyric: ";
199         }
200         | YYMARKER {
201                 dtor << "\n% Marker: ";
202         }
203         | YYCUE_POINT {
204                 dtor << "\n% Cue point: ";
205         }
206         ;
207
208 midi_event: 
209         running_status {
210         }
211         | data_entry {
212         }
213         | all_notes_off {
214         }
215         | note_off {
216         }
217         | note_on {
218         }
219         | polyphonic_aftertouch {
220         }
221         | controlmode_change {
222         }
223         | program_change {
224         }
225         | channel_aftertouch {
226         }
227         | pitchwheel_range {
228         }
229         ;
230
231 running_status:
232         RUNNING_STATUS U8 { //U8 {
233                 $$ = 0;
234         }
235         ;
236
237 data_entry:
238         DATA_ENTRY U8 {
239                 $$ = 0;
240         }
241         ;
242
243 all_notes_off:
244         ALL_NOTES_OFF U8 U8 {
245                 $$ = 0;
246         }
247         ;
248
249 note_off:
250         NOTE_OFF U8 U8 {
251                 int i = $1;
252                 i = i & ~0x80;
253                 $$ = midi_parser_l_g->note_end_midi_event_p( $1 & ~0x80, $2, $3 );
254         }
255         ;
256
257 note_on:
258         NOTE_ON U8 U8 {
259                 int i = $1;
260                 i = i & ~0x90;
261                 $$ = 0;
262                 midi_parser_l_g->note_begin( $1 & ~0x90, $2, $3 );
263         }
264         ;
265
266 polyphonic_aftertouch:
267         POLYPHONIC_AFTERTOUCH U8 U8 {
268                 $$ = 0;
269         }
270         ;
271
272 controlmode_change:
273         CONTROLMODE_CHANGE U8 U8 {
274                 $$ = 0;
275         }
276         ;
277
278 program_change:
279         PROGRAM_CHANGE U8 {
280                 $$ = 0;
281         }
282         ;
283
284 channel_aftertouch:
285         CHANNEL_AFTERTOUCH U8 U8 {
286                 $$ = 0;
287         }
288         ;
289
290 pitchwheel_range:
291         PITCHWHEEL_RANGE U8 U8 {
292                 $$ = 0;
293         }
294         ;
295
296 sysex_event:
297         SYSEX_EVENT1 DATA {
298                 $$ = 0;
299         }
300         | SYSEX_EVENT2 DATA { // U8 ?
301                 $$ = 0;
302         }
303         ;