]> git.donarmstrong.com Git - lilypond.git/commitdiff
patch::: 1.1.27.jcn1: koord gefixt
authorJan Nieuwenhuizen <janneke@gnu.org>
Fri, 5 Feb 1999 00:35:34 +0000 (01:35 +0100)
committerJan Nieuwenhuizen <janneke@gnu.org>
Fri, 5 Feb 1999 00:35:34 +0000 (01:35 +0100)
pl 27.jcn1
- complete redo of chord and chord name code
- small fixes

15 files changed:
NEWS
VERSION
input/test/chord-inversion.ly
input/test/chord-preserve.ly
input/test/chord-table.ly
lily/chord-name-engraver.cc
lily/chord.cc
lily/heads-engraver.cc
lily/include/chord-name-engraver.hh
lily/include/chord.hh
lily/include/lily-proto.hh
lily/include/musical-request.hh
lily/include/stem.hh
lily/musical-request.cc
lily/my-lily-parser.cc

diff --git a/NEWS b/NEWS
index 06c9a0038bb70be07c957433edf2e8817b1a9250..944aa057e11e0986b5b8be125068fbf52c59fc87 100644 (file)
--- 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 836eecaad1392a3519e1d54f973d992e5e3078ca..9a0ab9447edbaaa51a0405b77e18eeb60174ca27 100644 (file)
--- 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.
index 543502d4a03b1c7114ac25d97518ac7d28aa5eea..2e06840c5e2a25c735ad01ba371d0234d6d1c00b 100644 (file)
@@ -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
 }
index b7e39981341191eee5397ecf9b05b02389db9425..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -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.;
-       }
-}
index 14c758c52ef9fb8c2c0ba2050555dd30e4c84f88..98174f1cf7d6da52295ac7c3d6e7f38875be06f7 100644 (file)
@@ -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{
index 336eacb3ed4a36437d5485c61e58bc948e86f7b8..95784a44bcfdbbbe74734792b45a43836f0f6f36 100644 (file)
@@ -3,7 +3,7 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 1998 Jan Nieuwenhuizen <janneke@gnu.org>
+  (c) 1998, 1999 Jan Nieuwenhuizen <janneke@gnu.org>
 */
 
 #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<Tonic_req*> (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;
 }
index 26ae4ce2714059b200324da0238a0327321aa83c..c21e30825fca543b4e580c41ed2ca76744d81918 100644 (file)
@@ -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<Musical_pitch> pitch_arr)
 {
   pitch_arr_ = pitch_arr;
 }
 
