]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/chord.cc
release: 1.3.14
[lilypond.git] / lily / chord.cc
index 867add9c73235cee71b597822b330ae05c5aa5d2..89d4c4590ede0f1299db3c0a6be06477a4806cbd 100644 (file)
 */
 
 #include "chord.hh"
+#include "musical-request.hh"
 #include "warn.hh"
+#include "debug.hh"
+#include "molecule.hh"
+#include "paper-def.hh"
+#include "lookup.hh"
 
-// doesn't seem common, and we should know about this during parsing
-// #define INVERSION_ADDED_AS_BASE 1
 
-Chord::Chord (Array<Musical_pitch> pitch_arr)
+/*
+  construct from parser output
+*/
+Chord
+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)
+{
+  // urg: catch dim modifier: 3rd, 5th, 7th, .. should be lowered
+  bool dim_b = false;
+  for (int i=0; i < add_arr_p->size (); i++)
+    {
+      Musical_pitch* p = &(*add_arr_p)[i];
+      if (p->octave_i_ == -100)
+        {
+          p->octave_i_ = 0;
+         dim_b = true;
+       }
+    }
+  Chord::rebuild_transpose (add_arr_p, tonic, true);
+  Chord::rebuild_transpose (sub_arr_p, tonic, true);
+
+  Musical_pitch fifth = Chord::base_arr (tonic).top ();
+
+  /*
+    remove double adds (urg: sus4)
+   */
+  for (int i = add_arr_p->size () - 1; i >= 0 ; i--)
+    {
+      int j = Chord::find_pitch_i (add_arr_p, (*add_arr_p)[i]);
+      if ((j != -1) && (i != j))
+        {
+           add_arr_p->get (i);
+       } 
+    }
+
+  /*
+    default chord includes upto 5: <1, 3, 5>
+   */
+  add_arr_p->insert (tonic, 0);
+  Array<Musical_pitch> tmp = *add_arr_p;
+  int highest_step = Chord::step_i (tonic, tmp.top ());
+  if (highest_step < 5)
+    tmp.push (fifth);
+  else if (dim_b)
+    {
+      Musical_pitch* p = &add_arr_p->top ();
+      p->accidental_i_--;
+    }
+
+  /*
+    find missing thirds
+   */
+  Array<Musical_pitch> missing_arr = Chord::missing_thirds_pitch_arr (&tmp);
+  if (highest_step < 5)
+    missing_arr.push (fifth);
+
+  /*
+    if dim modifier is given: lower all missing
+   */
+  if (dim_b)
+    {
+      for (int i=0; i < missing_arr.size (); i++)
+        {
+         missing_arr[i].accidental_i_--;
+       }
+    }
+
+  /*
+    if additions include some 3, don't add third
+   */
+  Musical_pitch third = Chord::base_arr (tonic)[1];
+  if (Chord::find_notename_i (add_arr_p, third) != -1)
+    {
+      int i = Chord::find_pitch_i (&missing_arr, third);
+      if (i != -1)
+       missing_arr.get (i);
+    }
+  
+  /*
+    if additions include 4, assume sus4 and don't add third implicitely
+     C-sus (4) = c f g (1 4 5)
+   */
+  Musical_pitch sus = tonic;
+  sus.transpose (Musical_pitch (3));
+  if (Chord::find_pitch_i (add_arr_p, sus) != -1)
+    {
+      int i = Chord::find_pitch_i (&missing_arr, third);
+      if (i != -1)
+       missing_arr.get (i);
+    }
+
+  /*
+    if additions include some 5, don't add fifth
+   */
+  if (Chord::find_notename_i (add_arr_p, fifth) != -1)
+    {
+      int i = Chord::find_pitch_i (&missing_arr, fifth);
+      if (i != -1)
+       missing_arr.get (i);
+    }
+  
+  
+  /*
+    complete the list of thirds to be added
+   */
+  add_arr_p->concat (missing_arr);
+  add_arr_p->sort (Musical_pitch::compare);
+
+  Array<Musical_pitch> pitch_arr;
+  /*
+   add all that aren't subtracted
+   */
+  for (int i = 0; i < add_arr_p->size (); i++)
+    {
+      Musical_pitch p = (*add_arr_p)[i];
+      int j = 0;
+      for (; j < sub_arr_p->size (); j++)
+       if (p == (*sub_arr_p)[j])
+         {
+           sub_arr_p->del (j);
+           j = -1;
+           break;
+         }
+      if (j == sub_arr_p->size ())
+       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 ()));
+  return Chord (pitch_arr, inversion_p, bass_p);
+}
+
+/*
+  Construct from list of pitches and requests
+ */
+Chord
+to_chord (Array<Musical_pitch> pitch_arr, Tonic_req* tonic_req, Inversion_req* inversion_req, Bass_req* bass_req, bool find_inversion_b)
+{
+  Musical_pitch* inversion_p = 0;
+  Musical_pitch* bass_p = 0;
+
+  if (bass_req)
+    {
+      assert (pitch_arr[0].notename_i_ == bass_req->pitch_.notename_i_);
+      bass_p = new Musical_pitch (pitch_arr.get (0));
+    }
+    
+  if (inversion_req)
+    {
+      assert (pitch_arr[0].notename_i_ == inversion_req->pitch_.notename_i_);
+      inversion_p = new Musical_pitch (inversion_req->pitch_);
+      assert (tonic_req);
+      int tonic_i = Chord::find_notename_i (&pitch_arr, tonic_req->pitch_);
+      if (tonic_i)
+       Chord::rebuild_insert_inversion (&pitch_arr, tonic_i);
+    }
+    
+  if (find_inversion_b && !inversion_p)
+    {
+      int tonic_i = tonic_req
+       ? Chord::find_notename_i (&pitch_arr, tonic_req->pitch_) 
+       : Chord::find_tonic_i (&pitch_arr);
+       
+      if (tonic_i)
+       {
+         inversion_p = &pitch_arr[0];
+         Chord::rebuild_insert_inversion (&pitch_arr, tonic_i);
+       }
+    }
+
+  if (tonic_req)
+    {
+      assert (pitch_arr[0].notename_i_ == tonic_req->pitch_.notename_i_);
+    }
+
+  return Chord (pitch_arr, inversion_p, bass_p);
+}
+
+Chord::Chord ()
+{
+  inversion_b_ = false;
+  bass_b_ = false;
+}
+
+Chord::Chord (Array<Musical_pitch> pitch_arr, Musical_pitch* inversion_p, Musical_pitch* bass_p)
 {
   pitch_arr_ = pitch_arr;
+  inversion_b_ = false;
+  bass_b_ = false;
+  if (inversion_p)
+    {
+      inversion_pitch_ = *inversion_p;
+      inversion_b_ = true;
+      delete inversion_p;
+    }
+  if (bass_p)
+    {
+      bass_pitch_ = *bass_p;
+      bass_b_ = true;
+      delete bass_p;
+    }
+}
+  
+Chord::Chord (Chord const& chord)
+{
+  pitch_arr_ = chord.pitch_arr_;
+  inversion_b_ = chord.inversion_b_;
+  inversion_pitch_ = chord.inversion_pitch_;
+  bass_b_ = chord.bass_b_;
+  bass_pitch_ = chord.bass_pitch_;
+}
+  
+
+Array<Musical_pitch>
+Chord::base_arr (Musical_pitch p)
+{
+  Array<Musical_pitch> base;
+  base.push (p);
+  p.transpose (Musical_pitch (2));
+  base.push (p);
+  p.transpose (Musical_pitch (2, -1));
+  base.push (p);
+  return base;
 }
 
