From d864729ad03ef6962ae3ff3135c5a70ec248a178 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Fri, 5 Nov 1999 14:50:31 +0100 Subject: [PATCH] patch::: 1.3.2.jcn3 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 --- CHANGES | 10 + TODO | 4 + VERSION | 2 +- flower/include/array.hh | 4 +- flower/include/array.icc | 4 +- input/test/banter-chords.ly | 66 +++++ input/test/chords.ly | 4 +- lily/chord-name-engraver.cc | 29 +- lily/chord.cc | 410 ++++++++++++++++++++-------- lily/include/chord-name-engraver.hh | 3 +- lily/include/chord.hh | 35 ++- ly/chord-modifiers.ly | 2 + ly/paper11.ly | 6 + ly/paper13.ly | 5 + ly/paper16.ly | 6 + ly/paper20.ly | 5 + ly/paper23.ly | 5 + ly/paper26.ly | 7 + scm/chord-names.scm | 67 +++++ scm/lily.scm | 6 + 20 files changed, 535 insertions(+), 145 deletions(-) create mode 100644 input/test/banter-chords.ly create mode 100644 scm/chord-names.scm diff --git a/CHANGES b/CHANGES index e618029ba5..068c46dcaf 100644 --- 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 07f05fc75b..95366c40c2 100644 --- 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 ad6cafe6de..0d7c252ced 100644 --- 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. diff --git a/flower/include/array.hh b/flower/include/array.hh index d6349588aa..f8f6e352fd 100644 --- a/flower/include/array.hh +++ b/flower/include/array.hh @@ -13,7 +13,7 @@ #endif /// copy a bare (C-)array from #src# to #dest# sized #count# -template void arrcpy (T*dest, T*src, int count); +template 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 slice (int lower, int upper) ; + Array slice (int lower, int upper) const; void reverse(); }; diff --git a/flower/include/array.icc b/flower/include/array.icc index 8b876ce85d..71de84a8ac 100644 --- a/flower/include/array.icc +++ b/flower/include/array.icc @@ -19,7 +19,7 @@ */ template 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::remove_array_p () template INLINE Array -Array::slice (int lower, int upper) +Array::slice (int lower, int upper) const { assert (lower >= 0 && lower <=upper&& upper <= size_); Array r; diff --git a/input/test/banter-chords.ly b/input/test/banter-chords.ly new file mode 100644 index 0000000000..307b8656fa --- /dev/null +++ b/input/test/banter-chords.ly @@ -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" . ""))) + ) + 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 + > +} + diff --git a/input/test/chords.ly b/input/test/chords.ly index c74d502430..cf6251d30d 100644 --- a/input/test/chords.ly +++ b/input/test/chords.ly @@ -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 diff --git a/lily/chord-name-engraver.cc b/lily/chord-name-engraver.cc index ef0744d627..21f0a99f1a 100644 --- a/lily/chord-name-engraver.cc +++ b/lily/chord-name-engraver.cc @@ -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; diff --git a/lily/chord.cc b/lily/chord.cc index adef8d4991..8dbc57a6c7 100644 --- a/lily/chord.cc +++ b/lily/chord.cc @@ -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* add_arr_p, Array* 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* add_arr_p, Array* add_arr_p, Array 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 +Chord::base_arr (Musical_pitch p) +{ + Array 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* pitch_arr_p, Musical_pitch tonic) +Chord::rebuild_transpose (Array* 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 - if (q.notename_i_ == 6) - q.accidental_i_--; p.transpose (q); + // duh, c7 should mean + 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* add_arr_p, Array* sub_arr_p) const +Chord::find_additions_and_subtractions (Array pitch_arr, Array* add_arr_p, Array* 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 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 * add_arr_p, Array* add_arr_p, Arraypush (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 pitch_arr, Chord_name* name_p) const +{ + SCM chord = SCM_EOL; + Array 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 pitch_arr, Chord_name* name_p) const +{ Array add_arr; Array sub_arr; - find_additions_and_subtractions (&add_arr, &sub_arr); + find_additions_and_subtractions (pitch_arr, &add_arr, &sub_arr); - Array 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 const* pitch_arr_p) { @@ -648,3 +762,83 @@ Chord::rebuild_with_bass (Array* 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 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 +} diff --git a/lily/include/chord-name-engraver.hh b/lily/include/chord-name-engraver.hh index 4843fae8e9..f5e52ee782 100644 --- a/lily/include/chord-name-engraver.hh +++ b/lily/include/chord-name-engraver.hh @@ -28,8 +28,7 @@ protected: private: Array pitch_arr_; - Link_array text_p_arr_; - Array rebuild_pitch_arr (int tonic_i) const; + Chord* chord_p_; Tonic_req* tonic_req_; Inversion_req* inversion_req_; Bass_req* bass_req_; diff --git a/lily/include/chord.hh b/lily/include/chord.hh index 871189fafc..e568f70985 100644 --- a/lily/include/chord.hh +++ b/lily/include/chord.hh @@ -12,33 +12,56 @@ #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 base_arr (Musical_pitch p); static int find_tonic_i (Array const*); static int find_pitch_i (Array const*, Musical_pitch p); static int find_notename_i (Array const*, Musical_pitch p); static Array missing_thirds_pitch_arr (Array const* pitch_arr_p); static void rebuild_from_base (Array*, int base_i); static void rebuild_insert_inversion (Array*, int tonic_i); - static void rebuild_transpose (Array*, Musical_pitch tonic); + static void rebuild_transpose (Array*, Musical_pitch tonic, bool fix7_b); static void rebuild_with_bass (Array*, int bass_i); static int step_i (Musical_pitch tonic, Musical_pitch p); Chord (Array pitch_arr, Musical_pitch* inversion_p, Musical_pitch* bass_p); - Chord (Chord const& chord); - ~Chord (); + Chord (Chord const&); + virtual ~Chord (); Array to_pitch_arr () const; - String banter_str () const; - void find_additions_and_subtractions(Array* add_arr_p, Array* sub_arr_p) const; + void find_additions_and_subtractions(Array pitch_arr, Array* add_arr_p, Array* 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 pitch_arr, Chord_name* name_p) const; + void banter (Array pitch_arr, Chord_name* name_p) const; Array 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* add_arr_p, Array* sub_arr_p, Musical_pitch* inversion_p, Musical_pitch* bass_p); diff --git a/ly/chord-modifiers.ly b/ly/chord-modifiers.ly index ef3942dd66..6f16728730 100644 --- a/ly/chord-modifiers.ly +++ b/ly/chord-modifiers.ly @@ -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 } diff --git a/ly/paper11.ly b/ly/paper11.ly index 2026d92ba5..25222f488d 100644 --- a/ly/paper11.ly +++ b/ly/paper11.ly @@ -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"; } diff --git a/ly/paper13.ly b/ly/paper13.ly index afe0cd5651..65d412981e 100644 --- a/ly/paper13.ly +++ b/ly/paper13.ly @@ -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"; } diff --git a/ly/paper16.ly b/ly/paper16.ly index f9a2a248e3..14fab61a39 100644 --- a/ly/paper16.ly +++ b/ly/paper16.ly @@ -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"; } diff --git a/ly/paper20.ly b/ly/paper20.ly index 24983c1710..65f9100c73 100644 --- a/ly/paper20.ly +++ b/ly/paper20.ly @@ -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"; } diff --git a/ly/paper23.ly b/ly/paper23.ly index 46a9f25b8f..7a129b3356 100644 --- a/ly/paper23.ly +++ b/ly/paper23.ly @@ -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"; } diff --git a/ly/paper26.ly b/ly/paper26.ly index 84d29e891b..4842149001 100644 --- a/ly/paper26.ly +++ b/ly/paper26.ly @@ -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 index 0000000000..597679a2cf --- /dev/null +++ b/scm/chord-names.scm @@ -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" . ""))) + + ; urg, temp hack for accidental size: can't set from Chord:: + ((0 . 1) . ("C" ("feta-1" . ""))) + ((1 . 1) . ("D" ("feta-1" . ""))) + ((2 . 1) . ("E" ("feta-1" . ""))) + ((3 . 1) . ("F" ("feta-1" . ""))) + ((4 . 1) . ("G" ("feta-1" . ""))) + ((5 . 1) . ("A" ("feta-1" . ""))) + ((6 . 1) . ("B" ("feta-1" . ""))) + + ((0 . -1) . ("C" ("feta-1" . ""))) + ((1 . -1) . ("D" ("feta-1" . ""))) + ((2 . -1) . ("E" ("feta-1" . ""))) + ((3 . -1) . ("F" ("feta-1" . ""))) + ((4 . -1) . ("G" ("feta-1" . ""))) + ((5 . -1) . ("A" ("feta-1" . ""))) + ((6 . -1) . ("B" ("feta-1" . ""))) + ) + 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)))) + diff --git a/scm/lily.scm b/scm/lily.scm index 980344441c..a453194146 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -132,13 +132,19 @@ ;;;;;;;; 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") -- 2.39.5