]> git.donarmstrong.com Git - lilypond.git/blob - mi2mu/mudela-item.cc
12b1b1f3ec2a5d75e16cd54ac0c29caa521957ce
[lilypond.git] / mi2mu / mudela-item.cc
1 //
2 // mudela-item.cc -- implement Mudela_item
3 //
4 // copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
5
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"
14
15 Mudela_item::Mudela_item (Mudela_column* mudela_column_l)
16 {
17   mudela_column_l_ = mudela_column_l;
18 }
19
20 Mudela_item::~Mudela_item ()
21 {
22 }
23
24 Moment
25 Mudela_item::at_mom ()
26 {
27   return mudela_column_l_->at_mom ();
28 }
29
30 Moment
31 Mudela_item::duration_mom ()
32 {
33   return Moment (0);
34 }
35
36 void
37 Mudela_item::output (Mudela_stream& mudela_stream_r)
38 {
39   mudela_stream_r << str () << " ";
40 }
41
42 Mudela_key::Mudela_key (int accidentals_i, int minor_i)
43   : Mudela_item (0)
44 {
45   accidentals_i_ = accidentals_i;
46   minor_i_ = minor_i;
47 }
48
49 String
50 Mudela_key::str ()
51 {
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;
57   
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
62    
63   return String("\\key " + keyname  + ";\n");
64 }
65
66 String
67 Mudela_key::notename_str (int pitch_i)
68 {
69   // this may seem very smart,
70   // but it-s only an excuse not to read a notename table
71
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 ];
76
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))
80     {
81       accidental_i = - accidental_i;
82       notename_i =  (notename_i + 1) % 7;
83     }
84
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--;
95
96   /*
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.)
103     
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...)
109     
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.
113     
114     John Sankey <bf250@freenet.carleton.ca>
115
116    */
117
118   /* ok, bit ugly, but here we go */
119
120   if (minor_i_ && (accidentals_i_ == -1))
121     if (notename_str == "des")
122       notename_str = "cis";
123   
124   if (minor_i_ && (accidentals_i_ == -2))
125     if (notename_str == "ges")
126       notename_str = "fis";
127   
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;
131 }
132
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)
135 {
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;
143 }
144
145 Moment
146 Mudela_time_signature::bar_mom ()
147 {
148   Duration d;
149   d.durlog_i_ = den_i_;
150   return Moment (num_i_) * Duration_convert::dur2_mom (d);
151 }
152
153 int
154 Mudela_time_signature::clocks_1_i ()
155 {
156   return clocks_1_i_;
157 }
158
159 int
160 Mudela_time_signature::den_i ()
161 {
162   return den_i_;
163 }
164
165 int
166 Mudela_time_signature::num_i ()
167 {
168   return num_i_;
169 }
170
171 String
172 Mudela_time_signature::str ()
173 {
174   String str = "\\time "
175     + to_str (num_i_) + "/" + to_str (1 << den_i_)
176     + ";\n";
177   return str;
178 }
179
180
181 // statics Mudela_note
182 /*
183   this switch can be used to write simple plets like
184   c4*2/3
185   as
186   \plet 2/3; c4 \plet 1/1;
187  */
188 /*
189   UGH: .hh says false, .cc says true.
190   FIXME.
191  */
192 bool const Mudela_note::simple_plet_b_s;
193
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)
197 {
198   // junk dynamics
199   (void)dyn_i;
200   channel_i_ = channel_i;
201   pitch_i_ = pitch_i;
202   end_column_l_ = 0;
203 }
204
205 Duration
206 Mudela_note::duration ()
207 {
208   assert (end_column_l_);
209   Moment mom = end_column_l_->at_mom () - at_mom ();
210   return Duration_convert::mom2_dur (mom);
211 }
212
213 Moment
214 Mudela_note::duration_mom ()
215 {
216   assert (end_column_l_);
217   return end_column_l_->at_mom () - at_mom ();
218 }
219
220 String
221 Mudela_note::str ()
222 {
223   Duration dur = duration ();
224   if (dur.durlog_i_ < -10)
225     return "";
226
227   String name_str
228     = mudela_column_l_->mudela_score_l_->mudela_key_l_->notename_str (pitch_i_);
229
230   if (simple_plet_b_s)
231     return name_str + Duration_convert::dur2_str (dur) + " ";
232
233   String str;
234
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       + " { ";
242   
243
244   str += name_str;
245
246   Duration tmp = dur;
247   tmp.set_plet (1,1);
248   str += Duration_convert::dur2_str (tmp);
249
250   if (dur.plet_b ())
251     str += String (" }");
252
253   /* 
254      note of zero duration is nonsense, 
255      but let's output anyway for convenient debugging
256   */
257   if (!duration_mom ())
258     return String ("\n% ") + str + "\n";
259
260   return str + " ";
261 }
262
263 Mudela_skip::Mudela_skip (Mudela_column* mudela_column_l, Moment skip_mom)
264   : Mudela_item (mudela_column_l)
265 {
266   mom_ = skip_mom;
267 }
268
269 Duration
270 Mudela_skip::duration ()
271 {
272   return Duration_convert::mom2_dur (mom_);
273 }
274
275 Moment
276 Mudela_skip::duration_mom ()
277 {
278   return Duration_convert::dur2_mom (duration ());
279 }
280
281 String
282 Mudela_skip::str ()
283 {
284   if (!mom_)
285     return String ("");
286
287   Duration dur = duration ();
288   if (dur.durlog_i_<-10)
289     return "";
290
291   String str = "\\skip ";
292   str += Duration_convert::dur2_str (dur) + "; ";
293
294   return str;
295 }
296
297 Mudela_tempo::Mudela_tempo (int useconds_per_4_i)
298   : Mudela_item (0)
299 {
300   useconds_per_4_i_ = useconds_per_4_i;
301   seconds_per_1_mom_ = Moment(useconds_per_4_i_ *4, 1e6);
302 }
303
304 String
305 Mudela_tempo::str ()
306 {
307   String str = "\\tempo 4=";
308   str += to_str (get_tempo_i (Moment (1, 4)));
309   str += ";\n";
310   return str;
311 }
312
313 int
314 Mudela_tempo::useconds_per_4_i ()
315 {
316   return useconds_per_4_i_;
317 }
318
319 int
320 Mudela_tempo::get_tempo_i (Moment moment)
321 {
322   Moment m1 = Moment (60) / moment;
323   Moment m2 = seconds_per_1_mom_;
324   return m1 / m2;
325 }
326
327 Mudela_text::Mudela_text (Mudela_text::Type type, String text_str)
328   : Mudela_item (0)
329 {
330   type_ = type;
331   text_str_ = text_str;
332 }
333
334 String
335 Mudela_text::str ()
336 {
337   if (!text_str_.length_i ()
338       ||  (text_str_.length_i () != (int)strlen (text_str_.ch_C ())))
339     return "";
340
341   return "% " + text_str_ + "\n";
342 }