lilypond-1.1.40
[lilypond.git] / mi2mu / mudela-item.cc
blob12b1b1f3ec2a5d75e16cd54ac0c29caa521957ce
1 //
2 // mudela-item.cc -- implement Mudela_item
3 //
4 // copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
6 #include <assert.h>
7 #include "mi2mu-global.hh"
8 #include "string-convert.hh"
9 #include "duration-convert.hh"
10 #include "mudela-column.hh"
11 #include "mudela-item.hh"
12 #include "mudela-stream.hh"
13 #include "mudela-score.hh"
15 Mudela_item::Mudela_item (Mudela_column* mudela_column_l)
17 mudela_column_l_ = mudela_column_l;
20 Mudela_item::~Mudela_item ()
24 Moment
25 Mudela_item::at_mom ()
27 return mudela_column_l_->at_mom ();
30 Moment
31 Mudela_item::duration_mom ()
33 return Moment (0);
36 void
37 Mudela_item::output (Mudela_stream& mudela_stream_r)
39 mudela_stream_r << str () << " ";
42 Mudela_key::Mudela_key (int accidentals_i, int minor_i)
43 : Mudela_item (0)
45 accidentals_i_ = accidentals_i;
46 minor_i_ = minor_i;
49 String
50 Mudela_key::str ()
52 int key_i = 0;
53 if (accidentals_i_ >= 0)
54 key_i = ((accidentals_i_ % 7)[ "cgdaebf" ] - 'a' - 2) % 7;
55 else
56 key_i = ((-accidentals_i_ % 7)[ "cfbeadg" ] - 'a' - 2) % 7;
58 String keyname = (1) // !minor_i_)
59 ? to_str ((char) ((key_i + 2) % 7 + 'A'))
60 : to_str ((char) ((key_i + 2 - 2) % 7 + 'a'));
61 // heu, -2: should be - 1 1/2: A -> fis
63 return String("\\key " + keyname + ";\n");
66 String
67 Mudela_key::notename_str (int pitch_i)
69 // this may seem very smart,
70 // but it-s only an excuse not to read a notename table
72 // major scale: do-do
73 // minor scale: la-la (= + 5)
74 static int notename_i_a[ 12 ] = { 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6 };
75 int notename_i = notename_i_a[ (minor_i_ * 5 + pitch_i) % 12 ];
77 static int accidentals_i_a[ 12 ] = { 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 };
78 int accidental_i = accidentals_i_a[ (minor_i_ * 5 + pitch_i) % 12 ];
79 if (accidental_i && (accidentals_i_ < 0))
81 accidental_i = - accidental_i;
82 notename_i = (notename_i + 1) % 7;
85 String notename_str = to_str ((char)(((notename_i + 2) % 7) + 'a'));
86 while (accidental_i-- > 0)
87 notename_str += "is";
88 accidental_i++;
89 while (accidental_i++ < 0)
90 if ((notename_str == "a") || (notename_str == "e"))
91 notename_str += "s";
92 else
93 notename_str += "es";
94 accidental_i--;
97 By tradition, all scales now consist of a sequence of 7 notes each
98 with a distinct name, from amongst a b c d e f g. But, minor scales
99 have a wide second interval at the top - the 'leading note' is
100 sharped. (Why? it just works that way! Anything else doesn't sound as
101 good and isn't as flexible at saying things. In medieval times,
102 scales only had 6 notes to avoid this problem - the hexachords.)
104 So, the d minor scale is d e f g a b-flat c-sharp d - using d-flat
105 for the leading note would skip the name c and duplicate the name d.
106 Why isn't c-sharp put in the key signature? Tradition. (It's also
107 supposedly based on the Pythagorean theory of the cycle of fifths,
108 but that really only applies to major scales...)
110 Anyway, g minor is g a b-flat c d e-flat f-sharp g, and all the other
111 flat minor keys end up with a natural leading note. And there you
112 have it.
114 John Sankey <bf250@freenet.carleton.ca>
118 /* ok, bit ugly, but here we go */
120 if (minor_i_ && (accidentals_i_ == -1))
121 if (notename_str == "des")
122 notename_str = "cis";
124 if (minor_i_ && (accidentals_i_ == -2))
125 if (notename_str == "ges")
126 notename_str = "fis";
128 String de_octavate_str = to_str (',', (Mudela_note::c0_pitch_i_c_ + 11 - pitch_i) / 12);
129 String octavate_str = to_str ('\'', (pitch_i - Mudela_note::c0_pitch_i_c_) / 12);
130 return notename_str +de_octavate_str + octavate_str;
133 Mudela_time_signature::Mudela_time_signature (int num_i, int den_i, int clocks_4_i, int count_32_i)
134 : Mudela_item (0)
136 sync_dur_.durlog_i_ = 3;
137 sync_f_ = 1.0;
138 if (count_32_i != 8)
139 warning (_f ("#32 in quarter: %d", count_32_i));
140 num_i_ = num_i;
141 den_i_ = den_i;
142 clocks_1_i_ = clocks_4_i * 4;
145 Moment
146 Mudela_time_signature::bar_mom ()
148 Duration d;
149 d.durlog_i_ = den_i_;
150 return Moment (num_i_) * Duration_convert::dur2_mom (d);
154 Mudela_time_signature::clocks_1_i ()
156 return clocks_1_i_;
160 Mudela_time_signature::den_i ()
162 return den_i_;
166 Mudela_time_signature::num_i ()
168 return num_i_;
171 String
172 Mudela_time_signature::str ()
174 String str = "\\time "
175 + to_str (num_i_) + "/" + to_str (1 << den_i_)
176 + ";\n";
177 return str;
181 // statics Mudela_note
183 this switch can be used to write simple plets like
184 c4*2/3
186 \plet 2/3; c4 \plet 1/1;
189 UGH: .hh says false, .cc says true.
190 FIXME.
192 bool const Mudela_note::simple_plet_b_s;
194 Mudela_note::Mudela_note (Mudela_column* mudela_column_l,
195 int channel_i, int pitch_i, int dyn_i)
196 : Mudela_item (mudela_column_l)
198 // junk dynamics
199 (void)dyn_i;
200 channel_i_ = channel_i;
201 pitch_i_ = pitch_i;
202 end_column_l_ = 0;
205 Duration
206 Mudela_note::duration ()
208 assert (end_column_l_);
209 Moment mom = end_column_l_->at_mom () - at_mom ();
210 return Duration_convert::mom2_dur (mom);
213 Moment
214 Mudela_note::duration_mom ()
216 assert (end_column_l_);
217 return end_column_l_->at_mom () - at_mom ();
220 String
221 Mudela_note::str ()
223 Duration dur = duration ();
224 if (dur.durlog_i_ < -10)
225 return "";
227 String name_str
228 = mudela_column_l_->mudela_score_l_->mudela_key_l_->notename_str (pitch_i_);
230 if (simple_plet_b_s)
231 return name_str + Duration_convert::dur2_str (dur) + " ";
233 String str;
235 //ugh
236 if (dur.plet_b ())
237 str += String ("\\times ")
238 + String_convert::i2dec_str (dur.plet_.iso_i_, 0, 0)
239 + "/"
240 + String_convert::i2dec_str (dur.plet_.type_i_, 0, 0)
241 + " { ";
244 str += name_str;
246 Duration tmp = dur;
247 tmp.set_plet (1,1);
248 str += Duration_convert::dur2_str (tmp);
250 if (dur.plet_b ())
251 str += String (" }");
254 note of zero duration is nonsense,
255 but let's output anyway for convenient debugging
257 if (!duration_mom ())
258 return String ("\n% ") + str + "\n";
260 return str + " ";
263 Mudela_skip::Mudela_skip (Mudela_column* mudela_column_l, Moment skip_mom)
264 : Mudela_item (mudela_column_l)
266 mom_ = skip_mom;
269 Duration
270 Mudela_skip::duration ()
272 return Duration_convert::mom2_dur (mom_);
275 Moment
276 Mudela_skip::duration_mom ()
278 return Duration_convert::dur2_mom (duration ());
281 String
282 Mudela_skip::str ()
284 if (!mom_)
285 return String ("");
287 Duration dur = duration ();
288 if (dur.durlog_i_<-10)
289 return "";
291 String str = "\\skip ";
292 str += Duration_convert::dur2_str (dur) + "; ";
294 return str;
297 Mudela_tempo::Mudela_tempo (int useconds_per_4_i)
298 : Mudela_item (0)
300 useconds_per_4_i_ = useconds_per_4_i;
301 seconds_per_1_mom_ = Moment(useconds_per_4_i_ *4, 1e6);
304 String
305 Mudela_tempo::str ()
307 String str = "\\tempo 4=";
308 str += to_str (get_tempo_i (Moment (1, 4)));
309 str += ";\n";
310 return str;
314 Mudela_tempo::useconds_per_4_i ()
316 return useconds_per_4_i_;
320 Mudela_tempo::get_tempo_i (Moment moment)
322 Moment m1 = Moment (60) / moment;
323 Moment m2 = seconds_per_1_mom_;
324 return m1 / m2;
327 Mudela_text::Mudela_text (Mudela_text::Type type, String text_str)
328 : Mudela_item (0)
330 type_ = type;
331 text_str_ = text_str;
334 String
335 Mudela_text::str ()
337 if (!text_str_.length_i ()
338 || (text_str_.length_i () != (int)strlen (text_str_.ch_C ())))
339 return "";
341 return "% " + text_str_ + "\n";