2 // lilypond-staff.cc -- implement Lilypond_staff
4 // (c) 1997--2001 Jan Nieuwenhuizen <janneke@gnu.org>
9 #include "duration-convert.hh"
10 #include "string-convert.hh"
11 #include "midi2ly-proto.hh"
12 #include "midi2ly-global.hh"
13 #include "lilypond-column.hh"
14 #include "lilypond-item.hh"
15 #include "lilypond-staff.hh"
16 #include "lilypond-stream.hh"
17 #include "lilypond-voice.hh"
18 #include "lilypond-score.hh"
20 #include "killing-cons.tcc"
22 extern Lilypond_score
* lilypond_score_l_g
;
24 Lilypond_staff::Lilypond_staff (int number_i
, String copyright_str
, String track_name_str
, String instrument_str
)
27 copyright_str_
= copyright_str
;
28 instrument_str_
= instrument_str
;
29 name_str_
= track_name_str
;
31 lilypond_time_signature_l_
= 0;
32 lilypond_tempo_l_
= 0;
36 Lilypond_staff::add_item (Lilypond_item
* lilypond_item_p
)
38 lilypond_item_p_list_
.append (new Killing_cons
<Lilypond_item
> (lilypond_item_p
, 0));
39 if (lilypond_item_p
->lilypond_column_l_
)
40 lilypond_item_p
->lilypond_column_l_
->add_item (lilypond_item_p
);
43 Walk ITEMS and find voices. Remove categorised items.
47 * collect all channels into separate voices. Use chords for sim
48 notes on same channel.
49 * assume voices/assume chords modes.
53 Lilypond_staff::eat_voice (Cons_list
<Lilypond_item
>& items
)
55 Lilypond_voice
* voice_p
= new Lilypond_voice (this);
56 lilypond_voice_p_list_
.append (new Killing_cons
<Lilypond_voice
> (voice_p
, 0));
60 Link_array
<Lilypond_item
> now_items
;
61 for (Cons
<Lilypond_item
>** i
= &items
.head_
; *i
;)
63 while (*i
&& (*i
)->car_
->at_mom () < mom
)
66 Lilypond_note
* last_note
= 0;
67 Link_array
<Lilypond_item
> now_items
;
69 mom
= (*i
)->car_
->at_mom ();
70 while (*i
&& (*i
)->car_
->at_mom () == mom
)
72 Lilypond_note
* note
= dynamic_cast<Lilypond_note
*> ((*i
)->car_
);
74 /* ugh, should sort out (whether to) channel before */
75 && (note
->channel_i_
!= last_note
->channel_i_
76 || (note
->duration_mom ()
77 != last_note
->duration_mom ())))
79 Cons
<Lilypond_item
>* c
= items
.remove_cons (i
);
80 now_items
.push (c
->car_
);
86 if (now_items
.size ())
87 mom
= now_items
.top ()->at_mom ();
89 mom
+= last_note
->duration_mom ();
91 voice_p
->add_items (now_items
);
96 Lilypond_staff::id_str ()
98 String
id (name_str ());
99 char *cp
= id
.ch_l ();
100 char *end
= cp
+ id
.length_i ();
101 for (;cp
< end
; cp
++)
112 Lilypond_staff::name_str ()
114 if (name_str_
.length_i ())
116 return String ("track") + to_str (char ('A' - 1 + number_i_
));
122 Lilypond_staff::output (Lilypond_stream
& lilypond_stream_r
)
126 String trackbody
= "";
127 for (Cons
<Lilypond_voice
>* i
= lilypond_voice_p_list_
.head_
; i
; i
= i
->next_
)
129 String voicename
= id_str () + "voice" + to_str (char (c
+ 'A'));
131 lilypond_stream_r
<< voicename
<< " = \\notes ";
133 trackbody
+= "\\context Voice = " + voicename
+ " \\" + voicename
+ "\n";
134 lilypond_stream_r
<< '\n';
135 i
->car_
->output (lilypond_stream_r
);
137 lilypond_stream_r
<< '\n';
140 lilypond_stream_r
<< '\n';
141 lilypond_stream_r
<< _ ("% MIDI copyright:") << copyright_str_
<< '\n';
142 lilypond_stream_r
<< _ ("% MIDI instrument:") << instrument_str_
<< '\n';
143 lilypond_stream_r
<< id_str () << " = ";
144 lilypond_stream_r
<< "<\n" << trackbody
<< ">\n";
146 lilypond_stream_r
<< " % " << name_str () << '\n';
150 Lilypond_staff::output_lilypond_begin_bar (Lilypond_stream
& lilypond_stream_r
, Rational now_mom
, int bar_i
)
152 Rational bar_mom
= lilypond_time_signature_l_
->bar_mom ();
153 Rational into_bar_mom
= now_mom
- Rational (bar_i
- 1) * bar_mom
;
157 lilypond_stream_r
<< "|\n";
159 lilypond_stream_r
<< "% " << String_convert::i2dec_str (bar_i
, 0, ' ');
161 lilypond_stream_r
<< ":" << Duration_convert::dur2_str (Duration_convert::mom2_dur (into_bar_mom
));
162 lilypond_stream_r
<< '\n';
167 Lilypond_staff::process ()
170 group items into voices
173 assert (lilypond_score_l_g
);
174 lilypond_key_l_
= lilypond_score_l_g
->lilypond_key_l_
;
175 lilypond_time_signature_l_
= lilypond_score_l_g
->lilypond_time_signature_l_
;
176 lilypond_tempo_l_
= lilypond_score_l_g
->lilypond_tempo_l_
;
178 Cons_list
<Lilypond_item
> items
;
179 for (Cons
<Lilypond_item
>* i
= lilypond_item_p_list_
.head_
; i
; i
= i
->next_
)
180 items
.append (new Cons
<Lilypond_item
> (i
->car_
, 0));
182 while (items
.size_i ())