]> git.donarmstrong.com Git - lilypond.git/blob - m2m/midi-track.cc
partial: 0.0.39-1.jcn
[lilypond.git] / m2m / midi-track.cc
1 //
2 // midi-track.cc -- implement Midi_track
3 //
4 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
5
6 #include "m2m.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         tcol_p_list_.bottom().add( new Track_column( Moment( 0 ) ) );
18 }
19
20 void
21 Midi_track::add_begin_at( PointerList<Midi_voice*>& open_voices_r, Moment mom )
22 {
23         for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ )
24                 if ( i->begin_mom() == mom )
25                         open_voices_r.bottom().add( *i );
26 }
27
28 void
29 Midi_track::add_event( Moment mom, Midi_event* midi_event_p )
30 {
31         if ( ! midi_event_p )
32                 return;
33         tcol_l( mom - midi_event_p->mom() )->add_event( midi_event_p );
34 }
35
36 // too much red tape?
37 String
38 Midi_track::name_str()
39 {
40         return name_str_;
41 }
42
43 Moment
44 Midi_track::end_mom()
45 {
46         // heu..
47         Moment mom = 0.0;
48         for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ ) 
49                 mom = i->end_mom() >? mom;
50         return mom;
51 }
52
53 Midi_voice*
54 Midi_track::get_free_midi_voice_l( Moment mom )
55 {
56         for ( PCursor<Midi_voice*> midi_voice_l_pcur( midi_voice_p_list_.top() ); midi_voice_l_pcur.ok(); midi_voice_l_pcur++ )
57                 if ( midi_voice_l_pcur->end_mom() == mom )
58                         return *midi_voice_l_pcur;
59
60         Midi_voice* midi_voice_p = new Midi_voice( mom );
61         Midi_voice* midi_voice_l = midi_voice_p;
62         midi_voice_p_list_.bottom().add( midi_voice_p );
63         return midi_voice_l; 
64 }
65
66 Moment
67 Midi_track::next_begin_mom( Moment now_mom )
68 {
69 //      Moment begin_mom = Midi_track::end_mom() + 1;
70         Moment begin_mom = Midi_track::end_mom();
71         for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ )
72 //              if ( i->begin_mom() >= now_mom )
73                 if ( i->begin_mom() > now_mom )
74                         begin_mom = begin_mom <? i->begin_mom();
75         return begin_mom;
76 }
77
78 Moment
79 Midi_track::next_end_mom( Moment now_mom )
80 {
81         Moment end_mom = Midi_track::end_mom();
82         for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ ) 
83                 if ( i->end_mom() > now_mom )
84                         end_mom = end_mom <? i->end_mom();
85         return end_mom;
86 }
87
88 void
89 Midi_track::process()
90 {
91         for ( PCursor<Track_column*> tcol_l_pcur( tcol_p_list_.top() ); tcol_l_pcur.ok(); tcol_l_pcur++ )
92                 while ( tcol_l_pcur->midi_event_p_list_.size() ) 
93                         // shit, where has the T* PCursor::remove() gone??
94                         // i don-t want to get and delete, 
95                         // i want to (re)move!
96                         // is it renamed: get vs add/insert ?? (put/remove :-)  
97                         get_free_midi_voice_l( tcol_l_pcur->mom() )->add_event( tcol_l_pcur->midi_event_p_list_.top().remove_p() );
98
99         dtor << "ends: " << endl;
100         int n = 0;
101         for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ ) 
102                 vtor << "voice " << n++ << ": " << i->end_mom() << endl;
103         dtor << ":sdne" << endl;
104 }
105
106
107 void
108 Midi_track::output_mudela( Lily_stream& lily_stream_r )
109 {
110         lily_stream_r << name_str_ << " = music { $";
111         lily_stream_r.indent();
112         lily_stream_r << "% midi copyright:" << copyright_str_;
113         lily_stream_r.newline();
114         lily_stream_r << "% instrument:" << instrument_str_;
115         lily_stream_r.newline();
116
117         PointerList<Midi_voice*> open_voices;
118         Moment now_mom = 0.0;
119         Moment then_mom = 0.0;
120         while ( now_mom < end_mom() ) {
121                 add_begin_at( open_voices, now_mom );
122
123                 Moment begin_mom = next_begin_mom( now_mom ); 
124                 Moment end_mom = next_end_mom( now_mom ); 
125                 if ( ( begin_mom > now_mom ) && ( begin_mom < end_mom ) )
126                         then_mom = begin_mom;
127                 else 
128                         then_mom = end_mom;
129
130                 dtor << "begin: " << begin_mom << " end: " << end_mom << endl;
131                 dtor << "slice: " << now_mom << ", " << then_mom << endl;
132
133                 if ( open_voices.size() > 1 )
134                         lily_stream_r << "{ ";
135                 for ( PCursor<Midi_voice*> i( open_voices.top() ); i.ok(); i++ )
136                         lily_stream_r << i->mudela_str( now_mom, then_mom, open_voices.size() - 1 );
137                 if ( open_voices.size() > 1 )
138                         lily_stream_r << "} ";
139                 now_mom = then_mom;
140
141                 remove_end_at( open_voices, now_mom );
142         }
143         lily_stream_r.tnedni();
144         lily_stream_r << "$} % " << name_str_;
145         lily_stream_r.newline();
146 }
147
148 void
149 Midi_track::remove_end_at( PointerList<Midi_voice*>& open_voices_r, Moment mom )
150 {
151         for ( PCursor<Midi_voice*> i( open_voices_r.top() ); i.ok(); i++ )
152                 if ( i->end_mom() == mom ) {
153                         i.remove_p();  // remove? // no delete; only a copy
154                         if ( !i.ok() )
155                                 break;
156                 }
157 //                      i.del();  // remove? // no delete; only a copy
158 // plist is breendet
159 // duh, del and get will do a ++, but will fail if they render list empty
160 //              if ( i->end_mom() == mom ) {
161 //                      if ( i->size() > 1 )
162 //                              i.del();
163 //                      else
164 //                              i.junk(); // what-s in a name? (sic)
165 //              }
166 }
167
168 Track_column*
169 Midi_track::tcol_l( Moment mom )
170 {
171         for ( PCursor<Track_column*> tcol_l_pcur( tcol_p_list_.top() ); tcol_l_pcur.ok(); tcol_l_pcur++ ) {
172                 if ( tcol_l_pcur->mom() == mom )
173                         return *tcol_l_pcur;
174                 if ( tcol_l_pcur->mom() > mom ) {
175                         Track_column* tcol_p = new Track_column( mom );
176                         tcol_l_pcur.insert( tcol_p );
177                         return tcol_p;
178                 }
179         }
180
181         Track_column* tcol_p = new Track_column( mom );
182         tcol_p_list_.bottom().add( tcol_p );
183         return tcol_p;
184 }
185