2 // mudela-item.cc -- implement Mudela_item
4 // copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
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 ()
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
;
53 if (accidentals_i_
>= 0)
54 key_i
= ((accidentals_i_
% 7)[ "cgdaebf" ] - 'a' - 2) % 7;
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");
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
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)
89 while (accidental_i
++ < 0)
90 if ((notename_str
== "a") || (notename_str
== "e"))
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
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
)
136 sync_dur_
.durlog_i_
= 3;
139 warning (_f ("#32 in quarter: %d", count_32_i
));
142 clocks_1_i_
= clocks_4_i
* 4;
146 Mudela_time_signature::bar_mom ()
149 d
.durlog_i_
= den_i_
;
150 return Moment (num_i_
) * Duration_convert::dur2_mom (d
);
154 Mudela_time_signature::clocks_1_i ()
160 Mudela_time_signature::den_i ()
166 Mudela_time_signature::num_i ()
172 Mudela_time_signature::str ()
174 String str
= "\\time "
175 + to_str (num_i_
) + "/" + to_str (1 << den_i_
)
181 // statics Mudela_note
183 this switch can be used to write simple plets like
186 \plet 2/3; c4 \plet 1/1;
189 UGH: .hh says false, .cc says true.
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
)
200 channel_i_
= channel_i
;
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
);
214 Mudela_note::duration_mom ()
216 assert (end_column_l_
);
217 return end_column_l_
->at_mom () - at_mom ();
223 Duration dur
= duration ();
224 if (dur
.durlog_i_
< -10)
228 = mudela_column_l_
->mudela_score_l_
->mudela_key_l_
->notename_str (pitch_i_
);
231 return name_str
+ Duration_convert::dur2_str (dur
) + " ";
237 str
+= String ("\\times ")
238 + String_convert::i2dec_str (dur
.plet_
.iso_i_
, 0, 0)
240 + String_convert::i2dec_str (dur
.plet_
.type_i_
, 0, 0)
248 str
+= Duration_convert::dur2_str (tmp
);
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";
263 Mudela_skip::Mudela_skip (Mudela_column
* mudela_column_l
, Moment skip_mom
)
264 : Mudela_item (mudela_column_l
)
270 Mudela_skip::duration ()
272 return Duration_convert::mom2_dur (mom_
);
276 Mudela_skip::duration_mom ()
278 return Duration_convert::dur2_mom (duration ());
287 Duration dur
= duration ();
288 if (dur
.durlog_i_
<-10)
291 String str
= "\\skip ";
292 str
+= Duration_convert::dur2_str (dur
) + "; ";
297 Mudela_tempo::Mudela_tempo (int useconds_per_4_i
)
300 useconds_per_4_i_
= useconds_per_4_i
;
301 seconds_per_1_mom_
= Moment(useconds_per_4_i_
*4, 1e6
);
307 String str
= "\\tempo 4=";
308 str
+= to_str (get_tempo_i (Moment (1, 4)));
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_
;
327 Mudela_text::Mudela_text (Mudela_text::Type type
, String text_str
)
331 text_str_
= text_str
;
337 if (!text_str_
.length_i ()
338 || (text_str_
.length_i () != (int)strlen (text_str_
.ch_C ())))
341 return "% " + text_str_
+ "\n";