From 3c7d0c2e1ed1b752c0e0a3ce1dba04358308783c Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Mon, 1 Nov 1999 23:12:31 +0100 Subject: [PATCH] patch::: 1.3.2.jcn1 pl 2.jcn1 - chord fixes: * inversion request: no inversion guessing for chord entry * bass request: c/+b to add bass note not part of chord * -dim modifier works on all thirds * colon iso dash as tonic/modifier-additions separator * C:m5- displays as "Cdim" * C:m5-7- displays as "Co" --- CHANGES | 9 + Documentation/user/refman.itely | 28 +- Documentation/user/tutorial.itely | 16 +- TODO | 22 -- VERSION | 2 +- input/bugs/barline.ly | 2 +- input/bugs/monstrous.ly | 10 +- input/just-friends.ly | 19 +- input/test/chord-inversion.ly | 12 +- input/test/chord-table.ly | 2 +- input/test/chords.ly | 27 +- input/test/gmsusd.ly | 11 +- input/test/notemode-chords.ly | 2 +- input/tutorial/flowing.ly | 4 +- input/twinkle-pop.ly | 8 +- lily/chord-name-engraver.cc | 35 +- lily/chord.cc | 573 +++++++++++++++++----------- lily/include/chord-name-engraver.hh | 2 + lily/include/chord.hh | 31 +- lily/include/lily-proto.hh | 2 + lily/include/musical-request.hh | 14 +- lily/include/my-lily-parser.hh | 2 +- lily/lexer.ll | 6 + lily/my-lily-parser.cc | 25 +- lily/note-heads-engraver.cc | 8 + lily/parser.yy | 24 +- ly/chord-modifiers.ly | 4 +- 27 files changed, 549 insertions(+), 351 deletions(-) diff --git a/CHANGES b/CHANGES index 8cae195f22..e618029ba5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,12 @@ +pl 2.jcn1 + - chord fixes: + * inversion request: no inversion guessing for chord entry + * bass request: c/+b to add bass note not part of chord + * -dim modifier works on all thirds + * colon iso dash as tonic/modifier-additions separator + * C:m5- displays as "Cdim" + * C:m5-7- displays as "Co" + pl 3.jcn1 - moved bracket vars to params - reverted broken lilypond-devel diff --git a/Documentation/user/refman.itely b/Documentation/user/refman.itely index bea07dc13d..b772f4b7a7 100644 --- a/Documentation/user/refman.itely +++ b/Documentation/user/refman.itely @@ -1475,7 +1475,7 @@ Chord mode (see section XREF-modes [FIXME]). @example - @var{tonic}[@var{duration}][@code{-}@var{modifiers}][@code{^}@var{subtractions}][@code{/}@var{inversion}]. + @var{tonic}[@var{duration}][@code{-}@var{modifiers}][@code{^}@var{subtractions}][@code{/}@var{inversion}][@code{/+}@var{bass}]. @end example @var{tonic} should be the tonic note of the chord, and @var{duration} @@ -1493,15 +1493,15 @@ must be separated by a dot (`@code{.}'). @mudela[fragment,verbatim] \transpose c'' { \chords { - c1 c-3- c-7 c-8 - c-9 c-9-.5+.7+ c-3-.5- c-4.6.8 + c1 c:3- c:7 c:8 + c:9 c:9-.5+.7+ c:3-.5- c:4.6.8 } } @end mudela @end quotation -The second type of modifier that may appear after the `@code{-}' is a +The second type of modifier that may appear after the `@code{:}' is a named modifier. Named modifiers are listed in the file @file{chord-modifiers.ly}. The available modifiers are `@code{m}' and `@code{min}' which lower the 3rd half a step, `@code{aug}@indexcode{aug}' which @@ -1514,7 +1514,7 @@ which replaces the 5th with a 4th. @mudela[fragment,verbatim] \transpose c'' { \chords { - c1-m c-min7 c-maj c-aug c-dim c-sus + c1:m c:min7 c:maj c:aug c:dim c:sus } } @@ -1529,7 +1529,7 @@ separated by dots. @mudela[fragment,verbatim,center] \transpose c'' { \chords { - c1^3 c-7^5.3 c-8^7 + c1^3 c:7^5.3 c:8^7 } } @end mudela @@ -1543,7 +1543,21 @@ warning will be printed. @mudela[fragment,verbatim,center] \transpose c''' { \chords { - c1 c/e c/g c-7/e + c1 c/e c/g c:7/e + } + } + +@end mudela + +Bass notes can be added by `@code{/+}@indexcode{/+}' and +the name of a single note to a chord. This has the effect of +adding the specified note to the chord, lowered by an octave, +so it becomes the lowest note in the chord. + +@mudela[fragment,verbatim,center] + \transpose c''' { + \chords { + c1 c/+c c/+g c:7/+b } } diff --git a/Documentation/user/tutorial.itely b/Documentation/user/tutorial.itely index 5029f7fa34..a5d540afc5 100644 --- a/Documentation/user/tutorial.itely +++ b/Documentation/user/tutorial.itely @@ -346,8 +346,8 @@ text = \lyrics @{ accompaniment =\chords @{ r8 - c2-3- f-3-.7 d-min es4 c8-min r8 - c2-min f-min7 g-7^3.5 c-min @} + c2:3- f:3-.7 d:min es4 c8:min r8 + c2:min f:min7 g:7^3.5 c:min @} \score @{ \simultaneous @{ @@ -397,8 +397,8 @@ text = \lyrics { accompaniment =\chords { r8 - c2-3- f-3-.7 d-min es4 c8-min r8 - c2-min f-min7 g-7^3.5 c-min } + c2:3- f:3-.7 d:min es4 c8:min r8 + c2:min f:min7 g:7^3.5 c:min } \score { \simultaneous { @@ -513,7 +513,7 @@ of the chords you want, instead of the notes comprising the chord. @end example There is no accompaniment during the anacrusis.@example - c2-3- f-3-.7 + c2:3- f:3-.7 @end example A chord is started by the tonic of the chord. The @@ -523,19 +523,19 @@ be small. @code{7} modifies (adds) a seventh, which is small by default to create the @code{f a c es} chord. Multiple modifiers must be separated by a dot.@example - d-min es4 c8-min r8 + d:min es4 c8:min r8 @end example Some modifiers have predefined names, eg. @code{min} is the same as @code{3-}, so @code{d-min} is a minor @code{d} chord.@example - c2-min f-min7 g-7^3.5 c-min @} + c2:min f:min7 g:7^3.5 c:min @} @end example A named modifier @code{min} and a normal modifier @code{7} do not have to be separated by a dot. Tones from a chord are removed with chord subtractions. Subtractions are started with a caret, and they are -also separated by dots. In this example, @code{g-7^3.5} produces a +also separated by dots. In this example, @code{g:7^3.5} produces a minor seventh. The brace ends the sequential music. @example \score @{ diff --git a/TODO b/TODO index 813dcad6e0..07f05fc75b 100644 --- a/TODO +++ b/TODO @@ -36,28 +36,6 @@ John . * fix or replace feta-accordion.mf . * script engraver . * bracket pdf hack -. * Chords: -. * Bass/inversion pitch when not part of Chord -Sometimes a series of changing chords will be blocked out over a static tone -in the bass, usually this was referred to as a pedal tone (and it's been -continued to be used, even in contemporary music). Another less frequently -used practice is putting a non-chordal tone in the bass (that is not acting -as a pedal tone) in order to create tension or make a more colorful sound. -There are examples of this in the classsical literature, but its use is much -more prevalent today. For example, the chord sequence Dm7 - Dm7/G is such a -sequence, and the Dm7/G defies easy classification. Is it a G7(no 3rd)add -9/11? Or is it a G7(no 3rd)add2/4? Or perhaps Dm7 add11? It's a heck of a -lot easier to read to just leave it as Dm7/G! -. * Diminished does not mean 5- -When speaking of a chord, dimished can mean one of two things: A diminished -triad or a dimished seventh chord (which is distinctly different from what's -known as the 'half-diminished' chord). The triad is a root with a flat -third and flat fifth, and is notated (at least in America, someone else will -have to fill me in on other countries) as (using C as the root) Cdim, or Co. -The diminished seventh has a root with a flat third, flat fifth, and a -doubly flatted seventh (which is enharmonically equivalent to a sixth, and -from which comes tons of confusion). It is usually notated as (again, using -C as the root) Cdim7 or Co7. . * Mondrup: - I would like the possibility of forcing clef- and key- changes to be diff --git a/VERSION b/VERSION index af709f6918..ad6cafe6de 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=3 PATCH_LEVEL=2 -MY_PATCH_LEVEL= +MY_PATCH_LEVEL=jcn1 # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/input/bugs/barline.ly b/input/bugs/barline.ly index c9c9699906..97ac88ac61 100644 --- a/input/bugs/barline.ly +++ b/input/bugs/barline.ly @@ -15,7 +15,7 @@ melody = \notes \relative c' { accompaniment =\chords \sequential { r8 - c2-min f-min 7 + c2:min f:min 7 } \score { diff --git a/input/bugs/monstrous.ly b/input/bugs/monstrous.ly index 52ca68966f..e25ea236e5 100644 --- a/input/bugs/monstrous.ly +++ b/input/bugs/monstrous.ly @@ -1,12 +1,14 @@ +%% Chord gurus, is this ok now?? + monstrous= \chords{ \property Score.chordInversion = "1" - % /c is missing: - bes-6/c + % /c is/was missing: + bes:6/+c - % Cdim7 ?? - cis-3-.5-.6 + % Cdim7 + c:dim7 } \score{ diff --git a/input/just-friends.ly b/input/just-friends.ly index a6cc637cb3..3b273123c7 100644 --- a/input/just-friends.ly +++ b/input/just-friends.ly @@ -31,18 +31,17 @@ of a certain tune (Jazz, Real Book, for example), like \score{ \context ChordNames \chords{ - \property Score.chordInversion = 1 \property Score.barAtLineStart = 1 \repeat semi 2 { - f1-maj f-maj f-7 bes-7 - c-maj c-maj es es - d-7 g-7 b2-7/fis e-7 a1-7\break - d-7 d-7 d-7 g2-7 ges-7 - - f1-maj f1-maj f-7 bes-7 - c-maj c-maj es es - d-7 g-7 b2-7/fis e-7 a1-7\break - d-7 d2-7 g-7 c1-6 g2-7 c-7 + f1:maj f:maj f:7 bes:7 + c:maj c:maj es es + d:7 g:7 b2:7/fis e:7 a1:7\break + d:7 d:7 d:7 g2:7 ges:7 + + f1:maj f1:maj f:7 bes:7 + c:maj c:maj es es + d:7 g:7 b2:7/fis e:7 a1:7\break + d:7 d2:7 g:7 c1:6 g2:7 c:7 } } \paper{ diff --git a/input/test/chord-inversion.ly b/input/test/chord-inversion.ly index 315561dbca..c54281fa6d 100644 --- a/input/test/chord-inversion.ly +++ b/input/test/chord-inversion.ly @@ -5,14 +5,12 @@ TestedFeatures = "chord inversions"; } inversions = \notes\transpose c''\chords{ - % inversions ignored here - c1 c-sus c-6 c/e c/g c/d - % now try to find chords with inversions - \property Score.chordInversion = 1 - c1 c-sus c-6 - c/e - c/g + % inversions + c1 c:sus c:6 c/e c/g c/d % this triggers a warning: no 'd' in chord of c + + % added bass + c/+e c/+c c/+b } \score{ diff --git a/input/test/chord-table.ly b/input/test/chord-table.ly index 40e599521a..94df658308 100644 --- a/input/test/chord-table.ly +++ b/input/test/chord-table.ly @@ -5,7 +5,7 @@ enteredby = "jcn"; } tab = \notes\transpose c'''\chords{ - c1 c-m c-4 c-m4 c-5+ c-5- c-m5- c-5-.5+ c-6\break %c-m6\break + c1 c:m c:4 c:m4 c:5+ c:5- c:dim c:5-.5+ c:6\break %c:m6\break } \score{ diff --git a/input/test/chords.ly b/input/test/chords.ly index e4e3e756ce..c74d502430 100644 --- a/input/test/chords.ly +++ b/input/test/chords.ly @@ -7,26 +7,27 @@ Would this be acceptable/good enough/convenient for entry? C# cis Cb ces - Cm; Cmin c-3-; c-m; c-min - Caug c-5+; c-aug; - Cdim c-5-; c-dim - Cmaj7 c-7+; c-maj - C7 c-7 - Csus; Csus4 c-4; c-sus + Cm; Cmin c:3-; c:m; c:min + Caug c:5+; c:aug; + Cdim c:3-:5-; c:dim + Cmaj7 c:7+; c:maj + C7 c:7 + Csus; Csus4 c:4; c:sus %} scales = \notes \transpose c'' \chords{ % - c1-m c-min c4-dim c-aug c-sus c-maj - c1-6 c4-7 c-9 c-11 c-13 - c-m7 c-m.sus c-m7.sus - c1-7^5 c-13^5.7.9.11 - % c1-7^5 c-13^5 + c1:m c:min c4:dim c:aug c:sus c:maj + c1:6 c4:7 c:9 c:11 c:13 + c:m7 c:m.sus c:m7.sus + c4:dim7 c:dim9 c2:7^5 + c:13^5.7.9.11 + % c1:7^5 c:13^5 c1 g d a e b fis c1 f bes es as des ges - % wierd, multiple -add, ^sub - c-7+.9-^3.5 + % wierd, multiple :add, ^sub + c:7+.9-^3.5 % long c\breve c\longa } diff --git a/input/test/gmsusd.ly b/input/test/gmsusd.ly index 6217946830..9ba7522e20 100644 --- a/input/test/gmsusd.ly +++ b/input/test/gmsusd.ly @@ -8,20 +8,19 @@ gmsus=\notes\relative c \chords{ g1 % Gm7sus4: the hard way - g1-3-.4.7 + g1:3-.4.7 % another hard way: \notes< g'1 bes c d f > % bit easier: - g1-m.4.7 + g1:m.4.7 - g1-m7.sus - g1-m7.sus4 + g1:m7.sus + g1:m7.sus4 % and finally: - \property Score.chordInversion = 1 - g1-m7.sus/d + g1:m7.sus/d } \score{ diff --git a/input/test/notemode-chords.ly b/input/test/notemode-chords.ly index ed0c154902..5652aa1f0d 100644 --- a/input/test/notemode-chords.ly +++ b/input/test/notemode-chords.ly @@ -5,7 +5,7 @@ % 1.1.53: @x@ syntax dropped % if you want fingering, write chord explicitily; eg < c1-1 e-2 g-3 > % @c1@ @c-7@ @c-7^5@-1-3 - \chords { c1 c-7 c-7^5 } + \chords { c1 c:7 c:7^5 } } } diff --git a/input/tutorial/flowing.ly b/input/tutorial/flowing.ly index 74339f3ceb..597dd2bed8 100644 --- a/input/tutorial/flowing.ly +++ b/input/tutorial/flowing.ly @@ -18,8 +18,8 @@ text = \lyrics { accompaniment =\chords { r8 - c2-3- f-3-.7 d-min es4 c8-min r8 - c2-min f-min7 g-7^3.5 c-min } + c2:3- f:3-.7 d:min es4 c8:min r8 + c2:min f:min7 g:7^3.5 c:min } \score { \simultaneous { diff --git a/input/twinkle-pop.ly b/input/twinkle-pop.ly index eb4cc83b2f..9df29ef6de 100644 --- a/input/twinkle-pop.ly +++ b/input/twinkle-pop.ly @@ -25,12 +25,12 @@ melodie = \notes\relative c'' { acc = \chords { % why don't \skip, s4 work? c2 c f c - f c g-7 c - g f c g-7 % urg, bug! - g f c g-7 + f c g:7 c + g f c g:7 % urg, bug! + g f c g:7 % copy 1-8 c2 c f c - f c g-7 c + f c g:7 c } text = \lyrics{ diff --git a/lily/chord-name-engraver.cc b/lily/chord-name-engraver.cc index 4c57efac7e..ef0744d627 100644 --- a/lily/chord-name-engraver.cc +++ b/lily/chord-name-engraver.cc @@ -21,7 +21,8 @@ ADD_THIS_TRANSLATOR (Chord_name_engraver); Chord_name_engraver::Chord_name_engraver () { tonic_req_ = 0; - // bass_req_ = 0; + inversion_req_ = 0; + bass_req_ = 0; } void @@ -44,14 +45,16 @@ Chord_name_engraver::do_try_music (Music* m) tonic_req_ = t; return true; } -#if 0 + if (Inversion_req* i = dynamic_cast (m)) + { + inversion_req_ = i; + return true; + } if (Bass_req* b = dynamic_cast (m)) { bass_req_ = b; return true; } -#endif - return false; } @@ -63,20 +66,13 @@ Chord_name_engraver::do_process_requests () if (!pitch_arr_.size ()) return; - Chord chord (pitch_arr_); - Musical_pitch* inversion = 0; + bool find_inversion_b = false; SCM chord_inversion = get_property ("chordInversion", 0); - if (gh_boolean_p (chord_inversion) && gh_scm2bool (chord_inversion)) - { - int tonic_i = tonic_req_ - ? chord.find_notename_i (tonic_req_->pitch_) : chord.find_tonic_i (); - - if (tonic_i) - { - inversion = &pitch_arr_[0]; - chord.rebuild_insert_inversion (tonic_i); - } - } + 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); Text_item* item_p = new Text_item; @@ -90,7 +86,7 @@ Chord_name_engraver::do_process_requests () item_p->text_str_ = chord.banter_str (inversion); */ - 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)); @@ -106,4 +102,7 @@ Chord_name_engraver::do_pre_move_processing () text_p_arr_.clear (); pitch_arr_.clear (); tonic_req_ = 0; + inversion_req_ = 0; + bass_req_ = 0; } + diff --git a/lily/chord.cc b/lily/chord.cc index b0b081e217..adef8d4991 100644 --- a/lily/chord.cc +++ b/lily/chord.cc @@ -6,25 +6,214 @@ (c) 1999 Jan Nieuwenhuizen */ +#include "chord.hh" +#include "musical-request.hh" +#include "warn.hh" + + /* - FIXME: + construct from parser output +*/ +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 + 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); + Chord::rebuild_transpose (sub_arr_p, tonic); + + 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 = 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 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 missing_arr = Chord::missing_thirds_pitch_arr (&tmp); + if (highest_step < 5) + missing_arr.push (fifth); + + 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 = tonic; + third.transpose (Musical_pitch (2)); + 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); + } - A triad is a chord of three tones, and not an interval of a third. + /* + 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 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 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; -#include "chord.hh" -#include "warn.hh" + 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_); + } -// doesn't seem common, and we should know about this during parsing -// #define INVERSION_ADDED_AS_BASE 1 + return Chord (pitch_arr, inversion_p, bass_p); +} -Chord::Chord (Array pitch_arr) +Chord::Chord (Array pitch_arr, Musical_pitch* inversion_p, Musical_pitch* bass_p) { pitch_arr_ = pitch_arr; + inversion_p_ = inversion_p; + bass_p_ = bass_p; +} + +Chord::Chord (Chord const& chord) +{ + pitch_arr_ = chord.pitch_arr_; + inversion_p_ = chord.inversion_p_ ? new Musical_pitch (*chord.inversion_p_) : 0; + bass_p_ = chord.bass_p_ ? new Musical_pitch (*chord.bass_p_) : 0; +} + +Chord::~Chord () +{ + delete inversion_p_; + delete bass_p_; } -static void -rebuild_transpose (Musical_pitch tonic, Array* pitch_arr_p) +void +Chord::rebuild_transpose (Array* pitch_arr_p, Musical_pitch tonic) { for (int i = 0; i < pitch_arr_p->size (); i++) { @@ -39,8 +228,8 @@ rebuild_transpose (Musical_pitch tonic, Array* pitch_arr_p) pitch_arr_p->sort (Musical_pitch::compare); } -static int -find_pitch_i (Array const* pitch_arr_p, Musical_pitch p) +int +Chord::find_pitch_i (Array const* pitch_arr_p, Musical_pitch p) { for (int i = 0; i < pitch_arr_p->size (); i++) if (p == (*pitch_arr_p)[i]) @@ -48,8 +237,8 @@ find_pitch_i (Array const* pitch_arr_p, Musical_pitch p) return -1; } -static int -find_notename_i (Array const* pitch_arr_p, Musical_pitch p) +int +Chord::find_notename_i (Array const* pitch_arr_p, Musical_pitch p) { int i = find_pitch_i (pitch_arr_p, p); if (i == -1) @@ -64,11 +253,8 @@ find_notename_i (Array const* pitch_arr_p, Musical_pitch p) return i; } -/* - trap (NL) != trap(english) - */ -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; @@ -78,15 +264,15 @@ trap_i (Musical_pitch tonic, Musical_pitch p) return i; } -static Array -missing_triads_pitch_arr (Arrayconst* pitch_arr_p) +Array +Chord::missing_thirds_pitch_arr (Array const* pitch_arr_p) { - Array triads; + Array 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; @@ -95,12 +281,12 @@ missing_triads_pitch_arr (Arrayconst* 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) { @@ -113,7 +299,7 @@ missing_triads_pitch_arr (Arrayconst* 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 @@ -126,150 +312,51 @@ missing_triads_pitch_arr (Arrayconst* pitch_arr_p) /* - construct from parser output -*/ -Chord::Chord (Musical_pitch tonic, Array* add_arr_p, Array* 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 +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 tmp = *add_arr_p; - int highest_trap = trap_i (tonic, tmp.top ()); - if (highest_trap < 5) - tmp.push (fifth); - - /* - find missing triads - */ - Array 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 pitch_arr = pitch_arr_; + if (inversion_p_) { 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_p_->notename_i_) + && (pitch_arr[i].accidental_i_ == inversion_p_->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_p_->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_p_) + { + pitch_arr.insert (*bass_p_, 0); + rebuild_with_bass (&pitch_arr, 0); + } + return pitch_arr; } void -Chord::find_additions_and_subtractions(Array* add_arr_p, Array* sub_arr_p) const +Chord::find_additions_and_subtractions (Array* add_arr_p, Array* sub_arr_p) const { Musical_pitch tonic = pitch_arr_[0]; /* - construct an array of triads for a normal chord + construct an array of thirds for a normal chord */ Array all_arr; all_arr.push (tonic); all_arr.push (pitch_arr_.top ()); - all_arr.concat (missing_triads_pitch_arr (&all_arr)); + all_arr.concat (missing_thirds_pitch_arr (&all_arr)); all_arr.sort (Musical_pitch::compare); int i = 0; @@ -295,7 +382,7 @@ Chord::find_additions_and_subtractions(Array* add_arr_p, Array* add_arr_p, Array 5)) + if (step_i (tonic, pitch_arr_.top () > 5)) 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" + */ String -Chord::banter_str (Musical_pitch* inversion) const +Chord::banter_str () const { Musical_pitch tonic = pitch_arr_[0]; @@ -335,97 +430,133 @@ Chord::banter_str (Musical_pitch* inversion) const // 7 always means 7-... // scale.push (Musical_pitch (6, -1)); // b - rebuild_transpose (tonic, &scale); + rebuild_transpose (&scale, tonic); bool has3m_b = false; bool has4_b = false; + bool has5m_b = false; String str; + String minor_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) + int step = step_i (tonic, p); + if (step == 4) has4_b = true; - int accidental = p.accidental_i_ - scale[(trap - 1) % 7].accidental_i_; - if ((trap == 3) && (accidental == -1)) + int accidental = p.accidental_i_ - scale[(step - 1) % 7].accidental_i_; + if ((step == 3) && (accidental == -1)) { - tonic_str += "m"; + minor_str = "m"; has3m_b = true; } + /* + have Cdim rather than Cm5-, even if it's a prefix + */ + else if ((step == 5) && (accidental == -1) && has3m_b) + { + minor_str = "dim"; + has5m_b = true; + } else if (accidental - || (!(trap % 2) || ((i + 1 == add_arr.size ()) && (trap > 5)))) + || (!(step % 2) || ((i + 1 == add_arr.size ()) && (step > 5)))) { str += sep_str; - if ((trap == 7) && (accidental == 1)) - str += "maj7"; - else + sep_str = "/"; + if ((step == 7) && (accidental == 1)) + { + str += "maj7"; + } + else { - str += to_str (trap); - if (accidental) - str += accidental < 0 ? "-" : "+"; + /* + 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 + sep_str = ""; + } + else + { + str += to_str (step); + 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); + 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 (!((trap == 3) && (has3m_b || has4_b))) + 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)) { - str += sep_str + "no" + to_str (trap); + 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) + if (inversion_p_) { - inversion_str = inversion->str (); + inversion_str = inversion_p_->str (); inversion_str = "/" + inversion_str.left_str (1).upper_str () - + acc[inversion->accidental_i_ + 2]; - + + acc[inversion_p_->accidental_i_ + 2]; } - return tonic_str + "$^{" + str + "}$" + inversion_str; -} + 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]; -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); + return tonic_str + minor_str + "$^{" + str + "}$" + inversion_str + bass_str; } int -Chord::find_tonic_i () const +Chord::find_tonic_i (Array 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; @@ -433,11 +564,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; } } @@ -448,11 +579,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; @@ -466,14 +597,14 @@ Chord::find_tonic_i () const } void -Chord::rebuild_from_base (int base_i) +Chord::rebuild_from_base (Array* pitch_arr_p, int base_i) { assert (base_i >= 0); Musical_pitch last (0, 0, -5); Array new_arr; - for (int i = 0; i < pitch_arr_.size (); i++) + 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_; @@ -483,43 +614,37 @@ 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* 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* 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); } diff --git a/lily/include/chord-name-engraver.hh b/lily/include/chord-name-engraver.hh index 779197f70d..4843fae8e9 100644 --- a/lily/include/chord-name-engraver.hh +++ b/lily/include/chord-name-engraver.hh @@ -31,6 +31,8 @@ private: Link_array text_p_arr_; Array rebuild_pitch_arr (int tonic_i) const; Tonic_req* tonic_req_; + Inversion_req* inversion_req_; + Bass_req* bass_req_; }; #endif // CHORD_NAME_ENGRAVER_HH diff --git a/lily/include/chord.hh b/lily/include/chord.hh index 9b38abbb41..871189fafc 100644 --- a/lily/include/chord.hh +++ b/lily/include/chord.hh @@ -16,20 +16,33 @@ class Chord { public: - Chord (Array pitch_arr); - Chord (Musical_pitch tonic, Array* add_arr_p, Array* sub_arr_p, Musical_pitch* inversion_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_with_bass (Array*, int bass_i); + static int step_i (Musical_pitch tonic, Musical_pitch p); - void rebuild_from_base (int base_i); - void rebuild_insert_inversion (int tonic_i); - void rebuild_with_bass (int bass_i); + Chord (Array pitch_arr, Musical_pitch* inversion_p, Musical_pitch* bass_p); + Chord (Chord const& chord); + ~Chord (); - 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 to_pitch_arr () const; + + String banter_str () const; void find_additions_and_subtractions(Array* add_arr_p, Array* sub_arr_p) const; Array pitch_arr_; + Musical_pitch* inversion_p_; + Musical_pitch* bass_p_; }; +Chord to_chord (Musical_pitch tonic, Array* add_arr_p, Array* sub_arr_p, Musical_pitch* inversion_p, Musical_pitch* bass_p); + +Chord to_chord (Array pitch_arr, Tonic_req* tonic_req, Inversion_req* inversion_req, Bass_req* bass_req, bool find_inversion_b); + #endif // CHORD_HH diff --git a/lily/include/lily-proto.hh b/lily/include/lily-proto.hh index 9e397a0ad2..8db92ce5c2 100644 --- a/lily/include/lily-proto.hh +++ b/lily/include/lily-proto.hh @@ -44,6 +44,7 @@ struct Bar_column_engraver; struct Bar_engraver; struct Bar_req; struct Barcheck_req; +struct Bass_req; struct Beam; struct Beam_engraver; struct Beaming_info; @@ -101,6 +102,7 @@ struct Head_column; struct Idealspacing; struct Identifier; struct Input_file; +struct Inversion_req; struct Item; struct Key; struct Key_change_req; diff --git a/lily/include/musical-request.hh b/lily/include/musical-request.hh index b64f5eb65d..963f6079fa 100644 --- a/lily/include/musical-request.hh +++ b/lily/include/musical-request.hh @@ -97,7 +97,19 @@ protected: /// specify tonic of a chord struct Tonic_req : public Melodic_req { - VIRTUAL_COPY_CONS(Music); + VIRTUAL_COPY_CONS (Music); +}; + +/// specify inversion of a chord +struct Inversion_req : public Melodic_req +{ + VIRTUAL_COPY_CONS (Music); +}; + +/// specify bass of a chord +struct Bass_req : public Melodic_req +{ + VIRTUAL_COPY_CONS (Music); }; /// Put a note of specified type, height, and with accidental on the staff. diff --git a/lily/include/my-lily-parser.hh b/lily/include/my-lily-parser.hh index 301eb358ee..01944e6e2d 100644 --- a/lily/include/my-lily-parser.hh +++ b/lily/include/my-lily-parser.hh @@ -67,7 +67,7 @@ private: String init_str_; Simultaneous_music * get_note_element (Note_req * ,Duration *); - Simultaneous_music * get_chord (Musical_pitch, Array*, Array*, Musical_pitch*, Duration); + Simultaneous_music * get_chord (Musical_pitch tonic, Array* add_arr_p, Array* sub_arr_p, Musical_pitch* inversion_p, Musical_pitch* bass_p, Duration d); Simultaneous_music* get_rest_element (String, Duration *); Simultaneous_music* get_word_element (String, Duration*); String notename_str (Melodic_req* melodic); diff --git a/lily/lexer.ll b/lily/lexer.ll index 7c09d492e9..83beb3eb8e 100644 --- a/lily/lexer.ll +++ b/lily/lexer.ll @@ -359,6 +359,12 @@ HYPHEN -- - { return CHORD_MINUS; } + : { + return CHORD_COLON; + } + \/\+ { + return CHORD_BASS; + } \^ { return CHORD_CARET; } diff --git a/lily/my-lily-parser.cc b/lily/my-lily-parser.cc index 11ae2eeda4..3444be3383 100644 --- a/lily/my-lily-parser.cc +++ b/lily/my-lily-parser.cc @@ -163,20 +163,37 @@ My_lily_parser::get_rest_element (String s, Duration * duration_p) // junk me Simultaneous_music * -My_lily_parser::get_chord (Musical_pitch tonic, Array* add_arr_p, Array* sub_arr_p, Musical_pitch* inversion_p, Duration d) +My_lily_parser::get_chord (Musical_pitch tonic, Array* add_arr_p, Array* sub_arr_p, Musical_pitch* inversion_p, Musical_pitch* bass_p, Duration d) { Simultaneous_music*v = new Request_chord; v->set_spot (here_input ()); - Chord chord (tonic, add_arr_p, sub_arr_p, inversion_p); + Chord chord = to_chord (tonic, add_arr_p, sub_arr_p, inversion_p, bass_p); Tonic_req* t = new Tonic_req; t->pitch_ = tonic; v->add_music (t); - for (int i = 0; i < chord.pitch_arr_.size (); i++) + //urg + if (inversion_p + && Chord::find_notename_i (&chord.pitch_arr_, *inversion_p) > 0) { - Musical_pitch p = chord.pitch_arr_[i]; + Inversion_req* i = new Inversion_req; + i->pitch_ = *inversion_p; + v->add_music (i); + } + + if (bass_p) + { + Bass_req* b = new Bass_req; + b->pitch_ = *bass_p; + v->add_music (b); + } + + Array pitch_arr = chord.to_pitch_arr (); + for (int i = 0; i < pitch_arr.size (); i++) + { + Musical_pitch p = pitch_arr[i]; Note_req* n = new Note_req; n->pitch_ = p; n->duration_ = d; diff --git a/lily/note-heads-engraver.cc b/lily/note-heads-engraver.cc index d23ee6e806..74168092d4 100644 --- a/lily/note-heads-engraver.cc +++ b/lily/note-heads-engraver.cc @@ -29,6 +29,14 @@ Note_heads_engraver::do_try_music (Music *m) { return true; } + else if (Inversion_req* i = dynamic_cast (m)) + { + return true; + } + else if (Bass_req* b = dynamic_cast (m)) + { + return true; + } else if (Busy_playing_req * p = dynamic_cast (m)) { return notes_end_pq_.size (); diff --git a/lily/parser.yy b/lily/parser.yy index f6c73ca83a..6c02b4967e 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -187,7 +187,8 @@ yylex (YYSTYPE *s, void * v_l) %token VERSION /* escaped */ -%token E_EXCLAMATION E_SMALLER E_BIGGER E_CHAR CHORD_MINUS CHORD_CARET +%token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER +%token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET %type exclamations questions %token DIGIT @@ -236,7 +237,7 @@ yylex (YYSTYPE *s, void * v_l) %type pitch_list %type chord %type chord_additions chord_subtractions chord_notes chord_step -%type chord_note chord_inversion +%type chord_note chord_inversion chord_bass %type midi_block midi_body %type duration_length @@ -1455,15 +1456,15 @@ simple_element: ; chord: - steno_tonic_pitch optional_notemode_duration chord_additions chord_subtractions chord_inversion { - $$ = THIS->get_chord (*$1, $3, $4, $5, *$2); + steno_tonic_pitch optional_notemode_duration chord_additions chord_subtractions chord_inversion chord_bass { + $$ = THIS->get_chord (*$1, $3, $4, $5, $6, *$2); }; chord_additions: { $$ = new Array; } - | CHORD_MINUS chord_notes { + | CHORD_COLON chord_notes { $$ = $2; } ; @@ -1493,7 +1494,18 @@ chord_inversion: $$ = 0; } | '/' steno_tonic_pitch { - $$ = $2 + $$ = $2; + $$->set_spot (THIS->here_input ()); + } + ; + +chord_bass: + { + $$ = 0; + } + | CHORD_BASS steno_tonic_pitch { + $$ = $2; + $$->set_spot (THIS->here_input ()); } ; diff --git a/ly/chord-modifiers.ly b/ly/chord-modifiers.ly index 48cc2f09f4..ef3942dd66 100644 --- a/ly/chord-modifiers.ly +++ b/ly/chord-modifiers.ly @@ -6,7 +6,9 @@ m = \musicalpitch { 0 2 -1 } min = \musicalpitch { 0 2 -1 } aug = \musicalpitch { 0 4 1 } - dim = \musicalpitch { 0 4 -1 } + % urg! + % dim = \musicalpitch { -100 4 -1 } + dim = \musicalpitch { -100 2 -1 } % urg, not actually a chord-modifier, but it works % c7 -> , c 7+ -> c b maj = \musicalpitch { 0 6 1 } -- 2.39.5