]> git.donarmstrong.com Git - lilypond.git/commitdiff
patch::: 1.3.2.jcn3
authorJan Nieuwenhuizen <janneke@gnu.org>
Fri, 5 Nov 1999 13:50:31 +0000 (14:50 +0100)
committerJan Nieuwenhuizen <janneke@gnu.org>
Fri, 5 Nov 1999 13:50:31 +0000 (14:50 +0100)
pl 2.jcn3
- chords:
  * Chord is item
  * junked TeX hacking
  * configurable with styled strings from scm
  * fixes: dim, /no X, tonic != C

pl 2.jcn2
- chords from  scm

20 files changed:
CHANGES
TODO
VERSION
flower/include/array.hh
flower/include/array.icc
input/test/banter-chords.ly [new file with mode: 0644]
input/test/chords.ly
lily/chord-name-engraver.cc
lily/chord.cc
lily/include/chord-name-engraver.hh
lily/include/chord.hh
ly/chord-modifiers.ly
ly/paper11.ly
ly/paper13.ly
ly/paper16.ly
ly/paper20.ly
ly/paper23.ly
ly/paper26.ly
scm/chord-names.scm [new file with mode: 0644]
scm/lily.scm

diff --git a/CHANGES b/CHANGES
index e618029ba594db38a02358b9733d9c91de6d7298..068c46dcaf1f963b293dded3014712aba4daa8d6 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,13 @@
+pl 2.jcn3
+       - chords:
+         * Chord is item
+         * junked TeX hacking
+         * configurable with styled strings from scm
+         * fixes: dim, /no X, tonic != C
+
+pl 2.jcn2
+       - chords from  scm 
+
 pl 2.jcn1
        - chord fixes: 
           * inversion request: no inversion guessing for chord entry
diff --git a/TODO b/TODO
index 07f05fc75b2091ffbc2a5d3b6431192d28b0787d..95366c40c26455e9f92a6d3051aab525e911f708 100644 (file)
--- a/TODO
+++ b/TODO
@@ -18,6 +18,10 @@ Grep -i for TODO, FIXME and ugh/ugr/urg.
        ctor_dict["Score_element"]->create_func ();
 
 . * acc at tied note after linebreak.
+. * fix font-naming and selecting
+. * fix naming: \interline Context.staffLineLeading, staff_line_leading (),
+staff_position staff_space
+. * chord tonic: placement of accidental  C#, Cb (from scm and C++)
 . * note head on stem err msg in dutch.
 . *  why need to run -C mf twice?
 . * setting indent to 0 with \shape fails
diff --git a/VERSION b/VERSION
index ad6cafe6de7efc137d648d9e17db7c67a78d5019..0d7c252ced24a6f4bc92e72f6fc3b1195bb8b268 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond
 MAJOR_VERSION=1
 MINOR_VERSION=3
 PATCH_LEVEL=2
-MY_PATCH_LEVEL=jcn1
+MY_PATCH_LEVEL=jcn3
 
 # use the above to send patches: MY_PATCH_LEVEL is always empty for a
 # released version.
index d6349588aa03324d0c81e3a14573f9abf012e570..f8f6e352fdc7a0a92c7b609bfb7b2c1ea2f70c62 100644 (file)
@@ -13,7 +13,7 @@
 #endif
 
 /// copy a bare (C-)array from #src# to #dest# sized  #count#
