2 // lilypond-voice.cc -- implement Lilypond_voice
4 // (c) 1997--2001 Jan Nieuwenhuizen <janneke@gnu.org>
6 #include "string-convert.hh"
7 #include "midi2ly-global.hh"
8 #include "lilypond-column.hh"
9 #include "lilypond-item.hh"
10 #include "lilypond-staff.hh"
11 #include "lilypond-stream.hh"
12 #include "lilypond-voice.hh"
13 #include "lilypond-score.hh"
15 extern Lilypond_score* lilypond_score_l_g;
17 Lilypond_voice::Lilypond_voice (Lilypond_staff* lilypond_staff_l)
19 lilypond_staff_l_ = lilypond_staff_l;
20 threads_.push (new Cons_list<Lilypond_item>);
25 Lilypond_voice::add_items (Link_array<Lilypond_item>& items)
28 for (int i = 0; i < items.size (); i++)
30 Lilypond_item* item = items[i];
33 if (Lilypond_note* n = dynamic_cast<Lilypond_note*> (item))
38 if (to_thread >= threads_.size ())
39 threads_.push (new Cons_list<Lilypond_item>);
41 if (to_thread == 0 && item->at_mom () > mom_)
43 /* urg: skip should use refer to end-colum, not separate moment */
44 Rational r = item->at_mom () - mom_;
45 Lilypond_column* start = lilypond_score_l_g->find_column_l (mom_);
46 threads_[to_thread]->append (new Cons<Lilypond_item> (new Lilypond_skip (start, r), 0));
47 mom_ = item->at_mom ();
50 threads_[to_thread]->append (new Cons<Lilypond_item> (item, 0));
52 mom_ += item->duration_mom ();
57 analyse pitches to determine clef.
60 Lilypond_voice::get_clef () const
64 for (Cons<Lilypond_item> *cp = threads_[0]->head_; !n && cp; cp = cp->next_)
66 n = dynamic_cast<Lilypond_note*> (cp->car_);
75 return "\\clef \"bass\"\n";
77 return "\\clef \"treble\"\n";
82 static int const FAIRLY_LONG_VOICE_i = 6;
85 Lilypond_voice::output (Lilypond_stream& lilypond_stream_r)
87 lilypond_stream_r << "{ ";
88 if (threads_[0]->size_i () > FAIRLY_LONG_VOICE_i)
89 lilypond_stream_r << '\n';
92 lilypond_stream_r << get_clef () << '\n';
94 int current_bar_i = 0;
95 Rational bar_mom = lilypond_staff_l_->lilypond_time_signature_l_->bar_mom ();
97 Link_array <Cons<Lilypond_item> > heads;
98 for (int i = 1; i < threads_.size (); i++)
99 heads.push (threads_[i]->head_);
100 for (Cons<Lilypond_item>* i = threads_[0]->head_; i; i = i->next_)
102 Rational at_mom = i->car_->lilypond_column_l_->at_mom ();
103 int bar_i = (int) (at_mom / bar_mom) + 1;
104 if (bar_i > current_bar_i)
108 if (at_mom == Rational (bar_i - 1) * bar_mom)
109 lilypond_stream_r << "|";
110 lilypond_stream_r << "\n% ";
111 lilypond_stream_r << String_convert::i2dec_str (bar_i, 0, ' ');
112 lilypond_stream_r << '\n';
114 LOGOUT (NORMAL_ver) << "[" << bar_i << "]" << flush;
115 current_bar_i = bar_i;
118 if (dynamic_cast<Lilypond_note*> (i->car_)
121 && heads[0]->car_->at_mom () == at_mom)
123 lilypond_stream_r << '<';
125 lilypond_stream_r << *i->car_;
130 && heads[h]->car_->at_mom () == at_mom;
133 lilypond_stream_r << *heads[h]->car_;
134 heads[h] = heads[h]->next_;
136 lilypond_stream_r << '>';
139 lilypond_stream_r << *i->car_;
141 if (Lilypond_key* k = dynamic_cast<Lilypond_key*> (i->car_))
142 lilypond_staff_l_->lilypond_key_l_ = lilypond_score_l_g->lilypond_key_l_ = k;
145 if (threads_[0]->size_i () > FAIRLY_LONG_VOICE_i)
146 lilypond_stream_r << '\n';
148 lilypond_stream_r << "} ";