-// construct from parser output
-// urg: should split this up into understandable chunks
-Chord::Chord (Musical_pitch tonic, Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p, Musical_pitch* inversion_p)
+static void
+rebuild_transpose (Musical_pitch tonic, Array<Musical_pitch>* 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 <c bes>
       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<Musical_pitch> 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<Musical_pitch> 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 <c bes>
-      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<Musical_pitch>
+missing_triads_pitch_arr (Array<Musical_pitch>const* 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<Musical_pitch> triads;
   triads.push (third);   // c e 
@@ -70,49 +84,87 @@ Chord::Chord (Musical_pitch tonic, Array<Musical_pitch>* add_arr_p, Array<Musica
   triads.push (mthird);  // a c 
   triads.push (mthird);  // b d 
 
+  Musical_pitch tonic = (*pitch_arr_p)[0];
+  Musical_pitch last = tonic;
+  Array<Musical_pitch> 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<Musical_pitch>* add_arr_p, Array<Musical_pitch>* 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<Musical_pitch> 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<Musical_pitch>* add_arr_p, Array<Musica
         pitch_arr_.push (p);
     }
 
+  pitch_arr_.sort (Musical_pitch::compare);
+
   for (int i = 0; i < sub_arr_p->size (); 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<Musical_pitch>* add_arr_p, Array<Musica
     {
       int i = 0;
       for (; i < pitch_arr_.size (); i++)
-       if ((pitch_arr_[i].notename_i_ == inversion_p->notename_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<Musical_pitch> 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<Musical_pitch> add_arr;
+  Array<Musical_pitch> sub_arr;
+  int i = 0;
+  int j = 0;
+  while ((i < all_arr.size ()) || (j < pitch_arr_.size ()))
+    {
+      i = i <? all_arr.size () - 1;
+      j = j <? pitch_arr_.size () - 1;
+      Musical_pitch a = all_arr[i];
+      Musical_pitch p = pitch_arr_[j];
+      if (a == p)
+       {
+         i++;
+         j++;
+       }
+      else if ((p < a) || (p.notename_i_ == a.notename_i_))
+       {
+         add_arr.push (p);
+         j++;
+       }
+      else
+       {
+         sub_arr.push (a);
+         i++;
+       }
+    }
+      
+  /*
+    add highest addition, because it names chord
+   */
+  if (trap_i (tonic, pitch_arr_.top () > 5))
+    add_arr.push (pitch_arr_.top ());
+                          
   Array<Musical_pitch> 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<Musical_pitch> 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 ())
index 4e894ba4383d46692e6d7bb8f0f44a4768c29b9a..cd1719260dfb231104bf5efee80d10a656adaed4 100644 (file)
@@ -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 <Note_req *> (req_l))
+  if (Note_req * n =dynamic_cast <Note_req *> (m))
     {
       note_req_l_arr_.push (n);
       return true;
     }
+  if (Tonic_req* t = dynamic_cast<Tonic_req*> (m))
+    {
+      return true;
+    }
   return false;
 }
 
index 233714f017ce578569067613a359a7759555fdfe..4e13194916705fda53ad2b27035130b6d211ada9 100644 (file)
 #include "engraver.hh"
 #include "array.hh"
 #include "musical-pitch.hh"
-
 #include "lily-proto.hh"
 
-Array<Musical_pitch> rebuild_from_base_pitch_arr (Array<Musical_pitch> pitch_arr, int base_i);
-Array<Musical_pitch> rebuild_insert_inversion_pitch_arr (Array<Musical_pitch> pitch_arr, int tonic_i);
-Array<Musical_pitch> rebuild_with_bass_pitch_arr (Array<Musical_pitch> 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<Musical_pitch> pitch_arr_;
   Link_array<Item> text_p_arr_;
-
-  String banter_str (Array<Musical_pitch> pitch_arr, Musical_pitch* inversion) const;
-  int find_tonic_i () const;
   Array<Musical_pitch> rebuild_pitch_arr (int tonic_i) const;
+  Tonic_req* tonic_req_;
 };
 
 #endif // CHORD_NAME_ENGRAVER_HH
index 0fc7601aeb9b3f4b8a098615637e55a8de8bc03b..f43f23b212fb3de466bc90723ee33c46510a778e 100644 (file)
@@ -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<Musical_pitch> pitch_arr_;
-  int tonic_i_;
 };
 
 #endif // CHORD_HH
index 0c600002f8c8258a2c2dcfb94a9227afbb6d6498..bf37e6218903560302f16ea913851a149a051e21 100644 (file)
@@ -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;
index cdc293a5f63dcc8e741c996dd8b6c9500b40af07..3fcf3b9cd60c2e8342b63b36aba2727bf4f5882b 100644 (file)
@@ -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:
index c87555367f6d94ec4367fe325f30f6da362f049f..7e05f77640c0221d43f35188a000598424cc7f3f 100644 (file)
@@ -46,10 +46,10 @@ class Stem : public Item {
     */
   Direction  stem_xdir_;
 
-public:
   Link_array<Note_head> head_l_arr_;
   Link_array<Rest> rest_l_arr_;
     
+public:
   /// how many abbrev beam don't reach stem?
   int beam_gap_i_;
 
index a359be8dfd4072c22b5195eeecdded95ee75518d..b573a4f26476e3a73d300574f8c65ee4b752ddcc 100644 (file)
@@ -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)
 {
index 8cbd830662d8e3b9939d5d73f264b55f505ddb62..6f1809ca7b22baae1c50d9f1ae44a235ad81b2f0 100644 (file)
@@ -154,6 +154,10 @@ My_lily_parser::get_chord (Musical_pitch tonic, Array<Musical_pitch>* 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<Musical_pitch>* add_arr_p,
       v->add_music (n);
     }
 
-  v->set_spot (here_input ());
   return v;
 }