2 // mudela-item.cc -- implement Mudela_item
4 // copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
8 #include "midi2ly-global.hh"
9 #include "string-convert.hh"
10 #include "duration-convert.hh"
11 #include "mudela-column.hh"
12 #include "mudela-item.hh"
13 #include "mudela-stream.hh"
14 #include "mudela-score.hh"
16 Mudela_item::Mudela_item (Mudela_column
* mudela_column_l
)
18 mudela_column_l_
= mudela_column_l
;
21 Mudela_item::~Mudela_item ()
26 Mudela_item::at_mom ()
28 return mudela_column_l_
->at_mom ();
32 Mudela_item::duration_mom ()
38 Mudela_item::output (Mudela_stream
& mudela_stream_r
)
40 mudela_stream_r
<< str () << " ";
43 Mudela_key::Mudela_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 Mudela_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 (',', (Mudela_note::c0_pitch_i_c_
+ 11 - pitch_i
) / 12);
151 String octavate_str
= to_str ('\'', (pitch_i
- Mudela_note::c0_pitch_i_c_
) / 12);
152 return notename_str
+de_octavate_str
+ octavate_str
;
155 Mudela_time_signature::Mudela_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 Mudela_time_signature::bar_mom ()
171 d
.durlog_i_
= den_i_
;
172 return Rational (num_i_
) * Duration_convert::dur2_mom (d
);
176 Mudela_time_signature::clocks_1_i ()
182 Mudela_time_signature::den_i ()
188 Mudela_time_signature::num_i ()
194 Mudela_time_signature::str ()
196 String str
= "\\time "
197 + to_str (num_i_
) + "/" + to_str (1 << den_i_
)
203 // statics Mudela_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 Mudela_note::simple_plet_b_s
;
216 Mudela_note::Mudela_note (Mudela_column
* mudela_column_l
,
217 int channel_i
, int pitch_i
, int dyn_i
)
218 : Mudela_item (mudela_column_l
)
222 channel_i_
= channel_i
;
228 Mudela_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 Mudela_note::duration_mom ()
238 assert (end_column_l_
);
239 return end_column_l_
->at_mom () - at_mom ();
245 Duration dur
= duration ();
246 if (dur
.durlog_i_
< -10)
250 = mudela_column_l_
->mudela_score_l_
->mudela_key_l_
->notename_str (pitch_i_
);
253 return name_str
+ Duration_convert::dur2_str (dur
) + " ";
259 str
+= String ("\\times ")
260 + String_convert::i2dec_str (dur
.plet_
.iso_i_
, 0, 0)
262 + String_convert::i2dec_str (dur
.plet_
.type_i_
, 0, 0)
270 str
+= Duration_convert::dur2_str (tmp
);
273 str
+= String (" }");
276 note of zero duration is nonsense,
277 but let's output anyway for convenient debugging
279 if (!duration_mom ())
280 return String ("\n% ") + str
+ "\n";
285 Mudela_skip::Mudela_skip (Mudela_column
* mudela_column_l
, Rational skip_mom
)
286 : Mudela_item (mudela_column_l
)
292 Mudela_skip::duration ()
294 return Duration_convert::mom2_dur (mom_
);
298 Mudela_skip::duration_mom ()
300 return Duration_convert::dur2_mom (duration ());
309 Duration dur
= duration ();
310 if (dur
.durlog_i_
<-10)
313 String str
= "\\skip ";
314 str
+= Duration_convert::dur2_str (dur
) + "; ";
319 Mudela_tempo::Mudela_tempo (int useconds_per_4_i
)
322 useconds_per_4_i_
= useconds_per_4_i
;
323 seconds_per_1_mom_
= Rational(useconds_per_4_i_
*4, 1e6
);
329 String str
= "\\tempo 4=";
330 str
+= to_str (get_tempo_i (Rational (1, 4)));
336 Mudela_tempo::useconds_per_4_i ()
338 return useconds_per_4_i_
;
342 Mudela_tempo::get_tempo_i (Rational rational
)
344 Rational m1
= Rational (60) / rational
;
345 Rational m2
= seconds_per_1_mom_
;
349 Mudela_text::Mudela_text (Mudela_text::Type type
, String text_str
)
353 text_str_
= text_str
;
359 if (!text_str_
.length_i ()
360 || (text_str_
.length_i () != (int)strlen (text_str_
.ch_C ())))
363 return "% " + text_str_
+ "\n";