-template<class T> void arrcpy (T*dest, T*src, int count);
+template<class T> void arrcpy (T*dest, T const*src, int count);
 
 /**
   Scaleable array/stack template, for a type T with default constructor.
@@ -241,7 +241,7 @@ public:
       set_size (size_ + src.size_);
       arrcpy (array_p_+s,src.array_p_, src.size_);     
     }
-  Array<T> slice (int lower, int upper) ;
+  Array<T> slice (int lower, int upper) const; 
   void reverse();
 };
 
index 8b876ce85d2bca4e43ef1841ecec755f28f4d68e..71de84a8acb485f9111560a96f9bac5426c92cb0 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 template<class T> INLINE void 
-arrcpy (T*dest, T*src, int count)
+arrcpy (T*dest, T const* src, int count)
 {
   for (int i_shadows_local=0; i_shadows_local < count ; i_shadows_local++)
 #ifdef __powerpc__
@@ -98,7 +98,7 @@ Array<T>::remove_array_p ()
 
 template<class T> INLINE
 Array<T>
-Array<T>::slice (int lower, int upper)
+Array<T>::slice (int lower, int upper) const
 {
   assert (lower >= 0 && lower <=upper&& upper <= size_);
   Array<T> r;
diff --git a/input/test/banter-chords.ly b/input/test/banter-chords.ly
new file mode 100644 (file)
index 0000000..307b865
--- /dev/null
@@ -0,0 +1,66 @@
+\version "1.3.2";
+
+\header{
+enteredby =     "jcn";
+copyright =     "public domain";
+TestedFeatures =        "Banter named chords";
+}
+
+% test German (Banter) naming
+% for more conventional naming, comment scm stuff out
+
+% {
+#(set! pitch-names-alist
+      (append 
+      '(
+       ; use these for German naming
+       ((6 . 0) . ("H" ""))
+       ((6 . -1) . ("B" ("feta-1" . "\12")))
+       )
+      pitch-names-alist))
+
+#(set! chord-names-alist
+      (append 
+      '(
+        (((0 . 0) (2 . -1) (4 . -1)) . ("m" . ("script" . "5-")))
+       ; Co iso Cm5-7-
+       ; urg, niet te pruimen
+        ; (((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . ("" . ("feta-1" . ".")))
+        (((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . ("" . ("script" . "o")))
+       )))
+% }
+
+chord = \notes\transpose c''\chords{
+       % dim modifier means: lower all implicit additions
+       c:dim9
+       c:dim
+       c:dim7
+       % explicit additions are taken as entered:
+       c:m5-.7-
+       % note that 7 is a special case: it's always lowered by 1...
+       c:dim7-.9
+       c:dim9-.11
+
+       % test German names
+       b:dim7
+       bes:m5-
+
+       \break
+
+       c:sus2  %?
+       c:sus4
+       c^3
+       c^3.5
+       c:2.6^5
+       c:dim^5-
+       c:dim7^5-
+       cis:m5-
+}
+
+\score{
+       <
+               \context ChordNames \chord
+               \context Staff \chord
+       >
+}
+
index c74d5024304f974f5f42f14fb7c90d8d143e89e6..cf6251d30d3e0479e2b0b48ab6c4e96b95ed32d9 100644 (file)
@@ -1,4 +1,4 @@
-\version "1.2.0";
+\version "1.3.2";
 
 %{
 Would this be acceptable/good enough/convenient for entry?
@@ -9,7 +9,7 @@ Would this be acceptable/good enough/convenient for entry?
    Cb                     ces
    Cm; Cmin               c:3-; c:m; c:min
    Caug                   c:5+; c:aug;
-   Cdim                   c:3-:5-; c:dim
+   Cdim                   c:3-.5-; c:dim
    Cmaj7                  c:7+; c:maj
    C7                     c:7
    Csus; Csus4            c:4; c:sus
index ef0744d627219e1092001232021a8c859d383043..21f0a99f1ad7f4fa239b76293bc60574e0ba0233 100644 (file)
@@ -20,6 +20,7 @@ ADD_THIS_TRANSLATOR (Chord_name_engraver);
 
 Chord_name_engraver::Chord_name_engraver ()
 {
+  chord_p_ = 0;
   tonic_req_ = 0;
   inversion_req_ = 0;
   bass_req_ = 0;
@@ -61,7 +62,7 @@ Chord_name_engraver::do_try_music (Music* m)
 void
 Chord_name_engraver::do_process_requests ()
 {
-  if (text_p_arr_.size ())
+  if (chord_p_)
     return;
   if (!pitch_arr_.size ())
     return;
@@ -71,36 +72,20 @@ Chord_name_engraver::do_process_requests ()
   if (gh_boolean_p (chord_inversion))
     find_inversion_b = gh_scm2bool (chord_inversion);
 
-  Chord chord = to_chord (pitch_arr_, tonic_req_, inversion_req_, bass_req_, 
-    find_inversion_b);
+  chord_p_ = new Chord (to_chord (pitch_arr_, tonic_req_, inversion_req_, bass_req_, find_inversion_b));
     
-  Text_item* item_p =  new Text_item;
-
-  /*
-   TODO:
-     - switch on property, add american (?) chordNameStyle:
-       Chord::american_str (...)
-
-  SCM chordNameStyle = get_property ("chordNameStyle", 0);
-  if (chordNameStyle == "Banter")
-    item_p->text_str_ = chord.banter_str (inversion);
-   */
-
-  item_p->text_str_ = chord.banter_str ();
-  
-  text_p_arr_.push (item_p);
-  announce_element (Score_element_info (item_p, 0));
+  announce_element (Score_element_info (chord_p_, 0));
 }
 
 void
 Chord_name_engraver::do_pre_move_processing ()
 {
-  for (int i=0; i < text_p_arr_.size (); i++)
+  if (chord_p_)
     {
-      typeset_element (text_p_arr_[i]);
+      typeset_element (chord_p_);
     }
-  text_p_arr_.clear ();
   pitch_arr_.clear ();
+  chord_p_ = 0;
   tonic_req_ = 0;
   inversion_req_ = 0;
   bass_req_ = 0;
index adef8d4991c5e2f35ab1edd645515c788a6b3212..8dbc57a6c72bc6608f22fe2dfd931f516214e808 100644 (file)
@@ -9,7 +9,16 @@
 #include "chord.hh"
 #include "musical-request.hh"
 #include "warn.hh"
+#include "debug.hh"
+#include "molecule.hh"
+#include "paper-def.hh"
+#include "lookup.hh"
 
+SCM
+pitch2scm (Musical_pitch p)
+{
+  return gh_cons (gh_int2scm (p.notename_i_), gh_int2scm (p.accidental_i_));
+}
 
 /*
   construct from parser output
@@ -17,7 +26,7 @@
 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: 5th and 7th should be lowered
+  // urg: catch dim modifier: 3rd, 5th, 7th, .. should be lowered
   bool dim_b = false;
   for (int i=0; i < add_arr_p->size (); i++)
     {
@@ -28,12 +37,10 @@ to_chord (Musical_pitch tonic, Array<Musical_pitch>* add_arr_p, Array<Musical_pi
          dim_b = true;
        }
     }
-  Chord::rebuild_transpose (add_arr_p, tonic);
-  Chord::rebuild_transpose (sub_arr_p, tonic);
+  Chord::rebuild_transpose (add_arr_p, tonic, true);
+  Chord::rebuild_transpose (sub_arr_p, tonic, true);
 
-  Musical_pitch fifth = tonic;
-  fifth.transpose (Musical_pitch (2));
-  fifth.transpose (Musical_pitch (2, -1));
+  Musical_pitch fifth = Chord::base_arr (tonic).top ();
 
   /*
     remove double adds (urg: sus4)
@@ -68,19 +75,21 @@ to_chord (Musical_pitch tonic, Array<Musical_pitch>* add_arr_p, Array<Musical_pi
   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_--;
+         missing_arr[i].accidental_i_--;
        }
     }
 
   /*
     if additions include some 3, don't add third
    */
-  Musical_pitch third = tonic;
-  third.transpose (Musical_pitch (2));
+  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);
@@ -200,6 +209,7 @@ Chord::Chord (Array<Musical_pitch> pitch_arr, Musical_pitch* inversion_p, Musica
 }
 
 Chord::Chord (Chord const& chord)
