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