2 // mudela-item.cc -- implement Mudela_item
4 // copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
7 #include "midi2ly-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 ()
25 Mudela_item::at_mom ()
27 return mudela_column_l_
->at_mom ();
31 Mudela_item::duration_mom ()
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
)
45 accidentals_i_
= accidentals_i
;
49 char const *accname
[] = {"eses", "es", "", "is" , "isis"};
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;
71 notename_str
+= String (accname
[accidentals_i
+ 2]);
73 return "\\key " + notename_str
+ (minor_i_
? "\\minor" : "") + ";\n";
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
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))
92 notename_i
= (notename_i
+ 1) % 7;
95 String notename_str
= to_str ((char)(((notename_i
+ 2) % 7) + 'a'));
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
117 John Sankey <bf250@freenet.carleton.ca>
119 Let's also do a-minor: a b c d e f gis a
125 /* ok, bit ugly, but here we go -- jcn */
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
)
157 sync_dur_
.durlog_i_
= 3;
160 warning (_f ("#32 in quarter: %d", count_32_i
));
163 clocks_1_i_
= clocks_4_i
* 4;
167 Mudela_time_signature::bar_mom ()
170 d
.durlog_i_
= den_i_
;
171 return Moment (num_i_
) * Duration_convert::dur2_mom (d
);
175 Mudela_time_signature::clocks_1_i ()
181 Mudela_time_signature::den_i ()
187 Mudela_time_signature::num_i ()
193 Mudela_time_signature::str ()
195 String str
= "\\time "
196 + to_str (num_i_
) + "/" + to_str (1 << den_i_
)
202 // statics Mudela_note
204 this switch can be used to write simple plets like
207 \plet 2/3; c4 \plet 1/1;
210 UGH: .hh says false, .cc says true.
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
)
221 channel_i_
= channel_i
;
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
);
235 Mudela_note::duration_mom ()
237 assert (end_column_l_
);
238 return end_column_l_
->at_mom () - at_mom ();
244 Duration dur
= duration ();
245 if (dur
.durlog_i_
< -10)
249 = mudela_column_l_
->mudela_score_l_
->mudela_key_l_
->notename_str (pitch_i_
);
252 return name_str
+ Duration_convert::dur2_str (dur
) + " ";
258 str
+= String ("\\times ")
259 + String_convert::i2dec_str (dur
.plet_
.iso_i_
, 0, 0)
261 + String_convert::i2dec_str (dur
.plet_
.type_i_
, 0, 0)
269 str
+= Duration_convert::dur2_str (tmp
);
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";
284 Mudela_skip::Mudela_skip (Mudela_column
* mudela_column_l
, Moment skip_mom
)
285 : Mudela_item (mudela_column_l
)
291 Mudela_skip::duration ()
293 return Duration_convert::mom2_dur (mom_
);
297 Mudela_skip::duration_mom ()
299 return Duration_convert::dur2_mom (duration ());
308 Duration dur
= duration ();
309 if (dur
.durlog_i_
<-10)
312 String str
= "\\skip ";
313 str
+= Duration_convert::dur2_str (dur
) + "; ";
318 Mudela_tempo::Mudela_tempo (int useconds_per_4_i
)
321 useconds_per_4_i_
= useconds_per_4_i
;
322 seconds_per_1_mom_
= Moment(useconds_per_4_i_
*4, 1e6
);
328 String str
= "\\tempo 4=";
329 str
+= to_str (get_tempo_i (Moment (1, 4)));
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_
;
348 Mudela_text::Mudela_text (Mudela_text::Type type
, String text_str
)
352 text_str_
= text_str
;
358 if (!text_str_
.length_i ()
359 || (text_str_
.length_i () != (int)strlen (text_str_
.ch_C ())))
362 return "% " + text_str_
+ "\n";