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 (ly_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 ());
498 We want the smaller size, even if we're big ourselves.
501 mol.add_at_edge (X_AXIS, RIGHT,
503 paper_l ()->lookup_l (-2)->afm_find (String ("accidentals-") + to_str (p.accidental_i_)), 0.0);
508 diff_pitch (Musical_pitch tonic, Musical_pitch p)
510 Musical_pitch diff (p.notename_i_ - tonic.notename_i_,
511 p.accidental_i_ - tonic.accidental_i_,
512 p.octave_i_ - tonic.octave_i_);
514 while (diff.notename_i_ >= 7)
516 diff.notename_i_ -= 7;
519 while (diff.notename_i_ < 0)
521 diff.notename_i_ += 7;
525 diff.accidental_i_ -= (tonic.semitone_pitch () + diff.semitone_pitch ())
526 - p.semitone_pitch ();
532 Chord::user_chord_name (Array<Musical_pitch> pitch_arr, Chord_name* name_p) const
535 Array<Musical_pitch> chord_type = pitch_arr;
536 rebuild_transpose (&chord_type, diff_pitch (pitch_arr[0], Musical_pitch (0)), false);
538 for (int i= chord_type.size (); i--; )
539 chord = gh_cons (pitch2scm (chord_type[i]), chord);
541 SCM name = scm_eval (gh_list (ly_symbol2scm ("user-chord-name"), ly_quote_scm (chord), SCM_UNDEFINED));
542 if (name != SCM_UNSPECIFIED)
544 name_p->modifier_mol = ly_text2molecule (gh_car (name));
545 name_p->addition_mol = ly_text2molecule (gh_cdr (name));
552 Chord::banter (Array<Musical_pitch> pitch_arr, Chord_name* name_p) const
554 Array<Musical_pitch> add_arr;
555 Array<Musical_pitch> sub_arr;
556 find_additions_and_subtractions (pitch_arr, &add_arr, &sub_arr);
558 Array<Musical_pitch> scale;
559 for (int i=0; i < 7; i++)
560 scale.push (Musical_pitch (i));
562 Musical_pitch tonic = pitch_arr[0];
563 rebuild_transpose (&scale, tonic, true);
566 Does chord include this step? -1 if flat
569 for (int i=0; i<16; i++)
575 for (int i = 0; i < add_arr.size (); i++)
577 Musical_pitch p = add_arr[i];
578 int step = step_i (tonic, p);
579 int accidental = p.accidental_i_ - scale[(step - 1) % 7].accidental_i_;
580 if ((step < 16) && (has[step] != -1))
581 has[step] = accidental == -1 ? -1 : 1;
582 // only from guile table ?
583 if ((step == 3) && (accidental == -1))
589 || ((i == add_arr.size () - 1) && (step > 5))))
593 if ((step == 7) && (accidental == 1))
599 add_str += to_str (step);
601 add_str += accidental < 0 ? "-" : "+";
606 for (int i = 0; i < sub_arr.size (); i++)
608 Musical_pitch p = sub_arr[i];
609 int step = step_i (tonic, p);
611 if additions include 2 or 4, assume sus2/4 and don't display 'no3'
613 if (!((step == 3) && (has[2] || has[4])))
615 add_str += sep_str + "no" + to_str (step);
620 if (mod_str.length_i ())
621 name_p->modifier_mol.add_at_edge (X_AXIS, RIGHT,
622 lookup_l ()->text ("roman", mod_str, paper_l ()), 0);
623 if (add_str.length_i ())
625 if (!name_p->addition_mol.empty_b ())
626 add_str = "/" + add_str;
627 name_p->addition_mol.add_at_edge (X_AXIS, RIGHT,
628 lookup_l ()->text ("script", add_str, paper_l ()), 0);
633 This routine tries to guess tonic in a possibly inversed chord, ie
634 <e g c'> should produce: C.
635 This is only used for chords that are entered as simultaneous notes,
636 chords entered in \chord mode are fully defined.
639 Chord::find_tonic_i (Array<Musical_pitch> const* pitch_arr_p)
644 first try: base of longest line of thirds
648 for (int i = 0; i < pitch_arr_p->size (); i++)
651 int last_i = (*pitch_arr_p)[i % pitch_arr_p->size ()].notename_i_;
653 for (; j < pitch_arr_p->size (); j++)
655 int cur_i = (*pitch_arr_p)[(i + j + 1) % pitch_arr_p->size ()].notename_i_;
656 int gap = cur_i - last_i;
665 if (j - no_third_i > longest_i)
667 longest_i = j - no_third_i;
673 second try: note after biggest gap
678 for (int i = 0; i < pitch_arr_p->size (); i++)
680 int gap = (*pitch_arr_p)[i].notename_i_
681 - (*pitch_arr_p)[(i - 1 + pitch_arr_p->size ())
682 % pitch_arr_p->size ()].notename_i_;
696 Chord::rebuild_from_base (Array<Musical_pitch>* pitch_arr_p, int base_i)
698 assert (base_i >= 0);
699 Musical_pitch last (0, 0, -5);
700 Array<Musical_pitch> new_arr;
701 for (int i = 0; i < pitch_arr_p->size (); i++)
703 Musical_pitch p = (*pitch_arr_p)[(base_i + i) % pitch_arr_p->size ()];
706 p.octave_i_ = last.octave_i_;
713 *pitch_arr_p = new_arr;
717 Chord::rebuild_insert_inversion (Array<Musical_pitch>* pitch_arr_p, int tonic_i)
719 assert (tonic_i > 0);
720 Musical_pitch inversion = pitch_arr_p->get (0);
721 rebuild_from_base (pitch_arr_p, tonic_i - 1);
722 if (pitch_arr_p->size ())
724 inversion.octave_i_ = (*pitch_arr_p)[0].octave_i_ - 1;
725 while (inversion < (*pitch_arr_p)[0])
726 inversion.octave_i_++;
728 for (int i = 0; i < pitch_arr_p->size (); i++)
729 if ((*pitch_arr_p)[i] > inversion)
731 pitch_arr_p->insert (inversion, i);
737 Chord::rebuild_with_bass (Array<Musical_pitch>* pitch_arr_p, int bass_i)
739 assert (bass_i >= 0);
740 Musical_pitch bass = pitch_arr_p->get (bass_i);
741 // is lowering fine, or should others be raised?
742 if (pitch_arr_p->size ())
743 while (bass > (*pitch_arr_p)[0])
745 pitch_arr_p->insert (bass, 0);
749 Chord::do_brew_molecule_p () const
751 Musical_pitch tonic = pitch_arr_[0];
754 name.tonic_mol = pitch2molecule (tonic);
757 if user has explicitely listed chord name, use that
761 maybe we should check all sub-lists of pitches, not
762 just full list and base triad?
764 if (!user_chord_name (pitch_arr_, &name))
767 else, check if user has listed base triad
768 use user base name and add banter for remaining part
770 if ((pitch_arr_.size () > 2)
771 && user_chord_name (pitch_arr_.slice (0, 3), &name))
773 Array<Musical_pitch> base = base_arr (tonic);
774 base.concat (pitch_arr_.slice (3, pitch_arr_.size ()));
775 banter (base, &name);
778 else, use pure banter
782 banter (pitch_arr_, &name);
788 name.inversion_mol = lookup_l ()->text ("", "/", paper_l ());
790 Molecule mol = pitch2molecule (*inversion_p_);
791 name.inversion_mol.add_at_edge (X_AXIS, RIGHT, mol, 0);
796 name.bass_mol = lookup_l ()->text ("", "/", paper_l ());
797 Molecule mol = pitch2molecule (*bass_p_);
798 name.bass_mol.add_at_edge (X_AXIS, RIGHT, mol, 0);
801 // urg, howto get a good superscript_y?
802 Real super_y = lookup_l ()->text ("", "x", paper_l ()).dim_.y ().length ()/2;
803 if (!name.addition_mol.empty_b ())
804 name.addition_mol.translate (Offset (0, super_y));
806 Molecule* mol_p = new Molecule;
807 mol_p->add_at_edge (X_AXIS, RIGHT, name.tonic_mol, 0);
809 if (!name.modifier_mol.empty_b ())
810 mol_p->add_at_edge (X_AXIS, RIGHT, name.modifier_mol, 0);
811 if (!name.addition_mol.empty_b ())
812 mol_p->add_at_edge (X_AXIS, RIGHT, name.addition_mol, 0);
813 if (!name.inversion_mol.empty_b ())
814 mol_p->add_at_edge (X_AXIS, RIGHT, name.inversion_mol, 0);
815 if (!name.bass_mol.empty_b ())
816 mol_p->add_at_edge (X_AXIS, RIGHT, name.bass_mol, 0);
821 Chord::do_print () const
824 //DEBUG_OUT << "chord = " ...