-static void
-rebuild_transpose (Musical_pitch tonic, Array<Musical_pitch>* pitch_arr_p)
+void
+Chord::rebuild_transpose (Array<Musical_pitch>* pitch_arr_p, Musical_pitch tonic, bool fix7_b)
 {
   for (int i = 0; i < pitch_arr_p->size (); i++)
     {
       Musical_pitch p = tonic;
       Musical_pitch q = (*pitch_arr_p)[i];
-      // duh, c7 should mean <c bes>
-      if (q.notename_i_ == 6)
-        q.accidental_i_--;
       p.transpose (q);
+      // duh, c7 should mean <c bes>
+      if (fix7_b && (step_i (tonic, p) == 7))
+        p.accidental_i_--;
       (*pitch_arr_p)[i] = p;
     }
   pitch_arr_p->sort (Musical_pitch::compare);
 }
 
-static int
-find_pitch_i (Array<Musical_pitch> const* pitch_arr_p, Musical_pitch p)
+int
+Chord::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])
@@ -42,8 +268,8 @@ find_pitch_i (Array<Musical_pitch> const* pitch_arr_p, Musical_pitch p)
   return -1;
 }
 
-static int
-find_notename_i (Array<Musical_pitch> const* pitch_arr_p, Musical_pitch p)
+int
+Chord::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)
@@ -58,8 +284,8 @@ find_notename_i (Array<Musical_pitch> const* pitch_arr_p, Musical_pitch p)
   return i;
 }
 
