From 422167777039e4d1b8726adf018e1cae36281c9e Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Fri, 5 Feb 1999 01:35:34 +0100 Subject: [PATCH] patch::: 1.1.27.jcn1: koord gefixt pl 27.jcn1 - complete redo of chord and chord name code - small fixes --- NEWS | 4 + VERSION | 2 +- input/test/chord-inversion.ly | 3 +- input/test/chord-preserve.ly | 27 -- input/test/chord-table.ly | 2 +- lily/chord-name-engraver.cc | 41 +-- lily/chord.cc | 375 ++++++++++++++++++---------- lily/heads-engraver.cc | 8 +- lily/include/chord-name-engraver.hh | 18 +- lily/include/chord.hh | 3 +- lily/include/lily-proto.hh | 1 + lily/include/musical-request.hh | 7 + lily/include/stem.hh | 2 +- lily/musical-request.cc | 13 + lily/my-lily-parser.cc | 5 +- 15 files changed, 307 insertions(+), 204 deletions(-) diff --git a/NEWS b/NEWS index 06c9a0038b..944aa057e1 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +pl 27.jcn1 + - complete redo of chord and chord name code + - small fixes + pl 27 (feb 3) pl 26.uu1 diff --git a/VERSION b/VERSION index 836eecaad1..9a0ab9447e 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=1 PATCH_LEVEL=27 -MY_PATCH_LEVEL= +MY_PATCH_LEVEL=jcn1 # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/input/test/chord-inversion.ly b/input/test/chord-inversion.ly index 543502d4a0..2e06840c5e 100644 --- a/input/test/chord-inversion.ly +++ b/input/test/chord-inversion.ly @@ -9,9 +9,8 @@ inversions = \notes\transpose c''\chords{ c1 c-sus c-6 c/e c/g c/d % now try to find chords with inversions \property Score.chordInversion = 1 - \property Score.chordInversionPreserve = 1 c1 c-sus c-6 - c/e % c/e is not found because preserving doesn't work fully yet... + c/e c/g c/d % this triggers a warning: no 'd' in chord of c } diff --git a/input/test/chord-preserve.ly b/input/test/chord-preserve.ly index b7e3998134..e69de29bb2 100644 --- a/input/test/chord-preserve.ly +++ b/input/test/chord-preserve.ly @@ -1,27 +0,0 @@ -koorden = \chords{ - c1-2/d c-2.3/d -} - - -\score{ - < - \property Score.chordInversion = "1" - \type ChordNames { - \property Score.chordInversionPreserve = "0" - \koorden - \property Score.chordInversionPreserve = "1" - \koorden - } - \type Staff \notes\transpose c''{ - \property Score.chordInversionPreserve = "0" - \koorden - % preserving doesn't work for staff yet - % see lily/chord.cc - \property Score.chordInversionPreserve = "1" - \koorden - } - > - \paper{ - linewidth = -1.; - } -} diff --git a/input/test/chord-table.ly b/input/test/chord-table.ly index 14c758c52e..98174f1cf7 100644 --- a/input/test/chord-table.ly +++ b/input/test/chord-table.ly @@ -5,7 +5,7 @@ enteredby = "jcn"; } tab = \notes\transpose c'''\chords{ - c1 c-m c-4 c-m4 c-5+ c-5- c-m5- c-5.5+ c-6\break %c-m6\break + c1 c-m c-4 c-m4 c-5+ c-5- c-m5- c-5-.5+ c-6\break %c-m6\break } \score{ diff --git a/lily/chord-name-engraver.cc b/lily/chord-name-engraver.cc index 336eacb3ed..95784a44bc 100644 --- a/lily/chord-name-engraver.cc +++ b/lily/chord-name-engraver.cc @@ -3,7 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 1998 Jan Nieuwenhuizen + (c) 1998, 1999 Jan Nieuwenhuizen */ #include "chord-name-engraver.hh" @@ -20,6 +20,7 @@ ADD_THIS_TRANSLATOR (Chord_name_engraver); Chord_name_engraver::Chord_name_engraver () { + tonic_req_ = 0; } void @@ -37,6 +38,11 @@ Chord_name_engraver::do_try_music (Music* m) pitch_arr_.push (n->pitch_); return true; } + if (Tonic_req* t = dynamic_cast (m)) + { + tonic_req_ = t; + return true; + } return false; } @@ -48,37 +54,33 @@ Chord_name_engraver::do_process_requests () if (!pitch_arr_.size ()) return; - /* - Banter style chord names (almost). - TODO: - - move this stuff to new Item class Chord_name - - switch on property, add american (?) chordNameStyle - - Scalar chordNameStyle = get_property ("chordNameStyle", 0); - if (chordNameStyle == "Banter") - chord = pitches_to_banter (pitch_arr_)); - - */ - Chord chord (pitch_arr_); Musical_pitch* inversion = 0; Scalar chord_inversion = get_property ("chordInversion", 0); if (chord_inversion.to_bool ()) { - int tonic_i = chord.find_tonic_i (); + int tonic_i = tonic_req_ + ? chord.find_notename_i (tonic_req_->pitch_) : chord.find_tonic_i (); + if (tonic_i) { inversion = &pitch_arr_[0]; - Scalar preserve = get_property ("chordInversionPreserve", 0); - if (preserve.to_bool ()) - chord.rebuild_from_base (tonic_i); - else - chord.rebuild_insert_inversion (tonic_i); + chord.rebuild_insert_inversion (tonic_i); } } G_text_item* item_p = new G_text_item; + /* + TODO: + - switch on property, add american (?) chordNameStyle: + Chord::american_str (...) + + Scalar chordNameStyle = get_property ("chordNameStyle", 0); + if (chordNameStyle == "Banter") + item_p->text_str_ = chord.banter_str (inversion); + */ + item_p->text_str_ = chord.banter_str (inversion); Scalar style = get_property ("textstyle", 0); @@ -98,4 +100,5 @@ Chord_name_engraver::do_pre_move_processing () } text_p_arr_.clear (); pitch_arr_.clear (); + tonic_req_ = 0; } diff --git a/lily/chord.cc b/lily/chord.cc index 26ae4ce271..c21e30825f 100644 --- a/lily/chord.cc +++ b/lily/chord.cc @@ -9,57 +9,71 @@ #include "chord.hh" #include "warn.hh" +// doesn't seem common, and we should know about this during purple hit +// #define INVERSION_ADDED_AS_BASE 1 + Chord::Chord (Array pitch_arr) { pitch_arr_ = pitch_arr; } -// construct from parser output -// urg: should split this up into understandable chunks -Chord::Chord (Musical_pitch tonic, Array* add_arr_p, Array* sub_arr_p, Musical_pitch* inversion_p) +static void +rebuild_transpose (Musical_pitch tonic, Array* pitch_arr_p) { - for (int i = 0; i < add_arr_p->size (); i++) + for (int i = 0; i < pitch_arr_p->size (); i++) { Musical_pitch p = tonic; - Musical_pitch q = (*add_arr_p)[i]; + Musical_pitch q = (*pitch_arr_p)[i]; // duh, c7 should mean if (q.notename_i_ == 6) q.accidental_i_--; p.transpose (q); - (*add_arr_p)[i] = p; + (*pitch_arr_p)[i] = p; } - add_arr_p->sort (Musical_pitch::compare); - for (int i = 0; i < sub_arr_p->size (); i++) + pitch_arr_p->sort (Musical_pitch::compare); +} + +static int +find_pitch_i (Array const* pitch_arr_p, Musical_pitch p) +{ + for (int i = 0; i < pitch_arr_p->size (); i++) + if (p == (*pitch_arr_p)[i]) + return i; + return -1; +} + +static int +find_notename_i (Array const* pitch_arr_p, Musical_pitch p) +{ + int i = find_pitch_i (pitch_arr_p, p); + if (i == -1) { - Musical_pitch p = tonic; - Musical_pitch q = (*sub_arr_p)[i]; - // duh, c7 should mean - if (q.notename_i_ == 6) - q.accidental_i_--; - p.transpose (q); - (*sub_arr_p)[i] = p; + for (int i = 0; i < pitch_arr_p->size (); i++) + { + p.octave_i_ = (*pitch_arr_p)[i].octave_i_; + if (p == (*pitch_arr_p)[i]) + return i; + } } - sub_arr_p->sort (Musical_pitch::compare); + return i; +} +static int +trap_i (Musical_pitch tonic, Musical_pitch p) +{ + int i = p.notename_i_ - tonic.notename_i_ + + (p.octave_i_ - tonic.octave_i_) * 7; + while (i < 0) + i += 7; + i++; + return i; +} + +static Array +missing_triads_pitch_arr (Arrayconst* pitch_arr_p) +{ Musical_pitch third (2); Musical_pitch mthird (2, -1); - Musical_pitch missing; - missing = tonic; - missing.transpose (third); - - Musical_pitch p; - p = tonic; - p.transpose (third); - p.transpose (mthird); - - /* - must have minimum at 5 (3 is added automatically as missing) - */ - if (!add_arr_p->size ()) - add_arr_p->push (p); - else if ((add_arr_p->top () < p) && (add_arr_p->top ().notename_i_ != p.notename_i_)) - add_arr_p->push (p); - add_arr_p->sort (Musical_pitch::compare); Array triads; triads.push (third); // c e @@ -70,49 +84,87 @@ Chord::Chord (Musical_pitch tonic, Array* add_arr_p, Array missing_arr; + + for (int i = 0; i < pitch_arr_p->size ();) + { + Musical_pitch p = (*pitch_arr_p)[i]; + int trap = trap_i (tonic, p); + if (last.notename_i_ == p.notename_i_) + last.transpose (triads[(last.notename_i_ - tonic.notename_i_ + 7) % 7]); + if (trap > trap_i (tonic, last)) + { + while (trap > trap_i (tonic, last)) + { + if ((last.notename_i_ - tonic.notename_i_ + 7) % 7 == 6) + { + Musical_pitch special_seven = last; + Musical_pitch lower (0, -1); + special_seven.transpose (lower); + missing_arr.push (special_seven); + } + else + { + missing_arr.push (last); + } + last.transpose (triads[(last.notename_i_ - tonic.notename_i_ + 7) % 7]); + } + } + else + { + i++; + } + } + return missing_arr; +} + + +/* + construct from parser output +*/ +Chord::Chord (Musical_pitch tonic, Array* add_arr_p, Array* sub_arr_p, Musical_pitch* inversion_p) +{ + rebuild_transpose (tonic, add_arr_p); + rebuild_transpose (tonic, sub_arr_p); + + Musical_pitch fifth = tonic; + fifth.transpose (Musical_pitch (2)); + fifth.transpose (Musical_pitch (2, -1)); + /* - if first addition is 4, assume sus4 and don't add third implicitely + default chord includes upto 5: <1, 3, 5> */ - Musical_pitch sus (3); - sus.transpose (tonic); - if (add_arr_p->size ()) - if ((*add_arr_p)[0] == sus) - missing.transpose (mthird); + add_arr_p->insert (tonic, 0); + int highest_trap = trap_i (tonic, add_arr_p->top ()); + if (highest_trap < 5) + add_arr_p->push (fifth); /* - add missing triads + find missing triads */ - for (int i = 0; i < add_arr_p->size ();) + Array missing_arr = missing_triads_pitch_arr (add_arr_p); + + /* + if additions include 4, assume sus4 and don't add third implicitely + */ + Musical_pitch third = tonic; + third.transpose (Musical_pitch (2)); + Musical_pitch sus = tonic; + sus.transpose (Musical_pitch (3)); + if (::find_pitch_i (add_arr_p, sus) != -1) { - Musical_pitch p = (*add_arr_p)[i]; - if (p > missing) - while (p > missing) - { - if (p.notename_i_ != missing.notename_i_) - { - if ((missing.notename_i_ - tonic.notename_i_ + 7) % 7 == 6) - { - Musical_pitch special_seven = missing; - Musical_pitch lower (0, -1); - special_seven.transpose (lower); - add_arr_p->insert (special_seven, i++); - } - else - add_arr_p->insert (missing, i++); - } - missing.transpose (triads[(missing.notename_i_ - tonic.notename_i_ + 7) % 7]); - } - else if (p.notename_i_ == missing.notename_i_) - missing.transpose (triads[(missing.notename_i_ - tonic.notename_i_ + 7) % 7]); - else - i++; + int i = ::find_pitch_i (&missing_arr, third); + if (i != -1) + missing_arr.get (i); } - + /* - add tonic + complete the list of triads to be added */ - if (!add_arr_p->size () || ((*add_arr_p)[0] != tonic)) - add_arr_p->insert (tonic, 0); + add_arr_p->concat (missing_arr); + add_arr_p->sort (Musical_pitch::compare); /* add all that aren't subtracted @@ -132,6 +184,8 @@ Chord::Chord (Musical_pitch tonic, Array* add_arr_p, Arraysize (); i++) warning (_f ("invalid subtraction: not part of chord: %s", (*sub_arr_p)[i].str ())); @@ -140,32 +194,25 @@ Chord::Chord (Musical_pitch tonic, Array* add_arr_p, Arraynotename_i_) - && (pitch_arr_[i].accidental_i_ == inversion_p->accidental_i_)) - break; + { + if ((pitch_arr_[i].notename_i_ == inversion_p->notename_i_) + && (pitch_arr_[i].accidental_i_ == inversion_p->accidental_i_)) + break; + } if (i == pitch_arr_.size ()) - warning (_f ("invalid inversion pitch: not part of chord: %s", - inversion_p->str ())); + { + warning (_f ("invalid inversion pitch: not part of chord: %s", + inversion_p->str ())); + } else - { - /* - urg - should be run-time switchable "chordInversionPreserve", howto? - - there are two ways commonly used to rearrange a chord with - an inversion: - - 1. rebuild pitch list, taking inversion as base - */ -#if 0 - rebuild_from_base (i); + { +#if INVERSION_ADDED_AS_BASE + pitch_arr_.insert (pitch_arr_[i], 0); + rebuild_with_bass (0); #else - /* - or - 2. insert inversion as lowest (at first position) - */ rebuild_with_bass (i); #endif + } delete inversion_p; } @@ -176,6 +223,54 @@ Chord::banter_str (Musical_pitch* inversion) const { Musical_pitch tonic = pitch_arr_[0]; + //urg, should do translation in scheme. + char const *acc[] = {"\\textflat\\textflat ", "\\textflat ", "", "\\textsharp " , "\\textsharp\\textsharp "}; + String tonic_str = tonic.str (); + tonic_str = tonic_str.left_str (1).upper_str () + + acc[tonic.accidental_i_ + 2]; + + /* + all the triads that should be there + */ + Array all_arr; + all_arr.push (tonic); + all_arr.push (pitch_arr_.top ()); + all_arr.concat (missing_triads_pitch_arr (&all_arr)); + all_arr.sort (Musical_pitch::compare); + + Array add_arr; + Array sub_arr; + int i = 0; + int j = 0; + while ((i < all_arr.size ()) || (j < pitch_arr_.size ())) + { + i = i 5)) + add_arr.push (pitch_arr_.top ()); + Array scale; scale.push (Musical_pitch (0)); // c scale.push (Musical_pitch (1)); // d @@ -185,64 +280,54 @@ Chord::banter_str (Musical_pitch* inversion) const scale.push (Musical_pitch (5)); // a // 7 always means 7-... scale.push (Musical_pitch (6, -1)); // b - - - for (int i = 0; i < scale.size (); i++) - scale[i].transpose (tonic); - - //urg, should do translation in scheme. - char const *acc[] = {"\\textflat\\textflat ", "\\textflat ", "", "\\textsharp " , "\\textsharp\\textsharp "}; - String tonic_str = tonic.str (); - tonic_str = tonic_str.left_str (1).upper_str () - + acc[tonic.accidental_i_ + 2]; - - String add_str; - String sub_str; + + bool has3m_b = false; + bool has4_b = false; + String str; String sep_str; - String sub_sep_str; - int last_trap = 1; - for (int i=1; i < pitch_arr_.size (); i++) + for (int i = 0; i < add_arr.size (); i++) { - Musical_pitch p = pitch_arr_[i]; - int trap = p.notename_i_ - tonic.notename_i_ - + (p.octave_i_ - tonic.octave_i_) * 7; - while (trap < 0) - trap += 7; - trap++; - while (trap - last_trap > 2) - { - last_trap += 2; - sub_str += sub_sep_str + "no" + to_str (last_trap); - sub_sep_str = "/"; - } - last_trap = trap; + Musical_pitch p = add_arr[i]; + int trap = trap_i (tonic, p); + if (trap == 4) + has4_b = true; int accidental = p.accidental_i_ - scale[(trap - 1) % 7].accidental_i_; if ((trap == 3) && (accidental == -1)) - tonic_str += "m"; // hmm - else if (accidental || (!(trap % 2) || ((i + 1 == pitch_arr_.size ()) && (trap > 5)))) + { + tonic_str += "m"; + has3m_b = true; + } + else if (accidental + || (!(trap % 2) || ((i + 1 == add_arr.size ()) && (trap > 5)))) { - add_str += sep_str; + str += sep_str; if ((trap == 7) && (accidental == 1)) - add_str += "maj7"; + str += "maj7"; else { - add_str += to_str (trap); + str += to_str (trap); if (accidental) - add_str += accidental < 0 ? "-" : "+"; - // catch "C4/no3"; remove "no3" - if (trap == 4) - { - int i = sub_str.index_i ("no3"); - if (i != -1) - sub_str = sub_str.nomid_str (i, 3); - if (!sub_str.length_i ()) - sub_sep_str = ""; - } + str += accidental < 0 ? "-" : "+"; } sep_str = "/"; } } + for (int i = 0; i < sub_arr.size (); i++) + { + Musical_pitch p = sub_arr[i]; + int trap = trap_i (tonic, p); + /* + if chord has 3-, assume minor and don't display 'no3' + if additions include 4, assume sus4 and don't display 'no3' + */ + if (!((trap == 3) && (has3m_b || has4_b))) + { + str += sep_str + "no" + to_str (trap); + sep_str = "/"; + } + } + String inversion_str; if (inversion) { @@ -252,10 +337,19 @@ Chord::banter_str (Musical_pitch* inversion) const } - if (sub_str.length_i ()) - sub_str = sep_str + sub_str; - String str = tonic_str + "$^{" + add_str + sub_str + "}$" + inversion_str; - return str; + return tonic_str + "$^{" + str + "}$" + inversion_str; +} + +int +Chord::find_notename_i (Musical_pitch p) const +{ + return ::find_notename_i (&pitch_arr_, p); +} + +int +Chord::find_pitch_i (Musical_pitch p) const +{ + return ::find_pitch_i (&pitch_arr_, p); } int @@ -318,6 +412,7 @@ Chord::find_tonic_i () const void Chord::rebuild_from_base (int base_i) { + assert (base_i >= 0); Musical_pitch last (0, 0, -5); Array new_arr; for (int i = 0; i < pitch_arr_.size (); i++) @@ -338,6 +433,12 @@ Chord::rebuild_from_base (int base_i) void Chord::rebuild_insert_inversion (int tonic_i) { + assert (tonic_i > 0); +#if INVERSION_ADDED_AS_BASE + // inversion was added; don't insert + Musical_pitch inversion = pitch_arr_.get (0); + (void)inversion; +#else Musical_pitch inversion = pitch_arr_.get (0); rebuild_from_base (tonic_i - 1); if (pitch_arr_.size ()) @@ -352,11 +453,13 @@ Chord::rebuild_insert_inversion (int tonic_i) pitch_arr_.insert (inversion, i); break; } +#endif } void Chord::rebuild_with_bass (int bass_i) { + assert (bass_i >= 0); Musical_pitch inversion = pitch_arr_.get (bass_i); // is lowering fine, or should others be raised? if (pitch_arr_.size ()) diff --git a/lily/heads-engraver.cc b/lily/heads-engraver.cc index 4e894ba438..cd1719260d 100644 --- a/lily/heads-engraver.cc +++ b/lily/heads-engraver.cc @@ -16,13 +16,17 @@ Note_heads_engraver::Note_heads_engraver() } bool -Note_heads_engraver::do_try_music (Music *req_l) +Note_heads_engraver::do_try_music (Music *m) { - if (Note_req * n =dynamic_cast (req_l)) + if (Note_req * n =dynamic_cast (m)) { note_req_l_arr_.push (n); return true; } + if (Tonic_req* t = dynamic_cast (m)) + { + return true; + } return false; } diff --git a/lily/include/chord-name-engraver.hh b/lily/include/chord-name-engraver.hh index 233714f017..4e13194916 100644 --- a/lily/include/chord-name-engraver.hh +++ b/lily/include/chord-name-engraver.hh @@ -12,33 +12,25 @@ #include "engraver.hh" #include "array.hh" #include "musical-pitch.hh" - #include "lily-proto.hh" -Array rebuild_from_base_pitch_arr (Array pitch_arr, int base_i); -Array rebuild_insert_inversion_pitch_arr (Array pitch_arr, int tonic_i); -Array rebuild_with_bass_pitch_arr (Array pitch_arr, int bass_i); - - class Chord_name_engraver : public Engraver { +public: + Chord_name_engraver (); + VIRTUAL_COPY_CONS (Translator); + protected: virtual void do_pre_move_processing (); virtual void acknowledge_element (Score_element_info i); virtual void do_process_requests (); virtual bool do_try_music (Music* m); -public: - Chord_name_engraver (); - VIRTUAL_COPY_CONS (Translator); - private: Array pitch_arr_; Link_array text_p_arr_; - - String banter_str (Array pitch_arr, Musical_pitch* inversion) const; - int find_tonic_i () const; Array rebuild_pitch_arr (int tonic_i) const; + Tonic_req* tonic_req_; }; #endif // CHORD_NAME_ENGRAVER_HH diff --git a/lily/include/chord.hh b/lily/include/chord.hh index 0fc7601aeb..f43f23b212 100644 --- a/lily/include/chord.hh +++ b/lily/include/chord.hh @@ -25,9 +25,10 @@ public: String banter_str (Musical_pitch* inversion) const; int find_tonic_i () const; + int find_pitch_i (Musical_pitch p) const; + int find_notename_i (Musical_pitch p) const; Array pitch_arr_; - int tonic_i_; }; #endif // CHORD_HH diff --git a/lily/include/lily-proto.hh b/lily/include/lily-proto.hh index 0c600002f8..bf37e62189 100644 --- a/lily/include/lily-proto.hh +++ b/lily/include/lily-proto.hh @@ -251,6 +251,7 @@ struct Time_signature; struct Time_signature_change_req; struct Time_signature_engraver; struct Time_signature_performer; +struct Tonic_req; struct Translator; struct Translator_group; struct Timing_req; diff --git a/lily/include/musical-request.hh b/lily/include/musical-request.hh index cdc293a5f6..3fcf3b9cd6 100644 --- a/lily/include/musical-request.hh +++ b/lily/include/musical-request.hh @@ -88,6 +88,13 @@ struct Melodic_req :virtual Musical_req REQUESTMETHODS(Melodic_req); }; +/// specify tonic of a chord +struct Tonic_req : public Melodic_req +{ + Tonic_req (); + REQUESTMETHODS(Tonic_req); +}; + /// Put a note of specified type, height, and with accidental on the staff. class Note_req : public Rhythmic_req, virtual public Melodic_req { public: diff --git a/lily/include/stem.hh b/lily/include/stem.hh index c87555367f..7e05f77640 100644 --- a/lily/include/stem.hh +++ b/lily/include/stem.hh @@ -46,10 +46,10 @@ class Stem : public Item { */ Direction stem_xdir_; -public: Link_array head_l_arr_; Link_array rest_l_arr_; +public: /// how many abbrev beam don't reach stem? int beam_gap_i_; diff --git a/lily/musical-request.cc b/lily/musical-request.cc index a359be8dfd..b573a4f264 100644 --- a/lily/musical-request.cc +++ b/lily/musical-request.cc @@ -120,6 +120,19 @@ Melodic_req::do_print () const pitch_.print (); } + +Tonic_req::Tonic_req () +{ +} + +void +Tonic_req::do_print () const +{ +#ifndef NPRINT + Melodic_req::do_print (); +#endif +} + int Rhythmic_req::compare (Rhythmic_req const &r1, Rhythmic_req const &r2) { diff --git a/lily/my-lily-parser.cc b/lily/my-lily-parser.cc index 8cbd830662..6f1809ca7b 100644 --- a/lily/my-lily-parser.cc +++ b/lily/my-lily-parser.cc @@ -154,6 +154,10 @@ My_lily_parser::get_chord (Musical_pitch tonic, Array* add_arr_p, Chord chord (tonic, add_arr_p, sub_arr_p, inversion_p); + Tonic_req* t = new Tonic_req; + t->pitch_ = tonic; + v->add_music (t); + for (int i = 0; i < chord.pitch_arr_.size (); i++) { Musical_pitch p = chord.pitch_arr_[i]; @@ -163,7 +167,6 @@ My_lily_parser::get_chord (Musical_pitch tonic, Array* add_arr_p, v->add_music (n); } - v->set_spot (here_input ()); return v; } -- 2.39.5