]> git.donarmstrong.com Git - lilypond.git/blob - lily/chord.cc
patch::: 1.3.2.jcn1
[lilypond.git] / lily / chord.cc
1 /*
2   chord.cc -- implement Chord
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1999 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
8
9 #include "chord.hh"
10 #include "musical-request.hh"
11 #include "warn.hh"
12
13
14 /*
15   construct from parser output
16 */
17 Chord
18 to_chord (Musical_pitch tonic, Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p, Musical_pitch* inversion_p, Musical_pitch* bass_p)
19 {
20   // urg: catch dim modifier: 5th and 7th should be lowered
21   bool dim_b = false;
22   for (int i=0; i < add_arr_p->size (); i++)
23     {
24       Musical_pitch* p = &(*add_arr_p)[i];
25       if (p->octave_i_ == -100)
26         {
27           p->octave_i_ = 0;
28           dim_b = true;
29         }
30     }
31   Chord::rebuild_transpose (add_arr_p, tonic);
32   Chord::rebuild_transpose (sub_arr_p, tonic);
33
34   Musical_pitch fifth = tonic;
35   fifth.transpose (Musical_pitch (2));
36   fifth.transpose (Musical_pitch (2, -1));
37
38   /*
39     remove double adds (urg: sus4)
40    */
41   for (int i = add_arr_p->size () - 1; i >= 0 ; i--)
42     {
43       int j = Chord::find_pitch_i (add_arr_p, (*add_arr_p)[i]);
44       if ((j != -1) && (i != j))
45         {
46             add_arr_p->get (i);
47         } 
48     }
49
50   /*
51     default chord includes upto 5: <1, 3, 5>
52    */
53   add_arr_p->insert (tonic, 0);
54   Array<Musical_pitch> tmp = *add_arr_p;
55   int highest_step = Chord::step_i (tonic, tmp.top ());
56   if (highest_step < 5)
57     tmp.push (fifth);
58   else if (dim_b)
59     {
60       Musical_pitch* p = &add_arr_p->top ();
61       p->accidental_i_--;
62     }
63
64   /*
65     find missing thirds
66    */
67   Array<Musical_pitch> missing_arr = Chord::missing_thirds_pitch_arr (&tmp);
68   if (highest_step < 5)
69     missing_arr.push (fifth);
70
71   if (dim_b)
72     {
73       for (int i=0; i < missing_arr.size (); i++)
74         {
75           missing_arr[i].accidental_i_--;
76         }
77     }
78
79   /*
80     if additions include some 3, don't add third
81    */
82   Musical_pitch third = tonic;
83   third.transpose (Musical_pitch (2));
84   if (Chord::find_notename_i (add_arr_p, third) != -1)
85     {
86       int i = Chord::find_pitch_i (&missing_arr, third);
87       if (i != -1)
88         missing_arr.get (i);
89     }
90   
91   /*
92     if additions include 4, assume sus4 and don't add third implicitely
93      C-sus (4) = c f g (1 4 5)
94    */
95   Musical_pitch sus = tonic;
96   sus.transpose (Musical_pitch (3));
97   if (Chord::find_pitch_i (add_arr_p, sus) != -1)
98     {
99       int i = Chord::find_pitch_i (&missing_arr, third);
100       if (i != -1)
101         missing_arr.get (i);
102     }
103
104   /*
105     if additions include some 5, don't add fifth
106    */
107   if (Chord::find_notename_i (add_arr_p, fifth) != -1)
108     {
109       int i = Chord::find_pitch_i (&missing_arr, fifth);
110       if (i != -1)
111         missing_arr.get (i);
112     }
113   
114   
115   /*
116     complete the list of thirds to be added
117    */
118   add_arr_p->concat (missing_arr);
119   add_arr_p->sort (Musical_pitch::compare);
120
121   Array<Musical_pitch> pitch_arr;
122   /*
123    add all that aren't subtracted
124    */
125   for (int i = 0; i < add_arr_p->size (); i++)
126     {
127       Musical_pitch p = (*add_arr_p)[i];
128       int j = 0;
129       for (; j < sub_arr_p->size (); j++)
130         if (p == (*sub_arr_p)[j])
131           {
132             sub_arr_p->del (j);
133             j = -1;
134             break;
135           }
136       if (j == sub_arr_p->size ())
137         pitch_arr.push (p);
138     }
139
140   pitch_arr.sort (Musical_pitch::compare);
141
142   for (int i = 0; i < sub_arr_p->size (); i++)
143     warning (_f ("invalid subtraction: not part of chord: %s",
144                  (*sub_arr_p)[i].str ()));
145  
146   return Chord (pitch_arr, inversion_p, bass_p);
147 }
148
149 /*
150   Construct from list of pitches and requests
151  */
152 Chord
153 to_chord (Array<Musical_pitch> pitch_arr, Tonic_req* tonic_req, Inversion_req* inversion_req, Bass_req* bass_req, bool find_inversion_b)
154 {
155   Musical_pitch* inversion_p = 0;
156   Musical_pitch* bass_p = 0;
157
158   if (bass_req)
159     {
160       assert (pitch_arr[0].notename_i_ == bass_req->pitch_.notename_i_);
161       bass_p = new Musical_pitch (pitch_arr.get (0));
162     }
163     
164   if (inversion_req)
165     {
166       assert (pitch_arr[0].notename_i_ == inversion_req->pitch_.notename_i_);
167       inversion_p = new Musical_pitch (inversion_req->pitch_);
168       assert (tonic_req);
169       int tonic_i = Chord::find_notename_i (&pitch_arr, tonic_req->pitch_);
170       if (tonic_i)
171         Chord::rebuild_insert_inversion (&pitch_arr, tonic_i);
172     }
173     
174   if (find_inversion_b && !inversion_p)
175     {
176       int tonic_i = tonic_req
177         ? Chord::find_notename_i (&pitch_arr, tonic_req->pitch_) 
178         : Chord::find_tonic_i (&pitch_arr);
179         
180       if (tonic_i)
181         {
182           inversion_p = &pitch_arr[0];
183           Chord::rebuild_insert_inversion (&pitch_arr, tonic_i);
184         }
185     }
186
187   if (tonic_req)
188     {
189       assert (pitch_arr[0].notename_i_ == tonic_req->pitch_.notename_i_);
190     }
191
192   return Chord (pitch_arr, inversion_p, bass_p);
193 }
194
195 Chord::Chord (Array<Musical_pitch> pitch_arr, Musical_pitch* inversion_p, Musical_pitch* bass_p)
196 {
197   pitch_arr_ = pitch_arr;
198   inversion_p_ = inversion_p;
199   bass_p_ = bass_p;
200 }
201
202 Chord::Chord (Chord const& chord)
203 {
204   pitch_arr_ = chord.pitch_arr_;
205   inversion_p_ = chord.inversion_p_ ? new Musical_pitch (*chord.inversion_p_) : 0;
206   bass_p_ = chord.bass_p_ ? new Musical_pitch (*chord.bass_p_) : 0;
207 }
208
209 Chord::~Chord ()
210 {
211   delete inversion_p_;
212   delete bass_p_;
213 }
214
215 void
216 Chord::rebuild_transpose (Array<Musical_pitch>* pitch_arr_p, Musical_pitch tonic)
217 {
218   for (int i = 0; i < pitch_arr_p->size (); i++)
219     {
220       Musical_pitch p = tonic;
221       Musical_pitch q = (*pitch_arr_p)[i];
222       // duh, c7 should mean <c bes>
223       if (q.notename_i_ == 6)
224         q.accidental_i_--;
225       p.transpose (q);
226       (*pitch_arr_p)[i] = p;
227     }
228   pitch_arr_p->sort (Musical_pitch::compare);
229 }
230
231 int
232 Chord::find_pitch_i (Array<Musical_pitch> const* pitch_arr_p, Musical_pitch p)
233 {
234   for (int i = 0; i < pitch_arr_p->size (); i++)
235     if (p == (*pitch_arr_p)[i])
236       return i;
237   return -1;
238 }
239
240 int
241 Chord::find_notename_i (Array<Musical_pitch> const* pitch_arr_p, Musical_pitch p)
242 {
243   int i = find_pitch_i (pitch_arr_p, p);
244   if (i == -1)
245     {
246       for (int i = 0; i < pitch_arr_p->size (); i++)
247         {
248           p.octave_i_ = (*pitch_arr_p)[i].octave_i_;
249           if (p == (*pitch_arr_p)[i])
250             return i;
251         }
252     }
253   return i;
254 }
255
256 int
257 Chord::step_i (Musical_pitch tonic, Musical_pitch p)
258 {
259   int i = p.notename_i_ - tonic.notename_i_
260     + (p.octave_i_ - tonic.octave_i_) * 7;
261   while (i < 0)
262     i += 7;
263   i++;
264   return i;
265 }
266
267 Array<Musical_pitch>
268 Chord::missing_thirds_pitch_arr (Array<Musical_pitch> const* pitch_arr_p)
269 {
270   Array<Musical_pitch> thirds;
271
272   /* is the third c-e, d-f, etc. small or large? */
273   int minormajor_a[] = {0, -1, -1, 0,0,-1,-1};
274   for (int i=0; i < 7; i++)
275     thirds.push (Musical_pitch( 2, minormajor_a[i]));
276
277   Musical_pitch tonic = (*pitch_arr_p)[0];
278   Musical_pitch last = tonic;
279   Array<Musical_pitch> missing_arr;
280
281   for (int i = 0; i < pitch_arr_p->size ();)
282     {
283       Musical_pitch p = (*pitch_arr_p)[i];
284       int step = step_i (tonic, p);
285       if (last.notename_i_ == p.notename_i_)
286         last.transpose (thirds[(last.notename_i_ - tonic.notename_i_ + 7) % 7]);
287       if (step > step_i (tonic, last))
288         {
289           while (step > step_i (tonic, last))
290             {
291               if ((last.notename_i_ - tonic.notename_i_ + 7) % 7 == 6)
292                 {
293                   Musical_pitch special_seven = last;
294                   Musical_pitch lower (0, -1);
295                   special_seven.transpose (lower);
296                   missing_arr.push (special_seven);
297                 }
298               else
299                 {
300                   missing_arr.push (last);
301                 }
302               last.transpose (thirds[(last.notename_i_ - tonic.notename_i_ + 7) % 7]);
303             }
304         }
305       else
306         {
307           i++;
308         }
309     }
310   return missing_arr;
311 }
312
313
314 /*
315  Mangle into list of pitches.
316  For normal chord entry, inversion and bass pitches are retained in
317  specific *_requests
318  */
319 Array<Musical_pitch>
320 Chord::to_pitch_arr () const
321 {
322   Array<Musical_pitch> pitch_arr = pitch_arr_;
323   if (inversion_p_)
324     {
325       int i = 0;
326       for (; i < pitch_arr.size (); i++)
327         {
328           if ((pitch_arr[i].notename_i_ == inversion_p_->notename_i_)
329               && (pitch_arr[i].accidental_i_ == inversion_p_->accidental_i_))
330             break;
331         }
332       if (i == pitch_arr.size ())
333         {
334           warning (_f ("invalid inversion pitch: not part of chord: %s",
335                        inversion_p_->str ()));
336         }
337       else
338         rebuild_with_bass (&pitch_arr, i);
339     }
340
341   if (bass_p_)
342     {
343       pitch_arr.insert (*bass_p_, 0);
344       rebuild_with_bass (&pitch_arr, 0);
345     }
346   return pitch_arr;
347 }
348
349 void
350 Chord::find_additions_and_subtractions (Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p) const
351 {
352   Musical_pitch tonic = pitch_arr_[0];
353   /*
354     construct an array of thirds for a normal chord
355    */
356   Array<Musical_pitch> all_arr;
357   all_arr.push (tonic);
358   all_arr.push (pitch_arr_.top ());
359   all_arr.concat (missing_thirds_pitch_arr (&all_arr));
360   all_arr.sort (Musical_pitch::compare);
361   
362   int i = 0;
363   int j = 0;
364   while ((i < all_arr.size ()) || (j < pitch_arr_.size ()))
365     {
366       Musical_pitch a = all_arr [i <? all_arr.size () - 1];
367       Musical_pitch p = pitch_arr_ [j <? pitch_arr_.size () - 1];
368       /*
369         this pitch is present: do nothing, check next
370        */
371       if (a == p)
372         {
373           i++;
374           j++;
375         }
376       /*
377         found an extra pitch: chord addition
378        */
379       else if ((p < a) || (p.notename_i_ == a.notename_i_))
380         {
381           add_arr_p->push (p);
382           (j < pitch_arr_.size ()) ? j++ : i++;
383         }
384       /*
385         a third is missing: chord subtraction
386        */
387       else
388         {
389           sub_arr_p->push (a);
390           (i < all_arr.size ()) ? i++ : j++;
391         }
392     }
393       
394   /*
395     add highest addition, because it names chord
396     (1, 3 and) 5 not an addition: part of normal chord
397    */
398   if (step_i (tonic, pitch_arr_.top () > 5))
399     add_arr_p->push (pitch_arr_.top ());
400 }
401
402 /*
403   TODO:
404    reduce guess work: dim chord
405    other naming conventions `American'?
406    don't use TeX constructs
407    user defined chords-names for specific chords:
408       tonic, additions, subtractions, inversion, bass -> "my-chord-name"
409  */
410 String
411 Chord::banter_str () const
412 {
413   Musical_pitch tonic = pitch_arr_[0];
414
415   //urg, should do translation in scheme.
416   char const *acc[] = {"\\textflat\\textflat ", "\\textflat ", "", "\\textsharp " , "\\textsharp\\textsharp "};
417   String tonic_str = tonic.str ();
418   tonic_str = tonic_str.left_str (1).upper_str ()
419     + acc[tonic.accidental_i_ + 2];
420
421   Array<Musical_pitch> add_arr;
422   Array<Musical_pitch> sub_arr;
423   find_additions_and_subtractions (&add_arr, &sub_arr);
424                            
425
426   Array<Musical_pitch> scale;
427   for (int i=0; i < 7; i++)
428     scale.push (Musical_pitch (i));
429
430   // 7 always means 7-...
431   //  scale.push (Musical_pitch (6, -1)); // b
432
433   rebuild_transpose (&scale, tonic);
434   
435   bool has3m_b = false;
436   bool has4_b = false;
437   bool has5m_b = false;
438   String str;
439   String minor_str;
440   String sep_str;
441   for (int i = 0; i < add_arr.size (); i++)
442     {
443       Musical_pitch p = add_arr[i];
444       int step = step_i (tonic, p);
445       if (step == 4)
446         has4_b = true;
447       int accidental = p.accidental_i_ - scale[(step - 1) % 7].accidental_i_;
448       if ((step == 3) && (accidental == -1))
449         {
450           minor_str = "m";
451           has3m_b = true;
452         }
453       /*
454         have Cdim rather than Cm5-, even if it's a prefix
455        */
456       else if ((step == 5) && (accidental == -1) && has3m_b)
457         {
458           minor_str = "dim";
459           has5m_b = true;
460         }
461       else if (accidental
462                || (!(step % 2) || ((i + 1 == add_arr.size ()) && (step > 5))))
463         {
464           str += sep_str;
465           sep_str = "/";
466           if ((step == 7) && (accidental == 1))
467             {
468               str += "maj7";
469             }
470           else
471             {
472               /* 
473                 if has3m_b and has5m_b, assume dim
474                 don't mention dim-addition, except for chord-namer
475                */
476               if (((step/2) && (accidental == -1))
477                   && has3m_b && has5m_b)
478                 {
479                   if (i == add_arr.size () - 1)
480                     str += to_str (step);
481                   else
482                     sep_str = "";
483                 }
484               else
485                 {
486                   str += to_str (step);
487                   if (accidental)
488                     str += accidental < 0 ? "-" : "+";
489                 }
490             }
491         }
492     }
493
494   for (int i = 0; i < sub_arr.size (); i++)
495     {
496       Musical_pitch p = sub_arr[i];
497       int step = step_i (tonic, p);
498       /*
499         if chord has 3-, assume minor and don't display 'no3'
500         if additions include 4, assume sus4 and don't display 'no3'
501         if has3m_b and has5m_b, assume 'dim' chord
502       */
503       if (!((step == 3) && (has3m_b || has4_b))
504          && !((step/2) && (step !=3) && (step !=7 ) && (p.accidental_i_ == 0) && has3m_b && has5m_b)
505          && !((step == 7) && (p.accidental_i_ == -1) && has3m_b && has5m_b))
506         {
507           str += sep_str + "no" + to_str (step);
508           sep_str = "/";
509         }
510     }
511
512   /*
513    have Co rather than Cdim7
514    */
515   if (minor_str + str == "dim7")
516     {
517       minor_str = "";
518       str = "o";
519     }
520     
521
522   String inversion_str;
523   if (inversion_p_)
524     {
525       inversion_str = inversion_p_->str ();
526       inversion_str = "/" + inversion_str.left_str (1).upper_str ()
527         + acc[inversion_p_->accidental_i_ + 2];
528     }
529
530   String bass_str;
531   if (bass_p_)
532     {
533       bass_str = bass_p_->str ();
534       bass_str = "/" + bass_str.left_str (1).upper_str ()
535         + acc[bass_p_->accidental_i_ + 2];
536
537     }
538
539   return tonic_str + minor_str + "$^{" + str + "}$" + inversion_str + bass_str;
540 }
541
542 int
543 Chord::find_tonic_i (Array<Musical_pitch> const* pitch_arr_p)
544 {
545   /*
546     find tonic
547     
548     first try: base of longest line of thirds
549    */
550   int tonic_i = 0;
551   int longest_i = 0;
552   for (int i = 0; i < pitch_arr_p->size (); i++)
553     {
554       int no_third_i = 0;
555       int last_i = (*pitch_arr_p)[i % pitch_arr_p->size ()].notename_i_;
556       int j = 0;
557       for (; j < pitch_arr_p->size (); j++)
558         {
559           int cur_i = (*pitch_arr_p)[(i + j + 1) % pitch_arr_p->size ()].notename_i_;
560           int gap = cur_i - last_i;
561           while (gap < 0)
562             gap += 7;
563           gap %= 7;
564           if (gap == 2)
565             last_i = cur_i;
566           else
567             no_third_i++;
568         }
569       if (j - no_third_i > longest_i)
570         {
571           longest_i = j - no_third_i;
572           tonic_i = i;
573         }
574     }
575
576   /*
577     second try: note after biggest gap
578    */
579   int biggest_i = 0;
580   //  if (longest_i)
581   if (longest_i <= 1)
582     for (int i = 0; i < pitch_arr_p->size (); i++)
583       {
584         int gap = (*pitch_arr_p)[i].notename_i_
585           - (*pitch_arr_p)[(i - 1 + pitch_arr_p->size ()) 
586           % pitch_arr_p->size ()].notename_i_;
587         while (gap < 0)
588           gap += 7;
589         gap %= 7;
590         if (gap > biggest_i)
591           {
592             biggest_i = gap;
593             tonic_i = i;
594           }
595       }
596   return tonic_i;
597 }
598
599 void
600 Chord::rebuild_from_base (Array<Musical_pitch>* pitch_arr_p, int base_i)
601 {
602   assert (base_i >= 0);
603   Musical_pitch last (0, 0, -5);
604   Array<Musical_pitch> new_arr;
605   for (int i = 0; i < pitch_arr_p->size (); i++)
606     {
607       Musical_pitch p = (*pitch_arr_p)[(base_i + i) % pitch_arr_p->size ()];
608       if (p < last)
609         {
610           p.octave_i_ = last.octave_i_;
611           if (p < last)
612             p.octave_i_++;
613         }
614       new_arr.push (p);
615       last = p;
616     }
617   *pitch_arr_p = new_arr;
618 }
619
620 void
621 Chord::rebuild_insert_inversion (Array<Musical_pitch>* pitch_arr_p, int tonic_i)
622 {
623   assert (tonic_i > 0);
624   Musical_pitch inversion = pitch_arr_p->get (0);
625   rebuild_from_base (pitch_arr_p, tonic_i - 1);
626   if (pitch_arr_p->size ())
627     {
628       inversion.octave_i_ = (*pitch_arr_p)[0].octave_i_ - 1;
629       while (inversion < (*pitch_arr_p)[0])
630         inversion.octave_i_++;
631     }
632   for (int i = 0; i < pitch_arr_p->size (); i++)
633     if ((*pitch_arr_p)[i] > inversion)
634       {
635         pitch_arr_p->insert (inversion, i);
636         break;
637       }
638 }
639
640 void
641 Chord::rebuild_with_bass (Array<Musical_pitch>* pitch_arr_p, int bass_i)
642 {
643   assert (bass_i >= 0);
644   Musical_pitch bass = pitch_arr_p->get (bass_i);
645   // is lowering fine, or should others be raised?
646   if (pitch_arr_p->size ())
647     while (bass > (*pitch_arr_p)[0])
648       bass.octave_i_--;
649   pitch_arr_p->insert (bass, 0);
650 }