-static int
-trap_i (Musical_pitch tonic, Musical_pitch p)
+int
+Chord::step_i (Musical_pitch tonic, Musical_pitch p)
 {
   int i = p.notename_i_ - tonic.notename_i_
     + (p.octave_i_ - tonic.octave_i_) * 7;
@@ -69,15 +295,15 @@ trap_i (Musical_pitch tonic, Musical_pitch p)
   return i;
 }
 
-static Array<Musical_pitch>
-missing_triads_pitch_arr (Array<Musical_pitch>const* pitch_arr_p)
+Array<Musical_pitch>
+Chord::missing_thirds_pitch_arr (Array<Musical_pitch> const* pitch_arr_p)
 {
-  Array<Musical_pitch> triads;
+  Array<Musical_pitch> thirds;
 
   /* is the third c-e, d-f, etc. small or large? */
   int minormajor_a[] = {0, -1, -1, 0,0,-1,-1};
   for (int i=0; i < 7; i++)
-    triads.push (Musical_pitch( 2, minormajor_a[i]));
+    thirds.push (Musical_pitch( 2, minormajor_a[i]));
 
   Musical_pitch tonic = (*pitch_arr_p)[0];
   Musical_pitch last = tonic;
@@ -86,12 +312,12 @@ missing_triads_pitch_arr (Array<Musical_pitch>const* pitch_arr_p)
   for (int i = 0; i < pitch_arr_p->size ();)
     {
       Musical_pitch p = (*pitch_arr_p)[i];
-      int trap = trap_i (tonic, p);
+      int step = step_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))
+       last.transpose (thirds[(last.notename_i_ - tonic.notename_i_ + 7) % 7]);
+      if (step > step_i (tonic, last))
        {
-         while (trap > trap_i (tonic, last))
+         while (step > step_i (tonic, last))
            {
              if ((last.notename_i_ - tonic.notename_i_ + 7) % 7 == 6)
                {
@@ -104,7 +330,7 @@ missing_triads_pitch_arr (Array<Musical_pitch>const* pitch_arr_p)
                {
                  missing_arr.push (last);
                }
-             last.transpose (triads[(last.notename_i_ - tonic.notename_i_ + 7) % 7]);
+             last.transpose (thirds[(last.notename_i_ - tonic.notename_i_ + 7) % 7]);
            }
        }
       else
@@ -117,298 +343,134 @@ missing_triads_pitch_arr (Array<Musical_pitch>const* pitch_arr_p)
 
 
 /*
-  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)
+ Mangle into list of pitches.
+ For normal chord entry, inversion and bass pitches are retained in
+ specific *_requests
+ */
+Array<Musical_pitch>
+Chord::to_pitch_arr () const
 {
-  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));
-
-  /*
-    remove double adds (urg: sus4)
-   */
-  for (int i = add_arr_p->size () - 1; i >= 0 ; i--)
-    {
-      int j = ::find_pitch_i (add_arr_p, (*add_arr_p)[i]);
-      if ((j != -1) && (i != j))
-        {
-           add_arr_p->get (i);
-       } 
-    }
-
-  /*
-    default chord includes upto 5: <1, 3, 5>
-   */
-  add_arr_p->insert (tonic, 0);
-  Array<Musical_pitch> tmp = *add_arr_p;
-  int highest_trap = trap_i (tonic, tmp.top ());
-  if (highest_trap < 5)
-    tmp.push (fifth);
-
-  /*
-    find missing triads
-   */
-  Array<Musical_pitch> missing_arr = missing_triads_pitch_arr (&tmp);
-  if (highest_trap < 5)
-    missing_arr.push (fifth);
-
-  /*
-    if additions include some 3, don't add third
-   */
-  Musical_pitch third = tonic;
-  third.transpose (Musical_pitch (2));
-  if (::find_notename_i (add_arr_p, third) != -1)
-    {
-      int i = ::find_pitch_i (&missing_arr, third);
-      if (i != -1)
-       missing_arr.get (i);
-    }
-  
-  /*
-    if additions include 4, assume sus4 and don't add third implicitely
-     C-sus (4) = c f g (1 4 5)
-   */
-  Musical_pitch sus = tonic;
-  sus.transpose (Musical_pitch (3));
-  if (::find_pitch_i (add_arr_p, sus) != -1)
-    {
-      int i = ::find_pitch_i (&missing_arr, third);
-      if (i != -1)
-       missing_arr.get (i);
-    }
-
-  /*
-    if additions include some 5, don't add fifth
-   */
-  if (::find_notename_i (add_arr_p, fifth) != -1)
-    {
-      int i = ::find_pitch_i (&missing_arr, fifth);
-      if (i != -1)
-       missing_arr.get (i);
-    }
-  
-  
-  /*
-    complete the list of triads to be added
-   */
-  add_arr_p->concat (missing_arr);
-  add_arr_p->sort (Musical_pitch::compare);
-
-  /*
-   add all that aren't subtracted
-   */
-  for (int i = 0; i < add_arr_p->size (); i++)
-    {
-      Musical_pitch p = (*add_arr_p)[i];
-      int j = 0;
-      for (; j < sub_arr_p->size (); j++)
-       if (p == (*sub_arr_p)[j])
-         {
-           sub_arr_p->del (j);
-           j = -1;
-           break;
-         }
-      if (j == sub_arr_p->size ())
-       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 ()));
-
-  if (inversion_p)
+  Array<Musical_pitch> pitch_arr = pitch_arr_;
+  if (inversion_b_)
     {
       int i = 0;
-      for (; i < pitch_arr_.size (); i++)
+      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_))
+         if ((pitch_arr[i].notename_i_ == inversion_pitch_.notename_i_)
+             && (pitch_arr[i].accidental_i_ == inversion_pitch_.accidental_i_))
            break;
        }
