lilypond-1.3.124
[lilypond.git] / mi2mu / mudela-item.cc
blob58a1db586bbbf5bb2526200371270873ccc09bc9
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 char const *accname[] = {"eses", "es", "", "is" , "isis"};
51 String
52 Mudela_key::str ()
54 int key_i = accidentals_i_ >= 0
55 ? ((accidentals_i_ % 7) ["cgdaebf"] - 'a' - 2 -2 * minor_i_ + 7) % 7
56 : ((-accidentals_i_ % 7) ["cfbeadg"] - 'a' - 2 -2 * minor_i_ + 7) % 7;
58 String notename_str = !minor_i_
59 ? to_str ((char) ((key_i + 2) % 7 + 'A'))
60 : to_str ((char) ((key_i + 2) % 7 + 'a'));
62 // fis cis gis dis ais eis bis
63 static int sharps_i_a [7] = { 2, 4, 6, 1, 3, 5, 7 };
64 // bes es as des ges ces fes
65 static int flats_i_a [7] = { 6, 4, 2, 7, 5, 3, 1 };
66 int accidentals_i = accidentals_i_ >= 0
67 ? sharps_i_a [key_i] <= accidentals_i_ ? 1 : 0
68 : flats_i_a [key_i] <= -accidentals_i_ ? -1 : 0;
70 if (accidentals_i)
71 notename_str += String (accname [accidentals_i + 2]);
73 return "\\key " + notename_str + (minor_i_ ? "\\minor" : "") + ";\n";
76 String
77 Mudela_key::notename_str (int pitch_i)
79 // this may seem very smart,
80 // but it-s only an excuse not to read a notename table
82 // major scale: do-do
83 // minor scale: la-la (= + 5)
84 static int notename_i_a [12] = { 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6 };
85 int notename_i = notename_i_a [pitch_i % 12];
87 static int accidentals_i_a [12] = { 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 };
88 int accidental_i = accidentals_i_a [(minor_i_ * 5 + pitch_i) % 12];
89 if (accidental_i && (accidentals_i_ < 0))
91 accidental_i *= -1;
92 notename_i = (notename_i + 1) % 7;
95 String notename_str = to_str ((char)(((notename_i + 2) % 7) + 'a'));
96 if (accidental_i)
97 notename_str += String (accname [accidental_i + 2]);
100 By tradition, all scales now consist of a sequence of 7 notes each
101 with a distinct name, from amongst a b c d e f g. But, minor scales
102 have a wide second interval at the top - the 'leading note' is
103 sharped. (Why? it just works that way! Anything else doesn't sound as
104 good and isn't as flexible at saying things. In medieval times,
105 scales only had 6 notes to avoid this problem - the hexachords.)
107 So, the d minor scale is d e f g a b-flat c-sharp d - using d-flat
108 for the leading note would skip the name c and duplicate the name d.
109 Why isn't c-sharp put in the key signature? Tradition. (It's also
110 supposedly based on the Pythagorean theory of the cycle of fifths,
111 but that really only applies to major scales...)
113 Anyway, g minor is g a b-flat c d e-flat f-sharp g, and all the other
114 flat minor keys end up with a natural leading note. And there you
115 have it.
117 John Sankey <bf250@freenet.carleton.ca>
119 Let's also do a-minor: a b c d e f gis a
121 --jcn
125 /* ok, bit ugly, but here we go -- jcn */
128 if (minor_i_)
130 if ((accidentals_i_ == 0) && (notename_str == "as"))
131 notename_str = "gis";
132 else if ((accidentals_i_ == -1) && (notename_str == "des"))
133 notename_str = "cis";
134 else if ((accidentals_i_ == -2) && (notename_str == "ges"))
135 notename_str = "fis";
136 else if ((accidentals_i_ == 5) && (notename_str == "g"))
137 notename_str = "fisis";
138 else if ((accidentals_i_ == 6) && (notename_str == "d"))
139 notename_str = "cisis";
140 else if ((accidentals_i_ == 7) && (notename_str == "a"))
141 notename_str = "gisis";
143 if ((accidentals_i_ <= -6) && (notename_str == "b"))
144 notename_str = "ces";
145 if ((accidentals_i_ <= -7) && (notename_str == "e"))
146 notename_str = "fes";
149 String de_octavate_str = to_str (',', (Mudela_note::c0_pitch_i_c_ + 11 - pitch_i) / 12);
150 String octavate_str = to_str ('\'', (pitch_i - Mudela_note::c0_pitch_i_c_) / 12);
151 return notename_str +de_octavate_str + octavate_str;
154 Mudela_time_signature::Mudela_time_signature (int num_i, int den_i, int clocks_4_i, int count_32_i)
155 : Mudela_item (0)
157 sync_dur_.durlog_i_ = 3;
158 sync_f_ = 1.0;
159 if (count_32_i != 8)
160 warning (_f ("#32 in quarter: %d", count_32_i));
161 num_i_ = num_i;
162 den_i_ = den_i;
163 clocks_1_i_ = clocks_4_i * 4;
166 Moment
167 Mudela_time_signature::bar_mom ()
169 Duration d;
170 d.durlog_i_ = den_i_;
171 return Moment (num_i_) * Duration_convert::dur2_mom (d);
175 Mudela_time_signature::clocks_1_i ()
177 return clocks_1_i_;
181 Mudela_time_signature::den_i ()
183 return den_i_;
187 Mudela_time_signature::num_i ()
189 return num_i_;
192 String
193 Mudela_time_signature::str ()
195 String str = "\\time "
196 + to_str (num_i_) + "/" + to_str (1 << den_i_)
197 + ";\n";
198 return str;
202 // statics Mudela_note
204 this switch can be used to write simple plets like
205 c4*2/3
207 \plet 2/3; c4 \plet 1/1;
210 UGH: .hh says false, .cc says true.
211 FIXME.
213 bool const Mudela_note::simple_plet_b_s;
215 Mudela_note::Mudela_note (Mudela_column* mudela_column_l,
216 int channel_i, int pitch_i, int dyn_i)
217 : Mudela_item (mudela_column_l)
219 // junk dynamics
220 (void)dyn_i;
221 channel_i_ = channel_i;
222 pitch_i_ = pitch_i;
223 end_column_l_ = 0;
226 Duration
227 Mudela_note::duration ()
229 assert (end_column_l_);
230 Moment mom = end_column_l_->at_mom () - at_mom ();
231 return Duration_convert::mom2_dur (mom);
234 Moment
235 Mudela_note::duration_mom ()
237 assert (end_column_l_);
238 return end_column_l_->at_mom () - at_mom ();
241 String
242 Mudela_note::str ()
244 Duration dur = duration ();
245 if (dur.durlog_i_ < -10)
246 return "";
248 String name_str
249 = mudela_column_l_->mudela_score_l_->mudela_key_l_->notename_str (pitch_i_);
251 if (simple_plet_b_s)
252 return name_str + Duration_convert::dur2_str (dur) + " ";
254 String str;
256 //ugh
257 if (dur.plet_b ())
258 str += String ("\\times ")
259 + String_convert::i2dec_str (dur.plet_.iso_i_, 0, 0)
260 + "/"
261 + String_convert::i2dec_str (dur.plet_.type_i_, 0, 0)
262 + " { ";
265 str += name_str;
267 Duration tmp = dur;
268 tmp.set_plet (1,1);
269 str += Duration_convert::dur2_str (tmp);
271 if (dur.plet_b ())
272 str += String (" }");
275 note of zero duration is nonsense,
276 but let's output anyway for convenient debugging
278 if (!duration_mom ())
279 return String ("\n% ") + str + "\n";
281 return str + " ";
284 Mudela_skip::Mudela_skip (Mudela_column* mudela_column_l, Moment skip_mom)
285 : Mudela_item (mudela_column_l)
287 mom_ = skip_mom;
290 Duration
291 Mudela_skip::duration ()
293 return Duration_convert::mom2_dur (mom_);
296 Moment
297 Mudela_skip::duration_mom ()
299 return Duration_convert::dur2_mom (duration ());
302 String
303 Mudela_skip::str ()
305 if (!mom_)
306 return String ("");
308 Duration dur = duration ();
309 if (dur.durlog_i_<-10)
310 return "";
312 String str = "\\skip ";
313 str += Duration_convert::dur2_str (dur) + "; ";
315 return str;
318 Mudela_tempo::Mudela_tempo (int useconds_per_4_i)
319 : Mudela_item (0)
321 useconds_per_4_i_ = useconds_per_4_i;
322 seconds_per_1_mom_ = Moment(useconds_per_4_i_ *4, 1e6);
325 String
326 Mudela_tempo::str ()
328 String str = "\\tempo 4=";
329 str += to_str (get_tempo_i (Moment (1, 4)));
330 str += ";\n";
331 return str;
335 Mudela_tempo::useconds_per_4_i ()
337 return useconds_per_4_i_;
341 Mudela_tempo::get_tempo_i (Moment moment)
343 Moment m1 = Moment (60) / moment;
344 Moment m2 = seconds_per_1_mom_;
345 return m1 / m2;
348 Mudela_text::Mudela_text (Mudela_text::Type type, String text_str)
349 : Mudela_item (0)
351 type_ = type;
352 text_str_ = text_str;
355 String
356 Mudela_text::str ()
358 if (!text_str_.length_i ()
359 || (text_str_.length_i () != (int)strlen (text_str_.ch_C ())))
360 return "";
362 return "% " + text_str_ + "\n";