From dca1986050e88c5117fc88ff2855fb209c96a5b8 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Mon, 14 Dec 1998 22:55:48 +0100 Subject: [PATCH] patch::: 1.1.15.jcn1: pats pl 15.jcn1 - chord inversion: * enter C/E * display chord names according to boolean property \property Score.chordInversion; --- NEWS | 6 +++ TODO | 1 - VERSION | 2 +- init/property.ly | 4 +- input/test/chord-inversion.ly | 19 ++++++++ input/test/sleur.ly | 2 +- lily/chord-name-engraver.cc | 79 +++++++++++++++++++++++++++++++++- lily/include/my-lily-parser.hh | 2 +- lily/my-lily-parser.cc | 65 +++++++++++++++++++++------- lily/parser.yy | 28 +++++++++--- 10 files changed, 180 insertions(+), 28 deletions(-) create mode 100644 input/test/chord-inversion.ly diff --git a/NEWS b/NEWS index c4bbcd3efc..78915caecc 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +pl 15.jcn1 + - chord inversion: + * enter C/E + * display chord names according to boolean property + \property Score.chordInversion; + pl 15 pl 14.hwn1 diff --git a/TODO b/TODO index cbc7bc7157..16fe362e57 100644 --- a/TODO +++ b/TODO @@ -395,7 +395,6 @@ PROJECTS .. ? * chords - - jazz style inversions C/E => - guitar chords (fret diagrams) - other chord name styles (american(?) style) - basso continuo diff --git a/VERSION b/VERSION index 688692906a..13674bdc40 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=1 PATCH_LEVEL=15 -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/init/property.ly b/init/property.ly index 3d09808157..0c8cbb637b 100644 --- a/init/property.ly +++ b/init/property.ly @@ -57,10 +57,12 @@ timeSignatureStyle Cn/m Set symbol explicitly, n/m=2/2 or 4/4 timeSignatureStyle oldn/m Set symbol explicitly, n/m=2/2,3/2,3/4,4/4,6/4 or 9/4. - [Staff?] instrument ascii midi instrument table lookup +[Score] +chordInversion 0/1 Find and display chord with inversion? + 1) after beam slope damping table suggested in [Wanske] 2) [Wanske] as well as [Ross] suggests that beams sloped upward must not diff --git a/input/test/chord-inversion.ly b/input/test/chord-inversion.ly new file mode 100644 index 0000000000..686463e19f --- /dev/null +++ b/input/test/chord-inversion.ly @@ -0,0 +1,19 @@ +\header{ +enteredby = "jcn"; +copyright = "public domain"; +TestedFeatures = "chord inversions"; +} + +inversions = \notes\transpose c''\chords{ + c1 c-sus c-6 c/e c/g c/d + % now try to find chords with inversions + \property Score.chordInversion = 1 + c1 c-sus c-6 c/e c/g c/d +} + +\score{ + < + \type ChordNames \inversions + \type Staff \inversions + > +} diff --git a/input/test/sleur.ly b/input/test/sleur.ly index 112d7cc2c9..0f0490c502 100644 --- a/input/test/sleur.ly +++ b/input/test/sleur.ly @@ -1,6 +1,6 @@ \header{ enteredby = "jcn"; -copyright = "PD"; +copyright = "public domain"; TestedFeatures = "This file tests Feta embedded slurs" + "(Feta definitively is not an abbreviation of Font-En-TjA)"; } diff --git a/lily/chord-name-engraver.cc b/lily/chord-name-engraver.cc index 46bee3b37c..b9d87032e1 100644 --- a/lily/chord-name-engraver.cc +++ b/lily/chord-name-engraver.cc @@ -52,7 +52,6 @@ Chord_name_engraver::do_process_requests () TODO: - move this stuff to new Item class Chord_name - switch on property, add american (?) chordNameStyle - - jazz inversions Scalar chordNameStyle = get_property ("chordNameStyle"); if (chordNameStyle == "Banter") @@ -69,6 +68,73 @@ Chord_name_engraver::do_process_requests () if (alignment.isnum_b()) text_p->align_dir_= (Direction)(int)alignment; + + /* + find tonic: after longest line of triads + */ + + int tonic_i = 0; + Scalar chord_inversions = get_property ("chordInversion"); + if (chord_inversions.to_bool ()) + { + int longest_i = 0; + for (int i = 0; i < pitch_arr_.size (); i++) + for (int j = 0; j < pitch_arr_.size (); j++) + { + int gap = pitch_arr_[(i + j + 1) % pitch_arr_.size ()].notename_i_ + - pitch_arr_[(i + j) % pitch_arr_.size ()].notename_i_; + while (gap < 0) + gap += 7; + gap %= 7; + if (gap != 2) + { + if (j > longest_i) + { + longest_i = j; + tonic_i = i; + } + break; + } + } + + int biggest_i = 0; + if (!longest_i) + for (int i = 0; i < pitch_arr_.size (); i++) + { + int gap = pitch_arr_[i].notename_i_ + - pitch_arr_[(i - 1 + pitch_arr_.size ()) + % pitch_arr_.size ()].notename_i_; + while (gap < 0) + gap += 7; + gap %= 7; + if (gap > biggest_i) + { + biggest_i = gap; + tonic_i = i; + } + } + } + + Musical_pitch inversion = pitch_arr_[0]; + if (tonic_i) + { + Musical_pitch last (0, 0, -5); + Array pitches; + for (int i = 0; i < pitch_arr_.size (); i++) + { + Musical_pitch p = pitch_arr_[(tonic_i + i) % pitch_arr_.size ()]; + if (p < last) + { + p.octave_i_ = last.octave_i_; + if (p < last) + p.octave_i_++; + } + pitches.push (p); + last = p; + } + pitch_arr_ = pitches; + } + Musical_pitch tonic = pitch_arr_[0]; Array scale; @@ -81,6 +147,7 @@ Chord_name_engraver::do_process_requests () // 7 always means 7-... scale.push (Musical_pitch (6, -1)); // b + for (int i = 0; i < scale.size (); i++) scale[i].transpose (tonic); @@ -115,7 +182,15 @@ Chord_name_engraver::do_process_requests () } } - text_p->text_str_ = tonic_str + "$^{" + add_str + "}$"; + String inversion_str; + if (tonic_i) + { + inversion_str = inversion.str (); + inversion_str = "/" + inversion_str.left_str (1).upper_str () + + acc[tonic.accidental_i_ + 2]; + + } + text_p->text_str_ = tonic_str + "$^{" + add_str + "}$" + inversion_str; Text_item* item_p = new Text_item (text_p); item_p->dir_ = DOWN; item_p->fat_b_ = true; diff --git a/lily/include/my-lily-parser.hh b/lily/include/my-lily-parser.hh index 5dcb4ef38f..918e61d0e0 100644 --- a/lily/include/my-lily-parser.hh +++ b/lily/include/my-lily-parser.hh @@ -68,7 +68,7 @@ private: void add_requests (Simultaneous_music*v); Simultaneous_music * get_note_element (Note_req * ,Duration *); - Simultaneous_music * get_chord (Musical_pitch, Array*, Array*, Duration); + Simultaneous_music * get_chord (Musical_pitch, Array*, Array*, Musical_pitch*, Duration); Simultaneous_music* get_rest_element (String, Duration *); Simultaneous_music* get_word_element (String, Duration*); Melodic_req* get_melodic_req (Melodic_req* melodic, int quotes); diff --git a/lily/my-lily-parser.cc b/lily/my-lily-parser.cc index 88a05f6985..5dbe0e69c2 100644 --- a/lily/my-lily-parser.cc +++ b/lily/my-lily-parser.cc @@ -153,16 +153,11 @@ My_lily_parser::get_rest_element (String s, Duration * duration_p) } Simultaneous_music * -My_lily_parser::get_chord (Musical_pitch tonic, Array* add_arr_p, Array* sub_arr_p, Duration d) +My_lily_parser::get_chord (Musical_pitch tonic, Array* add_arr_p, Array* sub_arr_p, Musical_pitch* inversion_p, Duration d) { Simultaneous_music*v = new Request_chord; v->set_spot (here_input ()); - Note_req* n = new Note_req; - n->pitch_ = tonic; - n->duration_ = d; - v->add_music (n); - for (int i = 0; i < add_arr_p->size (); i++) { Musical_pitch p = tonic; @@ -253,26 +248,64 @@ My_lily_parser::get_chord (Musical_pitch tonic, Array* add_arr_p, i++; } + /* + add tonic + */ + if (!add_arr_p->size () || ((*add_arr_p)[0] != tonic)) + add_arr_p->insert (tonic, 0); + + 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]; - Note_req* n = new Note_req; - n->pitch_ = p; - n->duration_ = d; - for (int j = 0; j < sub_arr_p->size (); j++) + int j = 0; + for (; j < sub_arr_p->size (); j++) + if (p == (*sub_arr_p)[j]) + break; + if (j == sub_arr_p->size ()) + pitch_arr.push (p); + } + + if (inversion_p) + { + int i = 0; + for (; i < pitch_arr.size (); i++) + if ((pitch_arr[i].notename_i_ == inversion_p->notename_i_) + && (pitch_arr[i].accidental_i_ == inversion_p->accidental_i_)) + break; + if (i == pitch_arr.size ()) + warning (_ ("invalid inversion pitch (not part of chord)")); + else { - if (p == (*sub_arr_p)[j]) + Array pitches; + Musical_pitch last (0, 0, -5); + for (int j = 0; j < pitch_arr.size (); j++) { - delete n; - n = 0; - break; + Musical_pitch p = pitch_arr[(j + i) % pitch_arr.size ()]; + if (p < last) + { + p.octave_i_ = last.octave_i_; + if (p < last) + p.octave_i_++; + } + pitches.push (p); + last = p; } + pitch_arr = pitches; } - if (n) - v->add_music (n); + delete inversion_p; + } + + 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; + v->add_music (n); } v->set_spot (here_input ()); diff --git a/lily/parser.yy b/lily/parser.yy index d41a1e499d..202adcfcc2 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -251,7 +251,7 @@ yylex (YYSTYPE *s, void * v_l) %type pitch_list %type chord notemode_chord %type chord_additions chord_subtractions -%type chord_addsub chord_note +%type chord_addsub chord_note chord_inversion notemode_chord_inversion %type midi_block midi_body %type duration_length @@ -1407,13 +1407,13 @@ simple_element: ; chord: - steno_tonic_pitch notemode_duration chord_additions chord_subtractions { - $$ = THIS->get_chord (*$1, $3, $4, *$2); + steno_tonic_pitch notemode_duration chord_additions chord_subtractions chord_inversion { + $$ = THIS->get_chord (*$1, $3, $4, $5, *$2); }; notemode_chord: - steno_musical_pitch notemode_duration chord_additions chord_subtractions { - $$ = THIS->get_chord (*$1, $3, $4, *$2); + steno_musical_pitch notemode_duration chord_additions chord_subtractions notemode_chord_inversion { + $$ = THIS->get_chord (*$1, $3, $4, $5, *$2); }; chord_additions: @@ -1434,6 +1434,24 @@ chord_addsub: | CHORDMODIFIER_PITCH optional_dot ; +chord_inversion: + { + $$ = 0; + } + | '/' steno_tonic_pitch { + $$ = $2 + } + ; + +notemode_chord_inversion: + { + $$ = 0; + } + | '/' steno_musical_pitch { + $$ = $2 + } + ; + chord_note: UNSIGNED { $$ = new Musical_pitch; -- 2.39.5