]> git.donarmstrong.com Git - lilypond.git/blob - mi2mu/midi-track.cc
release: 0.0.41
[lilypond.git] / mi2mu / midi-track.cc
1 //
2 // midi-track.cc -- implement Midi_track
3 //
4 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
5
6 #include "mi2mu.hh"
7
8 Midi_track::Midi_track( int number_i, String copyright_str, String track_name_str, String instrument_str )
9 {
10         number_i_ = number_i;
11         copyright_str_ = copyright_str;
12         instrument_str_ = instrument_str;
13         if ( track_name_str.length_i() )
14                 name_str_ = track_name_str;
15         else
16                 name_str_ = String( "track" ) + String( number_i_ );
17         midi_time_p_ = new Midi_time( 4, 2, 24, 8 );
18         midi_tempo_p_ = new Midi_tempo( 1000000 );
19         tcol_p_list_.bottom().add( new Track_column( Moment( 0 ) ) );
20 }
21
22 Midi_track::~Midi_track()
23 {
24         delete midi_time_p_;
25         delete midi_tempo_p_;
26 }
27
28 void
29 Midi_track::add_begin_at( PointerList<Midi_voice*>& open_voices_r, Moment mom )
30 {
31         for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ )
32                 if ( i->begin_mom() == mom ) {
33                         dtor << "open_voices (" << open_voices_r.size() << "): +1\n";
34                         open_voices_r.bottom().add( *i );
35                 }
36 }
37
38 void
39 Midi_track::add_event( Moment mom, Midi_event* midi_event_p )
40 {
41         if ( ! midi_event_p )
42                 return;
43         tcol_l( mom - midi_event_p->mom() )->add_event( midi_event_p );
44 }
45
46 // too much red tape?
47 String
48 Midi_track::name_str()
49 {
50         return name_str_;
51 }
52
53 Moment
54 Midi_track::end_mom()
55 {
56         // heu..
57         Moment mom = 0.0;
58         for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ ) 
59                 mom = i->end_mom() >? mom;
60         return mom;
61 }
62
63 Midi_voice*
64 Midi_track::get_free_midi_voice_l( Moment mom )
65 {
66         for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ )
67                 if ( i->end_mom() == mom )
68                         return *i;
69
70         Midi_voice* midi_voice_p = new Midi_voice( mom );
71         Midi_voice* midi_voice_l = midi_voice_p;
72         midi_voice_p_list_.bottom().add( midi_voice_p );
73         return midi_voice_l; 
74 }
75
76 Moment
77 Midi_track::next_begin_mom( Moment now_mom )
78 {
79 //      Moment begin_mom = Midi_track::end_mom() + 1;
80         Moment begin_mom = Midi_track::end_mom();
81         for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ )
82 //              if ( i->begin_mom() >= now_mom )
83                 if ( i->begin_mom() > now_mom )
84                         begin_mom = begin_mom <? i->begin_mom();
85         return begin_mom;
86 }
87
88 Moment
89 Midi_track::next_end_mom( Moment now_mom )
90 {
91         Moment end_mom = Midi_track::end_mom();
92         for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ ) 
93                 if ( i->end_mom() > now_mom )
94                         end_mom = end_mom <? i->end_mom();
95         return end_mom;
96 }
97
98 void
99 Midi_track::process()
100 {
101         int bar_i = 1;
102         Moment bar_mom = midi_time_p_->bar_mom();
103
104         for ( PCursor<Track_column*> i( tcol_p_list_.top() ); i.ok(); i++ ) {
105                 int bars_i = (int)( i->mom() / bar_mom );
106                 if ( bars_i > bar_i )
107                         mtor << '[' << bar_i << flush; 
108                 while ( i->midi_event_p_list_.size() ) 
109                         // shit, where has the T* PCursor::remove() gone??
110                         // i don-t want to get and delete, 
111                         // i want to (re)move!
112                         // is it renamed: get vs add/insert ?? (put/remove :-)  
113                         get_free_midi_voice_l( i->mom() )->add_event( i->midi_event_p_list_.top().remove_p() );
114                 if ( bars_i > bar_i ) {
115                         bar_i++;
116                         mtor << ']' << flush; 
117                 }
118         }
119
120         dtor << "ends: " << endl;
121         int n = 0;
122         for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ ) 
123                 vtor << "voice " << n++ << ": " << i->end_mom() << endl;
124         dtor << ":sdne" << endl;
125 }
126
127
128 void
129 Midi_track::output_mudela( Lily_stream& lily_stream_r )
130 {
131         lily_stream_r << name_str_ << " = music { $";
132         lily_stream_r.indent();
133         lily_stream_r << "% midi copyright:" << copyright_str_;
134         lily_stream_r.newline();
135         lily_stream_r << "% instrument:" << instrument_str_;
136         lily_stream_r.newline();
137
138         int bar_i = 1;
139         Moment bar_mom = midi_time_p_->bar_mom();
140
141         PointerList<Midi_voice*> open_voices;
142         Moment now_mom = 0.0;
143         Moment then_mom = 0.0;
144         while ( now_mom < end_mom() ) {
145                 int bars_i = (int)( now_mom / bar_mom );
146                 if ( bars_i > bar_i )
147                         mtor << '[' << bar_i << flush; 
148                 add_begin_at( open_voices, now_mom );
149
150                 Moment begin_mom = next_begin_mom( now_mom ); 
151                 Moment end_mom = next_end_mom( now_mom ); 
152                 if ( ( begin_mom > now_mom ) && ( begin_mom < end_mom ) )
153                         then_mom = begin_mom;
154                 else 
155                         then_mom = end_mom;
156
157                 dtor << "begin: " << begin_mom << " end: " << end_mom << endl;
158                 dtor << "slice: " << now_mom << ", " << then_mom << endl;
159
160                 if ( open_voices.size() > 1 )
161                         lily_stream_r << "{ ";
162                 for ( PCursor<Midi_voice*> i( open_voices.top() ); i.ok(); i++ )
163                         lily_stream_r << i->mudela_str( now_mom, then_mom, open_voices.size() - 1 );
164                 if ( open_voices.size() > 1 )
165                         lily_stream_r << "} ";
166                 now_mom = then_mom;
167
168                 remove_end_at( open_voices, now_mom );
169                 if ( bars_i > bar_i ) {
170                         bar_i++;
171                         mtor << ']' << flush; 
172                 }
173         }
174         lily_stream_r.tnedni();
175         lily_stream_r << "$} % " << name_str_;
176         lily_stream_r.newline();
177 }
178
179 void
180 Midi_track::remove_end_at( PointerList<Midi_voice*>& open_voices_r, Moment mom )
181 {
182         for ( PCursor<Midi_voice*> i( open_voices_r.top() ); i.ok(); i++ )
183 //              if ( i->end_mom() == mom ) {
184                 if ( i->end_mom() <= mom ) {
185                         dtor << "open_voices (" << open_voices_r.size() << "): -1\n";
186                         i.remove_p();  // remove? // no delete; only a copy
187                         if ( !i.ok() )
188                                 break;
189                 }
190 }
191
192 void
193 Midi_track::set_tempo( int useconds_per_4_i )
194 {
195         delete midi_tempo_p_;
196         midi_tempo_p_ = new Midi_tempo( useconds_per_4_i );
197 }
198
199 void
200 Midi_track::set_time( int num_i, int den_i, int clocks_i, int count_32_i )
201 {
202         delete midi_time_p_;
203         midi_time_p_ = new Midi_time( num_i, den_i, clocks_i, count_32_i );
204 }
205
206 Track_column*
207 Midi_track::tcol_l( Moment mom )
208 {
209         for ( PCursor<Track_column*> i( tcol_p_list_.top() ); i.ok(); i++ ) {
210                 if ( i->mom() == mom )
211                         return *i;
212                 if ( i->mom() > mom ) {
213                         Track_column* tcol_p = new Track_column( mom );
214                         i.insert( tcol_p );
215                         return tcol_p;
216                 }
217         }
218
219         Track_column* tcol_p = new Track_column( mom );
220         tcol_p_list_.bottom().add( tcol_p );
221         return tcol_p;
222 }
223