2 // midi-track.cc -- implement Midi_track
4 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
8 Midi_track::Midi_track( int number_i, String copyright_str, String track_name_str, String instrument_str )
11 copyright_str_ = copyright_str;
12 instrument_str_ = instrument_str;
13 if ( track_name_str.length_i() )
14 name_str_ = track_name_str;
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 ) ) );
22 Midi_track::~Midi_track()
29 Midi_track::add_begin_at( PointerList<Midi_voice*>& open_voices_r, Moment mom )
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 );
39 Midi_track::add_event( Moment mom, Midi_event* midi_event_p )
43 tcol_l( mom - midi_event_p->mom() )->add_event( midi_event_p );
48 Midi_track::name_str()
58 for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ )
59 mom = i->end_mom() >? mom;
64 Midi_track::get_free_midi_voice_l( Moment mom )
66 for ( PCursor<Midi_voice*> i( midi_voice_p_list_.top() ); i.ok(); i++ )
67 if ( i->end_mom() == mom )
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 );
77 Midi_track::next_begin_mom( Moment now_mom )
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();
89 Midi_track::next_end_mom( Moment now_mom )
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();
102 Moment bar_mom = midi_time_p_->bar_mom();
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 ) {
116 mtor << ']' << flush;
120 dtor << "ends: " << endl;
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;
129 Midi_track::output_mudela( Lily_stream& lily_stream_r )
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();
139 Moment bar_mom = midi_time_p_->bar_mom();
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 );
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;
157 dtor << "begin: " << begin_mom << " end: " << end_mom << endl;
158 dtor << "slice: " << now_mom << ", " << then_mom << endl;
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 << "} ";
168 remove_end_at( open_voices, now_mom );
169 if ( bars_i > bar_i ) {
171 mtor << ']' << flush;
174 lily_stream_r.tnedni();
175 lily_stream_r << "$} % " << name_str_;
176 lily_stream_r.newline();
180 Midi_track::remove_end_at( PointerList<Midi_voice*>& open_voices_r, Moment mom )
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
193 Midi_track::set_tempo( int useconds_per_4_i )
195 delete midi_tempo_p_;
196 midi_tempo_p_ = new Midi_tempo( useconds_per_4_i );
200 Midi_track::set_time( int num_i, int den_i, int clocks_i, int count_32_i )
203 midi_time_p_ = new Midi_time( num_i, den_i, clocks_i, count_32_i );
207 Midi_track::tcol_l( Moment mom )
209 for ( PCursor<Track_column*> i( tcol_p_list_.top() ); i.ok(); i++ ) {
210 if ( i->mom() == mom )
212 if ( i->mom() > mom ) {
213 Track_column* tcol_p = new Track_column( mom );
219 Track_column* tcol_p = new Track_column( mom );
220 tcol_p_list_.bottom().add( tcol_p );