-      if (i == pitch_arr_.size ())
+      if (i == pitch_arr.size ())
        {
          warning (_f ("invalid inversion pitch: not part of chord: %s",
-                      inversion_p->str ()));
+                      inversion_pitch_.str ()));
        }
       else
-       {
-#if INVERSION_ADDED_AS_BASE
-         pitch_arr_.insert (pitch_arr_[i], 0);
-         rebuild_with_bass (0);
-#else
-         rebuild_with_bass (i);
-#endif
-         
-       }
-      delete inversion_p;
+       rebuild_with_bass (&pitch_arr, i);
+    }
+
+  if (bass_b_)
+    {
+      pitch_arr.insert (bass_pitch_, 0);
+      rebuild_with_bass (&pitch_arr, 0);
     }
+  return pitch_arr;
 }
 
 void
-Chord::find_additions_and_subtractions(Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p)
+Chord::find_additions_and_subtractions (Array<Musical_pitch> pitch_arr, Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p)
 {
-  Musical_pitch tonic = pitch_arr_[0];
+  Musical_pitch tonic = pitch_arr[0];
   /*
-    all the triads that should be there
+    construct an array of thirds for a normal chord
    */
   Array<Musical_pitch> all_arr;
   all_arr.push (tonic);
-  all_arr.push (pitch_arr_.top ());
-  all_arr.concat (missing_triads_pitch_arr (&all_arr));
+  if (step_i (tonic, pitch_arr.top ()) >= 5)
+    all_arr.push (pitch_arr.top ());
+  else
+    all_arr.push (base_arr (tonic).top ());
+  all_arr.concat (missing_thirds_pitch_arr (&all_arr));
   all_arr.sort (Musical_pitch::compare);
   
   int i = 0;
   int j = 0;
-  while ((i < all_arr.size ()) || (j < pitch_arr_.size ()))
+  Musical_pitch last_extra = tonic;
+  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];
+      Musical_pitch a = all_arr [i <? all_arr.size () - 1];
+      Musical_pitch p = pitch_arr[j <? pitch_arr.size () - 1];
+      /*
+        this pitch is present: do nothing, check next
+       */
       if (a == p)
        {
          i++;
          j++;
+         last_extra = tonic;
        }
