2 // lilypond-item.cc -- implement Lilypond_item
4 // (c) 1997--2001 Jan Nieuwenhuizen <janneke@gnu.org>
8 #include "midi2ly-global.hh"
9 #include "string-convert.hh"
10 #include "duration-convert.hh"
11 #include "lilypond-column.hh"
12 #include "lilypond-item.hh"
13 #include "lilypond-stream.hh"
14 #include "lilypond-score.hh"
16 Lilypond_item::Lilypond_item (Lilypond_column* lilypond_column_l)
18 lilypond_column_l_ = lilypond_column_l;
21 Lilypond_item::~Lilypond_item ()
26 Lilypond_item::at_mom ()
28 return lilypond_column_l_->at_mom ();
32 Lilypond_item::duration_mom ()
38 Lilypond_item::output (Lilypond_stream& lilypond_stream_r)
40 lilypond_stream_r << str () << " ";
43 Lilypond_key::Lilypond_key (int accidentals_i, int minor_i)
46 accidentals_i_ = accidentals_i;
50 char const *accname[] = {"eses", "es", "", "is" , "isis"};
55 int key_i = accidentals_i_ >= 0
56 ? ((accidentals_i_ % 7) ["cgdaebf"] - 'a' - 2 -2 * minor_i_ + 7) % 7
57 : ((-accidentals_i_ % 7) ["cfbeadg"] - 'a' - 2 -2 * minor_i_ + 7) % 7;
59 String notename_str = !minor_i_
60 ? to_str ((char) ((key_i + 2) % 7 + 'a'))
61 : to_str ((char) ((key_i + 2) % 7 + 'a'));
63 // fis cis gis dis ais eis bis
64 static int sharps_i_a [7] = { 2, 4, 6, 1, 3, 5, 7 };
65 // bes es as des ges ces fes
66 static int flats_i_a [7] = { 6, 4, 2, 7, 5, 3, 1 };
67 int accidentals_i = accidentals_i_ >= 0
68 ? sharps_i_a [key_i] <= accidentals_i_ ? 1 : 0
69 : flats_i_a [key_i] <= -accidentals_i_ ? -1 : 0;
72 notename_str += String (accname [accidentals_i + 2]);
74 return "\\key " + notename_str + (minor_i_ ? "\\minor" : "\\major") + "\n";
78 Lilypond_key::notename_str (int pitch_i)
80 // this may seem very smart,
81 // but it-s only an excuse not to read a notename table
84 // minor scale: la-la (= + 5)
85 static int notename_i_a [12] = { 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6 };
86 int notename_i = notename_i_a [pitch_i % 12];
88 static int accidentals_i_a [12] = { 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 };
89 int accidental_i = accidentals_i_a [(minor_i_ * 5 + pitch_i) % 12];
90 if (accidental_i && (accidentals_i_ < 0))
93 notename_i = (notename_i + 1) % 7;
96 String notename_str = to_str ((char)(((notename_i + 2) % 7) + 'a'));
98 notename_str += String (accname [accidental_i + 2]);
101 By tradition, all scales now consist of a sequence of 7 notes each
102 with a distinct name, from amongst a b c d e f g. But, minor scales
103 have a wide second interval at the top - the 'leading note' is
104 sharped. (Why? it just works that way! Anything else doesn't sound as
105 good and isn't as flexible at saying things. In medieval times,
106 scales only had 6 notes to avoid this problem - the hexachords.)
108 So, the d minor scale is d e f g a b-flat c-sharp d - using d-flat
109 for the leading note would skip the name c and duplicate the name d.
110 Why isn't c-sharp put in the key signature? Tradition. (It's also
111 supposedly based on the Pythagorean theory of the cycle of fifths,
112 but that really only applies to major scales...)
114 Anyway, g minor is g a b-flat c d e-flat f-sharp g, and all the other
115 flat minor keys end up with a natural leading note. And there you
118 John Sankey <bf250@freenet.carleton.ca>
120 Let's also do a-minor: a b c d e f gis a
126 /* ok, bit ugly, but here we go -- jcn */
131 if ((accidentals_i_ == 0) && (notename_str == "as"))
132 notename_str = "gis";
133 else if ((accidentals_i_ == -1) && (notename_str == "des"))
134 notename_str = "cis";
135 else if ((accidentals_i_ == -2) && (notename_str == "ges"))
136 notename_str = "fis";
137 else if ((accidentals_i_ == 5) && (notename_str == "g"))
138 notename_str = "fisis";
139 else if ((accidentals_i_ == 6) && (notename_str == "d"))
140 notename_str = "cisis";
141 else if ((accidentals_i_ == 7) && (notename_str == "a"))
142 notename_str = "gisis";
144 if ((accidentals_i_ <= -6) && (notename_str == "b"))
145 notename_str = "ces";
146 if ((accidentals_i_ <= -7) && (notename_str == "e"))
147 notename_str = "fes";
150 String de_octavate_str = to_str (',', (Lilypond_note::c0_pitch_i_c_ + 11 - pitch_i) / 12);
151 String octavate_str = to_str ('\'', (pitch_i - Lilypond_note::c0_pitch_i_c_) / 12);
152 return notename_str +de_octavate_str + octavate_str;
155 Lilypond_time_signature::Lilypond_time_signature (int num_i, int den_i, int clocks_4_i, int count_32_i)
158 sync_dur_.durlog_i_ = 3;
161 warning (_f ("#32 in quarter: %d", count_32_i));
164 clocks_1_i_ = clocks_4_i * 4;
168 Lilypond_time_signature::bar_mom ()
171 d.durlog_i_ = den_i_;
172 return Rational (num_i_) * Duration_convert::dur2_mom (d);
176 Lilypond_time_signature::clocks_1_i ()
182 Lilypond_time_signature::den_i ()
188 Lilypond_time_signature::num_i ()
194 Lilypond_time_signature::str ()
196 String str = "\\time "
197 + to_str (num_i_) + "/" + to_str (1 << den_i_)
203 // statics Lilypond_note
205 this switch can be used to write simple plets like
208 \plet 2/3; c4 \plet 1/1;
211 UGH: .hh says false, .cc says true.
214 bool const Lilypond_note::simple_plet_b_s;
216 Lilypond_note::Lilypond_note (Lilypond_column* lilypond_column_l,
217 int channel_i, int pitch_i, int dyn_i)
218 : Lilypond_item (lilypond_column_l)
222 channel_i_ = channel_i;
228 Lilypond_note::duration ()
230 assert (end_column_l_);
231 Rational mom = end_column_l_->at_mom () - at_mom ();
232 return Duration_convert::mom2_dur (mom);
236 Lilypond_note::duration_mom ()
238 assert (end_column_l_);
239 return end_column_l_->at_mom () - at_mom ();
243 Lilypond_note::str ()
245 Duration dur = duration ();
246 if (dur.durlog_i_ < -10)
250 = lilypond_column_l_->lilypond_score_l_->lilypond_key_l_->notename_str (pitch_i_);
253 return name_str + Duration_convert::dur2_str (dur) + " ";
258 if (dur.plet_b () && dur.plet_.type_i_ != 1)
261 str += String ("\\times ")
262 + String_convert::i2dec_str (dur.plet_.iso_i_, 0, 0)
264 + String_convert::i2dec_str (dur.plet_.type_i_, 0, 0)
273 str += Duration_convert::dur2_str (tmp);
277 if (dur.plet_.type_i_ != 1)
278 str += String (" }");
280 str += String ("*") + to_str (dur.plet_.iso_i_);
284 note of zero duration is nonsense,
285 but let's output anyway for convenient debugging
287 if (!duration_mom ())
288 return String ("\n% ") + str + "\n";
293 Lilypond_skip::Lilypond_skip (Lilypond_column* lilypond_column_l, Rational skip_mom)
294 : Lilypond_item (lilypond_column_l)
300 Lilypond_skip::duration ()
302 return Duration_convert::mom2_dur (mom_);
306 Lilypond_skip::duration_mom ()
308 return Duration_convert::dur2_mom (duration ());
312 Lilypond_skip::str ()
316 if (m.to_int () >= 1)
329 if (m > Rational (0))
332 Duration dur = Duration_convert::mom2_dur (m);
334 str += Duration_convert::dur2_str (dur);
340 Lilypond_tempo::Lilypond_tempo (int useconds_per_4_i)
343 useconds_per_4_i_ = useconds_per_4_i;
344 seconds_per_1_mom_ = Rational(useconds_per_4_i_ *4, 1e6);
348 Lilypond_tempo::str ()
350 String str = "\\tempo 4=";
351 str += to_str (get_tempo_i (Rational (1, 4)));
357 Lilypond_tempo::useconds_per_4_i ()
359 return useconds_per_4_i_;
363 Lilypond_tempo::get_tempo_i (Rational rational)
365 Rational m1 = Rational (60) / rational;
366 Rational m2 = seconds_per_1_mom_;
370 Lilypond_text::Lilypond_text (Lilypond_text::Type type, String text_str)
374 text_str_ = text_str;
378 Lilypond_text::str ()
380 if (!text_str_.length_i ()
381 || (text_str_.length_i () != (int)strlen (text_str_.ch_C ())))
384 return "% " + text_str_ + "\n";