]> git.donarmstrong.com Git - lilypond.git/blob - midi2ly/lilypond-item.cc
release: 1.5.4
[lilypond.git] / midi2ly / lilypond-item.cc
1 //
2 // lilypond-item.cc -- implement Lilypond_item
3 //
4 // copyright 1997 Jan Nieuwenhuizen <janneke@gnu.org>
5
6 #include <string.h>
7 #include <assert.h>
8 #include "midi2ly-global.hh"
9 #include "string-convert.hh"
10 #include "duration-convert.hh"
11 #include "lilypond-column.hh"
12 #include "lilypond-item.hh"
13 #include "lilypond-stream.hh"
14 #include "lilypond-score.hh"
15
16 Lilypond_item::Lilypond_item (Lilypond_column* lilypond_column_l)
17 {
18   lilypond_column_l_ = lilypond_column_l;
19 }
20
21 Lilypond_item::~Lilypond_item ()
22 {
23 }
24
25 Rational
26 Lilypond_item::at_mom ()
27 {
28   return lilypond_column_l_->at_mom ();
29 }
30
31 Rational
32 Lilypond_item::duration_mom ()
33 {
34   return Rational (0);
35 }
36
37 void
38 Lilypond_item::output (Lilypond_stream& lilypond_stream_r)
39 {
40   lilypond_stream_r << str () << " ";
41 }
42
43 Lilypond_key::Lilypond_key (int accidentals_i, int minor_i)
44   : Lilypond_item (0)
45 {
46   accidentals_i_ = accidentals_i;
47   minor_i_ = minor_i;
48 }
49
50 char const *accname[] = {"eses", "es", "", "is" , "isis"};
51
52 String
53 Lilypond_key::str ()
54 {
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;
58   
59   String notename_str = !minor_i_
60     ? to_str ((char) ((key_i + 2) % 7 + 'a'))
61     : to_str ((char) ((key_i + 2) % 7 + 'a'));
62
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;
70                                
71   if (accidentals_i)
72     notename_str += String (accname [accidentals_i + 2]);
73
74   return "\\key " + notename_str  + (minor_i_ ? "\\minor" : "\\major") + "\n";
75 }
76
77 String
78 Lilypond_key::notename_str (int pitch_i)
79 {
80   // this may seem very smart,
81   // but it-s only an excuse not to read a notename table
82
83   // major scale: do-do
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];
87
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))
91     {
92       accidental_i *= -1;
93       notename_i =  (notename_i + 1) % 7;
94     }
95
96   String notename_str = to_str ((char)(((notename_i + 2) % 7) + 'a'));
97   if (accidental_i)
98     notename_str += String (accname [accidental_i + 2]);
99
100   /*
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.)
107     
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...)
113     
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
116     have it.
117     
118     John Sankey <bf250@freenet.carleton.ca>
119
120     Let's also do a-minor: a b c d e f gis a
121
122     --jcn
123
124    */
125
126   /* ok, bit ugly, but here we go -- jcn */
127
128
129   if (minor_i_)
130     {
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";
143
144      if ((accidentals_i_ <= -6) && (notename_str == "b"))
145       notename_str = "ces";
146      if ((accidentals_i_ <= -7) && (notename_str == "e"))
147       notename_str = "fes";
148     }
149               
150   String de_octavate_str = to_str (',',  (Lilypond_note::c0_pitch_i_c_ + 11 - pitch_i) / 12);
151   String octavate_str = to_str ('\'',  (pitch_i - Lilypond_note::c0_pitch_i_c_) / 12);
152   return notename_str +de_octavate_str  + octavate_str;
153 }
154
155 Lilypond_time_signature::Lilypond_time_signature (int num_i, int den_i, int clocks_4_i, int count_32_i)
156   : Lilypond_item (0)
157 {
158   sync_dur_.durlog_i_ = 3;
159   sync_f_ = 1.0;
160   if (count_32_i != 8)
161     warning (_f ("#32 in quarter: %d", count_32_i));
162   num_i_ = num_i;
163   den_i_ = den_i;
164   clocks_1_i_ = clocks_4_i * 4;
165 }
166
167 Rational
168 Lilypond_time_signature::bar_mom ()
169 {
170   Duration d;
171   d.durlog_i_ = den_i_;
172   return Rational (num_i_) * Duration_convert::dur2_mom (d);
173 }
174
175 int
176 Lilypond_time_signature::clocks_1_i ()
177 {
178   return clocks_1_i_;
179 }
180
181 int
182 Lilypond_time_signature::den_i ()
183 {
184   return den_i_;
185 }
186
187 int
188 Lilypond_time_signature::num_i ()
189 {
190   return num_i_;
191 }
192
193 String
194 Lilypond_time_signature::str ()
195 {
196   String str = "\\time "
197     + to_str (num_i_) + "/" + to_str (1 << den_i_)
198     + "\n";
199   return str;
200 }
201
202
203 // statics Lilypond_note
204 /*
205   this switch can be used to write simple plets like
206   c4*2/3
207   as
208   \plet 2/3; c4 \plet 1/1;
209  */
210 /*
211   UGH: .hh says false, .cc says true.
212   FIXME.
213  */
214 bool const Lilypond_note::simple_plet_b_s;
215
216 Lilypond_note::Lilypond_note (Lilypond_column* lilypond_column_l,
217                           int channel_i, int pitch_i, int dyn_i)
218   : Lilypond_item (lilypond_column_l)
219 {
220   // junk dynamics
221   (void)dyn_i;
222   channel_i_ = channel_i;
223   pitch_i_ = pitch_i;
224   end_column_l_ = 0;
225 }
226
227 Duration
228 Lilypond_note::duration ()
229 {
230   assert (end_column_l_);
231   Rational mom = end_column_l_->at_mom () - at_mom ();
232   return Duration_convert::mom2_dur (mom);
233 }
234
235 Rational
236 Lilypond_note::duration_mom ()
237 {
238   assert (end_column_l_);
239   return end_column_l_->at_mom () - at_mom ();
240 }
241
242 String
243 Lilypond_note::str ()
244 {
245   Duration dur = duration ();
246   if (dur.durlog_i_ < -10)
247     return "";
248
249   String name_str
250     = lilypond_column_l_->lilypond_score_l_->lilypond_key_l_->notename_str (pitch_i_);
251
252   if (simple_plet_b_s)
253     return name_str + Duration_convert::dur2_str (dur) + " ";
254
255   String str;
256
257   //ugh
258   if (dur.plet_b ())
259     str += String ("\\times ")
260       + String_convert::i2dec_str (dur.plet_.iso_i_, 0, 0)
261       + "/"
262       + String_convert::i2dec_str (dur.plet_.type_i_, 0, 0)
263       + " { ";
264   
265
266   str += name_str;
267
268   Duration tmp = dur;
269   tmp.set_plet (1,1);
270   str += Duration_convert::dur2_str (tmp);
271
272   if (dur.plet_b ())
273     str += String (" }");
274
275   /* 
276      note of zero duration is nonsense, 
277      but let's output anyway for convenient debugging
278   */
279   if (!duration_mom ())
280     return String ("\n% ") + str + "\n";
281
282   return str + " ";
283 }
284
285 Lilypond_skip::Lilypond_skip (Lilypond_column* lilypond_column_l, Rational skip_mom)
286   : Lilypond_item (lilypond_column_l)
287 {
288   mom_ = skip_mom;
289 }
290
291 Duration
292 Lilypond_skip::duration ()
293 {
294   return Duration_convert::mom2_dur (mom_);
295 }
296
297 Rational
298 Lilypond_skip::duration_mom ()
299 {
300   return Duration_convert::dur2_mom (duration ());
301 }
302
303 String
304 Lilypond_skip::str ()
305 {
306   if (!mom_)
307     return String ("");
308
309   Duration dur = duration ();
310   if (dur.durlog_i_<-10)
311     return "";
312
313   String str = "\\skip ";
314   str += Duration_convert::dur2_str (dur);
315
316   return str;
317 }
318
319 Lilypond_tempo::Lilypond_tempo (int useconds_per_4_i)
320   : Lilypond_item (0)
321 {
322   useconds_per_4_i_ = useconds_per_4_i;
323   seconds_per_1_mom_ = Rational(useconds_per_4_i_ *4, 1e6);
324 }
325
326 String
327 Lilypond_tempo::str ()
328 {
329   String str = "\\tempo 4=";
330   str += to_str (get_tempo_i (Rational (1, 4)));
331   str += "\n";
332   return str;
333 }
334
335 int
336 Lilypond_tempo::useconds_per_4_i ()
337 {
338   return useconds_per_4_i_;
339 }
340
341 int
342 Lilypond_tempo::get_tempo_i (Rational rational)
343 {
344   Rational m1 = Rational (60) / rational;
345   Rational m2 = seconds_per_1_mom_;
346   return m1 / m2;
347 }
348
349 Lilypond_text::Lilypond_text (Lilypond_text::Type type, String text_str)
350   : Lilypond_item (0)
351 {
352   type_ = type;
353   text_str_ = text_str;
354 }
355
356 String
357 Lilypond_text::str ()
358 {
359   if (!text_str_.length_i ()
360       ||  (text_str_.length_i () != (int)strlen (text_str_.ch_C ())))
361     return "";
362
363   return "% " + text_str_ + "\n";
364 }