+  : Item (chord)
 {
   pitch_arr_ = chord.pitch_arr_;
   inversion_p_ = chord.inversion_p_ ? new Musical_pitch (*chord.inversion_p_) : 0;
@@ -210,19 +220,33 @@ Chord::~Chord ()
 {
   delete inversion_p_;
   delete bass_p_;
+  // AAARGH, why doesn't Score_elt do this?
+  unsmobify_self ();
+}
+
+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;
 }
 
 void
-Chord::rebuild_transpose (Array<Musical_pitch>* pitch_arr_p, Musical_pitch tonic)
+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);
@@ -347,24 +371,28 @@ Chord::to_pitch_arr () const
 }
 
 void
-Chord::find_additions_and_subtractions (Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p) const
+Chord::find_additions_and_subtractions (Array<Musical_pitch> pitch_arr, Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p) const
 {
-  Musical_pitch tonic = pitch_arr_[0];
+  Musical_pitch tonic = pitch_arr[0];
   /*
     construct an array of thirds for a normal chord
    */
   Array<Musical_pitch> all_arr;
   all_arr.push (tonic);
-  all_arr.push (pitch_arr_.top ());
+  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 ()))
     {
       Musical_pitch a = all_arr [i <? all_arr.size () - 1];
-      Musical_pitch p = pitch_arr_ [j <? pitch_arr_.size () - 1];
+      Musical_pitch p = pitch_arr[j <? pitch_arr.size () - 1];
       /*
         this pitch is present: do nothing, check next
        */
@@ -372,6 +400,7 @@ Chord::find_additions_and_subtractions (Array<Musical_pitch>* add_arr_p, Array<M
        {
          i++;
          j++;
+         last_extra = tonic;
        }
       /*
         found an extra pitch: chord addition
@@ -379,115 +408,221 @@ Chord::find_additions_and_subtractions (Array<Musical_pitch>* add_arr_p, Array<M
       else if ((p < a) || (p.notename_i_ == a.notename_i_))
        {
          add_arr_p->push (p);
-         (j < pitch_arr_.size ()) ? j++ : i++;
+         last_extra = p;
+         (j < pitch_arr.size ()) ? j++ : i++;
        }
       /*
         a third is missing: chord subtraction
        */
       else
        {
-         sub_arr_p->push (a);
+         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
-    (1, 3 and) 5 not an addition: part of normal 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 (step_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 ());
 }
 
+
 /*
-  TODO:
-   reduce guess work: dim chord
-   other naming conventions `American'?
-   don't use TeX constructs
-   user defined chords-names for specific chords:
-      tonic, additions, subtractions, inversion, bass -> "my-chord-name"
+  word is roman text or styled text:
+   "text"
+   ("style" . "text")
  */
-String
-Chord::banter_str () const
+Molecule
+Chord::ly_word2molecule (SCM scm) const
 {
-  Musical_pitch tonic = pitch_arr_[0];
+  String style;
+  if (gh_pair_p (scm))
+    {
+      style = ly_scm2string (gh_car (scm));
+      scm = gh_cdr (scm);
+    }
+  String text = ly_scm2string (scm);
+  return lookup_l ()->text (style, text, paper_l ());
+}
+
+/*
+ scm is word or list of words:
+   word
+   (word word)
+ */
+Molecule
+Chord::ly_text2molecule (SCM scm) const
+{
+  Molecule mol;
+  if (gh_list_p (scm))
+    {
+      while (gh_cdr (scm) != SCM_EOL)
+        {
+         mol.add_at_edge (X_AXIS, RIGHT, 
+            ly_word2molecule (gh_car (scm)), 0);
+         scm = gh_cdr (scm);
+       }
+      scm = gh_car (scm);
+    }  
+  mol.add_at_edge (X_AXIS, RIGHT, 
+    ly_word2molecule (scm), 0);
+  return mol;
+}
+
+Molecule
+Chord::pitch2molecule (Musical_pitch p) const
+{
+  SCM name = scm_eval (gh_list (gh_symbol2scm ("user-pitch-name"), ly_quote_scm (pitch2scm (p)), SCM_UNDEFINED));
 
-  //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];
+  if (name != SCM_UNSPECIFIED)
+    {
+      return ly_text2molecule (name);
+    }
+
+  Molecule mol = lookup_l ()->text ("", p.str ().left_str (1).upper_str (), paper_l ());
+  if (p.accidental_i_)
+    // urg, how to select the feta-1 font?
+    mol.add_at_edge (X_AXIS, RIGHT, 
+                    lookup_l ()->accidental (p.accidental_i_, 0), 0);
+  return mol;
+}
+
+Musical_pitch
+diff_pitch (Musical_pitch tonic, Musical_pitch  p)
+{
+  Musical_pitch diff (p.notename_i_ - tonic.notename_i_, 
+    p.accidental_i_ - tonic.accidental_i_, 
+    p.octave_i_ - tonic.octave_i_);
+
+  while  (diff.notename_i_ >= 7)
+    {
+      diff.notename_i_ -= 7;
+      diff.octave_i_ ++;
+    }
+  while  (diff.notename_i_ < 0)
+    {
+      diff.notename_i_ += 7;
+      diff.octave_i_ --;
+    }
+
+  diff.accidental_i_ -= (tonic.semitone_pitch () + diff.semitone_pitch ())
+    - p.semitone_pitch ();
+
+  return diff;
+}
 
+bool
+Chord::user_chord_name (Array<Musical_pitch> pitch_arr, Chord_name* name_p) const
+{
+  SCM chord = SCM_EOL;
+  Array<Musical_pitch> chord_type = pitch_arr;
+  rebuild_transpose (&chord_type, diff_pitch (pitch_arr[0], Musical_pitch (0)), false);
+
+  for (int i= chord_type.size (); i--; )
+    chord = gh_cons (pitch2scm (chord_type[i]), chord);
+
+  SCM name = scm_eval (gh_list (gh_symbol2scm ("user-chord-name"), ly_quote_scm (chord), SCM_UNDEFINED));
+  if (name != SCM_UNSPECIFIED)
+    {
+      name_p->modifier_mol = ly_text2molecule (gh_car (name));
+      name_p->addition_mol = ly_text2molecule (gh_cdr (name));
+      return true;
+    }
+  return false;
+}
+
+void
+Chord::banter (Array<Musical_pitch> pitch_arr, Chord_name* name_p) const
+{
   Array<Musical_pitch> add_arr;
   Array<Musical_pitch> sub_arr;
-  find_additions_and_subtractions (&add_arr, &sub_arr);
+  find_additions_and_subtractions (pitch_arr, &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 (&scale, tonic);
+  Musical_pitch tonic = pitch_arr[0];
+  rebuild_transpose (&scale, tonic, true);
   
-  bool has3m_b = false;
-  bool has4_b = false;
-  bool has5m_b = false;
-  String str;
-  String minor_str;
+  /*
+    Does chord include this step?  -1 if flat
+   */
+  int has[16];
+  for (int i=0; i<16; i++)
+    has[i] = 0;
+
+  String mod_str;
+  String add_str;
   String sep_str;
   for (int i = 0; i < add_arr.size (); i++)
     {
       Musical_pitch p = add_arr[i];
       int step = step_i (tonic, p);
-      if (step == 4)
-       has4_b = true;
       int accidental = p.accidental_i_ - scale[(step - 1) % 7].accidental_i_;
+      if ((step < 16) && (has[step] != -1))
+        has[step] = accidental == -1 ? -1 : 1;
       if ((step == 3) && (accidental == -1))
        {
-         minor_str = "m";
-         has3m_b = true;
+         mod_str = "m";
        }
       /*
-       have Cdim rather than Cm5-, even if it's a prefix
+        urg.
+       This routine gets a lot simpler, if we don't try to be catch
+       the 'dim' chords.  However, we'll have to list every exceptional
+       'dim' chord in scm: otherwise we'll get stuff like Cdim7-, iso
+       Cdim7, etc
        */
-      else if ((step == 5) && (accidental == -1) && has3m_b)
+#ifdef SMART_DIM
+      else if ((step == 5) && (accidental == -1) && (has[3] == -1))
        {
-         minor_str = "dim";
-         has5m_b = true;
+         mod_str = "dim";
        }
+#endif
       else if (accidental
-              || (!(step % 2) || ((i + 1 == add_arr.size ()) && (step > 5))))
+              || (!(step % 2) 
+              || ((i == add_arr.size () - 1) && (step > 5))))
         {
-         str += sep_str;
+         add_str += sep_str;
          sep_str = "/";
           if ((step == 7) && (accidental == 1))
            {
-              str += "maj7";
+              add_str += "maj7";
            }
          else
-            {
-             /* 
-               if has3m_b and has5m_b, assume dim
-               don't mention dim-addition, except for chord-namer
-              */
-              if (((step/2) && (accidental == -1))
-                 && has3m_b && has5m_b)
-               {
-                 if (i == add_arr.size () - 1)
-                    str += to_str (step);
-                 else
+#ifdef SMART_DIM
+           {
+             if ((step % 2) && (accidental == -1) 
+                && (has[3] == -1) && (has[5] == -1))
+               {               
+                 if (i != add_arr.size () - 1)
                    sep_str = "";
+                 else
+                   add_str += to_str (step);
                }
              else
+#endif
                {
-                  str += to_str (step);
-                  if (accidental)
-                    str += accidental < 0 ? "-" : "+";
+                 add_str += to_str (step);
+                 if (accidental)
+                   add_str += accidental < 0 ? "-" : "+";
                }
-            }
+#ifdef SMART_DIM
+           }
+#endif
        }
     }
 
@@ -496,49 +631,28 @@ Chord::banter_str () const
       Musical_pitch p = sub_arr[i];
       int step = step_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 has3m_b and has5m_b, assume 'dim' chord
+       if additions include 2 or 4, assume sus2/4 and don't display 'no3'
       */
-      if (!((step == 3) && (has3m_b || has4_b))
-         && !((step/2) && (step !=3) && (step !=7 ) && (p.accidental_i_ == 0) && has3m_b && has5m_b)
-         && !((step == 7) && (p.accidental_i_ == -1) && has3m_b && has5m_b))
+      if (!((step == 3) && (has[2] || has[4])))
        {
-         str += sep_str + "no" + to_str (step);
+         add_str += sep_str + "no" + to_str (step);
          sep_str = "/";
        }
     }
 
-  /*
-   have Co rather than Cdim7
-   */
-  if (minor_str + str == "dim7")
-    {
-      minor_str = "";
-      str = "o";
-    }
-    
-
-  String inversion_str;
-  if (inversion_p_)
+  if (mod_str.length_i ())
+    name_p->modifier_mol.add_at_edge (X_AXIS, RIGHT, 
+      lookup_l ()->text ("roman", mod_str, paper_l ()), 0);
+  if (add_str.length_i ())
     {
-      inversion_str = inversion_p_->str ();
-      inversion_str = "/" + inversion_str.left_str (1).upper_str ()
-       + acc[inversion_p_->accidental_i_ + 2];
+      if (!name_p->addition_mol.empty_b ())
+        add_str = "/" + add_str;
+      name_p->addition_mol.add_at_edge (X_AXIS, RIGHT,
+       lookup_l ()->text ("script", add_str, paper_l ()), 0);
     }
-
-  String bass_str;
-  if (bass_p_)
-    {
-      bass_str = bass_p_->str ();
-      bass_str = "/" + bass_str.left_str (1).upper_str ()
-       + acc[bass_p_->accidental_i_ + 2];
-
-    }
-
-  return tonic_str + minor_str + "$^{" + str + "}$" + inversion_str + bass_str;
 }
 
+
 int
 Chord::find_tonic_i (Array<Musical_pitch> const* pitch_arr_p)
 {
@@ -648,3 +762,83 @@ Chord::rebuild_with_bass (Array<Musical_pitch>* pitch_arr_p, int bass_i)
       bass.octave_i_--;
   pitch_arr_p->insert (bass, 0);
 }
+
+Molecule*
+Chord::do_brew_molecule_p () const
+{
+  Musical_pitch tonic = pitch_arr_[0];
+  
+  Chord_name name;
+  name.tonic_mol = pitch2molecule (tonic);
+
+  /*
+    if user has explicitely listed chord name, use that
+    
+    TODO
+    urg
+    maybe we should check all sub-lists of pitches, not
+    just full list and base triad?
+   */
+  if (!user_chord_name (pitch_arr_, &name))
+    {
+      /*
+        else, check if user has listed base triad
+       use user base name and add banter for remaining part
+       */
+      if ((pitch_arr_.size () > 2)
+         && user_chord_name (pitch_arr_.slice (0, 3), &name))
+        {
+         Array<Musical_pitch> base = base_arr (tonic);
+         base.concat (pitch_arr_.slice (3, pitch_arr_.size ()));
+         banter (base, &name);
+       }
+      /*
+        else, use pure banter
+       */
+      else
+       {
+         banter (pitch_arr_, &name);
+       }
+    }
+
+  if (inversion_p_)
+    {
+      name.inversion_mol = lookup_l ()->text ("", "/", paper_l ());
+      // zucht  const&
+      Molecule mol = pitch2molecule (*inversion_p_);
+      name.inversion_mol.add_at_edge (X_AXIS, RIGHT, mol, 0);
+    }
+
+  if (bass_p_)
+    {
+      name.bass_mol = lookup_l ()->text ("", "/", paper_l ());
+      Molecule mol = pitch2molecule (*bass_p_);
+      name.bass_mol.add_at_edge (X_AXIS, RIGHT, mol, 0);
+    }
+
+  // urg, howto get a good superscript_y?
+  Real super_y = lookup_l ()->text ("", "x", paper_l ()).dim_.y ().length ()/2;
+  if (!name.addition_mol.empty_b ())
+    name.addition_mol.translate (Offset (0, super_y));
+
+  Molecule* mol_p = new Molecule;
+  mol_p->add_at_edge (X_AXIS, RIGHT, name.tonic_mol, 0);
+  // huh?
+  if (!name.modifier_mol.empty_b ())
+    mol_p->add_at_edge (X_AXIS, RIGHT, name.modifier_mol, 0);
+  if (!name.addition_mol.empty_b ())
+    mol_p->add_at_edge (X_AXIS, RIGHT, name.addition_mol, 0);
+  if (!name.inversion_mol.empty_b ())
+    mol_p->add_at_edge (X_AXIS, RIGHT, name.inversion_mol, 0);
+  if (!name.bass_mol.empty_b ())
+    mol_p->add_at_edge (X_AXIS, RIGHT, name.bass_mol, 0);
+  return mol_p;
+}
+
+void
+Chord::do_print () const
+{
+#ifndef NPRINT
+  //DEBUG_OUT <<  "chord = " ...
+#endif
+}
index 4843fae8e999b32668af8af6fe1660eddc4af931..f5e52ee7823e0a048f68fe1d4bf8ffb8ccd2679d 100644 (file)
@@ -28,8 +28,7 @@ protected:
 
 private:
   Array<Musical_pitch> pitch_arr_;
-  Link_array<Item> text_p_arr_;
-  Array<Musical_pitch> rebuild_pitch_arr (int tonic_i) const;
+  Chord* chord_p_;
   Tonic_req* tonic_req_;
   Inversion_req* inversion_req_;
   Bass_req* bass_req_;
index 871189fafc1c958deea2962691daf27cbb1c76a0..e568f709854c704ff1f949bbf33df4d83a84b334 100644 (file)
 #include "array.hh"
 #include "musical-pitch.hh"
 #include "lily-proto.hh"
+#include "item.hh"
+#include "molecule.hh"
 
-class Chord
+class Chord_name
 {
 public:
+  Molecule tonic_mol;
+  Molecule modifier_mol;
+  Molecule addition_mol;
+  Molecule inversion_mol;
+  Molecule bass_mol;
+};
+
+class Chord : public Item
+{
+public:
+  VIRTUAL_COPY_CONS (Score_element);
+  static Array<Musical_pitch> base_arr (Musical_pitch p);
   static int find_tonic_i (Array<Musical_pitch> const*);
   static int find_pitch_i (Array<Musical_pitch> const*, Musical_pitch p);
   static int find_notename_i (Array<Musical_pitch> const*, Musical_pitch p);
   static Array<Musical_pitch> missing_thirds_pitch_arr (Array<Musical_pitch> const* pitch_arr_p);
   static void rebuild_from_base (Array<Musical_pitch>*, int base_i);
   static void rebuild_insert_inversion (Array<Musical_pitch>*, int tonic_i);
-  static void rebuild_transpose (Array<Musical_pitch>*, Musical_pitch tonic);
+  static void rebuild_transpose (Array<Musical_pitch>*, Musical_pitch tonic, bool fix7_b);
   static void rebuild_with_bass (Array<Musical_pitch>*, int bass_i);
   static int step_i (Musical_pitch tonic, Musical_pitch p);
 
   Chord (Array<Musical_pitch> pitch_arr, Musical_pitch* inversion_p, Musical_pitch* bass_p);
-  Chord (Chord const& chord);
-  ~Chord ();
+  Chord (Chord const&);
+  virtual ~Chord ();
 
 
   Array<Musical_pitch> to_pitch_arr () const;
 
-  String banter_str () const;
-  void find_additions_and_subtractions(Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p) const;
+  void find_additions_and_subtractions(Array<Musical_pitch> pitch_arr, Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p) const;
+
+  Molecule ly_word2molecule (SCM scm) const;
+  Molecule ly_text2molecule (SCM scm) const;
+  Molecule pitch2molecule (Musical_pitch p) const;
+  bool user_chord_name (Array<Musical_pitch> pitch_arr, Chord_name* name_p) const;
+  void banter (Array<Musical_pitch> pitch_arr, Chord_name* name_p) const;
 
   Array<Musical_pitch> pitch_arr_;
   Musical_pitch* inversion_p_;
   Musical_pitch* bass_p_;
+
+protected:
+  virtual Molecule* do_brew_molecule_p () const;
+  virtual void do_print () const;
 };
 
 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);
index ef3942dd66576cf82a7927e22077c095c1b5be33..6f16728730735c25ce8006e0e96b3ba6f2e01094 100644 (file)
@@ -2,6 +2,8 @@
  chord modifiers
 %}
 