+      /*
+        found an extra pitch: chord addition
+       */
       else if ((p < a) || (p.notename_i_ == a.notename_i_))
        {
          add_arr_p->push (p);
-         j++;
+         last_extra = p;
+         (j < pitch_arr.size ()) ? j++ : i++;
        }
+      /*
+        a third is missing: chord subtraction
+       */
       else
        {
-         sub_arr_p->push (a);
-         i++;
+         if (last_extra.notename_i_ != a.notename_i_)
+           sub_arr_p->push (a);
+         (i < all_arr.size ()) ? i++ : j++;
+         last_extra = tonic;
        }
     }
       
+  /* add missing basic steps */
+  if (step_i (tonic, pitch_arr.top ()) < 3)
+    sub_arr_p->push (base_arr (tonic)[1]);
+  if (step_i (tonic, pitch_arr.top ()) < 5)
+    sub_arr_p->push (base_arr (tonic).top ());
+
   /*
-    add highest addition, because it names chord
+    add highest addition, because it names chord, if greater than 5
+    or non-standard
+    (1, 3 and) 5 not additions: part of normal chord
    */
-  if (trap_i (tonic, pitch_arr_.top () > 5))
-    add_arr_p->push (pitch_arr_.top ());
+  if ((step_i (tonic, pitch_arr.top ()) > 5)
+       || pitch_arr.top ().accidental_i_)
+    add_arr_p->push (pitch_arr.top ());
 }
 
-String
-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];
-
-  Array<Musical_pitch> add_arr;
-  Array<Musical_pitch> sub_arr;
-  find_additions_and_subtractions (&add_arr, &sub_arr);
-                          
-
-  Array<Musical_pitch> scale;
-  for (int i=0; i < 7; i++)
-    scale.push (Musical_pitch (i));
-
-  // 7 always means 7-...
-  //  scale.push (Musical_pitch (6, -1)); // b
-
-  rebuild_transpose (tonic, &scale);
-  
-  bool has3m_b = false;
-  bool has4_b = false;
-  String str;
-  String sep_str;
-  for (int i = 0; i < add_arr.size (); i++)
-    {
-      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";
-         has3m_b = true;
-       }
-      else if (accidental
-              || (!(trap % 2) || ((i + 1 == add_arr.size ()) && (trap > 5))))
-        {
-         str += sep_str;
-          if ((trap == 7) && (accidental == 1))
-            str += "maj7";
-          else
-            {
-              str += to_str (trap);
-              if (accidental)
-                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)
-    {
-      inversion_str = inversion->str ();
-      inversion_str = "/" + inversion_str.left_str (1).upper_str ()
-       + acc[inversion->accidental_i_ + 2];
-
-    }
-
-  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);
-}
 
+/*
+  This routine tries to guess tonic in a possibly inversed chord, ie
+  <e g c'> should produce: C.
+  This is only used for chords that are entered as simultaneous notes,
+  chords entered in \chord mode are fully defined.
+ */
 int
