]> git.donarmstrong.com Git - lilypond.git/blob - mi2mu/my-midi-parser.cc
release: 0.1.8
[lilypond.git] / mi2mu / my-midi-parser.cc
1 //
2 // my-midi-parser.cc -- implement My_midi_parser
3 //
4 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
5
6 #include "string-convert.hh"
7 #include "duration-convert.hh"
8 #include "mi2mu-global.hh"
9 #include "my-midi-lexer.hh"
10 #include "my-midi-parser.hh"
11 #include "mudela-column.hh"
12 #include "mudela-item.hh"
13 #include "mudela-score.hh"
14 #include "mudela-staff.hh"
15
16 void
17 yyerror(char const* sz_l)
18 {
19     midi_parser_l_g->error (sz_l);
20 }
21
22
23 My_midi_parser* midi_parser_l_g = 0;
24
25 My_midi_parser::My_midi_parser (String filename_str, Sources *sources_l)
26 {
27     filename_str_ = filename_str;
28     midi_lexer_p_ = new My_midi_lexer (filename_str_,sources_l);
29     midi_lexer_l_g = midi_lexer_p_;    // ugh
30
31     bar_i_ = 1;
32
33     defined_ch_C_ = 0;
34     fatal_error_i_ = 0;
35     
36     mudela_column_l_ = 0;
37     mudela_score_p_ = new Mudela_score (1, 1, 1);
38
39
40     // ugh, belong to Mudela_{score,staff}
41     track_i_ = 0;
42     mudela_staff_l_ = 0;
43     mudela_key_p_ = 0;
44     mudela_tempo_p_ = 0;
45     mudela_meter_p_ = 0;
46
47     reset();
48 }
49
50 My_midi_parser::~My_midi_parser()
51 {
52     midi_lexer_l_g = 0;    // ugh
53
54     delete midi_lexer_p_;
55     delete mudela_key_p_;
56     delete mudela_tempo_p_;
57     delete mudela_meter_p_;
58     delete mudela_score_p_;
59 }
60
61 void
62 My_midi_parser::reset()
63 {
64 //    open_mudela_note_l_list_.clear();
65     open_mudela_note_l_list_.junk_links();
66
67     // ugh
68     delete mudela_key_p_;
69     mudela_key_p_ = new Mudela_key (0, 0);
70     // useconds per 4: 250000 === 60 4 per minute
71     delete mudela_tempo_p_;
72     mudela_tempo_p_ = new Mudela_tempo (1000000);
73     delete mudela_meter_p_;
74     mudela_meter_p_ = new Mudela_meter (4, 2, 24, 8);
75
76     bar_i_ = 1;
77     mudela_column_l_ = mudela_score_p_->mudela_column_l (0);
78
79     // ugh
80     copyright_str_ = "";
81     track_name_str_ = "";
82     instrument_str_ = "";
83 }
84
85 void
86 My_midi_parser::add_score (Mudela_score* mudela_score_p)
87 {
88     assert (mudela_score_p_);
89
90 #if 0 // ugh, already constructed
91     mudela_score_p_ = mudela_score_p;
92     if  (!mudela_column_l_)
93         mudela_column_l_ = mudela_score_p_->mudela_column_l (0);
94 #endif
95         
96     mudela_score_p_->mudela_key_l_ = mudela_key_p_;
97     mudela_score_p_->mudela_meter_l_ = mudela_meter_p_;
98     mudela_score_p_->mudela_tempo_l_ = mudela_tempo_p_;
99     bar_i_ = 1;
100 }
101
102 void
103 My_midi_parser::error (char const* sz_l)
104 {
105     midi_lexer_l_g->error (sz_l);
106
107     if  (fatal_error_i_)
108         exit (fatal_error_i_);
109 }
110
111 void
112 My_midi_parser::forward (int i)
113 {
114     if  (!i)
115         return;
116
117     Duration dur;
118     dur.type_i_ = (0);
119     dur.set_ticks (i);
120     Moment mom = at_mom() + Duration_convert::dur2_mom (dur);
121
122     mudela_column_l_ = mudela_score_p_->mudela_column_l (mom);
123
124     if  (i) {
125         int bars_i = (int) (mom / mudela_meter_p_->bar_mom());
126         if  (bars_i > bar_i_)
127             LOGOUT(NORMAL_ver) << '[' << bar_i_ << ']' << flush; 
128         bar_i_ = bars_i;
129     }
130 }
131
132 Moment
133 My_midi_parser::at_mom()
134 {
135     assert (mudela_column_l_);
136 //    return mudela_column_l_ ? mudela_column_l_->at_mom() : 0;
137     return mudela_column_l_->at_mom();
138 }
139
140 void
141 My_midi_parser::note_begin (int channel_i, int pitch_i, int dyn_i)
142 {
143     // junk dynamics
144     (void)dyn_i;
145
146     Mudela_note* p = new Mudela_note (mudela_column_l_, channel_i, pitch_i, dyn_i);
147 //  ugh, score doesn't know about last staff yet...
148 //    mudela_score_p_->add_item (p);
149     mudela_staff_l_->add_item (p);
150     open_mudela_note_l_list_.bottom().add (p);
151 }
152
153 void
154 My_midi_parser::note_end (int channel_i, int pitch_i, int aftertouch_i)
155 {
156     // junk dynamics
157     (void)aftertouch_i;
158
159     // find 
160     for  (PCursor<Mudela_note*> i (open_mudela_note_l_list_); i.ok(); i++) {
161         if  ( (i->pitch_i_ == pitch_i) &&  (i->channel_i_ == channel_i)) {
162             i->end_column_l_ = mudela_column_l_;
163             LOGOUT(DEBUG_ver) << "Note: " << pitch_i;
164             LOGOUT(DEBUG_ver) << "; " << i->mudela_column_l_->at_mom_;
165             LOGOUT(DEBUG_ver) << ", " << i->end_column_l_->at_mom_ << "\n";
166             i.remove_p();
167             return;
168         }
169     }
170     warning (String ("junking note-end event: ")
171         + " channel = " + String_convert::i2dec_str (channel_i, 0, ' ')
172         + ", pitch = " + String_convert::i2dec_str (pitch_i, 0, ' '));
173 }
174
175 void
176 My_midi_parser::note_end_all()
177 {
178     // find 
179     for  (PCursor<Mudela_note*> i (open_mudela_note_l_list_); i.ok(); i++) {
180         i->end_column_l_ = mudela_column_l_;
181         i.remove_p();
182         // ugh
183         if  (!i.ok())
184             break;
185     }
186 }
187
188 int
189 My_midi_parser::parse()
190 {
191     LOGOUT(NORMAL_ver) << "\nParsing..." << flush;
192     int i = ::yyparse();
193     if  (!i)
194         note_end_all();
195     return i;
196 }
197
198 void
199 My_midi_parser::set_division_4 (int division_4_i)
200 {
201     division_1_i_ = division_4_i * 4;
202     // ugh
203     Duration::division_1_i_s = division_1_i_;
204     if  (division_4_i < 0)
205         warning ("seconds iso metrical time");
206 }
207
208 void
209 My_midi_parser::set_key (int accidentals_i, int minor_i)
210 {
211     delete mudela_key_p_;
212     mudela_key_p_ = new Mudela_key (accidentals_i, minor_i);
213 }
214
215 void
216 My_midi_parser::set_meter (int num_i, int den_i, int clocks_i, int count_32_i)
217 {
218     delete mudela_meter_p_;
219     mudela_meter_p_ = new Mudela_meter (num_i, den_i, clocks_i, count_32_i);
220 }
221
222 void
223 My_midi_parser::set_tempo (int useconds_per_4_i)
224 {
225     delete mudela_tempo_p_;
226     mudela_tempo_p_ = new Mudela_tempo (useconds_per_4_i);
227 }
228