]> git.donarmstrong.com Git - lilypond.git/blob - m2m/midi-parser.y
release: 0.0.39-1
[lilypond.git] / m2m / midi-parser.y
1 %{
2
3 #include "m2m.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> INT8 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                 $$ = new Midi_track( midi_parser_l_g->track_i_++,
79                         // silly, cause not set yet!
80                         midi_parser_l_g->copyright_str_,
81                         midi_parser_l_g->track_name_str_,
82                         midi_parser_l_g->instrument_str_ );
83         }
84         | track event {
85                 $$->add_event( midi_parser_l_g->mom(), $2 );
86         }
87         ;
88
89 event:  
90         varint the_event {
91                 $$ = $2;
92                 if ( $2 ) {
93                         String str = $2->mudela_str( false );
94                         if ( str.length_i() )
95                                 dtor << str << " " << flush;
96                 }
97         }
98         ;
99         
100 varint:
101         VARINT {
102                 midi_parser_l_g->forward( $1 );
103         }
104         ;
105
106 the_event: 
107         meta_event { 
108         }
109         | midi_event {
110         }
111         | sysex_event {
112         }
113         ;
114
115 meta_event:
116         META_EVENT the_meta_event {
117                 $$ = $2;
118         }
119         |
120         META_EVENT INT8 INT8 INT8 {
121                 $$ = 0;
122         }
123         ;
124
125 the_meta_event:
126         SEQUENCE INT16 {
127         }
128         | text_event DATA {
129                 Midi_text::Type type = (Midi_text::Type)$1;
130                 $$ = 0;
131                 switch ( type )
132                         {
133                         case Midi_text::COPYRIGHT:
134                                 midi_parser_l_g->copyright_str_ = *$2;
135                                 break;
136                         case Midi_text::TRACK_NAME:
137                                 midi_parser_l_g->track_name_str_ = *$2;
138                                 while ( midi_parser_l_g->track_name_str_.index_i( ' ' ) != -1 )
139                                         *(midi_parser_l_g->track_name_str_.ch_l() + midi_parser_l_g->track_name_str_.index_i( ' ' ) ) = '_';
140                                 break;
141                         case Midi_text::INSTRUMENT_NAME:
142                                 midi_parser_l_g->instrument_str_ = *$2;
143                                 break;
144                         default:
145                                 $$ = new Midi_text( type, *$2 );
146                                 break;
147                         }
148                 dtor << *$2 << endl;
149                 delete $2;
150         }
151         | END_OF_TRACK {
152                 $$ = 0;
153         }
154         | TEMPO INT8 INT8 INT8 { 
155                 $$ = new Midi_tempo( ( $2 << 16 ) + ( $3 << 8 ) + $4 );
156                 dtor << $$->mudela_str( false ) << endl;
157                 midi_parser_l_g->set_tempo( ( $2 << 16 ) + ( $3 << 8 ) + $4 );
158         }
159         | SMPTE_OFFSET INT8 INT8 INT8 INT8 INT8 { 
160                 $$ = 0;
161         }
162         | TIME INT8 INT8 INT8 INT8 { 
163                 $$ = new Midi_time( $2, $3, $4, $5 );
164                 dtor << $$->mudela_str( true ) << endl;
165                 midi_parser_l_g->set_time( $2, $3, $4, $5 );
166         }
167         | KEY INT8 INT8 { 
168                 $$ = new Midi_key( $2, $3 );
169                 midi_parser_l_g->set_key( $2, $3  );
170         }
171         | SSME DATA {
172                 $$ = new Midi_text( (Midi_text::Type)0, *$2 );
173                 delete $2;
174         }
175         ;
176
177 text_event: 
178         YYTEXT {
179                 dtor << "\n% Text: ";
180         }
181         | YYCOPYRIGHT {
182                 dtor << "\n% Copyright: ";
183         }
184         | YYTRACK_NAME {
185                 dtor << "\n% Track  name: ";
186         }
187         | YYINSTRUMENT_NAME {
188                 dtor << "\n% Instrument  name: ";
189         }
190         | YYLYRIC {
191                 dtor << "\n% Lyric: ";
192         }
193         | YYMARKER {
194                 dtor << "\n% Marker: ";
195         }
196         | YYCUE_POINT {
197                 dtor << "\n% Cue point: ";
198         }
199         ;
200
201 midi_event: 
202         running_status {
203         }
204         | data_entry {
205         }
206         | all_notes_off {
207         }
208         | note_off {
209         }
210         | note_on {
211         }
212         | polyphonic_aftertouch {
213         }
214         | controlmode_change {
215         }
216         | program_change {
217         }
218         | channel_aftertouch {
219         }
220         | pitchwheel_range {
221         }
222         ;
223
224 running_status:
225         RUNNING_STATUS INT8 { //INT8 {
226                 $$ = 0;
227         }
228         ;
229
230 data_entry:
231         DATA_ENTRY INT8 {
232                 $$ = 0;
233         }
234         ;
235
236 all_notes_off:
237         ALL_NOTES_OFF INT8 INT8 {
238                 $$ = 0;
239         }
240         ;
241
242 note_off:
243         NOTE_OFF INT8 INT8 {
244                 int i = $1;
245                 i = i & ~0x80;
246                 $$ = midi_parser_l_g->note_end_midi_event_p( $1 & ~0x80, $2, $3 );
247         }
248         ;
249
250 note_on:
251         NOTE_ON INT8 INT8 {
252                 int i = $1;
253                 i = i & ~0x90;
254                 $$ = 0;
255                 midi_parser_l_g->note_begin( $1 & ~0x90, $2, $3 );
256         }
257         ;
258
259 polyphonic_aftertouch:
260         POLYPHONIC_AFTERTOUCH INT8 INT8 {
261                 $$ = 0;
262         }
263         ;
264
265 controlmode_change:
266         CONTROLMODE_CHANGE INT8 INT8 {
267                 $$ = 0;
268         }
269         ;
270
271 program_change:
272         PROGRAM_CHANGE INT8 {
273                 $$ = 0;
274         }
275         ;
276
277 channel_aftertouch:
278         CHANNEL_AFTERTOUCH INT8 INT8 {
279                 $$ = 0;
280         }
281         ;
282
283 pitchwheel_range:
284         PITCHWHEEL_RANGE INT8 INT8 {
285                 $$ = 0;
286         }
287         ;
288
289 sysex_event:
290         SYSEX_EVENT1 DATA {
291                 $$ = 0;
292         }
293         | SYSEX_EVENT2 DATA { // INT8 ?
294                 $$ = 0;
295         }
296         ;