2 chord.cc -- implement Chord
4 source file of the GNU LilyPond music typesetter
6 (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
10 #include "musical-request.hh"
13 #include "molecule.hh"
14 #include "paper-def.hh"
18 pitch2scm (Musical_pitch p)
20 return gh_cons (gh_int2scm (p.notename_i_), gh_int2scm (p.accidental_i_));
24 construct from parser output
27 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)
29 // urg: catch dim modifier: 3rd, 5th, 7th, .. should be lowered
31 for (int i=0; i < add_arr_p->size (); i++)
33 Musical_pitch* p = &(*add_arr_p)[i];
34 if (p->octave_i_ == -100)
40 Chord::rebuild_transpose (add_arr_p, tonic, true);
41 Chord::rebuild_transpose (sub_arr_p, tonic, true);
43 Musical_pitch fifth = Chord::base_arr (tonic).top ();
46 remove double adds (urg: sus4)
48 for (int i = add_arr_p->size () - 1; i >= 0 ; i--)
50 int j = Chord::find_pitch_i (add_arr_p, (*add_arr_p)[i]);
51 if ((j != -1) && (i != j))
58 default chord includes upto 5: <1, 3, 5>
60 add_arr_p->insert (tonic, 0);
61 Array<Musical_pitch> tmp = *add_arr_p;
62 int highest_step = Chord::step_i (tonic, tmp.top ());
67 Musical_pitch* p = &add_arr_p->top ();
74 Array<Musical_pitch> missing_arr = Chord::missing_thirds_pitch_arr (&tmp);
76 missing_arr.push (fifth);
79 if dim modifier is given: lower all missing
83 for (int i=0; i < missing_arr.size (); i++)
85 missing_arr[i].accidental_i_--;
90 if additions include some 3, don't add third
92 Musical_pitch third = Chord::base_arr (tonic)[1];
93 if (Chord::find_notename_i (add_arr_p, third) != -1)
95 int i = Chord::find_pitch_i (&missing_arr, third);
101 if additions include 4, assume sus4 and don't add third implicitely
102 C-sus (4) = c f g (1 4 5)
104 Musical_pitch sus = tonic;
105 sus.transpose (Musical_pitch (3));
106 if (Chord::find_pitch_i (add_arr_p, sus) != -1)
108 int i = Chord::find_pitch_i (&missing_arr, third);
114 if additions include some 5, don't add fifth
116 if (Chord::find_notename_i (add_arr_p, fifth) != -1)
118 int i = Chord::find_pitch_i (&missing_arr, fifth);
125 complete the list of thirds to be added
127 add_arr_p->concat (missing_arr);
128 add_arr_p->sort (Musical_pitch::compare);
130 Array<Musical_pitch> pitch_arr;
132 add all that aren't subtracted
134 for (int i = 0; i < add_arr_p->size (); i++)
136 Musical_pitch p = (*add_arr_p)[i];
138 for (; j < sub_arr_p->size (); j++)
139 if (p == (*sub_arr_p)[j])
145 if (j == sub_arr_p->size ())
149 pitch_arr.sort (Musical_pitch::compare);
151 for (int i = 0; i < sub_arr_p->size (); i++)
152 warning (_f ("invalid subtraction: not part of chord: %s",
153 (*sub_arr_p)[i].str ()));
155 return Chord (pitch_arr, inversion_p, bass_p);
159 Construct from list of pitches and requests
162 to_chord (Array<Musical_pitch> pitch_arr, Tonic_req* tonic_req, Inversion_req* inversion_req, Bass_req* bass_req, bool find_inversion_b)
164 Musical_pitch* inversion_p = 0;
165 Musical_pitch* bass_p = 0;
169 assert (pitch_arr[0].notename_i_ == bass_req->pitch_.notename_i_);
170 bass_p = new Musical_pitch (pitch_arr.get (0));
175 assert (pitch_arr[0].notename_i_ == inversion_req->pitch_.notename_i_);
176 inversion_p = new Musical_pitch (inversion_req->pitch_);
178 int tonic_i = Chord::find_notename_i (&pitch_arr, tonic_req->pitch_);
180 Chord::rebuild_insert_inversion (&pitch_arr, tonic_i);
183 if (find_inversion_b && !inversion_p)
185 int tonic_i = tonic_req
186 ? Chord::find_notename_i (&pitch_arr, tonic_req->pitch_)
187 : Chord::find_tonic_i (&pitch_arr);
191 inversion_p = &pitch_arr[0];
192 Chord::rebuild_insert_inversion (&pitch_arr, tonic_i);
198 assert (pitch_arr[0].notename_i_ == tonic_req->pitch_.notename_i_);
201 return Chord (pitch_arr, inversion_p, bass_p);
204 Chord::Chord (Array<Musical_pitch> pitch_arr, Musical_pitch* inversion_p, Musical_pitch* bass_p)
206 pitch_arr_ = pitch_arr;
207 inversion_p_ = inversion_p;
211 Chord::Chord (Chord const& chord)
214 pitch_arr_ = chord.pitch_arr_;
215 inversion_p_ = chord.inversion_p_ ? new Musical_pitch (*chord.inversion_p_) : 0;
216 bass_p_ = chord.bass_p_ ? new Musical_pitch (*chord.bass_p_) : 0;
223 // AAARGH, why doesn't Score_elt do this?
228 Chord::base_arr (Musical_pitch p)
230 Array<Musical_pitch> base;
232 p.transpose (Musical_pitch (2));
234 p.transpose (Musical_pitch (2, -1));
240 Chord::rebuild_transpose (Array<Musical_pitch>* pitch_arr_p, Musical_pitch tonic, bool fix7_b)
242 for (int i = 0; i < pitch_arr_p->size (); i++)
244 Musical_pitch p = tonic;
245 Musical_pitch q = (*pitch_arr_p)[i];
247 // duh, c7 should mean <c bes>
248 if (fix7_b && (step_i (tonic, p) == 7))
250 (*pitch_arr_p)[i] = p;
252 pitch_arr_p->sort (Musical_pitch::compare);
256 Chord::find_pitch_i (Array<Musical_pitch> const* pitch_arr_p, Musical_pitch p)
258 for (int i = 0; i < pitch_arr_p->size (); i++)
259 if (p == (*pitch_arr_p)[i])
265 Chord::find_notename_i (Array<Musical_pitch> const* pitch_arr_p, Musical_pitch p)
267 int i = find_pitch_i (pitch_arr_p, p);
270 for (int i = 0; i < pitch_arr_p->size (); i++)
272 p.octave_i_ = (*pitch_arr_p)[i].octave_i_;
273 if (p == (*pitch_arr_p)[i])
281 Chord::step_i (Musical_pitch tonic, Musical_pitch p)
283 int i = p.notename_i_ - tonic.notename_i_
284 + (p.octave_i_ - tonic.octave_i_) * 7;
292 Chord::missing_thirds_pitch_arr (Array<Musical_pitch> const* pitch_arr_p)
294 Array<Musical_pitch> thirds;
296 /* is the third c-e, d-f, etc. small or large? */
297 int minormajor_a[] = {0, -1, -1, 0,0,-1,-1};
298 for (int i=0; i < 7; i++)
299 thirds.push (Musical_pitch( 2, minormajor_a[i]));
301 Musical_pitch tonic = (*pitch_arr_p)[0];
302 Musical_pitch last = tonic;
303 Array<Musical_pitch> missing_arr;
305 for (int i = 0; i < pitch_arr_p->size ();)
307 Musical_pitch p = (*pitch_arr_p)[i];
308 int step = step_i (tonic, p);
309 if (last.notename_i_ == p.notename_i_)
310 last.transpose (thirds[(last.notename_i_ - tonic.notename_i_ + 7) % 7]);
311 if (step > step_i (tonic, last))
313 while (step > step_i (tonic, last))
315 if ((last.notename_i_ - tonic.notename_i_ + 7) % 7 == 6)
317 Musical_pitch special_seven = last;
318 Musical_pitch lower (0, -1);
319 special_seven.transpose (lower);
320 missing_arr.push (special_seven);
324 missing_arr.push (last);
326 last.transpose (thirds[(last.notename_i_ - tonic.notename_i_ + 7) % 7]);
339 Mangle into list of pitches.
340 For normal chord entry, inversion and bass pitches are retained in
344 Chord::to_pitch_arr () const
346 Array<Musical_pitch> pitch_arr = pitch_arr_;
350 for (; i < pitch_arr.size (); i++)
352 if ((pitch_arr[i].notename_i_ == inversion_p_->notename_i_)
353 && (pitch_arr[i].accidental_i_ == inversion_p_->accidental_i_))
356 if (i == pitch_arr.size ())
358 warning (_f ("invalid inversion pitch: not part of chord: %s",
359 inversion_p_->str ()));
362 rebuild_with_bass (&pitch_arr, i);
367 pitch_arr.insert (*bass_p_, 0);
368 rebuild_with_bass (&pitch_arr, 0);
374 Chord::find_additions_and_subtractions (Array<Musical_pitch> pitch_arr, Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p) const
376 Musical_pitch tonic = pitch_arr[0];
378 construct an array of thirds for a normal chord
380 Array<Musical_pitch> all_arr;
381 all_arr.push (tonic);
382 if (step_i (tonic, pitch_arr.top ()) >= 5)
383 all_arr.push (pitch_arr.top ());
385 all_arr.push (base_arr (tonic).top ());
386 all_arr.concat (missing_thirds_pitch_arr (&all_arr));
387 all_arr.sort (Musical_pitch::compare);
391 Musical_pitch last_extra = tonic;
392 while ((i < all_arr.size ()) || (j < pitch_arr.size ()))
394 Musical_pitch a = all_arr [i <? all_arr.size () - 1];
395 Musical_pitch p = pitch_arr[j <? pitch_arr.size () - 1];
397 this pitch is present: do nothing, check next
406 found an extra pitch: chord addition
408 else if ((p < a) || (p.notename_i_ == a.notename_i_))
412 (j < pitch_arr.size ()) ? j++ : i++;
415 a third is missing: chord subtraction
419 if (last_extra.notename_i_ != a.notename_i_)
421 (i < all_arr.size ()) ? i++ : j++;
426 /* add missing basic steps */
427 if (step_i (tonic, pitch_arr.top ()) < 3)
428 sub_arr_p->push (base_arr (tonic)[1]);
429 if (step_i (tonic, pitch_arr.top ()) < 5)
430 sub_arr_p->push (base_arr (tonic).top ());
433 add highest addition, because it names chord, if greater than 5
435 (1, 3 and) 5 not additions: part of normal chord
437 if ((step_i (tonic, pitch_arr.top ()) > 5)
438 || pitch_arr.top ().accidental_i_)
439 add_arr_p->push (pitch_arr.top ());
444 word is roman text or styled text:
449 Chord::ly_word2molecule (SCM scm) const
454 style = ly_scm2string (gh_car (scm));
457 String text = ly_scm2string (scm);
458 return lookup_l ()->text (style, text, paper_l ());
462 scm is word or list of words:
467 Chord::ly_text2molecule (SCM scm) const
472 while (gh_cdr (scm) != SCM_EOL)
474 mol.add_at_edge (X_AXIS, RIGHT,
475 ly_word2molecule (gh_car (scm)), 0);
480 mol.add_at_edge (X_AXIS, RIGHT,
481 ly_word2molecule (scm), 0);
486 Chord::pitch2molecule (Musical_pitch p) const
488 SCM name = scm_eval (gh_list (gh_symbol2scm ("user-pitch-name"), ly_quote_scm (pitch2scm (p)), SCM_UNDEFINED));
490 if (name != SCM_UNSPECIFIED)
492 return ly_text2molecule (name);
495 Molecule mol = lookup_l ()->text ("", p.str ().left_str (1).upper_str (), paper_l ());
497 // urg, how to select the feta-1 font?
498 mol.add_at_edge (X_AXIS, RIGHT,
499 lookup_l ()->accidental (p.accidental_i_, 0), 0);
504 diff_pitch (Musical_pitch tonic, Musical_pitch p)
506 Musical_pitch diff (p.notename_i_ - tonic.notename_i_,
507 p.accidental_i_ - tonic.accidental_i_,
508 p.octave_i_ - tonic.octave_i_);
510 while (diff.notename_i_ >= 7)
512 diff.notename_i_ -= 7;
515 while (diff.notename_i_ < 0)
517 diff.notename_i_ += 7;
521 diff.accidental_i_ -= (tonic.semitone_pitch () + diff.semitone_pitch ())
522 - p.semitone_pitch ();
528 Chord::user_chord_name (Array<Musical_pitch> pitch_arr, Chord_name* name_p) const
531 Array<Musical_pitch> chord_type = pitch_arr;
532 rebuild_transpose (&chord_type, diff_pitch (pitch_arr[0], Musical_pitch (0)), false);
534 for (int i= chord_type.size (); i--; )
535 chord = gh_cons (pitch2scm (chord_type[i]), chord);
537 SCM name = scm_eval (gh_list (gh_symbol2scm ("user-chord-name"), ly_quote_scm (chord), SCM_UNDEFINED));
538 if (name != SCM_UNSPECIFIED)
540 name_p->modifier_mol = ly_text2molecule (gh_car (name));
541 name_p->addition_mol = ly_text2molecule (gh_cdr (name));
548 Chord::banter (Array<Musical_pitch> pitch_arr, Chord_name* name_p) const
550 Array<Musical_pitch> add_arr;
551 Array<Musical_pitch> sub_arr;
552 find_additions_and_subtractions (pitch_arr, &add_arr, &sub_arr);
554 Array<Musical_pitch> scale;
555 for (int i=0; i < 7; i++)
556 scale.push (Musical_pitch (i));
558 Musical_pitch tonic = pitch_arr[0];
559 rebuild_transpose (&scale, tonic, true);
562 Does chord include this step? -1 if flat
565 for (int i=0; i<16; i++)
571 for (int i = 0; i < add_arr.size (); i++)
573 Musical_pitch p = add_arr[i];
574 int step = step_i (tonic, p);
575 int accidental = p.accidental_i_ - scale[(step - 1) % 7].accidental_i_;
576 if ((step < 16) && (has[step] != -1))
577 has[step] = accidental == -1 ? -1 : 1;
578 if ((step == 3) && (accidental == -1))
584 This routine gets a lot simpler, if we don't try to be catch
585 the 'dim' chords. However, we'll have to list every exceptional
586 'dim' chord in scm: otherwise we'll get stuff like Cdim7-, iso
590 else if ((step == 5) && (accidental == -1) && (has[3] == -1))
597 || ((i == add_arr.size () - 1) && (step > 5))))
601 if ((step == 7) && (accidental == 1))
608 if ((step % 2) && (accidental == -1)
609 && (has[3] == -1) && (has[5] == -1))
611 if (i != add_arr.size () - 1)
614 add_str += to_str (step);
619 add_str += to_str (step);
621 add_str += accidental < 0 ? "-" : "+";
629 for (int i = 0; i < sub_arr.size (); i++)
631 Musical_pitch p = sub_arr[i];
632 int step = step_i (tonic, p);
634 if additions include 2 or 4, assume sus2/4 and don't display 'no3'
636 if (!((step == 3) && (has[2] || has[4])))
638 add_str += sep_str + "no" + to_str (step);
643 if (mod_str.length_i ())
644 name_p->modifier_mol.add_at_edge (X_AXIS, RIGHT,
645 lookup_l ()->text ("roman", mod_str, paper_l ()), 0);
646 if (add_str.length_i ())
648 if (!name_p->addition_mol.empty_b ())
649 add_str = "/" + add_str;
650 name_p->addition_mol.add_at_edge (X_AXIS, RIGHT,
651 lookup_l ()->text ("script", add_str, paper_l ()), 0);
657 Chord::find_tonic_i (Array<Musical_pitch> const* pitch_arr_p)
662 first try: base of longest line of thirds
666 for (int i = 0; i < pitch_arr_p->size (); i++)
669 int last_i = (*pitch_arr_p)[i % pitch_arr_p->size ()].notename_i_;
671 for (; j < pitch_arr_p->size (); j++)
673 int cur_i = (*pitch_arr_p)[(i + j + 1) % pitch_arr_p->size ()].notename_i_;
674 int gap = cur_i - last_i;
683 if (j - no_third_i > longest_i)
685 longest_i = j - no_third_i;
691 second try: note after biggest gap
696 for (int i = 0; i < pitch_arr_p->size (); i++)
698 int gap = (*pitch_arr_p)[i].notename_i_
699 - (*pitch_arr_p)[(i - 1 + pitch_arr_p->size ())
700 % pitch_arr_p->size ()].notename_i_;
714 Chord::rebuild_from_base (Array<Musical_pitch>* pitch_arr_p, int base_i)
716 assert (base_i >= 0);
717 Musical_pitch last (0, 0, -5);
718 Array<Musical_pitch> new_arr;
719 for (int i = 0; i < pitch_arr_p->size (); i++)
721 Musical_pitch p = (*pitch_arr_p)[(base_i + i) % pitch_arr_p->size ()];
724 p.octave_i_ = last.octave_i_;
731 *pitch_arr_p = new_arr;
735 Chord::rebuild_insert_inversion (Array<Musical_pitch>* pitch_arr_p, int tonic_i)
737 assert (tonic_i > 0);
738 Musical_pitch inversion = pitch_arr_p->get (0);
739 rebuild_from_base (pitch_arr_p, tonic_i - 1);
740 if (pitch_arr_p->size ())
742 inversion.octave_i_ = (*pitch_arr_p)[0].octave_i_ - 1;
743 while (inversion < (*pitch_arr_p)[0])
744 inversion.octave_i_++;
746 for (int i = 0; i < pitch_arr_p->size (); i++)
747 if ((*pitch_arr_p)[i] > inversion)
749 pitch_arr_p->insert (inversion, i);
755 Chord::rebuild_with_bass (Array<Musical_pitch>* pitch_arr_p, int bass_i)
757 assert (bass_i >= 0);
758 Musical_pitch bass = pitch_arr_p->get (bass_i);
759 // is lowering fine, or should others be raised?
760 if (pitch_arr_p->size ())
761 while (bass > (*pitch_arr_p)[0])
763 pitch_arr_p->insert (bass, 0);
767 Chord::do_brew_molecule_p () const
769 Musical_pitch tonic = pitch_arr_[0];
772 name.tonic_mol = pitch2molecule (tonic);
775 if user has explicitely listed chord name, use that
779 maybe we should check all sub-lists of pitches, not
780 just full list and base triad?
782 if (!user_chord_name (pitch_arr_, &name))
785 else, check if user has listed base triad
786 use user base name and add banter for remaining part
788 if ((pitch_arr_.size () > 2)
789 && user_chord_name (pitch_arr_.slice (0, 3), &name))
791 Array<Musical_pitch> base = base_arr (tonic);
792 base.concat (pitch_arr_.slice (3, pitch_arr_.size ()));
793 banter (base, &name);
796 else, use pure banter
800 banter (pitch_arr_, &name);
806 name.inversion_mol = lookup_l ()->text ("", "/", paper_l ());
808 Molecule mol = pitch2molecule (*inversion_p_);
809 name.inversion_mol.add_at_edge (X_AXIS, RIGHT, mol, 0);
814 name.bass_mol = lookup_l ()->text ("", "/", paper_l ());
815 Molecule mol = pitch2molecule (*bass_p_);
816 name.bass_mol.add_at_edge (X_AXIS, RIGHT, mol, 0);
819 // urg, howto get a good superscript_y?
820 Real super_y = lookup_l ()->text ("", "x", paper_l ()).dim_.y ().length ()/2;
821 if (!name.addition_mol.empty_b ())
822 name.addition_mol.translate (Offset (0, super_y));
824 Molecule* mol_p = new Molecule;
825 mol_p->add_at_edge (X_AXIS, RIGHT, name.tonic_mol, 0);
827 if (!name.modifier_mol.empty_b ())
828 mol_p->add_at_edge (X_AXIS, RIGHT, name.modifier_mol, 0);
829 if (!name.addition_mol.empty_b ())
830 mol_p->add_at_edge (X_AXIS, RIGHT, name.addition_mol, 0);
831 if (!name.inversion_mol.empty_b ())
832 mol_p->add_at_edge (X_AXIS, RIGHT, name.inversion_mol, 0);
833 if (!name.bass_mol.empty_b ())
834 mol_p->add_at_edge (X_AXIS, RIGHT, name.bass_mol, 0);
839 Chord::do_print () const
842 //DEBUG_OUT << "chord = " ...