+#(eval-string (ly-gulp-file "chord-names.scm"))
+
 \chordmodifiers {
        m       = \musicalpitch { 0 2 -1 }
        min     = \musicalpitch { 0 2 -1 }
index 2026d92ba536c8371940c524855661a87fb907c9..25222f488d0047d34a24b163ce37a55e8476f743 100644 (file)
@@ -11,6 +11,7 @@ paper_eleven = \paper {
        font_large = 8.;
        font_Large = 6.;
        font_normal = 5.;
+       font_script = 4.;
 
        font_finger = 4.;
        font_volta = 4.;
@@ -18,10 +19,15 @@ paper_eleven = \paper {
        font_dynamic = 10.;
        font_mark = 6.;
        magnification_dynamic = -4.0;
+
        -1=\font "feta11"
        -2=\font "feta11"
        0=\font "feta11"
 
+       "font_feta-2" = 11.;
+       "font_feta-1" = 11.;
+       "font_feta" = 11.;
+
        \include "params.ly";
 }
 
index afe0cd5651acc36eabce1c512c3006f314085486..65d412981e976835751971599d4244a7c1c73303 100644 (file)
@@ -11,6 +11,7 @@ paper_thirteen = \paper {
        font_large = 8.;
        font_Large = 6.;
        font_normal = 5.;
+       font_script = 4.;
 
        font_finger = 4.;
        font_volta = 4.;
@@ -20,6 +21,10 @@ paper_thirteen = \paper {
 
        0=\font "feta13"
        -1=\font "feta11"
+
+       "font_feta-2" = 11.;
+       "font_feta-1" = 11.;
+       "font_feta" = 13.;
        
        \include "params.ly";
 }
index f9a2a248e3964d09a30e4a95f59a8338900502ea..14fab61a393479666a135adb1c1ed6496254bdf8 100644 (file)
@@ -14,6 +14,8 @@ paper_sixteen = \paper {
        font_large = 12.;
        font_Large = 10.;
        font_normal = 8.;
+       font_script = 7.;
+
        magnification_dynamic = 1.0;
        font_finger = 4.;
        font_volta = 5.;
@@ -25,6 +27,10 @@ paper_sixteen = \paper {
        -1 = \font "feta13"
        -2 = \font "feta11"
        
+       "font_feta-2" = 11.;
+       "font_feta-1" = 13.;
+       "font_feta" = 16.;
+
        \include "params.ly";
 }
 
index 24983c1710ba96fdfd5557bf34fa76cf07d65d95..65f9100c738c9db35f2dce3157633af33d16a548 100644 (file)
@@ -9,6 +9,7 @@ paper_twenty = \paper {
        font_large = 12.;
        font_Large = 12.;       
        font_normal = 10.;
+       font_script = 8.;
 
        font_finger = 5.;
        font_volta = 8.;
@@ -31,6 +32,10 @@ paper_twenty = \paper {
        -1 = \font "feta16"
        0 = \font "feta20"
 
+       "font_feta-2" = 13.;
+       "font_feta-1" = 16.;
+       "font_feta" = 20.;
+
        \include "params.ly";
 }
 
index 46a9f25b8fd6d38ef172a44ec45ee6ad44fc2da4..7a129b3356b4d107a2d813ba71e632a257f8eb6f 100644 (file)
@@ -9,6 +9,7 @@ paper_twentythree = \paper {
        font_large = 12.;
        font_Large = 12.;       
        font_normal = 10.;
+       font_script = 8.;
 
        font_finger = 5.;
        font_volta = 8.;
@@ -26,6 +27,10 @@ paper_twentythree = \paper {
        -1 = \font "feta20"
        0 = \font "feta23"
 
+       "font_feta-2" = 16.;
+       "font_feta-1" = 20.;
+       "font_feta" = 23.;
+
        \include "params.ly";
 }
 
index 84d29e891b63c7336b686821557e63e85f792c53..4842149001ac96897177d96bba57edbcdf6f9b39 100644 (file)
@@ -9,6 +9,8 @@ paper_twentysix = \paper {
        font_large = 14.;
        font_Large = 17.;       
        font_normal = 12.;
+       font_script = 10.;
+
        font_dynamic = 10.;
        % Ugh
        magnification_dynamic = 4.;
@@ -22,6 +24,11 @@ paper_twentysix = \paper {
        0=\font "feta26"
        -1 = \font "feta23"
        -2 = \font "feta20"
+
+       "font_feta-2" = 20.;
+       "font_feta-1" = 23.;
+       "font_feta" = 26.;
+
        \include "params.ly";
 }
 
diff --git a/scm/chord-names.scm b/scm/chord-names.scm
new file mode 100644 (file)
index 0000000..597679a
--- /dev/null
@@ -0,0 +1,67 @@
+;; pitch: (notename . accidental)
+;; list:  (list-of-pitches . (modifier-string . addition-subtraction-string))
+
+;; if a complete chord is found, use name
+;; if a chord's base triad is found (c e g), use name
+
+(define pitch-names-alist '())
+(set! pitch-names-alist
+      (append 
+      '(
+       ; use these for German naming
+       ;((6 . 0) . ("H" ""))
+       ;((6 . -1) . ("B" ("feta-1" . "\12")))
+
+       ; urg, temp hack for accidental size: can't set from Chord::
+       ((0 . 1) . ("C" ("feta-1" . "\10")))
+       ((1 . 1) . ("D" ("feta-1" . "\10")))
+       ((2 . 1) . ("E" ("feta-1" . "\10")))
+       ((3 . 1) . ("F" ("feta-1" . "\10")))
+       ((4 . 1) . ("G" ("feta-1" . "\10")))
+       ((5 . 1) . ("A" ("feta-1" . "\10")))
+       ((6 . 1) . ("B" ("feta-1" . "\10")))
+
+       ((0 . -1) . ("C" ("feta-1" . "\12")))
+       ((1 . -1) . ("D" ("feta-1" . "\12")))
+       ((2 . -1) . ("E" ("feta-1" . "\12")))
+       ((3 . -1) . ("F" ("feta-1" . "\12")))
+       ((4 . -1) . ("G" ("feta-1" . "\12")))
+       ((5 . -1) . ("A" ("feta-1" . "\12")))
+       ((6 . -1) . ("B" ("feta-1" . "\12")))
+       )
+      pitch-names-alist))
+
+(define (user-pitch-name pitch)
+  (let ((entry (assoc pitch pitch-names-alist)))
+       (if entry
+          (cdr entry))))
+
+(define chord-names-alist '())
+(set! chord-names-alist
+      (append 
+      '(
+       ; C iso C.no3.no5
+       (((0 . 0)) . ("" . ""))
+       ; C iso C.no5
+       (((0 . 0) (2 . 0)) . ("" . ""))
+       ; Cm iso Cm.no5
+       (((0 . 0) (2 . -1)) . ("m" . ""))
+       ; Cdim iso Cm5-
+       (((0 . 0) (2 . -1) (4 . -1)) . ("dim" . ""))
+       ; Co iso Cm5-7-
+       ; urg
+        ; (((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . ("" . ("feta-1" . ".")))
+        (((0 . 0) (2 . -1) (4 . -1) (6 . -2)) . ("" . ("script" . "o")))
+       ; Cdim9
+       (((0 . 0) (2 . -1) (4 . -1) (6 . -2) (1 . -1)) . ("dim" . ("script" . "9")))
+       (((0 . 0) (2 . -1) (4 . -1) (6 . -2) (1 . -1) (3 . -1)) . ("dim" . ("script" . "11")))
+       )
+      chord-names-alist))
+
+(define (user-chord-name chord)
+  ;(display chord)
+  ;(newline)
+  (let ((entry (assoc chord chord-names-alist)))
+       (if entry
+          (cdr entry))))
+
index 980344441cd422a74c4270ca61b9be3d766206e2..a453194146b0020c8c7a43a0d391786831503759 100644 (file)
 
 ;;;;;;;; TeX
 
+;; this is silly, can't we use something like
+;; roman-0, roman-1 roman+1 ?
 (define cmr-alist 
   '(("bold" . "cmbx") 
     ("dynamic" . "feta-din") 
+    ("feta" . "feta") 
+    ("feta-1" . "feta") 
+    ("feta-2" . "feta") 
     ("finger" . "feta-nummer") 
     ("typewriter" . "cmtt") 
     ("italic" . "cmti") 
     ("roman" . "cmr") 
+    ("script" . "cmr") 
     ("large" . "cmbx") 
     ("Large" . "cmbx") 
     ("mark" . "feta-nummer")