-Chord::find_tonic_i () const
+Chord::find_tonic_i (Array<Musical_pitch> const* pitch_arr_p)
 {
   /*
     find tonic
     
-    first try: base of longest line of triads
+    first try: base of longest line of thirds
    */
   int tonic_i = 0;
   int longest_i = 0;
-  for (int i = 0; i < pitch_arr_.size (); i++)
+  for (int i = 0; i < pitch_arr_p->size (); i++)
     {
-      int no_triad_i = 0;
-      int last_i = pitch_arr_[i % pitch_arr_.size ()].notename_i_;
+      int no_third_i = 0;
+      int last_i = (*pitch_arr_p)[i % pitch_arr_p->size ()].notename_i_;
       int j = 0;
-      for (; j < pitch_arr_.size (); j++)
+      for (; j < pitch_arr_p->size (); j++)
        {
-         int cur_i = pitch_arr_[(i + j + 1) % pitch_arr_.size ()].notename_i_;
+         int cur_i = (*pitch_arr_p)[(i + j + 1) % pitch_arr_p->size ()].notename_i_;
          int gap = cur_i - last_i;
          while (gap < 0)
            gap += 7;
@@ -416,11 +478,11 @@ Chord::find_tonic_i () const
          if (gap == 2)
            last_i = cur_i;
          else
-           no_triad_i++;
+           no_third_i++;
        }
-      if (j - no_triad_i > longest_i)
+      if (j - no_third_i > longest_i)
        {
-         longest_i = j - no_triad_i;
+         longest_i = j - no_third_i;
          tonic_i = i;
        }
     }
@@ -431,11 +493,11 @@ Chord::find_tonic_i () const
   int biggest_i = 0;
   //  if (longest_i)
   if (longest_i <= 1)
-    for (int i = 0; i < pitch_arr_.size (); i++)
+    for (int i = 0; i < pitch_arr_p->size (); i++)
       {
-       int gap = pitch_arr_[i].notename_i_
-         - pitch_arr_[(i - 1 + pitch_arr_.size ()) 
-         % pitch_arr_.size ()].notename_i_;
+       int gap = (*pitch_arr_p)[i].notename_i_
+         - (*pitch_arr_p)[(i - 1 + pitch_arr_p->size ()) 
+         % pitch_arr_p->size ()].notename_i_;
        while (gap < 0)
          gap += 7;
        gap %= 7;
@@ -449,14 +511,14 @@ Chord::find_tonic_i () const
 }
 
 void
-Chord::rebuild_from_base (int base_i)
+Chord::rebuild_from_base (Array<Musical_pitch>* pitch_arr_p, 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++)
+  for (int i = 0; i < pitch_arr_p->size (); i++)
     {
-      Musical_pitch p = pitch_arr_[(base_i + i) % pitch_arr_.size ()];
+      Musical_pitch p = (*pitch_arr_p)[(base_i + i) % pitch_arr_p->size ()];
       if (p < last)
        {
          p.octave_i_ = last.octave_i_;
@@ -466,43 +528,38 @@ Chord::rebuild_from_base (int base_i)
       new_arr.push (p);
       last = p;
     }
-  pitch_arr_ = new_arr;
+  *pitch_arr_p = new_arr;
 }
 
 void
-Chord::rebuild_insert_inversion (int tonic_i)
+Chord::rebuild_insert_inversion (Array<Musical_pitch>* pitch_arr_p, 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 ())
+  Musical_pitch inversion = pitch_arr_p->get (0);
+  rebuild_from_base (pitch_arr_p, tonic_i - 1);
+  if (pitch_arr_p->size ())
     {
-      inversion.octave_i_ = pitch_arr_[0].octave_i_ - 1;
-      while (inversion < pitch_arr_[0])
+      inversion.octave_i_ = (*pitch_arr_p)[0].octave_i_ - 1;
+      while (inversion < (*pitch_arr_p)[0])
        inversion.octave_i_++;
     }
-  for (int i = 0; i < pitch_arr_.size (); i++)
-    if (pitch_arr_[i] > inversion)
+  for (int i = 0; i < pitch_arr_p->size (); i++)
+    if ((*pitch_arr_p)[i] > inversion)
       {
-       pitch_arr_.insert (inversion, i);
+       pitch_arr_p->insert (inversion, i);
        break;
       }
-#endif
 }
 
 void
-Chord::rebuild_with_bass (int bass_i)
+Chord::rebuild_with_bass (Array<Musical_pitch>* pitch_arr_p, int bass_i)
 {
   assert (bass_i >= 0);
-  Musical_pitch inversion = pitch_arr_.get (bass_i);
+  Musical_pitch bass = pitch_arr_p->get (bass_i);
   // is lowering fine, or should others be raised?
-  if (pitch_arr_.size ())
-    while (inversion > pitch_arr_[0])
-      inversion.octave_i_--;
-  pitch_arr_.insert (inversion, 0);
+  if (pitch_arr_p->size ())
+    while (bass > (*pitch_arr_p)[0])
+      bass.octave_i_--;
+  pitch_arr_p->insert (bass, 0);
 }
+