2 chord.cc -- implement Chord
4 source file of the GNU LilyPond music typesetter
6 (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
12 A triad is a chord of three tones, and not an interval of a third.
18 // doesn't seem common, and we should know about this during parsing
19 // #define INVERSION_ADDED_AS_BASE 1
21 Chord::Chord (Array<Musical_pitch> pitch_arr)
23 pitch_arr_ = pitch_arr;
27 rebuild_transpose (Musical_pitch tonic, Array<Musical_pitch>* pitch_arr_p)
29 for (int i = 0; i < pitch_arr_p->size (); i++)
31 Musical_pitch p = tonic;
32 Musical_pitch q = (*pitch_arr_p)[i];
33 // duh, c7 should mean <c bes>
34 if (q.notename_i_ == 6)
37 (*pitch_arr_p)[i] = p;
39 pitch_arr_p->sort (Musical_pitch::compare);
43 find_pitch_i (Array<Musical_pitch> const* pitch_arr_p, Musical_pitch p)
45 for (int i = 0; i < pitch_arr_p->size (); i++)
46 if (p == (*pitch_arr_p)[i])
52 find_notename_i (Array<Musical_pitch> const* pitch_arr_p, Musical_pitch p)
54 int i = find_pitch_i (pitch_arr_p, p);
57 for (int i = 0; i < pitch_arr_p->size (); i++)
59 p.octave_i_ = (*pitch_arr_p)[i].octave_i_;
60 if (p == (*pitch_arr_p)[i])
68 trap (NL) != trap(english)
71 trap_i (Musical_pitch tonic, Musical_pitch p)
73 int i = p.notename_i_ - tonic.notename_i_
74 + (p.octave_i_ - tonic.octave_i_) * 7;
81 static Array<Musical_pitch>
82 missing_triads_pitch_arr (Array<Musical_pitch>const* pitch_arr_p)
84 Array<Musical_pitch> triads;
86 /* is the third c-e, d-f, etc. small or large? */
87 int minormajor_a[] = {0, -1, -1, 0,0,-1,-1};
88 for (int i=0; i < 7; i++)
89 triads.push (Musical_pitch( 2, minormajor_a[i]));
91 Musical_pitch tonic = (*pitch_arr_p)[0];
92 Musical_pitch last = tonic;
93 Array<Musical_pitch> missing_arr;
95 for (int i = 0; i < pitch_arr_p->size ();)
97 Musical_pitch p = (*pitch_arr_p)[i];
98 int trap = trap_i (tonic, p);
99 if (last.notename_i_ == p.notename_i_)
100 last.transpose (triads[(last.notename_i_ - tonic.notename_i_ + 7) % 7]);
101 if (trap > trap_i (tonic, last))
103 while (trap > trap_i (tonic, last))
105 if ((last.notename_i_ - tonic.notename_i_ + 7) % 7 == 6)
107 Musical_pitch special_seven = last;
108 Musical_pitch lower (0, -1);
109 special_seven.transpose (lower);
110 missing_arr.push (special_seven);
114 missing_arr.push (last);
116 last.transpose (triads[(last.notename_i_ - tonic.notename_i_ + 7) % 7]);
129 construct from parser output
131 Chord::Chord (Musical_pitch tonic, Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p, Musical_pitch* inversion_p)
133 rebuild_transpose (tonic, add_arr_p);
134 rebuild_transpose (tonic, sub_arr_p);
136 Musical_pitch fifth = tonic;
137 fifth.transpose (Musical_pitch (2));
138 fifth.transpose (Musical_pitch (2, -1));
141 remove double adds (urg: sus4)
143 for (int i = add_arr_p->size () - 1; i >= 0 ; i--)
145 int j = ::find_pitch_i (add_arr_p, (*add_arr_p)[i]);
146 if ((j != -1) && (i != j))
153 default chord includes upto 5: <1, 3, 5>
155 add_arr_p->insert (tonic, 0);
156 Array<Musical_pitch> tmp = *add_arr_p;
157 int highest_trap = trap_i (tonic, tmp.top ());
158 if (highest_trap < 5)
164 Array<Musical_pitch> missing_arr = missing_triads_pitch_arr (&tmp);
165 if (highest_trap < 5)
166 missing_arr.push (fifth);
169 if additions include some 3, don't add third
171 Musical_pitch third = tonic;
172 third.transpose (Musical_pitch (2));
173 if (::find_notename_i (add_arr_p, third) != -1)
175 int i = ::find_pitch_i (&missing_arr, third);
181 if additions include 4, assume sus4 and don't add third implicitely
182 C-sus (4) = c f g (1 4 5)
184 Musical_pitch sus = tonic;
185 sus.transpose (Musical_pitch (3));
186 if (::find_pitch_i (add_arr_p, sus) != -1)
188 int i = ::find_pitch_i (&missing_arr, third);
194 if additions include some 5, don't add fifth
196 if (::find_notename_i (add_arr_p, fifth) != -1)
198 int i = ::find_pitch_i (&missing_arr, fifth);
205 complete the list of triads to be added
207 add_arr_p->concat (missing_arr);
208 add_arr_p->sort (Musical_pitch::compare);
211 add all that aren't subtracted
213 for (int i = 0; i < add_arr_p->size (); i++)
215 Musical_pitch p = (*add_arr_p)[i];
217 for (; j < sub_arr_p->size (); j++)
218 if (p == (*sub_arr_p)[j])
224 if (j == sub_arr_p->size ())
228 pitch_arr_.sort (Musical_pitch::compare);
230 for (int i = 0; i < sub_arr_p->size (); i++)
231 warning (_f ("invalid subtraction: not part of chord: %s",
232 (*sub_arr_p)[i].str ()));
237 for (; i < pitch_arr_.size (); i++)
239 if ((pitch_arr_[i].notename_i_ == inversion_p->notename_i_)
240 && (pitch_arr_[i].accidental_i_ == inversion_p->accidental_i_))
243 if (i == pitch_arr_.size ())
245 warning (_f ("invalid inversion pitch: not part of chord: %s",
246 inversion_p->str ()));
250 #if INVERSION_ADDED_AS_BASE
251 pitch_arr_.insert (pitch_arr_[i], 0);
252 rebuild_with_bass (0);
254 rebuild_with_bass (i);
263 Chord::find_additions_and_subtractions(Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p) const
265 Musical_pitch tonic = pitch_arr_[0];
267 construct an array of triads for a normal chord
269 Array<Musical_pitch> all_arr;
270 all_arr.push (tonic);
271 all_arr.push (pitch_arr_.top ());
272 all_arr.concat (missing_triads_pitch_arr (&all_arr));
273 all_arr.sort (Musical_pitch::compare);
277 while ((i < all_arr.size ()) || (j < pitch_arr_.size ()))
279 Musical_pitch a = all_arr [i <? all_arr.size () - 1];
280 Musical_pitch p = pitch_arr_ [j <? pitch_arr_.size () - 1];
282 this pitch is present: do nothing, check next
290 found an extra pitch: chord addition
292 else if ((p < a) || (p.notename_i_ == a.notename_i_))
295 (j < pitch_arr_.size ()) ? j++ : i++;
298 a triad is missing: chord subtraction
303 (i < all_arr.size ()) ? i++ : j++;
308 add highest addition, because it names chord
309 (1, 3 and) 5 not an addition: part of normal chord
311 if (trap_i (tonic, pitch_arr_.top () > 5))
312 add_arr_p->push (pitch_arr_.top ());
316 Chord::banter_str (Musical_pitch* inversion) const
318 Musical_pitch tonic = pitch_arr_[0];
320 //urg, should do translation in scheme.
321 char const *acc[] = {"\\textflat\\textflat ", "\\textflat ", "", "\\textsharp " , "\\textsharp\\textsharp "};
322 String tonic_str = tonic.str ();
323 tonic_str = tonic_str.left_str (1).upper_str ()
324 + acc[tonic.accidental_i_ + 2];
326 Array<Musical_pitch> add_arr;
327 Array<Musical_pitch> sub_arr;
328 find_additions_and_subtractions (&add_arr, &sub_arr);
331 Array<Musical_pitch> scale;
332 for (int i=0; i < 7; i++)
333 scale.push (Musical_pitch (i));
335 // 7 always means 7-...
336 // scale.push (Musical_pitch (6, -1)); // b
338 rebuild_transpose (tonic, &scale);
340 bool has3m_b = false;
344 for (int i = 0; i < add_arr.size (); i++)
346 Musical_pitch p = add_arr[i];
347 int trap = trap_i (tonic, p);
350 int accidental = p.accidental_i_ - scale[(trap - 1) % 7].accidental_i_;
351 if ((trap == 3) && (accidental == -1))
357 || (!(trap % 2) || ((i + 1 == add_arr.size ()) && (trap > 5))))
360 if ((trap == 7) && (accidental == 1))
364 str += to_str (trap);
366 str += accidental < 0 ? "-" : "+";
372 for (int i = 0; i < sub_arr.size (); i++)
374 Musical_pitch p = sub_arr[i];
375 int trap = trap_i (tonic, p);
377 if chord has 3-, assume minor and don't display 'no3'
378 if additions include 4, assume sus4 and don't display 'no3'
380 if (!((trap == 3) && (has3m_b || has4_b)))
382 str += sep_str + "no" + to_str (trap);
387 String inversion_str;
390 inversion_str = inversion->str ();
391 inversion_str = "/" + inversion_str.left_str (1).upper_str ()
392 + acc[inversion->accidental_i_ + 2];
396 return tonic_str + "$^{" + str + "}$" + inversion_str;
400 Chord::find_notename_i (Musical_pitch p) const
402 return ::find_notename_i (&pitch_arr_, p);
406 Chord::find_pitch_i (Musical_pitch p) const
408 return ::find_pitch_i (&pitch_arr_, p);
412 Chord::find_tonic_i () const
417 first try: base of longest line of triads
421 for (int i = 0; i < pitch_arr_.size (); i++)
424 int last_i = pitch_arr_[i % pitch_arr_.size ()].notename_i_;
426 for (; j < pitch_arr_.size (); j++)
428 int cur_i = pitch_arr_[(i + j + 1) % pitch_arr_.size ()].notename_i_;
429 int gap = cur_i - last_i;
438 if (j - no_triad_i > longest_i)
440 longest_i = j - no_triad_i;
446 second try: note after biggest gap
451 for (int i = 0; i < pitch_arr_.size (); i++)
453 int gap = pitch_arr_[i].notename_i_
454 - pitch_arr_[(i - 1 + pitch_arr_.size ())
455 % pitch_arr_.size ()].notename_i_;
469 Chord::rebuild_from_base (int base_i)
471 assert (base_i >= 0);
472 Musical_pitch last (0, 0, -5);
473 Array<Musical_pitch> new_arr;
474 for (int i = 0; i < pitch_arr_.size (); i++)
476 Musical_pitch p = pitch_arr_[(base_i + i) % pitch_arr_.size ()];
479 p.octave_i_ = last.octave_i_;
486 pitch_arr_ = new_arr;
490 Chord::rebuild_insert_inversion (int tonic_i)
492 assert (tonic_i > 0);
493 #if INVERSION_ADDED_AS_BASE
494 // inversion was added; don't insert
495 Musical_pitch inversion = pitch_arr_.get (0);
498 Musical_pitch inversion = pitch_arr_.get (0);
499 rebuild_from_base (tonic_i - 1);
500 if (pitch_arr_.size ())
502 inversion.octave_i_ = pitch_arr_[0].octave_i_ - 1;
503 while (inversion < pitch_arr_[0])
504 inversion.octave_i_++;
506 for (int i = 0; i < pitch_arr_.size (); i++)
507 if (pitch_arr_[i] > inversion)
509 pitch_arr_.insert (inversion, i);
516 Chord::rebuild_with_bass (int bass_i)
518 assert (bass_i >= 0);
519 Musical_pitch inversion = pitch_arr_.get (bass_i);
520 // is lowering fine, or should others be raised?
521 if (pitch_arr_.size ())
522 while (inversion > pitch_arr_[0])
523 inversion.octave_i_--;
524 pitch_arr_.insert (inversion, 0);